Pwn_notes
常规思路
- 检查保护情况
- 判断漏洞函数,如 gets,scanf 等
- 计算目标变量在堆栈中距离 epb 的偏移
- 分析是否已经载入可利用的函数,如 system,execve 等
- 分析是否有字符串/bin/sh
IDA Pro 使用技巧
IDA Pro7.0使用技巧总结
返回地址偏移获取
用 gets(&s) 作为例子
方法一:IDA && pattern.py
gdb 函数断点,查看 esp、ebp,结合 IDA 如: char s; // [esp+1Ch] [ebp-64h] ,计算变量 s 地址距离 ebp 的偏移,返回地址为 ebp+4(64位+8)
使用 pattern.py
生成字符串,先结合 linux_serevr/linux_server64 以及 IDA 远程调试,通过在服务端将 pattern 生成的字符串作为输入确定覆盖的 ebp 的内容,使用命令:python3 pattern.py 0x41366441
(比如覆盖的 ebp 内容为 0x41366441,对应字符串 A6dA)计算输入的 s 缓冲区地址距离 ebp 相差多少字节,如下图:
ebp 的内容可通过 IDA 获取,综上,偏移为 108 字节,ebp 之后是返回地址,即 108+4=112 字节
方法二:Gdb && pattern.py
- gdb file_name
python pattern.py 500
,生成填充字符
- 将
pattern.py
生成的字符粘贴至 gdb 调试窗口,查看报错信息
python pattern.py 0x37654136
,查看偏移量
即偏移为 140 字节,距离返回地址的偏移为 140 + 4 = 144 字节
GDB 调试技巧
基础操作
- s 步入执行,n 步过执行,c语言级别的断点定位,s会进入C函数内部,但是不会进入没有定位信息的函数
- si 步入执行,ni 步过执行,汇编级别的断点定位
- b 在某处下断点,可以用
- b * adrress
- b function_name
- info b #查看断点信息
- delete 1 #删除第一个断点
- b 7 ,表示在源代码中第七行下断点,也可以 b a.c:7 来指定具体文件
- c 继续
- r 执行
- disas addr 查看 addr 处前后的反汇编代码,也可以是函数名字
查看数据
- p 系列
- p system/main 显示某个函数地址
- p $esp 显示寄存器
- p/x p/a p/b p/s …
- p 0xff - 0xea 计算器
- print &VarName 查看变量地址
- p * 0xffffebac 查看某个地址处的值
- x系列
- x/xw addr 显示某个地址处开始的16进制内容,如果有符号表会加载符号表
- x/x $esp 查看 esp 寄存器中的值
- x/s addr 查看 addr 处的字符串
- x/b addr 查看 addr 处的字符
- x/i addr 查看 addr 处的反汇编结果
- gx,wx,bx,分别表示查看八字节,四字节,单字节,前面还可以跟数字,表示查看的数量,如 x/20gx
- info系列
- info register $ebp 查看寄存器ebp中的内容 (简写为 i r ebp)
- i r eflags 查看状态寄存器
- i r ss 查看段寄存器
- i b 查看断点信息
- i functions 查看所有的函数
- disass addr 查看 addr 处前后的反汇编代码
- stack 20 查看栈内 20 个值
- vmmap 查看映射状况
- elfheader 查看 elf 文件中各个段的起始地址
- argc 打印出参数的数量。
- args 打印出 argv 的内容
- telescope +地址,直接以栈的形式查看某个地址
查找数据
- search 查找内存中的各种数据,能搜各种字节大小的数据,指针,整数,可用-h查看具体用法
- pwndbg 支持rop,ropper,ROPgadget
- plt,got,查看对应的表的内容
- code,查看 elf 的偏移基址
- canary 查看 canary 的值
- retaddr 打印出包含返回地址的堆栈地址
- find addr,+len,“/bin/sh” 查找字符串,peda 可直接 find “/bin/sh”
修改数据
- set $esp=0x110 修改寄存器的值
- set *0xf7ff3234=0x08042334 修改内存的值
- set args “asdasg” “afdasgasg” “agasdsa” 分别给参数1,2,3赋值
- set args “python -c ‘print “1234\x7f\xde”‘“ 这个参数中用 python 脚本重写了一下,避免有些字符无法正确设置
- r “arg1” “arg2” “arg3” 设置参数
- run $(perl -e ‘print “A”x20’)
- run $(perl -e ‘print “A”x20’)
- 使用 cyclic 100 创建100字符,用来溢出输入,再用 cyclic -l xxx 得到偏移
参考:https://z3r3f.gitee.io/2018/12/03/GDB及其插件的常用调试技巧/
Pwndbg/Peda/Gef
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#pwndbg
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh
#peda
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit
#gef
wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.sh| sh
wget -q -O ~/.gdbinit-gef.py https://github.com/hugsy/gef/raw/master/gef.py
echo source ~/.gdbinit-gef.py >> ~/.gdbinit
|
gdb 插件自动选择脚本,放环境变量路径中,可通过 echo $PATH 查看环境变量(也可通过 vim ~/.gdbinit 注释掉不用的插件)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#!/bin/bash
function Mode_change {
name=$1
gdbinitfile=~/.gdbinit #这个路径按照你的实际情况修改
# gdbinitfile=/root/Desktop/mode
peda="source ~/peda/peda.py" #这个路径按照你的实际情况修改
gef="source ~/.gdbinit-gef.py" #这个路径按照你的实际情况修改
pwndbg="source /opt/pwndbg/gdbinit.py" #这个路径按照你的实际情况修改
sign=$(cat $gdbinitfile | grep -n "#this place is controled by user's shell")
#此处上面的查找内容要和你自己的保持一致
pattern=":#this place is controled by user's shell"
number=${sign%$pattern}
location=$[number+2]
parameter_add=${location}i
parameter_del=${location}d
message="TEST"
if [ $name -eq "1" ];then
sed -i "$parameter_del" $gdbinitfile
sed -i "$parameter_add $peda" $gdbinitfile
echo -e "Please enjoy the peda!\n"
elif [ $name -eq "2" ];then
sed -i "$parameter_del" $gdbinitfile
sed -i "$parameter_add $gef" $gdbinitfile
echo -e "Please enjoy the gef!\n"
else
sed -i "$parameter_del" $gdbinitfile
sed -i "$parameter_add $pwndbg" $gdbinitfile
echo -e "Please enjoy the pwndbg!\n"
fi
}
echo -e "Please choose one mode of GDB?\n1.peda 2.gef 3.pwndbg"
read -p "Input your choice:" num
if [ $num -eq "1" ];then
Mode_change $num
elif [ $num -eq "2" ];then
Mode_change $num
elif [ $num -eq "3" ];then
Mode_change $num
else
echo -e "Error!\nPleasse input right number!"
fi
gdb $1 $2 $3 $4 $5 $6 $7 $8 $9
|
ROPgadget/one_gadget
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 先安装 Capstone,它是一个轻量级的多平台架构支持的反汇编架构。
sudo apt-get install python-capstone
# 下载好 ROPgadget 解压,并进入文件夹中
python setup.py install
#查找汇编代码
ROPgadget --binary file_name --only 'pop|ret'
#查找字符串
ROPgadget --binary file_name --string '/bin/sh'
#one_gadget
sudo apt install ruby
gem install one_gadget
|
1
2
3
4
|
// 安装
gem install seccomp-tools
// 使用
seccomp-tools dump ./orw
|
LibcSearcher
1
2
3
4
|
sudo pip install capstone
git clone https://github.com/lieanu/LibcSearcher.git
cd LibcSearcher
python setup.py develop
|
qemu
arm 环境
1
2
3
4
5
|
sudo apt-get install qemu
sudo apt-get install qemu-system qemu-user-static binfmt-support
#依赖
sudo apt-get install -y gcc-arm-linux-gnueabi
sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi build-essential gdb-arm-none-eabi synaptic gcc-aarch64-linux-gnu eclipse-cdt git
|
编译相关
编译 32 位程序:
1
2
3
4
5
6
7
8
9
10
|
#安装依赖
sudo apt-get install build-essential module-assistant gcc-multilib g++-multilib
or apt-get install libc6-dev-i386
#编译
gcc -m32 -fno-stack-protector -z execstack -o demo demo.c
#关闭 ASLR
echo 0 > /proc/sys/kernel/randomize_va_space
#打开 ASLR
echo 2 > /proc/sys/kernel/randomize_va_space
|