Pwn_notes

常规思路

  • 检查保护情况
  • 判断漏洞函数,如 gets,scanf 等
  • 计算目标变量在堆栈中距离 epb 的偏移
  • 分析是否已经载入可利用的函数,如 system,execve 等
  • 分析是否有字符串/bin/sh

IDA Pro 使用技巧

IDA Pro7.0使用技巧总结

返回地址偏移获取

用 gets(&s) 作为例子

方法一:IDA && pattern.py

  1. gdb 函数断点,查看 esp、ebp,结合 IDA 如: char s; // [esp+1Ch] [ebp-64h] ,计算变量 s 地址距离 ebp 的偏移,返回地址为 ebp+4(64位+8)

  2. 使用 pattern.py 生成字符串,先结合 linux_serevr/linux_server64 以及 IDA 远程调试,通过在服务端将 pattern 生成的字符串作为输入确定覆盖的 ebp 的内容,使用命令:python3 pattern.py 0x41366441(比如覆盖的 ebp 内容为 0x41366441,对应字符串 A6dA)计算输入的 s 缓冲区地址距离 ebp 相差多少字节,如下图:

pattern

ebp 的内容可通过 IDA 获取,综上,偏移为 108 字节,ebp 之后是返回地址,即 108+4=112 字节

方法二:Gdb && pattern.py

  1. gdb file_name

gdb

  1. python pattern.py 500,生成填充字符

pattern1

  1. pattern.py生成的字符粘贴至 gdb 调试窗口,查看报错信息

error_info

  1. python pattern.py 0x37654136,查看偏移量

get offset

即偏移为 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

Seccomp Tools

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