ROPgadget
ROPgadget –binary 文件名 –only “指令|指令” | grep 寄存器或者其他存在的字段
查找汇编指令的地址
例子:
ROPgadget –binary get_started_3dsctf_2016 –only “mov|ret” |grep eax
ROPgadget –binary get_started_3dsctf_2016 –only “mov|ret” |grep ‘: mov eax’
–only ” | “ 表示只返回含有xx指令或xx指令的gadget
grep 表示含有什么什么特定字段(通常是寄存器)的指令
但是grep能寻找的必须是连续的指令中间不能隔开,连空格都必须一致才能被搜索到
比如你想要搜索
0x080701a8 : mov eax, ecx ; ret
,你可以用命令ROPgadget --binary get_started_3dsctf_2016 --only "mov|ret" |grep 'eax, ecx'
;命令ROPgadget --binary get_started_3dsctf_2016 --only "mov|ret" |grep 'eax,ecx'
无法成功因为逗号和ecx之间少了一个空格取地址的指令[edx]无法被识别,[ ]在ROPgadget中貌似是表示含有[ ]内字母的指令
比如 ROPgadget –binary get_started_3dsctf_2016 –only “mov|ret” |grep ‘[edx]’得到的是这样
ROPgadget –binary 文件名 –sting ‘/bin/sh’
查找字符串地址
例子:
ROPgadget –binary 文件名 –sting ‘/bin/sh’
ROPgadget –binary 文件名 –sting ‘/sh’
ROPgadget –binary 文件名 –sting ‘sh’
ROPgadget –binary 文件名 –sting ‘cat flag’
ROPgadget –binary 文件名 –sting ‘cat flag.txt’
![(
vmmap
vmmap [-h] [pages_filter]
首先vmmap需要在pwndbg,且程序运行时使用
- 输入vmmap,显示出程序运行时所用到的所有地址段
- 输入vmmap 地址 ,显示该地址对应的地址段
- vmmap -h,提示帮助;-w只显示可写的部分;-x只显示可执行的部分
例子:
第一行,表明了哪个颜色对应哪个段,
start和end对应该地址段的起始和结束位置
Perm 是该段的权限,rwx代表可读、可写、可执行
Size表示该段大小
Offset表示这段与程序基址的偏移
File表示加载的是什么
vim
命令模式下:
$ 行末
^ 行首
L 屏幕底行
H 屏幕顶行
yy 拷贝该行
dd 删除该行
P 前粘贴
p 后粘贴
D 删除至行尾
u 撤销
gg 光标移至行首
dG 删除光标行及光标行以下全部内容
底线命令模式下:
:wq 保存并退出
:%d 删除全部内容
:%s 替换 参考(万里哥我滴神)
pwndbg
基本指令
- r = run 运行程序,如果你当前已经在运行程序了,再输入r会重新运行程序
- b = break 下断点,在调试pwn中,一般是 b 0xabcde ,abcde是在ida中看到的地址,如b 0x400908
- c = continue 继续运行程序直到停在下一个断点
- n = next 下一行,一般装了pwndbg之后下一行指的是下一条汇编,但是如果调试的程序是带调试信息的,一般会跳几行汇编
- ni = nexti 下一条指令,这个就是真正的下一条汇编指令
- s = step 单步进入函数
- d = delete 删除断点,后面可带数字,说明删除第几个断点,如果不带参数,说明删除全部断点
- x 查看内存
c,n,ni这几个程序都可以带一个数字,用来代表连续运行这个指令多少次
x/num xg 地址 64位查看某处地址
x/num xw 地址 32位查看某处地址
s/num s 地址 查看从地址开始的num个字符串
b *$rebase(地址) 用于开启PIE该指令会在基址+地址处下断点
https://wizardforcel.gitbooks.io/100-gdb-tips/content/index.html
100个gdb小技巧
gdb制定程序运行的参数
gdb –args binary value
gdb调试改变地址或地址指向值
set addr_old = addr
set *addr_old = addr
bt
显示函数所有调用栈的信息
bt n
显示栈顶的n个调用信息
bt -n
显示栈底的n个调用信息
中间加full表示 显示栈中所有帧的完全信息如:函数参数,本地变量
ASLR和pie编译
查看系统当前ASLR打开情况
sudo cat /proc/sys/kernel/randomize_va_space
ASLR的三个级别 :
0, 不开启任何随机化;
1, 开启stack、libraries [、executable base(special libraries -^-) if PIE is enabled while compiling] 的随机化;
2,开启heap随机化。
PIE编译出来的executable如果ASLR=0的话,基址也是不会变的(有能力但没使用),如果ASLR=1的话,即使按照ASLR定义这个级别似乎不会对heap基址随机化,但是由于executable的基址已经随机化了,所以heap的基址自然也就被随机化了
指令关闭ASLR
sysctl -w kernel.randomize_va_space=0
echo 0 > /proc/sys/kernel/randomize_va_space
fPIE选项仅能在编译可执行码时用,不能用于编译库。所以,如果想要PIE的程序,需要你除了在gcc增加-fPIE选项外,还需要在ld时增加-pie选项才能产生这种代码。即gcc -fpie -pie来编译程序。单独使用哪一个都无法达到效果。
gcc helloworld.c
file a.out a.out:
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
file a.out a.out:
ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
未开启PIE的文件属性为executable,开启的为shared object
注意PIE随机程序加载基地址,要和libc的随机libc库基地址区分
shellcode
pwntools生成的shellcode默认64位
shellcode = asm(shellcraft.sh())
要生成32位的shellcode需要指定
shellcode = asm(shellcraft.sh(),arch=’i386’,os=’linux’)
手动反汇编汇编指令
xx = asm(‘’’
‘’’)
GCC编译指令
gcc各保护编译指令
https://blog.csdn.net/tabactivity/article/details/126660974
https://zoepla.github.io/2018/04/gcc%E7%9A%84%E7%BC%96%E8%AF%91%E5%85%B3%E4%BA%8E%E7%A8%8B%E5%BA%8F%E4%BF%9D%E6%8A%A4%E5%BC%80%E5%90%AF%E7%9A%84%E9%80%89%E9%A1%B9/
全开
gcc test.c -o test -z noexecstack -z now -fstack-protector -fpie -pie
全关
gcc test.c -o test -z execstack -z norelro -fno-stack-protector -no-pie
sudo sh -c “echo 0 > /proc/sys/kernel/randomize_va_space”关闭ASLR
把0换成2就是开启
编译时加上 -m32 即编译成32位程序
https://blog.csdn.net/Jason_ZhouYetao/article/details/81606358
关于符号表
readelf binary -p .comment
或 objdump -s --section=.comment binary
可以查看程序或编译器版本
readelf,objdump,去符号表,恢复符号表
上链接
readelf
objdump
去符号表
恢复符号表
patchelf
patchef四部曲
ldd binary
列出动态库依赖
strings 题目给的libc名 | grep ubuntu
快速找到Libc文件对应版本
(cp 想替换的文件到赛题目录)
patchelf –set-interpreter ./ld-2.27.so ./binary
—————————对应的ld文件—-pwn文件
patchelf –replace-needed libc.so.6 ./libc-2.27.so ./binary
————————-原本的libc—-要替换的libc—–pwn文件
(若只用上述命令碰到如下报错时)
patchelf –replace-needed libpthread.so.0 ./libpthread-2.31.so ./binary
——————————–原本的 ——— 要替换的
Linux命令
pwd :获取当前所在目录路径
realpath file : 获取文件地址
pip list查看已安装包
pip show 包名 查看包安装路径