寒假一回来,一段时间没用,有点手生了,觉得还是需要写一篇博客来梳理一下常见工具的使用.

主要是静态分析、动态分析、脚本编写、小工具

静态分析:IDA pro

ida 里面很多奇怪的东西

dword ptr

qword ptr

ida的数据类型:https://blog.csdn.net/m0_43406494/article/details/109110983

图形模式

设置一下这俩,行号和显示数据内容

image-20230303204724726

箭头

红色: 条件跳转没有被采用

绿色: 条件跳转被采用

蓝色: 无条件跳转被采用

方向向上表示循环

文本模式

image-20230303205201647

在设置里可以打开 auto comments 自动注释

视图文件操作

选择Windows中的Reset Desktop返回默认 视图

选择Windows中的Save Desktop保存这个 新视图

配置文件吗??

后退操作 esc

前进操作 ctrl+enter

常用快捷键:

Table 切换视图

快捷键

p 在汇编中函数开头使用p,从当前地址处解析为函数

u

c 转换成代码

数据操作:

shift + f12 显示字符串string

D – 设置数据 (Data) 1字节 2字节 4字节 8字节 进行循环

C – 设置代码 (Code) 设置为指令

A – 设置ASCII字符串 (ASCII)

*设置数组

O – 设置地址偏移 (Offset)

U – 取消定义 (Undefine)

X – 交叉引用查找 (Cross-reference, Xref)

函数操作

P – 创建函数 Del – 删除函数 Ctrl+E – 修改函数(函数窗口)

Alt+P 修改函数(反汇编窗口)

伪代码操作

N – 修改标识符名称 (Name)

Y – 修改标识符类型 (tYpe) 比如int类型还是double还是什么

搜索

alt+t查找字符串

a 转换成字符串

d 分开的字符

G跳转指定地址

x 交叉引用 (函数和数据都有)

: 加一条注释

; 所有交叉引用都会回显这个注释

类型

  • WORD (w) 16位 无符号数值

  • DWORD (dw) 32位 无符号数值

脚本编写

动态分析:gdb(pwndbg插件)

There are a number of good gdb crash courses / reference manuals:

pwn.college https://www.youtube.com/watch?v=r185fCzdw8Y

pwndbg官方文档:https://browserpwndbg.readthedocs.io/en/docs/

https://github.com/pwndbg/pwndbg/blob/dev/FEATURES.md

gdb官方文档:

【CppCon 2016 比你知道更多的 GDB 知识,GDB - A Lot More Than You Knew 中英字幕】 https://www.bilibili.com/video/BV1Zk4y1w7ih/?share_source=copy_web&vd_source=2d8fb63a145457ff1a7e34f534a732e6

https://www.bilibili.com/video/BV1p14y1y7zv/?share_source=copy_web&vd_source=2d8fb63a145457ff1a7e34f534a732e6

TUI mode

control + x + a

ctrl + L重新绘制

ctrl + x + 2 两个窗口

ctrl + x + 1显示一个src窗口

ctrl + x + a 传统模式

ctrl p 上一个命令 ctrl n下一个

python 可以查看断点 下断点

可逆调试??? reverse-stepi

Target native does not support this command

使用前输入target record-full

触发间接性的错误, 需要多次运行, 设置条件判断

image-20231113161842093

image-20231113162334467

commond命令

调整

把 stack 和 backtrace的行数减少,不然看不见上面的汇编了

配置文件:https://github.com/pwndbg/pwndbg/blob/dev/FEATURES.md

修改配置文件就可以了

找到pwndbg的下载目录的这个文件pwndbg/pwndbg/commands/context.py

1
2
3
4
5
6
7
8
751行
stack_lines = pwndbg.gdblib.config.add_param(
"context-stack-lines", 8, "number of lines to print in the stack context"
)
766行
backtrace_lines = pwndbg.gdblib.config.add_param(
"context-backtrace-lines", 8, "number of lines to print in the backtrace context"
)

启动调试

gdb filename

gdb processName PID 或者 gdb -p

添加参数

gdb -args ./a.out a b c

断点相关

b 函数名,如果有符号表的话可以,例如b gets

b 地址 例如:b *0x3123213 这样打

info b 查看断点信息

delete n 删除n号断点

运行

r 运行程序,会一直运行,直到比如需要输入什么东西等

s 从头开始运行,断到第一行

c 运行到下一个断点

调试地址 就是 这个程序的基地址 + ida中的地址

n 单步执行,(有函数的话直接跳过不进入)

