0x00 IDA pro
1. 两个版本
ida pro安装完成之后,会生成两个快捷方式,一个是ida pro(32-bit)一个是ida pro(64-bit),分别对应32位和64位程序
2. 分析程序
将文件拖动到ida中即可分析程序
常用快捷键
空格是看汇编
重命名 n
切换标签 tab
反编译F5
看汇编 空格
看字符串 shift + F12 ,
看各个段的位置 ctrl + s
查看反编译函数:tab/F5
查看字符串窗口:shift + F12
跳转到指定地址:G
追踪函数(交叉引用):X
解析成字符:R
反汇编窗口切换文本跟图形:space
重命名函数:N
退回到上个操作:esc
0x01 GDB
加载分析程序
gdb ./ret2text
退出gdb
q
运行程序
r / run
中断运行
ctrl + c
继续运行
c
下断点
b 函数名
b *函数地址
b function/b *addr
单步步入:
单步执行
ni #单步步过
si #单步步入
finish # 步出
计算器
p/d
查看当前函数汇编
disass
中断调试
gdb.attach(p)
退出当前函数
fini
查看当前文件权限
vmmap
查看栈结构
satck 大小
查看堆结构
heap
查看指定内存地址
x/40gx 地址
0x02 Pwntools
pwntools介绍
Pwntools是一个CTF框架和漏洞利用开发库,用Python开发,旨在让使用者简单快速的编写exploit。
几乎涵盖了做pwn题目脚本所需要用到的各种工具。
导入pwntools
from pwn import *
建立连接
建立连接对于解pwn题尤为重要,比赛时,一般会给你一个pwn题目文件(一般是linux elf文件),还会给你一个nc地址。
- elf文件用于本地调试,发现漏洞
- nc地址用于攻击,获取flag
因此,我们需要与nc服务器和elf文件建立连接。
与程序文件建立连接
我们可以利用pwnlib.elf模块来连接程序文件。
r = process('./bin') #本地创建进程,本地调试
elf = ELF('./process') #process为题目给出的程序文件
与服务器建立连接
我们通过pwnlib.tubes模块来连接服务器
r = remote('ip',port) #在对应位置填入题目给出的ip和端口
设置目标架构和操作系统
我们可以通过设置目标架构和操作系统,来告诉pwntools我们程序的运行环境,pwntools会自动帮我们调整对应的编译格式和字节序。
context.arch = 'i386' #32位程序设置为i386;64位程序设置为amd64,如果已经导入elf文件,可以写成context.arch = elf.arch
context.binary = './process' #可以用这种方法自动设置成适当的值
context.os = 'linux' #设置系统信息
context.log_level = 'debug' #可在屏幕上打印debug信息
context.terminal = ['tmux', 'splitw', '-h'] #告诉pwntools你的终端信息,方便后期动态调试
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context.terminal = ['ssh', '-x', 'sh', '-c']
context.endian = 'big' #设置字节序为大端序,小端序设置为little
交互
在了解了上述的一些准备工作之后,我们可以尝试开始和程序进行交互了。
接收数据
r.recv() #接收数据
r.recvline() #接收一行数据
r.recvall() #接收数据,直到达到EOF
发送数据
r.send() #发送数据
r.sendline() #发送一行数据
r.sendlineafter('str',payload) #当接收到指定数据时,发送数据
shell交互
r.interactive()
获取函数地址
当我们成功连接到程序文件时,我们可以利用pwntools快速获取函数地址。
例如获取puts函数地址:
puts_got_addr = elf.got['puts'] #获取puts函数got表地址
puts_plt_addr = elf.plt['puts'] #获取puts函数plt表地址
puts_sym_addr = elf.symbols['puts'] #获取puts函数符号表地址
shellcraft
我们做题时,会经常用到shellcode,但是每次都从网上找对应的shellcode会大大降低我们的做题效率。shellcraft模块可以帮我们自动生成shellcode。
shellcraft.sh()
打包解包&汇编
在我们发送和接收数据时,会经常使用打包解包操作。
p32() #将数据打包成32位二进制格式,字节序由context.endian设置
p64() #将数据打包成64位二进制格式,字节序由context.endian设置
u32() #将32位二进制格式数据解包
u64() #将64位二进制格式数据解包
有时我们也会用到汇编操作,例如我们要发送shellcode:
shellcode = asm(shellcraft.sh())
r.sendline(shellcode)
0x03 one_gadget
Github:GitHub - david942j/one_gadget: The best tool for finding one gadget RCE in libc.so.6
1. 支持架构:
- i386
- amd64 (x86-64)
- aarch64 (ARMv8)
2. 用法
$ one_gadget
# Usage: one_gadget <FILE|-b BuildID> [options]
# -b, --build-id BuildID BuildID[sha1] of libc.
# -f, --[no-]force-file Force search gadgets in file instead of build id first.
# -l, --level OUTPUT_LEVEL The output level.
# OneGadget automatically selects gadgets with higher successful probability.
# Increase this level to ask OneGadget show more gadgets it found.
# Default: 0
# -n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file.
# -r, --[no-]raw Output gadgets offset only, split with one space.
# -s, --script exploit-script Run exploit script with all possible gadgets.
# The script will be run as 'exploit-script $offset'.
# --info BuildID Show version information given BuildID.
# --base BASE_ADDRESS The base address of libc.
# Default: 0
# --version Current gem version.
#eg:
$ one_gadget libc.so
root@ubuntu:~/pwn$ one_gadget libc-2.23.so
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf0274 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1117 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
0x04 checksec
1. 用法
检查保护机制
$ checksec ./pwn
0x05 ROPgadget
Github:GitHub - JonathanSalwan/ROPgadget: This tool lets you search your gadgets on your binaries to facilitate your ROP exploitation. ROPgadget supports ELF, PE and Mach-O format on x86, x64, ARM, ARM64, PowerPC, SPARC, MIPS, RISC-V 64, and RISC-V Compressed architectures.
1. 用法
usage: ROPgadget.py [-h] [-v] [-c] [--binary <binary>] [--opcode <opcodes>]
[--string <string>] [--memstr <string>] [--depth <nbyte>]
[--only <key>] [--filter <key>] [--range <start-end>]
[--badbytes <byte>] [--rawArch <arch>] [--rawMode <mode>]
[--rawEndian <endian>] [--re <re>] [--offset <hexaddr>]
[--ropchain] [--thumb] [--console] [--norop] [--nojop]
[--callPreceded] [--nosys] [--multibr] [--all] [--noinstr]
[--dump] [--silent] [--align ALIGN] [--mipsrop <rtype>]
description:
ROPgadget lets you search your gadgets on a binary. It supports several
file formats and architectures and uses the Capstone disassembler for
the search engine.
formats supported:
- ELF
- PE
- Mach-O
- Raw
architectures supported:
- x86
- x86-64
- ARM
- ARM64
- MIPS
- PowerPC
- Sparc
optional arguments:
-h, --help show this help message and exit
-v, --version Display the ROPgadget's version
-c, --checkUpdate Checks if a new version is available
--binary <binary> Specify a binary filename to analyze
--opcode <opcodes> Search opcode in executable segment
--string <string> Search string in readable segment
--memstr <string> Search each byte in all readable segment
--depth <nbyte> Depth for search engine (default 10)
--only <key> Only show specific instructions
--filter <key> Suppress specific mnemonics
--range <start-end> Search between two addresses (0x...-0x...)
--badbytes <byte> Rejects specific bytes in the gadget's address
--rawArch <arch> Specify an arch for a raw file
x86|arm|arm64|sparc|mips|ppc
--rawMode <mode> Specify a mode for a raw file 32|64|arm|thumb
--rawEndian <endian> Specify an endianness for a raw file little|big
--re <re> Regular expression
--offset <hexaddr> Specify an offset for gadget addresses
--ropchain Enable the ROP chain generation
--thumb Use the thumb mode for the search engine (ARM only)
--console Use an interactive console for search engine
--norop Disable ROP search engine
--nojop Disable JOP search engine
--callPreceded Only show gadgets which are call-preceded
--nosys Disable SYS search engine
--multibr Enable multiple branch gadgets
--all Disables the removal of duplicate gadgets
--noinstr Disable the gadget instructions console printing
--dump Outputs the gadget bytes
--silent Disables printing of gadgets during analysis
--align ALIGN Align gadgets addresses (in bytes)
--mipsrop <rtype> MIPS useful gadgets finder
stackfinder|system|tails|lia0|registers
examples:
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --ropchain
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --depth 3
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --string "main"
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --string "m..n"
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --opcode c9c3
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --only "mov|ret"
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --only "mov|pop|xor|ret"
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --filter "xchg|add|sub|cmov.*"
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --norop --nosys
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --range 0x08041000-0x08042000
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --string main --range 0x080c9aaa-0x080c9aba
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --memstr "/bin/sh"
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --console
ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --badbytes "00|01-1f|7f|42"
ROPgadget.py --binary ./test-suite-binaries/Linux_lib64.so --offset 0xdeadbeef00000000
ROPgadget.py --binary ./test-suite-binaries/elf-ARMv7-ls --depth 5
ROPgadget.py --binary ./test-suite-binaries/elf-ARM64-bash --depth 5
ROPgadget.py --binary ./test-suite-binaries/raw-x86.raw --rawArch=x86 --rawMode=32
0x06 LibcSearcher
Github:GitHub - lieanu/LibcSearcher: glibc offset search for ctf.
1. 简介
这是针对CTF比赛所做的小工具,在泄露了Libc中的某一个函数地址后,常常为不知道对方所使用的操作系统及libc的版本而苦恼,常规方法就是挨个把常见的Libc.so从系统里拿出来,与泄露的地址对比一下最后12位。
2. 安装
git clone https://github.com/lieanu/LibcSearcher.git
cd LibcSearcher
python setup.py develop
3. 用法
from LibcSearcher import *
#第二个参数,为已泄露的实际地址,或最后12位(比如:d90),int类型
libc = LibcSearcher("fgets", 0X7ff39014bd90)
libc.dump("system") #system 偏移
libc.dump("str_bin_sh") #/bin/sh 偏移
libc.dump("__libc_start_main_ret")
注:如遇到无法找到对应libc库的情况,可以使用在线的查找工具
http://game2.ericdshen.com:31337/
0x07 GCC编译
命令参数
1.关掉DEP/NX(堆栈不可执行)
gcc -z execstack -o level level.c
2.关掉Stack Protector/Canary(栈保护)
gcc -fno-stack-protector -o level level.c
3.关掉/开启程序ASLR/PIE(程序随机化保护)
gcc -no-pie level level.c gcc -pie level level.c
4.关闭/开启整个linux系统的ASLR保护
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space exit sudo -s echo 2 > /proc/sys/kernel/randomize_va_space
5.64位linux下面的GCC编译出一个32位可执行程序
#加参数 -m32 gcc -m32 -z execstack -fno-stack-protector -o level level.c
6.关闭所有保护
gcc -z execstack -fno-stack-protector -no-pie -o level level.c
0x08 常用命令
1. file命令
查看文件类型
$ file ./pwn
2. ldd命令
查看库
$ ldd ./pwn
3. objdump命令
反汇编
$ objdump -d -M intel ./pwn
def dbg():
gdb.attach(r)
pause()
在需要调试的地方插入dbg(),如果我们之前在context.terminal中设置好终端类型,会自动帮我们开启新的终端窗口并打开gdb调试。
查看文件在硬盘中的结构
objdump -s elf
版权归原作者 加冕@ 所有, 如有侵权,请联系我们删除。