网络安全介绍、CTFpwn基础:gdb工具命令

2024-08-24 88 0

一、概念以及背景:

首先厘清概念:什么是栈溢出?什么是pwn?什么是网络安全?

大多数人首先是遇到网络安全问题、工作需要才遇到这些,而不是自然而然地从学校了解,即便在校学生,当初也不都是出于自己的意愿选择了网络安全相关专业,所以我们先从问题出发,分别了解这些名词。

什么是网络安全?!

2017年5月12日起,全球范围内爆发基于Windows网络共享协议进行攻击传播的蠕虫恶意代码,这是不法分子通过改造之前泄露的NSA黑客武器库中“永恒之蓝”攻击程序发起的网络攻击事件。五个小时内,包括英国、俄罗斯、整个欧洲以及中国国内多个高校校内网、大型企业内网和政府机构专网中招,被勒索支付高额赎金才能解密恢复文件,对重要数据造成严重损失。[1]首先我们能从中确认,没有网络安全就会在遇到网络有关的问题时,出现不可挽回的经济损失;从事件影响里能看到多国的相关单位包括政府、银行、电力系统、通讯系统、能源企业、机场等重要基础设施都被波及,律师事务所DLA Piper的多个美国办事处也受到影响。中国亦有跨境企业的欧洲分部中招。

2024年7·19微软蓝屏事件是指当地时间2024年7月19日美国网络安全企业“群集打击”(CrowdStrike)软件出现问题引发的操作系统蓝屏、全球宕机事件 。此次微软蓝屏波及不少国家地区,影响全球近千万台使用Windows的设备,导致航空公司、银行、电信公司和媒体、健康医疗等各个行业陷入混乱 。“微软蓝屏”登上热搜,不少打工人晒出电脑蓝屏画面,戏称“感谢微软,提前放假”[2]。从事件结果我们了解到该事件已经造成了全球性的影响:多国石油、天然气、电力、股票、货币和债券交易商都在19日当天难以正常展开交易。运营伦敦证券交易所的LSEG集团表示,旗下Workspace新闻和数据平台遭遇宕机,影响了全球用户。欧洲能源交易所称,使用其Trayport电力和天然气交易平台的客户在交易中遇到了问题。石油巨头壳牌、英国石油和维多能源集团的至少六名交易消息人士表示,业务受到了影响。[3]

从这跨越7年的事件中,我们能总结到网络安全会影响到多方面如经济、金融、股票、债券交易、重要基础设施、舆论、用户使用感受等。

什么是栈溢出?!

对于永恒之蓝,我们二进制的网安研究人员能注意到永恒之蓝利用的就是445端口的SMB服务,缓冲区溢出漏洞[4-6]。EternalBlue达到其攻击目的事实上利用了3个独立的漏洞:第一个也就是CVE-2017-0144被用于引发越界内存写;第二个漏洞则用于绕过内存写的长度限制;第三个漏洞被用于攻击数据的内存布局。

栈溢出漏洞就是缓冲区溢出漏洞的一种,在现实世界中栈溢出漏洞越来越少,主要出现在iot固件中,linux以及Windows等平台下的已经很少了。但只要他出现了,就其危害性依然很严重,很容易导致RCE。如CVE-2023-27021:是路由器的栈溢出漏洞,攻击者可深入利用并实现RCE。

在Web应用程序中,RCE(远程代码执行)攻击确实存在绕过防火墙和WAF(Web应用程序防火墙)的可能性,在二进制漏洞像CVE-2023-27997 ,其严重性得分为 9.8 分(满分 10 分),则让300000 台设备受到严重影响,Bishop Fox 说:“尽管已经呼吁所有用户快速修补漏洞,但仍有 30 多万FortiGate 防火墙设备容易受到攻击。"[9],在奇安信的技术研究院的研究报告中点出“该漏洞可以实现栈上越界写”“劫持RIP”"ROP"并评价道“该漏洞与去年的CVE-2023-27997XOR导致的堆溢出漏洞类似,都是看起来比较鸡肋的溢出漏洞,利用过程比较Trick,更像是一道CTF题目。但是与传统攻击堆管理器的CTF题目相比,真实漏洞更多的需要借助上下文的结构体和代码逻辑完成利用。”[10]

什么是pwn!

PWN(也称为pwn)是黑客和信息安全领域中的一种术语,通常指通过利用系统或设备的漏洞来攻破或控制它们。这个词语源自英文单词“own”,意为“拥有”,在黑客文化中象征着成功实施攻击并获得目标系统的控制权。

