PWN笔记更新中

2025-1-26 274 1/26

PWN(二进制漏洞)

术语

exploit
用于攻击的脚本与方案
payload
攻击载荷,是目标进程被劫持控制流的数据
shellcode
调用攻击目标的shell代码

基础知识

PWN笔记更新中

 

可执行文件的分类
Windows:PE(Portable Executable)
    可执行程序
        .exe
    动态链接库
        .dll
    静态链接库
        .lib

Linux: ELF(Executable and Linkable Format)
    可执行程序
        .out
    动态链接库
        .so
    静态链接库
        .a

ELF文件头表(ELF header)
    记录了ELF文件的组织结构
程序头表/段表(Program header table)
    告诉系统如何创建进程
    生成进程的可执行文件必须拥有此结构
    重定位文件不一定需要
节头标(Section header table)
    记录了ELF文件的节区信息
    用于链接的目标文件必须拥有此结构
    其他类型目标文件不一定需要

可执行文件
广义:文件中的数据是可执行代码的文件
.out .exe .sh .py
狭义:文件中的数据是机器码的文件
.out .exe .dll .so

段(segment)与节(section)

- 代码段(text segment):包含了代码与只读数据。其中的节有:
-  .text 节:存放程序的机器代码。(例如存放main函数)
-  .rodata 节(readonly data):存放只读数据,如字符串常量等。
-  .hash 节、 .dynsym 节、 .dynstr 节、 .plt 节(解析动态函数的实际地址)、 .rel.got 节等。

- 数据段(data segment):包含了可读可写数据。常见的节包括:
-  .data 节:用于声明了的全局变量。
-  .dynamic 节、 .got 节(全局偏移表,Global Offset Table)、 .got.plt 节。
-  .bss 节:用于存放还未声明的全局变量,在磁盘中并不占用空间,运行的时候可能会占用内存空间。
PWN笔记更新中

 

大端序与小端序

大端序列

低地址存放数据低位、高地址存放数据高位
我们所主要关注的格式

小端序列

低地址存放数据高位、高地址存放数据低位

AMD64寄存器结构

r开头是64位寄存器
e开头是32位寄存器
    rax 8Bytes
    eax 4Bytes
    ax  2Bytes
    ah  1Byte
    al  1Byte

RIP
    存放当前执行的指令的地址
RSP
    存放当前栈帧的栈顶地址
RBP
    存放当前栈帧的栈底地址
RAX
    通用寄存器。存放函数返回值
64位 低32位 低16位 低8位 描述
rax eax ax al 累加器
rbx ebx bx bl 基地址
rcx ecx cx cl 循环记数器
rdx edx dx dl 数据寄存器,通常扩展A寄存器
rsi esi si sil 字符串操作的源索引
rdi edi di dil 字符串操作的目的索引
rbp ebp bp bpl 栈指针
rsp esp sp spl 基地址指针(栈帧基地址)
r8 r8d r8w r8b 新增通用寄存器
r9 r9d r9w r9b 新增通用寄存器
r10 r10d r10w r10b 新增通用寄存器
r11 r11d r11w r11b 新增通用寄存器
r12 r12d r12w r12b 新增通用寄存器
r13 r13d r13w r13b 新增通用寄存器
r14 r14d r14w r14b 新增通用寄存器
r15 r15d r15w r15b 新增通用寄存器

可执行文件结构

PWN笔记更新中

 

PWN笔记更新中

 

基础汇编

__cdecl函数调用约定
push ebp;mov ebp;sub esp,28h
28h 表示开辟40个字节空间
esp 栈顶,目前函数的栈顶
ebp 栈基址,目前函数的栈的基地址
push 指令为压栈指令
push ebp 表示将ebp的值压入栈中
mov ebp,esp 表示将esp的值拷贝到ebp,即ebp=esp
sub esp,28h 开辟40字节的空间

逆向过程中会遇到的函数

c语言

