PWN一些用到的指令和工具


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 包名 查看包安装路径


文章作者: lmarch2
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 lmarch2 !
评论
  目录