s 单步进入,有函数的话会进入

finish 执行完当前函数,返回调用它的函数

怎么查看自己当前在哪一行??和下面的代码??

disass

运行的时候 怎么 添加参数? run arg1 arg2…

查看信息

codebase 查看地址 (调试地址 就是 这个程序的基地址 + ida中的地址)

vmmap查看内存映射mmap地址 信息

teles 查看栈的信息

p 变量名 查看变量地址

info

reg 查看寄存器信息

dereference $esp 是啥??

查看内存信息

使用examine命令(简写是x)来查看内存地址中的值

x/nuf 例如x /20wx 0x0000000

n是个数,表示从当前地址往后显示的内存的长度,即显示几个地址的内容

u表示,从当前地址往后请求的字节数,不指定的话默认4bytes,32位.b表示单字节,h表示双字节,w表示四字节,g表示八字节。

f是显示的格式( i可以查看汇编代码)

image-20220929162158033

1
2
3
4
5
6
7
8
9
pwndbg> x/4bx 0x7fffffffe490
0x7fffffffe490: 0x00 0x80 0x00 0x00
pwndbg> x/4hx 0x7fffffffe490
0x7fffffffe490: 0x8000 0x0000 0x0001 0x0000
pwndbg> x/4wx 0x7fffffffe490
0x7fffffffe490: 0x00008000 0x00000001 0x55554759 0x00005555
pwndbg> x/4gx 0x7fffffffe490
0x7fffffffe490: 0x0000000100008000 0x0000555555554759
0x7fffffffe4a0: 0x0000000000000000 0xa2698e7a0212c01a

堆相关

heap 查看堆的信息

heap bins 查看bins的信息

heap chunks 查看chunk的信息

Vis 查看堆内存

修改内存、寄存器等 方便调试

set $eip = xxxx

set {unsigned int}0x8048a51=0x0

find 内存搜索

其他

watch 监测点?

canary

q 退出

display /3i $rip 设置单步执行后自动显示的内容,这里显示后续三条指令

查看寄存器

(gdb) i r (gdb) i r a # 查看所有寄存器(包括浮点、多媒体) (gdb) i r esp (gdb) i r pc

info reg

调试一下输出为16进制吧: set output-radix 16

eb address [data [data …]]

p sizeof()查看变量、结构体大小

结构体相关

p 结构体名字

p *(struct xxx *) addr

1
2
3
4
5
6
pwndbg> p *(DSI *) dsi
value of type `DSI' requires 67416 bytes, which is more than max-value-size
pwndbg> p dsi
$4 = (DSI *) 0x5555555b8960
pwndbg> p *(DSI *) 0x5555555b8960
value of type `DSI' requires 67416 bytes, which is more than max-value-size

调试技巧

下好断点,然后多用c,在堆的调试中很好用

pwntools中加input()

gdb中怎么看文件描述符呢,有多少个,打开的 ll /proc/1562844/fd 需要看进程信息

https://www.cnblogs.com/mfryf/p/5329770.html

vmmap 查看内存分布

子进程调试

https://blog.csdn.net/cjfeii/article/details/21647663

set detach-on-fork off

有好几种模式

info threads

切换线程

info inferiors

https://blog.csdn.net/bsp_mpu6050/article/details/107886383

脚本编写:pwntools

官方文档:https://docs.pwntools.com

https://pwntools-docs-zh.readthedocs.io/zh_CN/dev/gdb.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from pwn import *

context.log_level= "debug"

io = process("./pwn3")

context.terminal = ['tmux', 'splitw', '-h']
gdb.attach(io,"b main")
#pause()


#io.sendlineafter('Input:',payload)

io.interactive()


from pwn import *

context.log_level= "debug"

io = process("./pwn3")

context.terminal = ['tmux', 'splitw', '-h']
gdb.debug(io,"b main")
#pause()


#io.sendlineafter('Input:',payload)

io.interactive()

https://blog.csdn.net/fjh1997/article/details/105434992/

配合gdb

在输入一段数据后 断下,比如字符串的那个例子,我们想要查看刚刚输入完数据后的情况,

第一种方法,找到断点

1
2
3
4
5
6
7
8
  0x5655563b <fmtstr+110>    push   0x63
0x5655563d <fmtstr+112> lea eax, [ebp - 0x70]
0x56555640 <fmtstr+115> push eax
0x56555641 <fmtstr+116> call fgets@plt <fgets@plt>

