脚本说明

这是专门为本地调试与远程答题准备的脚本,依靠命令行参数进行控制。

本脚本支持的功能有:

  • 本地调试

    • 开启tmux调试
    • 设置gdb断点,支持函数名断点地址断点文件名:行号断点$rebase(0x00)断点
    • 设置gdb script,可以设置任何内置的gdb命令
  • 远程答题
    • 默认支持buuctf上解题的主机,只需要指定远程port
    • 显式指定远程ipport
  • 可使用装饰器函数、偏函数
    • 在执行函数前、后线程休眠指定秒数
    • 记录函数执行日志
    • int16解析16进制字符串为整数
  • 可自由定制
    • 依托click模块,可以自行定制更多功能

脚本内容

#!/usr/bin/python3
# -*- encoding: utf-8 -*- # @File : do_pwn_template.py
# @Time : 2021/04/02 21:15:43
# @Author : Roderick Chan
# @Email : ch22166@163.com
# @Desc : pwn题本地调试、远程攻击脚本 '''
==========================================================================================
本脚本为pwn题所编写,利用click模块配置命令行参数,
能方便地进行本地调试和远程解题。
本地命令示例:
python3 exp.py filename --tmux 1 --gdb-breakpoint 0x804802a --gdb-breakpoint printf
python3 exp.py filename -t 1 -gb 0x804802a -gb printf
python3 exp.py filename -t 1 -gs "x /12gx \$rebase(0x202080)" -sf 0 -pl "warn"
即可开始本地调试,并且会断在地址或函数处。先启动tmux后,--tmux才会有效。 远程命令示例:
python3 exp.py filename -i 127.0.0.1 -p 22164
python3 exp.py filename -p 22164
可以连接指定的IP和端口。目前在刷buuctf上的题,所以填了默认ip,只指定端口即可。 ==========================================================================================
''' from pwn import *
from LibcSearcher import LibcSearcher
import click
import sys
import os
import time
import functools print(__doc__) FILENAME = '#' # 要执行的文件名
DEBUG = 1 # 是否为调试模式
TMUX = 0 # 是否开启TMUX
GDB_BREAKPOINT = None # 当tmux开启的时候,断点的设置
GDB_SCRIPT = None # 当tmux开启的时候, gdb_script的设置,可以是任意有效的语句
IP = None # 远程连接的IP
PORT = None # 远程连接的端口
LOCAL_LOG = 1 # 本地LOG是否开启
PWN_LOG_LEVEL = 'debug' # pwntools的log级别设置
STOP_FUNCTION = 1 # STOP方法是否开启 CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) @click.command(context_settings=CONTEXT_SETTINGS, short_help='Do pwn!')
@click.argument('filename', nargs=1, type=str, required=0, default=None)
@click.option('-d', '--debug', default=True, type=bool, nargs=1, help='Excute program at local env or remote env. Default value: True.')
@click.option('-t', '--tmux', default=False, type=bool, nargs=1, help='Excute program at tmux or not. Default value: False.')
@click.option('-gb', '--gdb-breakpoint', default=[], type=str, multiple=True, help="Set a gdb breakpoint while tmux is enabled, is a hex address or '\$rebase' addr or a function name. Multiple setting supported. Default value:'[]'")
@click.option('-gs', '--gdb-script', default=None, type=str, help="Set a gdb script while tmux is enabled, the script will be passed to gdb and use '\\n' or ';' to split lines. Default value:None")
@click.option('-i', '--ip', default=None, type=str, nargs=1, help='The remote ip addr. Default value: None.')
@click.option('-p', '--port', default=None, type=int, nargs=1, help='The remote port. Default value: None.')
@click.option('-ll', '--local-log', default=True, type=bool, nargs=1, help='Set local log enabled or not. Default value: True.')
@click.option('-pl', '--pwn-log', type=click.Choice(['debug', 'info', 'warn', 'error', 'notset']), nargs=1, default='debug', help='Set pwntools log level. Default value: debug.')
@click.option('-sf', '--stop-function', default=True, type=bool, nargs=1, help='Set stop function enabled or not. Default value: True.')
def parse_command_args(filename, debug, tmux, gdb_breakpoint, gdb_script,
ip, port, local_log, pwn_log, stop_function):
'''FILENAME: The filename of current directory to pwn'''
global FILENAME, DEBUG, TMUX, GDB_BREAKPOINT, GDB_SCRIPT, IP, PORT, LOCAL_LOG, PWN_LOG_LEVEL, STOP_FUNCTION
# assign
FILENAME = filename
DEBUG = debug
TMUX = tmux
GDB_BREAKPOINT = gdb_breakpoint
GDB_SCRIPT = gdb_script
IP = ip
PORT = port
LOCAL_LOG = local_log
PWN_LOG_LEVEL = pwn_log
STOP_FUNCTION = stop_function # change
if PORT: # 远程下这些是需要关闭的
DEBUG = 0
TMUX = 0
STOP_FUNCTION = 0
GDB_BREAKPOINT = None
GDB_SCRIPT = None
if IP is None:
IP = 'node3.buuoj.cn' if DEBUG:
IP = None
PORT = None # assert
assert not (FILENAME is None and PORT is None), 'para error'
assert not (FILENAME is None and DEBUG == 1), 'para error'
assert not (PORT is not None and DEBUG == 1), 'para error'
assert not (DEBUG == 0 and TMUX == 1), 'para error' # print
click.echo('=' * 50)
click.echo(' [+] Args info:\n')
if FILENAME:
click.echo(' filename: %s' % FILENAME)
click.echo(' debug enabled: %d' % DEBUG)
click.echo(' tmux enabled: %d' % TMUX)
if GDB_BREAKPOINT:
click.echo(' gdb breakpoint: %s' % GDB_BREAKPOINT)
if IP:
click.echo(' remote ip: %s' % IP)
if PORT:
click.echo(' remote port: %d' % PORT)
click.echo(' local log enabled: %d' % LOCAL_LOG)
click.echo(' pwn log_level: %s' % PWN_LOG_LEVEL)
click.echo(' stop function enabled: %d' % STOP_FUNCTION)
click.echo('=' * 50) parse_command_args.main(standalone_mode=False) # 退出条件,只要参数有 -h 或 --help就退出
if len(sys.argv) > 1:
for arg in sys.argv:
if '-h' == arg or '--help' == arg:
sys.exit(0) if DEBUG:
io = process('{}'.format(FILENAME))
else:
io = remote(IP, PORT) if TMUX:
context.update(terminal=['tmux', 'splitw', '-h'])
tmp_all_gdb = ""
if GDB_BREAKPOINT is not None or len(GDB_BREAKPOINT) > 0:
# 解析每一条gdb-breakpoint
for gb in GDB_BREAKPOINT:
if gb.startswith('0x') or gb.startswith('$rebase('):
tmp_all_gdb += "b *{}\n".format(gb) # 带上*
else: # 传入函数
tmp_all_gdb += "b {}\n".format(gb) # 不带*
if GDB_SCRIPT is not None:
tmp_all_gdb += GDB_SCRIPT.replace("\\n", "\n").replace(";", "\n") + "\n"
tmp_all_gdb += "c\n"
gdb.attach(io, gdbscript=tmp_all_gdb) if FILENAME:
cur_elf = ELF('{}'.format(FILENAME))
print('[+] libc used ===> {}'.format(cur_elf.libc)) def LOG_ADDR(addr_name:str, addr:int):
if LOCAL_LOG:
log.success("{} ===> {}".format(addr_name, hex(addr)))
else:
pass def LOG_ADDR_EX(addr_name:str):
'''
存储地址的变量名,字符串
如:a = 0xdeadbeef
调用: LOG_ADDR_EX('a') '''
if LOCAL_LOG:
# 利用eval函数, 首先检索一下
if addr_name in globals() or addr_name in vars():
tmp_var = eval(addr_name)
log.success("{} ===> {}".format(addr_name, hex(tmp_var)))
else:
log.warn("No variable named: '" + addr_name + "'")
else:
pass def STOP():
if not STOP_FUNCTION:
return
print("stop...{} {}".format(sys._getframe().f_lineno, proc.pidof(io)))
pause() ############### 定义一些偏函数 ################### int16 = functools.partial(int, base=16) #################### END ######################## ############### 定义一些装饰器函数 ############### def time_count(func):
'''
装饰器:统计函数运行时间
'''
@functools.wraps(func)
def wrapper(*args, **kwargs):
print('=' * 50)
print('function #{}# start...'.format(func.__name__))
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print('function #{}# end...execute time: {} s / {} min'.format(func.__name__, end - start, (end - start) / 60))
return res
return wrapper def sleep_call(second:int=1, mod:int=1):
"""
装饰器:在调用函数前后线程先睡眠指定秒数 Args:
second: 休眠秒数
mod: 0 不休眠; 1 为调用前休眠; 2 为调用后休眠; 3 为前后均修眠
"""
if mod > 3 or mod < 0:
mod = 1
def wrapper1(func):
@functools.wraps(func)
def wrapper2(*args, **kwargs):
if mod & 1:
time.sleep(second)
res = func(*args, **kwargs)
if mod & 2:
time.sleep(second)
return res
return wrapper2
return wrapper1 #################### END ######################## context.update(log_level=PWN_LOG_LEVEL) # 一般需要带上文件,可注释改行语句
assert FILENAME is not None, 'give me a file!'
##################################################
##############以下为攻击代码#######################
##################################################

使用

使用详情基本在注释里面写得很清楚了,这里展示一下输入python exp.py -h后显示的帮助信息:

笔记本屏幕有点小······

以下为全部显示内容:

==========================================================================================
本脚本为pwn题所编写,利用click模块配置命令行参数,
能方便地进行本地调试和远程解题。
本地命令示例:
python3 exp.py filename --tmux 1 --gdb-breakpoint 0x804802a --gdb-breakpoint printf
python3 exp.py filename -t 1 -gb 0x804802a -gb printf
python3 exp.py filename -t 1 -gs "x /12gx $rebase(0x202080)" -sf 0 -pl "warn"
即可开始本地调试,并且会断在地址或函数处。先启动tmux后,--tmux才会有效。 远程命令示例:
python3 exp.py filename -i 127.0.0.1 -p 22164
python3 exp.py filename -p 22164
可以连接指定的IP和端口。目前在刷buuctf上的题,所以填了默认ip,只指定端口即可。 ========================================================================================== Usage: do_pwn_template.py [OPTIONS] [FILENAME] FILENAME: The filename of current directory to pwn Options:
-d, --debug BOOLEAN Excute program at local env or remote env.
Default value: True. -t, --tmux BOOLEAN Excute program at tmux or not. Default
value: False. -gb, --gdb-breakpoint TEXT Set a gdb breakpoint while tmux is enabled,
is a hex address or '$rebase' addr or a
function name. Multiple setting supported.
Default value:'[]' -gs, --gdb-script TEXT Set a gdb script while tmux is enabled, the
script will be passed to gdb and cannot be
identified with gdb-breakpoint
simultaneously. Default value:None -i, --ip TEXT The remote ip addr. Default value: None.
-p, --port INTEGER The remote port. Default value: None.
-ll, --local-log BOOLEAN Set local log enabled or not. Default value:
True. -pl, --pwn-log [debug|info|warn|error|notset]
Set pwntools log level. Default value:
debug. -sf, --stop-function BOOLEAN Set stop function enabled or not. Default
value: True. -h, --help Show this message and exit.

使用示例

本地调试:

输入:python3 exp.py ./ycb_2020_babypwn -t 1 -gs "b malloc\nb free"



自动下断点mallocfree

输入:python3 exp.py ./ycb_2020_babypwn -t 1 -gb "\$rebase(0xc1f)",这里要加上转义字符,否会失败。



同样命中断点!

远程攻击:

输入:python3 exp.py ./ycb_2020_babypwn -i "127.0.0.1" -p 6666

参考与引用

pwn题命令行解题脚本的更多相关文章

  1. Linux Shell远程执行命令(命令行与脚本方式)

    需求:经常需要在一台服务器远程到其他节点的服务器上执行一些shell命令,如果分别ssh到每台主机上再去执行很麻烦,因此能有个集中管理的方式就好了.介绍两种shell命令远程执行的方法. 方式一: s ...

  2. Linux命令行与脚本编程大全第一章

    1, 2,linux内核:内存管理.进程管理.文件管理.设备管理. 其中内存管理如下图: 通过命令 cat/proc/meminfo查看系统的内存状态.通过ipcs查看共享内存.信号量.消息队列信息. ...

  3. MySQL命令行SQL脚本的导入导出小结(数据库的备份与还原)

    1.设置环境变量 要想在命令行下各处都能执行mysql命令,必须在系统变量Path中添加mysql的命令所在的目录.例如我安装的是集成PHP环境的mysql,在D盘xampps下,则我需要将" ...

  4. MySQL命令行导入脚本文件

    通过命令行执行sql脚本文件的方法: cmd命令行下: C:\users\test_dir>"C:\Program Files\MySQL\MySQL Server 5.7\bin\m ...

  5. jmeter命令行执行脚本_动态参数设置

    从04月换公司开始,就没静下来心来学习,其中发生了比较多的事情吧,不过不管如何,没坚持学习还是因为懒.本周交接完,下周去入职新公司,该静下心来学点什么了. ---------------------- ...

  6. 【jmeter】无GUI界面,命令行运行测试脚本

    一.应用场景 1.无需交互界面或受环境限制(linux text model) 2.远程或分布式执行 3.持续集成,通过shell脚本或批处理命令均可执行,生成的测试结果可被报表生成模块直接使用,便于 ...

  7. Jmeter:非 GUI 命令行执行脚本文件

    介绍 进行性能测试时,Jmeter 官方文档声明是不建议在 GUI 执行的,此时需要用到命令行. 第一步:环境配置 把 Jmeter安装目录\bin 添加到 系统环境变量path 第二步:命令参数 - ...

  8. Laravel5 (cli)命令行执行脚本及定时任务

    Artisan是Laravel自带的命令行接口名称,它提供了很多有用的命令想要查看所有可用的Artisan命令,可使用list命令查看: 1 php artisan list 每个命令都可以用help ...

  9. 按shift键调出命令行的脚本

    打开Notepad++,粘贴以下命令,并将文件命名为opencmdhere.reg(注意:文件编码格式为UCS-2 Little Endian,否则会导致中文乱码),再双击打开即可 Windows R ...

随机推荐

  1. MDN Browser Compatibility Report 2020

    MDN Browser Compatibility Report 2020 top pain point https://mdn-web-dna.s3-us-west-2.amazonaws.com/ ...

  2. taro 禁用滚动事件

    taro 禁用滚动事件 禁止 Modal 蒙层下面的页面的内容跟随滚动 https://github.com/NervJS/taro/issues/3980 https://github.com/Ne ...

  3. 2020 新型肺炎病毒疫情 & 远程办公

    2020 新型肺炎病毒疫情 & 远程办公 2020 新型肺炎病毒疫情 https://zhuanlan.zhihu.com/p/104406687 钉钉 微信 code gitlab PRD ...

  4. ffmpeg concat设置绝对路径

    https://superuser.com/questions/718027/ffmpeg-concat-doesnt-work-with-absolute-path/1551017#1551017 ...

  5. 一文助你了解NGK商城

    按照NGK的发展逻辑,将会在2021年上半年上线链商商城,解决传统消费行业真伪难辨的弊端,之后,将会推出小额支付功能,让NGK真正成为结算中的数字资产,目前两者落地性应用已经在开发内测阶段中,期初的部 ...

  6. 09、IO流—File类与IO流

    目录 一.File类 基本认识 实用方法 获取功能 重命名功能(包含剪切) 判断功能 创建.删除文件 实际小案例 二.IO流 1.认识IO流 2.IO流基类介绍 字节流基类介绍 字符流基类介绍 三.节 ...

  7. Warning: Cannot update during an existing state transition (such as within `render`). Render 报错

    原来 修改(不用在构造函数里面定义)

  8. 微信小程序:如何实现两个按钮在最右侧并排

    要实现的效果: wxml端代码: <view  class="prepare_param">                         <view clas ...

  9. SpringBoot解决特殊符号 []报400问题

    当遇到特殊符号传递给后台时,如果不加处理,就会报400的错误,解决办法有两种. 1.前台解决 前台解决的方法就是把这些特殊符号转义,转义之后浏览器和后台都可以识别. //对特殊字符进行转义 encod ...

  10. 按照阿里巴巴规范创建Java线程池

    前言 Executors Executors 是一个Java中的工具类.提供工厂方法来创建不同类型的线程池. 常用方法: 1.newSingleThreadExecutor   介绍:创建一个单线程的 ...