在CTF比赛中,栈溢出攻击的工作流程如下:

  1. 找到漏洞:首先需要识别出目标系统中的栈缓冲区溢出漏洞。这通常通过分析程序的源代码、二进制文件。

  2. 构造攻击载荷,覆盖返回地址:攻击者会编写一段特定的恶意代码,这段代码包含在栈上执行的指令。这些指令可以是任意的汇编语言指令,也可以是系统调用、ROP、gadget等。

  3. 执行攻击代码:在CTF比赛中,选手们写出Python脚本,一般命名为exp.py,运行后就得到目标系统的控制权。

二、基本知识记录

Pwntools功能详解与应用案例

安装如下

#pwntools
sudo apt-get update
sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade pwntools
#Ubuntu20以上自带gdb:
mkdir $HOME/Documents/GDB-Plug-in
cd $HOME/Documents/GDB-Plug-in

git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh
git clone https://github.com/scwuaptx/Pwngdb.git 
cp $HOME/Documents/GDB-Plug-in/Pwngdb/.gdbinit ~/ #或者自己改

git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

#LibcSearcher 
git clone https://github.com/lieanu/LibcSearcher.git
cd LibcSearcher
python setup.py develop

加载Pwndbg插件:在GDB中,你需要加载Pwndbg插件。输入以下命令加载Pwndbg:

source /path/to/pwndbg/gdbinit.py
/path/to/pwndbg`是你安装Pwndbg的路径。

(一)pwntools

简介和参考网址(官网和翻译)

Pwntools是一个用于CTF(Capture The Flag)和漏洞利用开发的Python库,它简化了与二进制文件、网络连接、调试和shellcode生成的交互。

官网中文文档地址:https://pwntools-docs-zh.readthedocs.io/zh-cn/dev/intro.html、https://blog.csdn.net/kelxLZ/article/details/123152529(翻译了https://github.com/Gallopsled/pwntools-tutorial)

以下是一些常见的Pwntools函数及其使用方法:

1.管道-输入输出、打包、进程和连接

管道是方便高效的I/O包装器,里面包含了你需要执行的大多数类型的I/O。

1.1基础IO模块:接收数据

  • recv(numb = 2048, timeout = dufault): 接收任意数量的字符串,长度为numb,单位是字节,timeout指定超时

  • recvline(keepends=True, timeout=default): 接受一行数据直到到回车\n,timeout指定超时;keepends=False不保留结尾的\n

  • recvlines(N) :接收 N(数字) 行输出

  • recvuntil("dlimes",drop=fasle) : 接受数据知道我们设置的标志出现

  • recvall(): 接受到EOF

  • recvrepeat(timeout = default): 接收到EOF或timeout

1.2基础IO模块:发送数据

  • sendline(data): 发送一行数据,并在数据末尾添加换行符。例如,sendline("Hello, world!")表示发送一行数据“Hello, world!”。换言之:· 发送payload,并进行换行(末尾**\n**) =send( )+ \n

  • send(data): 发送数据,不添加换行符。换言之:· 发送payload

  • sendafter(some_string, payload): 接收到 some_string 后, 发送你的 payload

1.3打包和解包

  • p32(x): 打包一个整数到四个字节。

  • u32(x): 解包四个字节到一个整数。

  • p64(x): 打包一个整数到八个字节。

  • u64(x): 解包八个字节到一个整数。

>>>importstruct

>>>p32(0xdeadbeef) == struct.pack('I', 0xdeadbeef)

True

>>>u32(b'abcd') == struct.unpack('I', b'abcd')[0]

True

>>>u8(b'A') == 0x41

True

网络安全介绍、CTFpwn基础:gdb工具命令插图

1.4连接:进程操作

  • process(image): 创建并启动一个新的进程。

  • remote(url, port): 连接到远程服务器并执行指定的命令。

  • interactive():进行回话互动

2.ELF文件操作

2.1elf操作

  • ELF(image): 加载并操作ELF文件。

    from pwn import *
    
    e = ELF('/bin/bash')
    # [*] '/bin/bash'
    #     Arch:     amd64-64-little
    #     RELRO:    Partial RELRO
    #     Stack:    Canary found
    #     NX:       NX enabled
    #     PIE:      No PIE
    #     FORTIFY:  Enabled
    
    

    e.address = 0x12340000 ,改变ELF文件的基址(比如为ASLR做调整)是非常直接和简单的。

  • · 使用符号表

    · symbols['a_function'] 找到 a_function 的地址 ,列出所有已知的符号,包括下面的符号。优先考虑PLT条目,而不是GOT条目。

    · 程序开始时plt=symbols

    · 我想,假如有个自定义的函数a_function,这里的symbols就能体现作用了

    · got['a_function'] 找到 a_function的 got

    · plt['a_function'] 找到 a_function 的 plt

    · functions['list_all_jobs']只包含函数符号表(需要DWARF符号表)

    · next(e.search(b"some_characters")) 找到包含 some_characters(字符串,汇编代码或者某个数值)的地址.

    或者

    for address in e.search('/bin/sh\x00'):
        print hex(address)
    

    · bss() 得bss段的地址

    补充:启动一个调试器,并将其连接到ELF上。这在测试shellcode时是非常有用的,不需要用C语言包装器来加载和调试它。

    >>> io = elf.debug()
    # vs
    >>> io = gdb.debug(elf.path)
    

2.2文件I/O:可以对elf文件进一步操作

from pwn import *

write('filename', 'data1')
read('filename')
# 'data1'
read('filename', 1)
# 'd'

2.3DynELF

  • DynELF(image): 动态分析ELF文件,获取信息如堆栈偏移等。

    DynELF的基本利用模板为:

    p= process('./binary') #32位的elf文件
    
    def leak(address):
        #各种预处理
        payload = "xxxxxxxx" + address + "xxxxxxxх"
        p.send(payload)
        #能各种处理
        data = p.recv(4)
    
        log.debug("%#x =>%s"%(address,(data or '').encode('hex')))
        return data
    
    d = DynELF(leak, elf=ELF("./binary"))#初始化DynELF模块
    systemAddress = d.lookup('system','libc') #在libc文件中搜赛system函数的地址
    

    感觉已经通过LibcSearcher替代了。

3汇编和反汇编shellcraft

  • asm(data, arch): 将字节字符串反汇编为可读的汇编代码。

    asm(pwnlib.shellcraft.thumb.linux.sh(), arch="thumb") # 生成执行sh的shellcode并编译

    # 可以将thumb换成对应cpu

    # 读取flag并输出到标准输出pwnlib.shellcraft.i386.linux.cat("flag", fd=1)

    # 使用forkbomb破坏系统(慎用)pwnlib.shellcraft.i386.linux.forkbomb()

    shellcraft模块是shellcode的模块,包含一些生成shellcode的函数

    asm()函数接收一个字符串作为参数,得到汇编码的机器代码。

    例:

    1. asm('mov eax, 0')

    2. '\xb8\x00\x00\x00\x00'

    摘取官网:

    >>>asm('nop')

    b'\x90'

    >>>asm('nop', arch='arm')

    b'\x00\xf0 \xe3'

    提醒:asm会受context的设置影响

  • disasm(data, arch): 将字节字符串汇编为可读的汇编代码

4环境和调试:

4.1指定libc版本运行pwn题 or 使用patchelf

from pwn import *

libc_path = "/usr/local/libc/libc-2.23.so"

ld_path = "/usr/local/libc/ld-2.23.so"

p = process([ld_path, "./prog"], env={"LD_PRELOAD":libc_path})

libc模块的使用/libcsearcher的使用:

libc.dump('execve') 得libc里’execve’和和基地址的偏移

#elf.symbol 等 多个去寻址

4.2设置context

context(arch='arm', os='linux', endian='big', word_size=32,log_level = 'debug')

context.terminal = ['tmux','splitw','-h']

# 设置成debug,pwntools会将所有io数据等输出,方便编写poc的时候进行调试,而arch可以设置攻击目标的指令构架。

一般来说我们设置context只需要简单的一句话:

context(os='linux', arch='amd64', log_level='debug')

1.os是设置系统为Linux系统

2.arch是设置架构为amd64,可以简单的认为设置为64位的模式,32位对应'i386' 3.log_level设置日志输出等级为debug,这句话在调试的时候一般会设置,这样pwntools会将完整的io过程都打印下来,使得调试更加方便,可以避免在完成CTF题目时出现一些和IO相关的错误

4.3gdb调试:

有关gdb命令请详见第二节:(二)GDB以及一些插件的命令,还有gdb脚本的编写。

1、GDB下启动一个进程,一句话:io = gdb.debug("/bin/bash", gdbscript='continue')

2、附加到一个正在运行的进程
>>> io = process('binary')
>>> gdb.attach(io, gdbscript='continue')
3、远程服务器

想调试的二进制文件运行在一个远程服务器上,只要服务器在当前机器上运行,调试你所连接的进程(而不是服务器本身)也可以完成。

socat = process(['socat', 'TCP-LISTEN:4141,reuseaddr,fork', 'EXEC:binary -i'])
4、调试异构架构

pwntools调试异构架构(如ARM或PowerPC)很容易

>>> context.arch = 'arm'
>>> elf = ELF.from_assembly(shellcraft.echo("Hello, world!\n") + shellcraft.exit())
>>> process(elf.path).recvall()
b'Hello, world!\n'

5、调试时附加环境变量

>>> io = gdb.debug(['bash', '-c', 'echo $HELLO'], env={'HELLO': 'WORLD'})
>>> io.recvline()
b'WORLD\n'

ROP模块

寻找gadget可以使用ROPgadget、Xgadget以及ropper

ROP对象实现了getattr的功能,可以直接通过func call的形式来添加函数,rop.read(0, elf.bss(0x80))实际相当于rop.call('read', (0, elf.bss(0x80)))。 通过多次添加函数调用,最后使用str将整个rop chain dump出来就可以了。

call(resolvable, arguments=()) : 添加一个调用,resolvable可以是一个符号,也可以是一个int型地址,注意后面的参数必须是元组否则会报错,即使只有一个参数也要写成元组的形式(在后面加上一个逗号)

chain() : 返回当前的字节序列,即payload

dump() : 直观地展示出当前的rop chain

raw() : 在rop chain中加上一个整数或字符串

search(move=0, regs=None, order=’size’) : 按特定条件搜索gadget

unresolve(value) : 给出一个地址,反解析出符号

elf.address = 0xff000000#设置elf基地址
rop = ROP(elf)#创建ROP对象
rop.gadgets#查看所有gadgets ,
#将原始数据添加到ROP栈中:
rop.raw(0xdeadbeef)
rop.raw(0xcafebabe)
rop.raw('asdf')
#输出ROP栈:
print(rop.dump())
# 0x0000:       0xdeadbeef
# 0x0004:       0xcafebabe
# 0x0008:          b'asdf' 'asdf'
#-------------------------------#
#想从它那里得到原始字节。我们可以使用byte()方法来实现这个功能:
print(hexdump(bytes(rop)))
# 00000000  ef be ad de  be ba fe ca  61 73 64 66               │····│····│asdf│
# 0000000c
#-------------------------------#
#⭐⭐⭐⭐⭐调用任意函数⭐⭐⭐⭐⭐:
elf = ELF('/bin/sh')
rop = ROP(elf)
rop.call(0xdeadbeef, [0, 1])
print(rop.dump())
# 0x0000:       0xdeadbeef 0xdeadbeef(0, 1, 2, 3)
# 0x0004:          b'baaa' <return address>
# 0x0008:              0x0 arg0
# 0x000c:              0x1 arg1
#⭐⭐使用函数名来调用函数⭐⭐:你的库在其GOT/PLT中有你想调用的函数,或者有二进制的符号,你可以直接调用函数名。
context.binary = elf = ELF('/bin/sh')
rop = ROP(elf)
rop.execve(0xdeadbeef)
print(rop.dump())
# 0x0000:           0x61aa pop rdi; ret
# 0x0008:       0xdeadbeef [arg0] rdi = 3735928559
# 0x0010:           0x5824 execve
#⭐⭐多个elf:一个使用/bin/sh以及其libc的例子。
context.binary = elf = ELF('/bin/sh')
libc = elf.libc

elf.address = 0xAA000000
libc.address = 0xBB000000

rop.rax
# Gadget(0xaa00eb87, ['pop rax', 'ret'], ['rax'], 0x10)
rop.rbx
# Gadget(0xaa005fd5, ['pop rbx', 'ret'], ['rbx'], 0x10)
rop.rcx
# Gadget(0xbb09f822, ['pop rcx', 'ret'], ['rcx'], 0x10)
rop.rdx
# Gadget(0xbb117960, ['pop rdx', 'add rsp, 0x38', 'ret'], ['rdx'], 0x48)
#⭐:rax和rbx的gadgets是在主二进制文件中(0xAA…),而后两个是在libc(0xBB…)。
#⭐⭐更复杂的函数调用:
rop.memcpy(0xaaaaaaaa, 0xbbbbbbbb, 0xcccccccc)
print(rop.dump())
# 0x0000:       0xbb11c1e1 pop rdx; pop r12; ret
# 0x0008:       0xcccccccc [arg2] rdx = 3435973836
# 0x0010:      b'eaaafaaa' <pad r12>
# 0x0018:       0xaa0061aa pop rdi; ret
# 0x0020:       0xaaaaaaaa [arg0] rdi = 2863311530
# 0x0028:       0xaa005f73 pop rsi; ret
# 0x0030:       0xbbbbbbbb [arg1] rsi = 3149642683
# 0x0038:       0xaa0058a4 memcpy
#⭐⭐获取一个shell:当我们了解了pwntools的ROP功能时,获得一个shell是很容易的!我们直接调用execve,并从内存中的某个地方找到一个"/bin/sh/x00 "的实例作为第一个参数传递进去。
context.binary = elf = ELF('/bin/sh')
libc = elf.libc

elf.address = 0xAA000000
libc.address = 0xBB000000

rop = ROP([elf, libc])
binsh = next(libc.search(b"/bin/sh\x00"))
rop.execve(binsh, 0, 0)

其他功能:

misc/crypto/简单的re/auto stackoverflow fuzz:简单且实用的功能

1、auto

stackoverflow fuzz:样例生成,用法:

cyclic(0x100) # 生成一个0x100大小的pattern,即一个特殊的字符串

cyclic_find(0x61616161) # 找到该数据在pattern中的位置

cyclic_find('aaaa') # 查找位置也可以使用字符串去定位

比如,我们在栈溢出的时候,首先构造cyclic(0x100),或者更长长度的pattern,进行输入,输入后pc的值变味了0x61616161,那么我们通过cyclic_find(0x61616161)就可以得到从哪一个字节开始会控制PC寄存器了,避免了很多没必要的计算。

2、哈希和编码

Base64
'hello' == b64d(b64e('hello'))
Hashes
md5sumhex('hello') == '5d41402abc4b2a76b9719d911017c592'
write('file', 'hello')
md5filehex('file') == '5d41402abc4b2a76b9719d911017c592'
sha1sumhex('hello') == 'aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d'
URL Encoding
urlencode("Hello, World!") == '%48%65%6c%6c%6f%2c%20%57%6f%72%6c%64%21'
Hex Encoding
enhex('hello')
# '68656c6c6f'
unhex('776f726c64')
# 'world'

pwntools简单模板:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from pwn import *

# 配置部分
context.arch = 'amd64'  # 或 'i386'
context.log_level = 'debug'  # 或 'info', 'error'
execve_file = './target_executable'  # 目标可执行文件路径
libc_file = '/path/to/libc.so.6'  # libc文件路径
host = 'target_ip'  # 目标IP
port = target_port  # 目标端口

# 信号处理
for sig in [signal.SIGINT, signal.SIGHUP, signal.SIGTERM]:
    signal.signal(sig, lambda signum, frame: exit(0))

# 主逻辑
if __name__ == '__main__':
    if args.LOCAL:
        io = process(execve_file)
    else:
        io = remote(host, port)

    if args.GDB:
        gdb.attach(io, gdbscript='''...''')  # GDB脚本

    # 栈溢出部分
    overflow_offset = 0x80  # 假设偏移量为0x80
    return_address = 0x00400596  # 假设的返回地址

    # 构造栈溢出payload
    payload_overflow = flat(
        'A' * overflow_offset,  # 填充字符
        return_address  # 返回地址
    )

    # 发送栈溢出payload
    io.recvuntil('...')
    io.sendline(payload_overflow)

    # 格式化字符串部分
    format_string_offset = 0x10  # 假设格式化字符串的偏移量
    target_address = 0x00400500  # 假设要修改的目标地址
    target_value = 0xdeadbeef  # 假设要写入的值

    # 构造格式化字符串payload
    payload_format_string = flat(
        p32(target_address),  # 要写入的地址
        '%{}c'.format(target_value & 0xffff),  # 用于写入低16位的值
        '%{}$hn'.format(format_string_offset)  # 用于写入到指定地址
    )

    # 发送格式化字符串payload
    io.recvuntil('...')
    io.sendline(payload_format_string)

    # 交互模式
    io.interactive()


bug整理

1、作者做题中遇到过因为脚本里写有中文而不能运行的情况,此时把“# - coding:utf-8 --”复制到开头第一行即可

2、python3的 byte类型和python2的不一样,前者发送的数据都要加b,如· sendline(b"echo hello") 发送payload,并进行换行(末尾**\n**;· recvuntil(b',');sh.recvline(timeout=1);· send(b'string'),

如果是python2的脚本可以在文件首行添加:

#!/usr/bin/python2

# -- coding:utf-8 --

3、接收不到的问题:

send发送的,有时候会接收不了。(改成sendline)

有时候是sendline发送的,要注意回车。

4、麻烦:

关于Python3的bytes对象,有一个值得一提的 “麻烦”。当对它们进行迭代时,你会得到整数,而不是bytes对象。这是与Python2的巨大差异,也是一个主要的烦恼。

见此文:https://blog.csdn.net/kelxLZ/article/details/123152529

字符操作:

  • ordlist() 将字符串内容转换成ascii码,以列表的形式

  • unordlist() 将列表中的ascii码转换成字符串

5、以上关于pwntools的还有日志没有写

(二)GDB以及一些插件的命令

通过网盘分享的文件:pwndbg食用方式.pdf
链接: https://pan.baidu.com/s/1vA20_JU84xJZk9qk5wz7UQ?pwd=ur2x 提取码: ur2x

pwndbg简介:Exploit Development and Reverse Engineering with GDB Made Easy = 利用GDB开发和逆向工程变得容易

GDB及插件的常见命令的表格

gdb+pwndbg/gef +pwngdb

命令 缩写 效果 备注
gdb <*pid> 添加新程序
gdb attach 负载运行的程序
set args <*argv> 设置程序运行参数
show args 查看设置好的运行参数
quit q 退出gdb
symbol sy 导入符号表
info <*b> i 查看程序的状态/*查看断点
list l 显示源代码(debug模式)
display disp 跟踪查看某个变量
start s 启动程序并中断在入口debug模式停在main(),否则停在start()
run r 直接运行程序直到断点
continue c 暂停后继续执行程序
next n (ni) 单步步过
step s (si) 单步步入,函数跟踪
finish fin 跳出,执行到函数返回处
break /* b 下断点
watch 下内存断点并监视内存情况
print p 打印符号信息(debug模式)
info registers i r a 查看所有寄存器
i r <esp/ebp..> 查看某个寄存器
set $esp = 0x01 修改某个寄存器的值
reg查看内存布局 查看所有寄存器的值
p $寄存器代号 查看指定寄存器的值
i proc mappings 查看内存布局
frame f 查看栈帧
backtrace bt 查看堆栈情况
b *地址 在指定地址设置断点
b 函数名 在指定函数设置断点
heap 查看分配的chunk
vis 更漂亮的显示堆块
vmmap 查看内存分配情况
bin 查看 Bin 情况
x /<n/f/u> 显示内存信息,具体用法附在下面
libcsearch '字符串'context 查看libc动态地址****查找字符串所在地址:打印 pwnbdg 页面信息
dps 优雅地显示内存信息
disassemble 打印函数信息
vmmap 显示程序内存结构
search <*argv> 搜索内存中的值输入 search -h 可查询用法
checksec 查看程序保护机制
parseheap 优雅地查看分配的chunk
aslr <on/off> 打开/关闭 ASLR 保护
pshow 显示各种踏板选项和其他设置
dumpargs 显示在调用指令处停止时传递给函数的参数
dumprop 显示特定内存范围内的所有ROP gadgets
elfheader 从调试的elf文件获取头信息
elfsymbol 从ELF文件获取非调试符号信息
procinfo 显示来自/proc/pid的各种信息
readelf 从elf文件获取头信息

pwndbg

Start Commands 中文描述
attachp 附加到指定的进程ID、进程名称或设备文件。
entry 从调试程序的入口点地址开始执行。
sstart 'tbreak __libc_start_main; run' 的别名。
start [main, init] 在最方便的位置开始调试程序,停止在第一个位置。
Step/Next/Continue Commands 中文描述
nextcall 在下一个调用指令处中断。
nextjmp [nextjump] 在下一个跳转指令处中断。
nextproginstr 在属于正在运行程序的下一个指令处中断。
nextret 在下一个返回或类似指令处中断。
nextsyscall [nextsc] 在下一个不带分支的系统调用处中断。
stepover [so] 在此指令后的指令处中断。
stepret 通过'步进'到它处中断下一个返回或类似指令。
stepsyscall [stepsc] 通过带分支的系统调用处中断下一个系统调用。
stepuntilasm 在下一个匹配的指令处中断。
xuntil 继续执行,直到到达指定的地址或函数。
Context Commands 中文描述
context [ctx] 打印当前的寄存器、指令和栈上下文。
contextoutput [ctx-out] 设置上下文部分的输出。
contextunwatch [ctx-unwatch, cunwatch] 移除之前添加的用于监视的表达式。
contextwatch [ctx-watch, cwatch] 添加一个用于上下文显示的表达式。
regs 打印所有寄存器并增强信息。
Heap Commands 中文描述
arena 打印一个arena的内容。
arenas 列出进程的所有arenas。
bins 打印一个arena的所有bin及其线程的tcache。
fastbins 打印arena的快速bin。
find_fake_fast 查找与指定地址重叠的假快速或tcache块。
heap 迭代打印堆上的块。
heap_config 显示与堆相关的配置。
hi 在所有堆中搜索地址是否属于一个块,如果是,打印该块。
largebins 打印arena的大块。
malloc_chunk 打印一个块。
mp 打印mp_结构的属性。
smallbins 打印arena的小块。
tcache 打印线程的tcache内容。
tcachebins 打印tcache的内容。
top_chunk 打印与arena的顶块相关的信息。
try_free 检查如果用给定的地址调用free会发生什么。
unsortedbin 打印arena的未排序bin的内容。
vis_heap_chunks 显示堆上的块。
Breakpoint Commands 中文描述
breakrva [brva] 在PIE基址的RVA处设置断点。
ignore 将断点编号N的忽略计数设置为COUNT。
Memory Commands 中文描述
distance 打印两个参数之间的距离,或者打印地址的页基的偏移量。
hexdump 在指定的地址或模块名称处进行十六进制转储。
leakfind 尝试查找给定起始地址的泄漏链。
memfrob 给内存区域的内存进行加密(异或操作)。
mmap 调用mmap系统调用,并打印其结果地址。
mprotect 调用mprotect系统调用,并打印其结果值。
p2p 指针到指针链搜索。在给定的映射中搜索所有指向指定映射的指针。
probeleak 指针扫描以查找可能的偏移泄漏。
search 在内存中搜索字节序列、字符串、指针和整数值。
telescope | tel 从指定的地址递归地解引用指针。
vmmap [lm, address, vprot, libs] 打印虚拟内存映射页面。
vmmap_add 添加虚拟内存映射页面。
vmmap_clear 清除vmmap缓存。
vmmap_load 从ELF文件加载虚拟内存映射页面。
xinfo 显示指定地址相对于各种有用位置的偏移量。
xor 在给定的地址处用键进行异或操作。
Stack Commands 中文描述
canary 打印当前栈金丝雀|canary。
retaddr 打印包含返回地址的栈地址。
stack 在指定计数和偏移处对栈数据进行解引用。
stackf 在指定计数和偏移处对栈数据进行解引用,并打印整个栈帧。
Register Commands 中文描述
cpsr [xpsr, pstate] 打印ARM CPSR或xPSR寄存器。
fsbase 打印FS基址。也见$fsbase。
gsbase 打印GS基址。也见$gsbase。
setflag [flag] 修改标志寄存器。
Process Commands 中文描述
killthreads 杀死所有或指定的线程。
pid [getpid] 获取PID。
procinfo 显示关于运行进程的信息。
Linux/libc/ELF Commands 中文描述
argc 打印参数的数量。
argv 打印argv的内容。
aslr 检查当前ASLR状态,或者打开/关闭它。
auxv 打印Auxiliary ELF Vector的信息。
elfsections 打印ELF头中的段映射。
envp [env, environ] 打印环境变量。
errno 将errno(或参数)转换为其字符串表示。
got 显示全局偏移表(GOT)的状态。
gotplt 如果存在,打印.got.plt段中的任何符号。
linkmap 显示Link Map的状态。
onegadget 显示onegadget。
piebase 从PIE基址计算RVA的虚拟地址。
plt 如果存在,打印.plt段中的任何符号。
threads 列出属于选定子进程的所有线程。
tls 打印当前线程本地存储(TLS)的基址。
track-got 控制GOT跟踪。
track-heap 管理堆跟踪器。
Disassemble Commands 中文描述
emulate 类似于nearpc,但会从当前$PC处向前模拟指令。
nearpc [pdisass, u] 在指定地址附近进行反汇编。
Misc Commands 中文描述
asm 将shellcode汇编成字节。
break-if-not-taken 在分支未执行时中断。
break-if-taken 在分支执行时中断。
checksec 使用checksec打印二进制文件的安全设置。
comm 在汇编代码中添加注释。
cyclic 创建/查找循环模式。
cymbol 在C语言中添加、显示、加载、编辑或删除自定义结构。
down 选择并打印由当前栈帧调用的栈帧。
dt 输出类型(如ucontext_t)的信息。
dumpargs [args] 打印确定的调用指令的参数。
getfile 获取当前文件。
ipi 启动一个交互式的IPython提示符。
patch 用给定的代码或字节修改指定的指令。
patch_list 列出所有补丁。
patch_revert 在给定的地址处撤销补丁。
plist 转储链表的元素。
sigreturn 显示特定地址处的SigreturnFrame。
spray 用cyclic()生成的值填充内存。
tips 显示提示。
up 选择并打印调用当前栈帧的栈帧。
valist 转储va_list的参数。
Kernel Commands 中文描述
kbase 查找内核虚拟基址。
kchecksec 检查内核硬化配置选项。
kcmdline 返回内核命令行(/proc/cmdline)。
kconfig 输出内核配置(需要CONFIG_IKCONFIG)。
kversion 输出内核版本(/proc/version)。
slab 打印slab分配器的信息。
Integrations Commands 中文描述
ai 向GPT-3询问当前调试上下文的问题。
ghidra 使用Ghidra反编译给定的函数。
j 使用IDA的游标与GDB同步。
r2 [radare2] 启动radare2。
r2pipe 通过r2pipe执行状态radare2命令。
rop [ropgadget] 使用Jon Salwan的ROPgadget工具输出ROP gadget。
ropper 使用ropper进行ROP gadget搜索。
rz [rizin] 启动rizin。
rzpipe 通过rzpipe执行状态rizin命令。
save_ida 保存ida数据库。
WinDbg Commands 中文描述
bc 清除指定索引的断点。
bd 禁用指定索引的断点。
be 启用指定索引的断点。
bl 列出断点。
bp 在指定地址设置断点。
da 在指定地址处转储字符串。
db 从指定地址开始转储N字节。
dc 从指定地址开始进行十六进制转储。
dd 从指定地址开始转储N双字。
dds [kd, dps, dqs] 在指定地址处转储指针和符号。
dq 从指定地址开始转储N四字。
ds 在指定地址处转储字符串。
dw 从指定地址开始转储N字。
eb 在指定地址处写入十六进制字节。
ed 在指定地址处写入十六进制双字。
eq 在指定地址处写入十六进制四字。
ew 在指定地址处写入十六进制字。
eza 在指定地址处写入字符串。
go 'continue'命令的Windbg兼容别名。
k 打印回溯(别名'bt')。
ln 列出给定值附近的符号。
pc 'nextcall'命令的Windbg兼容别名。
命令别名 中文描述
peb 不是Windows命令。
pwndbg Commands 中文描述
---------- ----------
pwndbg 打印所有pwndbg命令的列表。
reinit_pwndbg 使pwndbg重新初始化所有状态。
reload 重新加载pwndbg。
theme 显示pwndbg特有的主题配置。
themefile 生成当前pwndbg主题选项的配置文件。
version 显示GDB、Python和pwndbg的版本。
Developer Commands 中文描述
dev_dump_instruction 转储内部PwndbgInstruction属性。

Pwngdb:

以下是根据您提供的信息整理的表格,并包含了英文注释:

命令别名 中文描述 备注
libc 打印libc的基址
ld 打印ld的基址
codebase 打印代码段的基址
heap 打印堆的基址
got 打印全局偏移表信息
dyn 打印动态节信息
findcall 查找某些函数调用
bcall 在某些函数调用处设置断点
tls 打印线程本地存储地址
at 通过进程名称附加
findsyscall 查找系统调用
fmtarg 计算格式字符串的索引
force 计算在force房间的nb
heapinfo 打印堆的一些信息 heapinfo (Address of arena): 默认是当前线程的arena;
如果启用了tcache,它将显示缓存条目的信息
heapinfoall 打印堆的所有信息 (所有线程)
arenainfo 打印所有arena的信息
chunkinfo 打印chunk的信息 chunkinfo (Address of victim): 打印受害chunkd的信息
chunkptr 打印chunk的信息 chunkptr (Address of user ptr): 打印用户指针的chunk信息
mergeinfo 打印merge的信息 mergeinfo (Address of victim): 打印受害地址的merge信息
printfastbin 打印fastbin的一些信息
tracemalloc on 跟踪malloc和free,检测错误 tracemalloc on: 需要先运行进程,然后开启tracemalloc;
您可以在pwngdb.py中设置DEBUG,然后它将打印所有malloc和空闲信息,例如屏幕截图。
parseheap 解析堆布局
magic 打印glibc中的有用变量和函数
fp 显示FILE结构 fp (Address of FILE): 显示FILE结构的地址
fpchain 显示FILE的链表
orange 在_IO_flush_lockp中测试house of orange条件 orange (Address of FILE): 测试FILE的house of orange条件;
(glibc version <= 2.23)仅在glibc版本小于等于2.23时有效

(三)LibcSearcher:

git clone https://github.com/lieanu/LibcSearcher.git
cd LibcSearcher
python setup.py develop
from LibcSearcher import *

# 第二个参数,为已泄露的实际地址, 或最后12位(例如:d90),int类型
obj = LibcSearcher("fgets", 0X7ff39014bd90)

obj.dump("system")           # 输出 system 函数的偏移
obj.dump("str_bin_sh")       # 输出 /bin/sh 的偏移
obj.dump("__libc_start_main_ret")

一些注意事项,在较高版本的python中会提示你使用虚拟环境。


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

如何使用CODASM编码Payload并降低熵值
SessionExec:一款针对会话安全的安全命令测试工具
Arkime:一款大规模数据包捕获和索引数据库系统
从蓝队流量角度分析Shiro-550反序列化漏洞
万字长文浅谈三高系统建设方法论和实践
你遇到过哪些奇葩面试题目;如何考察渗透测试与安全管理能力| FB甲方群话题讨论

发布评论