0x56555646 <fmtstr+121> add esp, 0x10
0x56555649 <fmtstr+124> sub esp, 0xc
0x5655564c <fmtstr+127> lea eax, [ebp - 0x70]

attach的时候断到断点这里就好了,然后 gdb那边c, 然后pwntools这边执行一下(回车) 即可, 或者不用pause, 直接在gdb那c一下就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

context.log_level= "debug"

io = process("./vul32")
#io = process("./pwn3","b main")

context.terminal = ['tmux', 'splitw', '-h']
gdb.attach(io,"break *0x56555646")
#gdb.debug("./vul32","break main")
pause()
io.sendline("aaaaaa")
pause()
#io.sendlineafter('Input:',payload)

io.interactive()

__kernel_vsyscall+ 一上来的这个是什么?????????? 这是进入到了内核里面吧 可以通过backtrace来看

#6 0xf7e4b29c in _IO_fgets

#7 0x56555646 in fmtstr ()
#8 0x565556a5 in main ()
#9 0xf7dfdfa1 in __libc_start_main (main=0x56
555685

, argc=1, argv

确实是进入到断点后的位置

右边c的时候,需要左边pwntools这边进行输入,右边不能进行输入的

第二种,直接在开头就断点就好了

pwntools基础操作

send和sendline的区别,send只是发送数据,sendline发送一行数据,也就是除了数据,还会加一个换行(回车)

https://blog.csdn.net/weixin_45556441/article/details/113982718

安装

apt-get install libffi-dev,libssl-dev

pip install pwntools

环境变量设置

​ 许多都是通过全局变量context进行设置的,例如操作系统,架构,字节序等

1
2
context.os = 'linux'
context.log_level = "debug" True

连接及交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
file = process("./pwn")		#本地文件         

p= remote("xx.xx.xx.xx",12345) #远程
p.send(payload) #发送数据
p.sendline(payload) #发送数据并添加换行符
p.senduntil?
p.sendafter(string)
p.sendlineafter()

p.recv(count) # 接收count长度的信息
p.recvuntil(string,drop=True or False) #返回直到接收到指定字符串的信息,drop参数可以指定是否包含终止字符串

p.clear() # 清空消息缓存
p.interactive() # 与程序进行交互

编码类

​ 漏洞利用时,payload可能有各种形式,8.16,32,64位、大端小端,pwntools提供了编码和解码的函数,p开头是编码,u开头是解码,后面跟着的是位数. 此外还提供了asm和disasm两个函数进行汇编和反汇编的转换

1
2
p32(0x8040000)  '\x00\x00\x04\x08'
hex(u32('\x00\x00\x04\x08')) '0x8040000'

文件信息获取类

​ 获取二进制文件或者libc等的got plt表地址,或者偏移等

1
2
3
4
5
6
elf = ELF('bin-path') #加载二进制文件
elf.got['fun_name'] #获取对应函数的got表地址
elf.plt['fun_name'] #获取对应函数的plt表地址
libc = ELF('libc-path') #加载二进制文件
libc.symbols[‘system’] #获取函数地址
libc.sym['system'] 有什么区别??

symbols和got plt的关系???3

libc地址计算类

格式化字符串

shellcode

Shellcraft.sh()

patchelf

patchelf –set-interpreter /home/ubuntu/glibc-all-in-one/libs/2.23-0ubuntu11.3_i386/ld-linux.so.2 ./a.out
patchelf –set-rpath /home/ubuntu/glibc-all-in-one/libs/2.23-0ubuntu11.3_i386/ ./a.out

gadget相关工具

ROPgadget

ROPgadget –binary rop –only ‘pop|ret’ | grep ‘eax’

ROPgadget –binary ret2syscall –only ‘int’

ROPgadget –binary ret2syscall –string ‘/bin/sh’

objdump

image-20230221224643726

image-20230221224632067

image-20230221224616734

libcsearch

https://blog.csdn.net/qq_44108455/article/details/105458234

https://blog.csdn.net/csdn546229768/article/details/121177641

apt get install zstd

https://libc.blukat.me

https://libc.rip

https://github.com/niklasb/libc-database

https://github.com/lieanu/LibcSearcher

Linux自带工具

file

​ 查看文件基本信息

image-20230222132901291

ldd

打印依赖的共享库文件

image-20230222132915670

nm

打印可执行程序的符号信息

image-20230222132921275

strings

查看可打印字符串信息

image-20230222132932791

objdump

打印可执行程序的信息

-h 打印section头信息

image-20230222132942474

-d 打印可执行section汇编

image-20230222132950821

readelf

查看data段