ctf(pwn&reverse)总结
0x01 PWN
checksec下载安装
git clone https://github.com/slimm609/checksec.sh.git
sudo ln -s /xx/xx/checksec /usr/local/bin/checksec #建立软链接,源地址需要是绝对路径
ida
F5/tab 查看伪代码
空格 查看汇编代码
视图->打开子视图->字符串 :查看所有字符串
编辑->修补程序 :修改程序 修改完后点击修补程序应用到输入文件即可保存修改
1、如何找到使用.rodata里数据的汇编行
选中字符串后鼠标右键点击交叉引用列表
2、查看二进制里所有的字符串
视图->子视图->字符串
2、ida联合gdb进行远程调试
F8单步调试,F9单步进入函数
https://uuzdaisuki.com/2020/02/04/ida%E8%BF%9C%E7%A8%8B%E8%B0...
python pwntools
安装 :pip install pwntools
环境:ubuntu python64位
调试:context(os='linux', arch='amd64', log_level='debug') 32位时改为i386
导入外部lib:from ctypes import *
ex:使用c的rand函数
libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
libc.srand(1)
libc.rand()
- sendlineafter("在什么字符串后面发送数据",要发送的数据)
- ljust(num,b'a') 补全payload,使长度为num字节
- recvlineuntil() 可以截取收到内容中想要的数据
- asm(shellcraft.sh()) 生成shell,使用前需要用context声明环境
- elf=ELF(filepath) 解析elf文件,输出checksec数据
- 使用p32等 from pwnlib.util.packing import p32
pwn
汇编转机器码
from pwn import *
context.arch='i386' #指定架构
print(asm('mov eax, 0'))
gdb
- gdb filename :调试某个文件
- info reg 查看寄存器的值
- info args:打印当前函数参数名机值
- info frame:打印当前函数的栈信息
- info locals:打印当前函数所有局部变量及值
- c(continue):继续执行/n(next):单步跟踪/s(step):步入
- ni/si都是汇编级别的断点定位。si会进入汇编和C函数内部,ni不会。
- start:重新启动程序
- x /8gx:以16进制 输出8个64位数
x /10x $sp:输出当前堆栈栈顶往下10个栈里的值 - set $edx=0x12 修改寄存器的值
- set args in/test.mp3 设置程序的参数
show args 显示设置的参数 - r < test.txt 从标准输入进行读取,先创建一个文件
- p 变量名 查看变量在内存中的位置及值
p/x $rax 查看rax寄存器里的值 - disa main 查看main函数的反汇编代码
- bt 查看调用栈
gdb ./test core 调试core文件
设置断点 1、b *0x111111 : 在0x11111处下断点,记得前面要加* 2、b func_name 3、b /src/codefile.cc:81。gdb将在运行到源码文件/src/codefile.cc的第81行中断 删除断点 delete [断点编号] 查看断点 info break
pwndbg
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
sudo #./setup.sh
命令
- parseheap 展示堆结构
- fastbins fastbins指针
pwn
- 将汇编转成机器码
from pwn import *
context.arch='i386' #指定架构
print(asm('mov eax, 0'))
questions
- 遇到执行elf文件提示没有那个目录或文件
解决:
Ubuntu 32位库的安装:
ubuntu64位默认没有32位的库,所以32位的ELF文件无法执行,会提示找不到文件或者文件夹,所以需要手动安装32位的库。
sudo apt install libc6-dev-i386
sudo apt-get install lib32z1 - 实验不同版本的glibc,patchelf和glibc-all-in-one
https://blog.csdn.net/qq_41560595/article/details/114597342
0x02 reverse
elf文件upx脱壳 :kali下 upx -d 源文件 -o 目标文件
0x03 汇编知识点
1、32位计算机常用寄存器
2、x86-64位架构中的寄存器
寄存器 描述
RAX 通用寄存器,可用于存储整数数据或指针
RBX 通用寄存器,可用于存储整数数据或指针
RCX 通用寄存器,可用于存储整数数据或指针
RDX 通用寄存器,可用于存储整数数据或指针
RDI 存储函数参数
RSI 存储函数参数
RBP 存储函数局部变量
RSP 存储函数栈指针
R8-R15 存储函数参数或临时数据
RIP 存储下一条要执行的指令的地址
RFLAGS 存储处理器状态信息,例如进位标志、零标志和符号标志等
XMM0-XMM15 扩展多媒体寄存器,可用于存储浮点数和矢量数据
3、标识寄存器
4、syscall命令
syscall 指令用于在 x86-64 架构的 64 位模式下将控制权从用户空间代码转移到内核。当执行 syscall 时,处理器将当前 RIP(指令指针)保存在 RCX 寄存器中,将当前的 RFLAGS 寄存器保存在 R11 寄存器中。系统调用号加载到 RAX 寄存器中,而系统调用参数依次放置在 RDI、RSI、RDX、R10、R8 和 R9 寄存器中。
系统调用完成后,返回值存储在 RAX 寄存器中。R11 寄存器包含系统调用返回时的 RFLAGS 值,RCX 寄存器包含保存的 RIP 值。内核通过执行 iretq 指令将控制权返回给用户空间代码,该指令恢复保存的 RIP 和 RFLAGS 值,并切换回用户模式执行。
5、标志寄存器 https://en.wikipedia.org/wiki/FLAGS_register
0x04 深度拓展
gdb原理
https://mp.weixin.qq.com/s/teERWh9IRMuO6tieOZNNng
1、gdb ./a.out
以这种方式直接运行时,首先,gdb解析a.out文件的符号。接下来我们输入 run 命令,gdb通过 fork() 一个新进程,然后通过 ptrace(PTRACE_TRACEME, 0, NULL, NULL); 设置traceme模式。最后执行 exec 启动加载要调试的文件。
2、attach pid
在调试PWN题时,通过attach pid来追踪要调试的进程。gdb通过执行 ptrace(PTRACE_ATTACH,pid, 0, 0) 来对目标进程进行追踪。
3、gdb server的target remote
在gdb+qemu调试内核时,经常用到target remote来attach到qemu上对vmlinux进行调试。二者之间有特殊的定义好的数据信息通信的格式,进行通信。
4、汇编转化成机器码 调试测试写好的汇编
https://www.cnblogs.com/ZIKH26/articles/15845766.html
Docker逃逸
白风之下阅读 483
安全地在前后端之间传输数据 - 「3」真的安全吗?
边城赞 29阅读 6.4k评论 5
安卓逆向之破解某成人APP播放次数限制
悖论赞 3阅读 1.4k评论 3
http 和 https 的通信过程及区别
tiny极客赞 2阅读 2.8k评论 2
支付对接常用的加密方式介绍以及java代码实现
京东云开发者赞 3阅读 486
JWT 登录认证
tiny极客赞 2阅读 978评论 1
什么是跨域?如何解决跨域?
tiny极客赞 1阅读 825评论 1
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。