read 是一个系统调用,用于从文件描述符(fd)中读取数据到缓冲区(buf)
read(fd, buf, nbytes);
    fd:文件描述符,是一个非负整数,用于标识打开的文件。它通常通过 open 系统调用获得。
    buf:指向缓冲区的指针,用于存储从文件描述符读取的数据。
    nbytes:要读取的最大字节数。

system($0)等于system(/bin/sh) $0的ascii为0x24 0x30

python

flat 函数是 pwntools 提供的一个非常实用的工具,用于将多个值打包成一个字节字符串(byte string),这在构造攻击载荷(payload)时非常有用
remote('域名或ip',端口号)指定服务器
变量名.sendlineafter('需要等待的字符串',发送的数据)等待出现指定字符串再发送数据
elf.sym['函数名']读取函数的地址

工具环境

pwntools
gdb & pwndbg
IDA
其他工具

pwntools

下载地址:https://github.com/Gallopsled/pwntools
python安装:pip install pwntools(python -m pip install pwntools)
linux安装:apt-get install python3-pwntools

pwntools基本用法

from pwn import *#导入pwntools所有函数
context(arch='i386',os='linux')#指定目标系统环境
#(可写为context.arch="i386", context.os = "linux")
r = remote('exploitme.example.com', 31337)#第一个参数表示目标ip或域名,第二个参数表示端口号
#以下代码用于发送
r.send(asm(shellcraft.sh()))
#以下代码表示,将控制器给用户
r.interactive()
#send和sendline的区别
'''
send('a')发送a
sendline('a')发送a\n
'''
#一下代码用于接收
recv(n)
recvuntil(par1)
'''
recv(n)表示这个进程接收n字节的数据,recvuntil(par1)表示接收到par1就停止。两个函数的返回值都为接收到的数据
'''

常用的代码有:

context.arch="amd64" 表示预设目标环境的架构为AMD64
context.log_level="debug",表示预设log的级别是debug,一般用于调试。debub级别表示打印与进程交互的信息,默认是不打印的。
context.endian="little",表示预设目标环境是小端序(大部分机器都采用小端序)。如果将payload的形式改为大端序,可以写为context.endian="big".

recvline()表示读取一行数据

pwndbg

pwndbg下载地址:https://github.com/pwndbg/pwndbg

pwndbg常用命令

命令 解释 示例
r,c run:从头开始运行
continue:继续运行
 
b<函数名>
b*<地址>
d
设置断点到函数名
设置断点到某个特定地址
删除断点
b main
b* 0x401000
d 1
i Info:查看各类信息 info b(查看断点信息)
info proc mapping(查看内存分配)
si,ni,finish si:相当于其他调速器中的”Step Into(单步跟踪进入)“
ni:相当于其他调速器中的”Step Over“(单步跟踪)
si/ni:针对的是汇编指令,而s/n针对的是源代码
finish:跳出当前函数,相当于Step Out
 
x/<n/u/f> 查看内存地址的值
n表示长度,u表示字节数
f表示输出格式,其中x为十六进制,s为字符串,i为指令,b表示单字节,h表示双字节,w表示四字节,g表示八字节
x/20wx 0x7fffffffe81d(20表示20个单元,x表示hex编码,w表示word类型,该语句表示从地址0x7ffffffffe81d以hex编码查看20个word类型数据)
set 设置寄存器和内存值 set $eax = 0x004000000
set *0x8048a51=0x0

IDA

IDA快捷键

c code,将光标地址处的内容解析成代码
p public,在函数开始处使用p,从当前地址声明一个函数
d data,将光标地址处的代码解析成数据
u undefine,与p成对使用,取消函数的定义
x 查看光标地址的交叉引用
f5 查看汇编语言对应的c伪代码

其他工具

keypatch下载地址:https://github.com/keystone-engine/keypatch
one_gadget下载地址:https://github.com/david942j/one_gadget(linux下载:gem install one-gadget)
ROPgadget下载地址:https://github.com/JonathanSalwan/ROPgadget

栈溢出入门

栈的概念

1.栈满足先进后出原则
2.栈是向下生长的
3.压入数据是从右到左的
- THE END -
Tag:

1月26日19:35

最后修改:2025年1月26日
3

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论