二进制安全:PWN:pwntools工具的用法

pwntools是一个CTF框架和开发库。它是用Python编写的,是为快速原型设计和开发而设计的,旨在使利用漏洞的编写尽可能简单。

Pwntools模块:

asm :汇编与反汇编
dynelf:远程符号泄露
elf: elf文件操作
gdb:启用gdb调试

from pwn import
This imports a lot of functionality into the global namespace. You can now assemble, disassemble, pack, unpack, and many other things with a single function.
A full list of everything that is imported is available on from pwn import *

Making Connections 尝试连接

You need to talk to the challenge binary in order to pwn it ,right?
pwntools makes this stupid simple with its pwnlib.tubes module.
为了我们和底层进行交互,我们会用到pwnlib.tubes 模块

This exposes a standard interface to talk to processes, sockets, serial ports, and all manner of things, along with some nifty helpers for common tasks. For example, remote connections via
这是公开了一个标准接口,用于与进程、套接字、串行端口和各种各样的东西进行通信,以及一些用于常见任务的漂亮助手。例如,通过

当然也很容易监听:

>>> conn = remote('ftp.ubuntu.com',21)
>>> conn.recvline() # doctest: +ELLIPSIS
b'220 ...'
>>> conn.send(b'USER anonymous\r\n')
>>> conn.recvuntil(b' ', drop=True)
b'331'
>>> conn.recvline()
b'Please specify the password.\r\n'
>>> conn.close()

当然也很容易监听:

>>> l = listen()
>>> r = remote('localhost', l.lport)
>>> c = l.wait_for_connection()
>>> r.send(b'hello')
>>> c.recv()
b'hello'
Interacting with processes is easy thanks to 多亏了pwnlib.tubes.process.
>>> sh = process('/bin/sh')
>>> sh.sendline(b'sleep 3; echo hello world;')
>>> sh.recvline(timeout=1)
b''
>>> sh.recvline(timeout=5)
b'hello world\n'
>>> sh.close()

不仅可以通过编程方式与流程交互,还可以实际与流程交互。

>>> sh.interactive() # doctest: +SKIP
$ whoami
linux 

甚至还有一个ssh模块,当你使用ssh连接到本地执行/setuid攻击时候,可以使用它的
pwnlib.tubes.ssh文件,你可以迅速生成进程并获取输出,或者生成一个进程管一样与之交互(process tube)。

pwnlib.tubes.ssh文件,你可以迅速生成进程并获取输出,或者生成一个进程管一样与之交互(process tube)。
>>> shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
>>> shell['whoami']
b'bandit0'
>>> shell.download_file('/etc/motd')
>>> sh = shell.run('sh')
>>> sh.sendline(b'sleep 3; echo hello world;') 
>>> sh.recvline(timeout=1)
b''
>>> sh.recvline(timeout=5)
b'hello world\n'
>>> shell.close()

Packing Integers(包装整数)

利用漏洞写入的一个常见任务是在Python所看到的整数和以字节序列表示的整数之间进行转换。通常人们求助于内置的struct模块。
No more remembering unpacking codes, and littering your code with helper routines.
pwntools能使用pwnlib.util.packing更简单。不需要记住太多的解包代码,也不许要使用助手历程乱扔代码。

>>> import struct
>>> p32(0xdeadbeef) == struct.pack('I', 0xdeadbeef)
True
>>> leet = unhex('37130000')
>>> u32(b'abcd') == struct.unpack('I', b'abcd')[0]
True
打包/解包操作是为了许多常见的位宽定义的。
>>> u8(b'A') == 0x41
True

Setting the Target Architecture and OS 设置目标体系结构和操作系统

The target architecture can generally be specified as an argument to the routine that requires it.
目标体系结构通常可以指定为需要它的例程的参数.

>>> asm('nop')
b'\x90'
>>> asm('nop', arch='arm')
b'\x00\xf0 \xe3'

However, it can also be set once in the global context. The operating system, word size, and endianness can also be set here.
但是,也可以在全局上下文中设置一次。操作系统、字号和结尾也可以在这里设置。

>>> context.arch      = 'i386'
>>> context.os        = 'linux'
>>> context.endian    = 'little'
>>> context.word_size = 32
此外,您可以使用速记一次设置所有值。
>>> asm('nop')
b'\x90'
>>> context(arch='arm', os='linux', endian='big', word_size=32)
>>> asm('nop')
b'\xe3 \xf0\x00'

Setting Logging Verbosity设置日志详细信息

You can control the verbosity of the standard pwntools logging via您可以通过以下方式控制标准pwntools日志的详细程度:
For example setting:

>>> context.log_level = 'debug'

Will cause all of the data sent and received by a tube to be printed to the screen.

Assembly and Disassembly组装和拆卸

Never again will you need to run some already-assembled pile of shellcode from the internet!
你再也不需要从互联网上运行一些已经编译好的shellcode了(already-assembled pile)
The pwnlib.asm module is full of awesome.

>>> enhex(asm('mov eax, 0'))
'b800000000'

But if you do, it’s easy to suss out!

>>> print(disasm(unhex('6a0258cd80ebf9')))
   0:   6a 02                   push   0x2
   2:   58                      pop    eax
   3:   cd 80                   int    0x80
   5:   eb f9                   jmp    0x0

However, you shouldn’t even need to write your own shellcode most of the time! pwntools comes with the pwnlib.shellcraft module, which is loaded with useful time-saving shellcodes.
但是,你不需要花大多时间编间写你自己的shellcode代码,pwntools自带的pwnlib模块,其实夹在了有用的省时的shellcode

Let’s say that we want to setreuid(getuid(), getuid()) followed by duping file descriptor 4 tostdin, stdout, and stderr, and then pop a shell!
假设我们要设置reuid(getuid(),getuid()),然后将文件描述符4复制到stdin、stdout和stderr,然后弹出一个shell!

>>> enhex(asm(shellcraft.setreuid() + shellcraft.dupsh(4))) # doctest: +ELLIPSIS
'6a3158cd80...'

Misc Tools 杂项工具

不需要写了,多亏了pwnlib.util.fiddling.
Find offsets in your buffer that cause a crash.在缓冲区中查找导致崩溃的偏移量

>>> print(cyclic(20).decode())
aaaabaaacaaadaaaeaaa
>>> # Assume EIP = 0x62616166 (b'faab' which is pack(0x62616166))  at crash time
>>> print(cyclic_find(b'faab'))
120

ELF Manipulation (ELF操作)

不需要写太多的代码了,在运行时使用,pwnlib.elf

>>> e = ELF('/bin/cat')
>>> print(hex(e.address)) #doctest: +SKIP
0x400000
>>> print(hex(e.symbols['write'])) #doctest: +SKIP
0x401680
>>> print(hex(e.got['write'])) #doctest: +SKIP
0x60b070
>>> print(hex(e.plt['write'])) #doctest: +SKIP
0x401680
You can even patch and save the files.
>>> e = ELF('/bin/cat')
>>> e.read(e.address, 4)
b'\x7fELF'
>>> e.asm(e.address, 'ret')
>>> e.save('/tmp/quiet-cat')
>>> disasm(open('/tmp/quiet-cat','rb').read(1))
'   0:   c3                      ret'
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT鹅

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值