前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二进制学习

二进制学习

作者头像
wywwzjj
发布2023-05-09 14:28:10
9870
发布2023-05-09 14:28:10
举报
文章被收录于专栏:wywwzjj 的技术博客

每天学点新东西

代码语言:javascript
复制
exeinfo 可以看到壳信息
upx -d  upx脱壳

编译x86程序依赖
sudo apt-get install -y build-essential module-assistant gcc-multilib g++-multilib

搜索shellcode
gdb-peda$ shellcode search sh
Connecting to shell-storm.org...
Found 289 shellcodes
ScId	Title
[132]	Aix - execve /bin/sh - 88 bytes
[134]	Alpha - /bin/sh - 80 bytes
[107]	BSD/ppc - execve(/bin/sh) - 128 bytes
[814]	BSD/x86 - setreuid(geteuid(), geteuid()) and execve(/bin/sh, /bin/sh, 0)
[92]	BSD/x86 - execve(/bin/sh) & setuid(0) - 29 bytes
[601]	BSD/x86 - bindshell on port 2525 - 167 bytes
[362]	BSD/x86 - execve /bin/sh Crypt /bin/sh - 49 bytes
[93]	BSD/x86 - execve(/bin/sh) - 27 bytes
[144]	Cisco IOS - Connectback shellcode v1.0
[142]	Cisco IOS - Tiny shellcode v1.0
[143]	Cisco IOS - Bind shellcode v1.0
[131]	Sco/x86 - execve(/bin/sh, ..., NULL) - 43 bytes
[106]	FreeBSD/x86-64 - exec(/bin/sh) Shellcode - 31 bytes

查看 shellcode
gdb-peda$ shellcode display 98
Connecting to shell-storm.org...

; sm4x - 2008
; reverse portbind /bin/sh
; NULL free if address is.
; setuid(0); socket(); connect(); exit();
; 89 bytes
; FreeBSD 7.0-RELEASE

global _start
_start:

xor     eax, eax

; --- setuid(0)
push    eax
push    eax
mov     al, 0x17
push    eax
int     0x80



socat tcp-l:4000,fork exec:./pwn
nc 127.0.0.1 4000

libc查询 http://libcdb.com/

查找到gadget

代码语言:javascript
复制
objdump -d babypwn4 | egrep "ret|pop"

linux下shellcode的编写

  • 在 shellcode 中不能出现 /x00也就是NULL字符,当出现NULL字符的时候将会导致shellcode被截断,从而无法完成其应有的功能
  • 有一个int $0x80来执行系统调用

windows shellcode

代码语言:javascript
复制
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <windows.h>

int main(void) {
    char *shellcode =
            "\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b"
            "\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09"
            "\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d"
            "\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03"
            "\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81"
            "\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04"
            "\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03"
            "\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3"
            "\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68"
            "\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68"
            "\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9"
            "\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65"
            "\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01"
            "\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68"
            "\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68"
            "\x72\x6c\x64\x21\x68\x6f\x20\x57\x6f\x68"
            "\x48\x65\x6c\x6c\x8b\xcc\x57\x57\x51\x57"
            "\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c"
            "\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78"
            "\x69\x74\x54\x53\xff\xd6\x57\xff\xd0";
    DWORD why_must_this_variable;
    BOOL ret = VirtualProtect(
            shellcode,
            strlen(shellcode),
            PAGE_EXECUTE_READWRITE,
            &why_must_this_variable
    );
    if (!ret) {
        printf("VirtualProtect\n");
        return 0;
    }
    //printf("strlen(shellcode)=%d\n", strlen(shellcode));
    ((void (*)(void)) shellcode)();
    return 0;
}

pwn全景图

求余数运算反汇编,两者等价。

代码语言:javascript
复制
v5 = 3 * v0 - 0X30 * ((unsigned __int64)(0xAAAAAAAAAAAAAAABLL * (unsigned __int128)(3 * v0) >> 64) >> 5);

v5 = 3 * v0 % 0x30;

Assembly

Intel vs AT&T

  • 操作数顺序不同
  • 寄存器记法有差异
  • 立即数记法有差异
  • 访存寻址计法不同
  • 操作码助记符不同
image.png
image.png

程序模板

代码语言:javascript
复制
TITLE Program Template  ; 标题可有可无

include irvine32.inc  ; 包含头文件

.data
; 数据区,声明全局变量
val1 dword 10000h
val2 dword 40000h
val3 dword 20000h
finalVal dword ?

.code
; 代码区
main PROC
	mov eax, val1		; start with 10000h
	add eax, val2		; add 40000h
	sub eax, val3		; subtract 20000h
	mov finalVal, eax	; store the result (30000h)
	call DumpRegs		; display the registers
	exit
main ENDP

funcName PROC

	ret
funcName ENDP

END main

寄存器

代码语言:javascript
复制
;    16 bits	8 bits	8 bits
eax     ax 		  ah 	  al 	; 累加器,是很多加、乘法指令的缺省寄存器
ebx		bx		  bh	  bl	; 基地址寄存器,在内存寻址时存放基地址
ecx		cx		  ch	  cl	; 计数器,是 rep 和 loop 的内定计数器
edx 	dx		; 总是用来放整数除法产生的余数
esp 	sp		; 栈顶指针
ebp		bp		; 基址指针
edi		di		; 目的变址
esi		si		; 源变址
eip		ip		; 指令指针,指向下一条指令的内存地址
eflags	flags 	; 标志

数据类型

代码语言:javascript
复制
var db ?   ; 声明一个字节,未初始化
var db 64  ; 声明一个字节,初始值为 64
db 10	   ; 声明一个没有 label 的字节,值为 10
var dw ?   ; 2 字节
var dd 40  ; 4 字节
arr dd 1, 2, 3  ; 数组,初始值为 1, 2, 3
arr db 10 dup(?)  ; 10个元素的数组,未初始化
arr dd 100 dup(0) ; 100 个元素,初始化为 0
str db 'hello',0  ; 字符串,注意 0 结尾

寻址模式

直接内存寻址

寄存器间接寻址

代码语言:javascript
复制
mov eax, [ebx]  ; 将 ebx 值指示的内存地址中的 4 个字节传送到 eax 中
mov [var], ebx  ; 将 ebx 的内容传送到 var 值指示的内存地址中
movsx dest, src  ; 8 / 16 bits => 16 / 32 bits,扩展传送

常用指令

mov

代码语言:javascript
复制
mov <reg>, <reg>
mov <reg>, <mem>
mov <mem>, <reg>
mov <reg>, <const>
mov <mem>, <const>

mov byte ptr [var], 5

push

代码语言:javascript
复制
push <reg32>

pop

lea

Load Effective Address

代码语言:javascript
复制
lea <reg32>, <mem>

lea eax, [var] 		 ;将地址 var 放入寄存器 eax 中
lea edi, [ebx+4*esi] ;edi = ebx+4*esi
; 某些编译器会使用 lea 指令来进行算数运算

leave

代码语言:javascript
复制
在32位汇编下相当于:
mov esp,ebp;//将ebp指向(ebp内部应当保存一个地址,所谓指向即这个地址对应的空间)的值赋给esp
pop ebp
 
leave指令将EBP寄存器的内容复制到ESP寄存器中,以释放分配给该过程的所有堆栈空间。
然后,它从堆栈恢复EBP寄存器的旧值。

ret

代码语言:javascript
复制
push src  ; 将 src 的数据存入栈中,不允许使用立即数寻址方式。
pushad  ;通用寄存器全入栈
pop dst  ; 用 dst 接收出栈数据,不能使用 cs 段寄存器
popad  ; 通用寄存器依次出栈

dumpregs  ; 显示所有寄存器信息
dumpmem  ; 显示所有内存信息


inc reg/mem  ; ++
dec reg/mem  ; --

xlat  ; 换码指令,默认 al 寄存器?

xchg reg, mem/reg  ; 交换两操作数内容
; 两操作数中必须有一个在寄存器中
; 操作数不能为段寄存器和立即数
; 源和目的操作数类型要一致

shl opr, cnt  ; 逻辑左移 cnt 位
shr opr, cnt
sal opr, cnt  ; 算术左移,同逻辑左移
sar opr, cnt
rol opr, cnt  ; 循环左移
ror opr, cnt

call writestring  ; 显示 edx 中的值
readstring buffer ; 输入字符串存到 buffer?

; 输入输入函数
readint
; 返回值:cf = 0  => 输入存放在 eax 中,cf = 1  =>  输入无效

writeint
; 输出 eax 中的整数

; 类型 ptr 内存操作数或标号

cmp dword ptr [edx + 4*esi], 8  ; 强转后直接能比较

rep stosed  ; 重复?

; 函数写完了记得 ret
sub esp, 8
add esp 12  ; 注意回收栈中分配空间
adc ; 进位加法,从进位标志寄存器中读值

控制转移

代码语言:javascript
复制
jmp ;无条件
j[condition] ;条件跳转
cmp
call
ret
代码语言:javascript
复制
JE   ;等于则跳转
JNE  ;不等于则跳转

JZ   ;为 0 则跳转
JNZ  ;不为 0 则跳转

JS   ;为负则跳转
JNS  ;不为负则跳转

JC   ;进位则跳转
JNC  ;不进位则跳转

JO   ;溢出则跳转
JNO  ;不溢出则跳转

JA   ;无符号大于则跳转
JNA  ;无符号不大于则跳转
JAE  ;无符号大于等于则跳转
JNAE ;无符号不大于等于则跳转

JG   ;有符号大于则跳转
JNG  ;有符号不大于则跳转
JGE  ;有符号大于等于则跳转
JNGE ;有符号不大于等于则跳转

JB   ;无符号小于则跳转
JNB  ;无符号不小于则跳转
JBE  ;无符号小于等于则跳转
JNBE ;无符号不小于等于则跳转

JL   ;有符号小于则跳转
JNL  ;有符号不小于则跳转
JLE  ;有符号小于等于则跳转
JNLE ;有符号不小于等于则跳转

JP   ;奇偶位置位则跳转
JNP  ;奇偶位清除则跳转
JPE  ;奇偶位相等则跳转
JPO  ;奇偶位不等则跳转

Clang

C 语言的奇技淫巧 https://jin-yang.github.io/post/program-c-tips.html

常用函数

代码语言:javascript
复制
sprintf();

static

静态全局变量:自动初始化为 0,只在声明它的整个文件中可见。

静态函数:只能在声明它的文件当中可见,不能被其他文件使用,降低命名冲突。

Reverse

C++逆向学习三步走 https://bbs.pediy.com/thread-113689.htm

要求

  • 熟悉如操作系统,汇编语言,加解密等相关知识
  • 具有丰富的多种高级语言的编程经验
  • 熟悉多种编译器的编译原理
  • 较强的程序理解和逆向分析能力

常规逆向流程

  1. 使用strings/file/binwalk/IDA等静态分析工具收集信息,并根据这些静态信息进行google/github搜索
  2. 研究程序的保护方法,如代码混淆,保护壳及反调试等技术,并设法破除或绕过保护
  3. 反汇编目标软件,快速定位到关键代码进行分析
  4. 结合动态调试,验证自己的初期猜想,在分析的过程中理清程序功能
  5. 针对程序功能,写出对应脚本,求解出 flag

定位关键代码 tips

  1. 分析控制流 控制流可以参见 IDA 生成的控制流程图(CFG),沿着分支循环和函数调用,逐块地阅读反汇编代码进行分析。
  2. 利用数据、代码交叉引用 比如输出的提示字符串,可以通过数据交叉引用找到对应的调用位置,进而找出关键代码。代码交叉引用比如图形界面程序获取用户输入,就可以使用对应的 windowsAPI 函数,我们就可以通过这些 API 函数调用位置找到关键代码。

逆向 tips

  1. 编码风格 每个程序员的编码风格都有所不同,熟悉开发设计模式的同学能更迅速地分析出函数模块功能
  2. 集中原则 程序员开发程序时,往往习惯将功能相关的代码或是数据写在同一个地方,而在反汇编代码中也能显示出这一情况,因此在分析时可以查看关键代码附近的函数和数据。
  3. 代码复用 代码复用情况非常普遍,而最大的源代码仓库 Github 则是最主要的来源。在分析时可以找一些特征(如字符串,代码风格等)在 Github 搜索,可能会发现类似的代码,并据此恢复出分析时缺失的符号信息等。
  4. 七分逆向三分猜 合理的猜测往往能事半功倍,遇到可疑函数却看不清里面的逻辑,不妨根据其中的蛛丝马迹猜测其功能,并依据猜测继续向下分析,在不断的猜测验证中,或许能帮助你更加接近代码的真相。
  5. 区分代码 拿到反汇编代码,必须能区分哪些代码是人为编写的,而哪些是编译器自动附加的代码。人为编写的代码中,又有哪些是库函数代码,哪些才是出题人自己写的代码,出题人的代码又经过编译器怎样的优化?我们无须花费时间在出题人以外的代码上,这很重要。如果当你分析半天还在库函数里乱转,那不仅体验极差,也没有丝毫效果。
  6. 耐心 无论如何,给予足够的时间,总是能将一个程序分析地透彻。但是也不应该过早地放弃分析。相信自己肯定能在抽茧剥丝的过程中突破问题。

动态分析

动态分析的目的在于定位关键代码后,在程序运行的过程中,借由输出信息(寄存器,内存变化,程序输出)等来验证自己的推断或是理解程序功能

主要方法有:调试,符号执行,污点分析

借用系统调用的跟踪工具看一下宏观动作?

  • strace:trace all system call
  • ltrace:trace all library call
  • ptrace
  • dtruss(Mac)

算法和数据结构识别

  • 常用算法识别

如 Tea / XTea / XXTea / IDEA / RC4 / RC5 / RC6 / AES / DES / IDEA / MD5 / SHA256 / SHA1 等加密算法,大数加减乘除、最短路等传统算法

  • 常用数据结构识别

如图、树、哈希表等高级数据结构在汇编代码中的识别。

代码混淆

比如使用OLLVMmovfuscator花指令虚拟化SMC等工具技术对代码进行混淆,使得程序分析十分困难。

那么对应的也有反混淆技术,最主要的目的就是复原控制流。比如模拟执行符号执行

保护壳

保护壳类型有许多,简单的压缩壳可以归类为如下几种

  • unpack -> execute 直接将程序代码全部解压到内存中再继续执行程序代码
  • unpack -> execute -> unpack -> execute … 解压部分代码,再边解压边执行
  • unpack -> [decoder | encoded code] -> decode -> execute 程序代码有过编码,在解压后再运行函数将真正的程序代码解码执行

对于脱壳也有相关的方法,比如单步调试法ESP定律等等

反调试

反调试意在通过检测调试器等方法避免程序被调试分析。比如使用一些 API 函数如IsDebuggerPresent检测调试器,使用SEH异常处理,时间差检测等方法。也可以通过覆写调试端口、自调试等方法进行保护。

非常规逆向思路

非常规逆向题设计的题目范围非常之广,可以是任意架构的任意格式文件。

  • lua / python / java / lua-jit / haskell / applescript / js / solidity / webassembly / etc..
  • firmware / raw bin / etc..
  • chip8 / avr / clemency / risc-v / etc.

但是逆向工程的方法学里不惧怕这些未知的平台格式,遇到这样的非常规题,我们也有一些基本的流程可以通用

前期准备

  • 阅读文档。快速学习平台语言的方法就是去阅读官方文档。
  • 官方工具。官方提供或建议的工具必然是最合适的工具
  • 教程。在逆向方面,也许有许多前辈写出了专门针对该平台语言的逆向教程,因此也可以快速吸收这其中的知识。

找工具

主要找文件解析工具反汇编器调试器反编译器。其中反汇编器是必需的,调试器也包含有相应的反汇编功能,而对于反编译器则要自求多福了,得之我幸失之我命。

找工具总结起来就是:Google 大法好。合理利用 Google 搜索语法,进行关键字搜索可以帮助你更快更好地找到合适工具。

寻找主入口(main函数)

字符串搜索法

栈回溯法

逐步分析法

Stack Overflow

学习环境 https://exploit.education/phoenix/stack-five

视频教程 https://www.youtube.com/watch?v=HSlhY4Uy8SA

手把手教你栈溢出从入门到放弃

https://zhuanlan.zhihu.com/p/25816426

https://zhuanlan.zhihu.com/p/25892385

ctf-wiki https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic-rop-zh/#ret2text

Pwn入坑指南 https://www.cnblogs.com/wintrysec/p/10616856.html

熊师傅推荐的题库 https://github.com/scwuaptx/HITCON-Training

视频教程 入门学习路线 https://www.bilibili.com/video/av13427867

发生栈溢出的基本前提:

  • 程序必须向栈上写入数据;
  • 写入的数据大小没有被良好地控制。

Basic

调用约定

  • 实现了层面(底层)的规范
  • 约定了函数之间如何传递参数
  • 约定了函数如何传递返回值

ebp(rbp) 用途:

  • 索引栈上的参数,例如 x86 下,ebp + 8 指向第一个参数
  • 保存栈顶位置 esp(rsp)

常见 x86 调用约定:

  • 调用者负责清理栈上的参数(Caller Clean-up)
    • cdecl
      • 用栈传参
      • 用 eax 保存返回值
    • optlink
  • 被调用者负责清理栈上的参数(Callee Clean-up)
    • stdcall
    • fastcall

需要注意的是,32 位和 64 位程序有以下简单的区别:

  • x86
    • 函数参数函数返回地址的上方
  • x64
    • System V AMD64 ABI (Linux、FreeBSD、macOS 等采用) 中前六个整型或指针参数依次保存在 RDI, RSI, RDX, RCX, R8 和 R9 寄存器中,如果还有更多的参数的话才会保存在栈上。
    • 内存地址不能大于 0x00007FFFFFFFFFFF,6 个字节长度,否则会抛出异常。
    • cdecl 使用寄存器 rdi、rsi、rdx、rcx、r8、r9 传前 6 个,第七个及以上使用栈传递
代码语言:javascript
复制
int callee(int a, int b, int c) {
    return a + b + c;
}

int caller(void) {
    int ret;

    ret = callee(1, 2, 3);
    ret += 4;
    return ret;
}
代码语言:javascript
复制
pwndbg> disass callee
Dump of assembler code for function callee:
   0x000004ed <+0>:		push   ebp
   0x000004ee <+1>:		mov    ebp,esp
   0x000004f0 <+3>:		mov    edx,DWORD PTR [ebp+0x8]
   0x000004f3 <+6>:		mov    eax,DWORD PTR [ebp+0xc]
   0x000004f6 <+9>:		add    edx,eax
   0x000004f8 <+11>:	mov    eax,DWORD PTR [ebp+0x10]
   0x000004fb <+14>:	add    eax,edx
   0x000004fd <+16>:	pop    ebp
   0x000004fe <+17>:	ret    
End of assembler dump.

pwndbg> disass caller
Dump of assembler code for function caller:
   0x000004ff <+0>:		push   ebp
   0x00000500 <+1>:		mov    ebp,esp
   0x00000502 <+3>:		sub    esp,0x10
   0x00000505 <+6>:		push   0x3
   0x00000507 <+8>:		push   0x2
   0x00000509 <+10>:	push   0x1
   0x0000050b <+12>:	call   0x4ed <callee>
   0x00000510 <+17>:	add    esp,0xc
   0x00000513 <+20>:	mov    DWORD PTR [ebp-0x4],eax
   0x00000516 <+23>:	add    DWORD PTR [ebp-0x4],0x4
   0x0000051a <+27>:	mov    eax,DWORD PTR [ebp-0x4]
   0x0000051d <+30>:	leave  
   0x0000051e <+31>:	ret    
End of assembler dump.

类型

修改返回地址,让其指向溢出数据中的一段指令(shellcode

修改返回地址,让其指向内存中已有的某个函数(return2libc

修改返回地址,让其指向内存中已有的一段指令(ROP

修改某个被调用函数的地址,让其指向另一个函数(hijack GOT

Format Strings

函数

基本介绍

printf

输出到 stdout

fprintf

输出到指定 FILE 流

vprintf

根据参数列表格式化输出到 stdout

vfprintf

根据参数列表格式化输出到指定 FILE 流

sprintf

输出到字符串

snprintf

输出指定字节数到字符串

vsprintf

根据参数列表格式化输出到字符串

vsnprintf

根据参数列表格式化输出指定字节到字符串

setproctitle

设置 argv

syslog

输出日志

err, verr, warn, vwarn 等

……

Array Indexing

Bad Seed

Z3 & Symbolic Execution(angr)

ROP

Return Oriented Programming

Partial Overwrite

Stack Pivoting

SIGROP(SROP)

ret2csu

ret2system

Heap Exploitation

Double Frees

Heap Consolidation

Use after Frees

Protostar: heap0

protostar: heap1

protostar: heap2

unlink() Exploitation

Heap Grooming

Fastbin Attack

Unsortedbin Attack

Largebin Attack

GLibc Tcache

House of Spirit

House of Lore

House of Force

House of Einherjar

House of Orange

Miscellaneous

Grab Bag

Shell coding

Patching

.NET

Security Protection Mechanism

代码语言:javascript
复制
$checksec fog
[*] '/mnt/hgfs/shared/other/pwn/fog/fog'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

NX

NX enabled如果这个保护开启就是意味着栈中数据没有执行权限,以前的经常用的call esp或者jmp esp的方法就不能使用,但是可以利用rop这种方法绕过。

代码语言:javascript
复制
关闭:-z execstack
开启:-z noexecstack

开启了的话堆栈会变的可执行,可执行的话可能意味着可以执行shellcode

RELRO

RELRO 会有 Partial RELRO 和F ULL RELRO,若开启 FULL RELRO,意味着无法修改got表,否则能劫持程序流程。

代码语言:javascript
复制
关闭:-z norelro
开启(部分):-z lazy
开启(完全):-z now

Stack (Canary)

如果栈中开启 Canary found,那么就不能用直接用溢出的方法覆盖栈中返回地址,而是要通过改写指针与局部变量、leak canary、overwrite canary 的方法来绕过。

代码语言:javascript
复制
关闭:-fno-stack-protector
启用(只为局部变量中含有 char 数组的函数插入保护代码):-fstack-protector
启用(为所有函数插入保护代码):-fstack-protector-all

没开启的话,栈溢出会变的更加容易

PIE

Position Independent Executable 地址随机化。 没开启的话,程序的基地址就是已知的了(0x400000)

代码语言:javascript
复制
关闭: -no-pie
开启: -pie -fPIC

Linux 平台下还有地址空间分布随机化(ASLR)的机制,即使可执行文件开启了 PIE 保护,还需要系统开启 ASLR 才会真正打乱基址,否则程序运行时依旧会在加载一个固定的基址上(不过和 No PIE 时基址不同)。

我们可以通过修改 /proc/sys/kernel/randomize_va_space 来控制 ASLR 启动与否,具体的选项有:

  • 0,关闭 ASLR,没有随机化。栈、堆、.so 的基地址每次都相同。
  • 1,普通的 ASLR。栈基地址、mmap 基地址、.so 加载基地址都将被随机化,但是堆基地址没有随机化。
  • 2,增强的 ASLR,在 1 的基础上,增加了堆基地址随机化。
代码语言:javascript
复制
sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'

FORTIFY

FORTIFY_SOURCE 机制对格式化字符串有两个限制

  • 包含%n的格式化字符串不能位于程序内存中的可写地址。
  • 当使用位置参数时,必须使用范围内的所有参数。所以如果要使用%7$x,你必须同时使用1,2,3,4,5和6。
代码语言:javascript
复制
关闭:-D_FORTIFY_SOURCE=0
开启(只会在编译的时候检查):-D_FORTIFY_SOURCE=1 -O1
开启(强检查):-D_FORTIFY_SOURCE=2 -O2

开启的话就是不能用 %n,%hn,%hhn 这种的,%4$p 也不行了。

Bypass

程序没有开启地址随机化:

代码语言:javascript
复制
def debug(addr):
    raw_input('debug:')
    gdb.attach(r, "b *" + addr)

在程序运行时调用这个函数就可以调试了

程序开启地址随机化:

代码语言:javascript
复制
wordSz = 4
hwordSz = 2
bits = 32
PIE = 0
mypid=0
def leak(address, size):
   with open('/proc/%s/mem' % mypid) as mem:
      mem.seek(address)
      return mem.read(size)

def findModuleBase(pid, mem):
   name = os.readlink('/proc/%s/exe' % pid)
   with open('/proc/%s/maps' % pid) as maps:
      for line in maps:
         if name in line:
            addr = int(line.split('-')[0], 16)
            mem.seek(addr)
            if mem.read(4) == "\x7fELF":
               bitFormat = u8(leak(addr + 4, 1))
               if bitFormat == 2:
                  global wordSz
                  global hwordSz
                  global bits
                  wordSz = 8
                  hwordSz = 4
                  bits = 64
               return addr
   log.failure("Module's base address not found.")
   sys.exit(1)

def debug(addr = 0):
    global mypid
    mypid = proc.pidof(r)[0]
    raw_input('debug:')
    with open('/proc/%s/mem' % mypid) as mem:
        moduleBase = findModuleBase(mypid, mem)
        gdb.attach(r, "set follow-fork-mode parent\nb *" + hex(moduleBase+addr))

由于开启地址随机化之后ida pro打开程序后,显示的是程序的偏移地址,而不是实际的地址,当程序加载后程序的程序的实际地址是:基地址+偏移地址,调用debug函数的时候只要把偏移地址传递进去就好

泄露libc地址和版本的方法

【1】利用格式化字符串漏洞泄露栈中的数据,从而找到libc的某个函数地址,再利用libc-database来判断远程libc的版本,之后再计算出libc的基址,一般做题我喜欢找__libc_start_main的地址

【2】利用write这个函数,pwntools有个很好用的函数DynELF去利用这个函数计算出程序的各种地址,包括函数的基地址,libc的基地址,libc中system的地址

【3】利用printf函数,printf函数输出的时候遇到0x00时候会停止输出,如果输入的时候没有在最后的字节处填充0x00,那么输出的时候就可能泄露栈中的重要数据,比如libc的某个函数地址

简单的栈溢出

程序没有开启任何保护:

方法一:传统的教材思路是把shellcode写入栈中,然后查找程序中或者libc中有没有call esp或者jmp esp,比如这个题目: http://blog.csdn.net/niexinming/article/details/76893510

方法二:但是现代操作系统中libc中会开启地址随机化,所以先寻找程序中system的函数,再布局栈空间,调用gets(.bss),最后调用system(‘/bin/sh’) 比如这个题目:http://blog.csdn.net/niexinming/article/details/78796408

方法三:覆盖虚表方式利用栈溢出漏洞,这个方法是m4x师傅教我的方法,我觉得很巧妙,比如这个题目:http://blog.csdn.net/niexinming/article/details/78144301

开启nx的程序

开启nx之后栈和bss段就只有读写权限,没有执行权限了,所以就要用到rop这种方法拿到系统权限,如果程序很复杂,或者程序用的是静态编译的话,那么就可以使用ROPgadget这个工具很方便的直接生成rop利用链。有时候好多程序不能直接用ROPgadget这个工具直接找到利用链,所以就要手动分析程序来getshell了,比如这两个题目: http://blog.csdn.net/niexinming/article/details/78259866

开启canary的程序

开启canary后就不能直接使用普通的溢出方法来覆盖栈中的函数返回地址了,要用一些巧妙的方法来绕过或者利canary本身的弱点来攻击

【1】利用canary泄露flag,这个方法很巧妙的运用了canary本身的弱点,当__stack_check_fail时,会打印出正在运行中程序的名称,所以,我们只要将__libc_argv[0]覆盖为flag的地址就能将flag打印出来,比如这个题目: http://blog.csdn.net/niexinming/article/details/78522682

【2】利用printf函数泄露一个子进程的Canary,再在另一个子进程栈中伪造Canary就可以绕过Canary的保护了,比如这个题目:http://blog.csdn.net/niexinming/article/details/78681846

开启PIE的程序

【1】利用printf函数尽量多打印一些栈中的数据,根据泄露的地址来计算程序基地址,libc基地址,system地址,比如这篇文章中echo2的wp: http://blog.csdn.net/niexinming/article/details/78512274

【2】利用write泄露程序的关键信息,这样的话可以很方便的用DynELF这个函数了,比如这个文章中的rsbo2的题解:http://blog.csdn.net/niexinming/article/details/78620566

全部保护开启

如果程序的栈可以被完全控制,那么程序的保护全打开也会被攻破,比如这个题目:http://blog.csdn.net/niexinming/article/details/78666941

格式化字符串漏洞

格式化漏洞现在很难在成熟的软件中遇到,但是这个漏洞却很有趣

【1】pwntools有很不错的函数FmtStr和fmtstr_payload来自动计算格式化漏洞的利用点,并且自动生成payload,比如这个题目:http://blog.csdn.net/niexinming/article/details/78699413http://blog.csdn.net/niexinming/article/details/78512274 中echo的题解

【2】格式化漏洞也是信息泄露的好伴侣,比如这个题目中制造格式化字符串漏洞泄露各种数据 http://blog.csdn.net/niexinming/article/details/78768850

uaf漏洞

如果把堆释放之后,没有把指针指针清0,还让指针保存下来,那么就会引发很多问题,比如这个题目 http://blog.csdn.net/niexinming/article/details/78598635

任意位置写

如果程序可以在内存中的任意位置写的话,那么威力绝对很大

【1】虽然只能写一个字节,但是依然可以控制程序的并getshell,比如这个题目 http://blog.csdn.net/niexinming/article/details/78542089

【2】修改got表是个控制程序流程的好办法,很多ctf题目只要能通过各种方法控制got的写入,就可以最终得到胜利,比如这个题目: http://blog.csdn.net/niexinming/article/details/78542089

【3】如果能计算出libc的基地址的话,控制top_chunk指针也是解题的好方法,比如这个题目: http://blog.csdn.net/niexinming/article/details/78759363

Virus

病毒通常会遵循如下相同步骤:

  1. 定位要感染的文件(一直等待直到打开某些东西,或者搜索目录)
  2. 检查某个文件是否已经被感染
  3. 如果已感染,跳过
  4. 保存文件日期/时间
  5. 设置一个跳转跳到我们的代码保存前几个字节
  6. 添加病毒主体代码
  7. 恢复文件日期/时间

DOS

COM 简介

DOS 内存布局

COM 覆盖型病毒

COM 伴随型病毒

COM 寄生型病毒

隐藏技术

变形技术

反跟踪、反调试、反分析

驻留内存

其他

Executable

ELF

ELF (Executable and Linkable Format)文件,也就是在 Linux 中的目标文件,主要有以下三种类型

  • 可重定位文件(Relocatable File),包含由编译器生成的代码以及数据。链接器会将它与其它目标文件链接起来从而创建可执行文件或者共享目标文件。在 Linux 系统中,这种文件的后缀一般为 .o
  • 可执行文件(Executable File),就是我们通常在 Linux 中执行的程序。
  • 共享目标文件(Shared Object File),包含代码和数据,这种文件是我们所称的库文件,一般以 .so 结尾。一般情况下,它有以下两种使用情景:
    • 链接器(Link eDitor, ld)可能会处理它和其它可重定位文件以及共享目标文件,生成另外一个目标文件。
    • 动态链接器(Dynamic Linker)将它与可执行文件以及其它共享目标组合在一起生成进程镜像。

关于 Link eDitor 的命名,https://en.wikipedia.org/wiki/GNU_linker

目标文件由汇编器和链接器创建,是文本程序的二进制形式,可以直接在处理器上运行。那些需要虚拟机才能够执行的程序 (Java) 不属于这一范围。

PE

Tools

pwntools

Pwntools is a python ctf library designed for rapid exploit development. It essentially help us write exploits quickly, and has a lot of useful functionality behind it.

Also one thing to note, pwntools has Python2 and Python3 versions. Atm this course uses the Python2, but I have plans to switch it all over to Python3. Just keep in mind that some things change between Python2 to the Python3 versions, however the changes are relatively small.

Installation

It’s fairly simple process. The installation process is pretty much just using pip:

代码语言:javascript
复制
$    sudo pip install pwn

If you have any problems, google will help a lot.

Using it

So this is going to be an explanation on how you do various things with pwntools. It will only cover a small bit of functionality.

If we want to import it into python:

代码语言:javascript
复制
from pwn import *

Now one thing that pwntools does for us, is it has some nice piping functionality which helps with IO. If we want to connect to the server at github.com (if you have an IP address, just swap out the dns name with the IP address) on port 9000 via tcp:

代码语言:javascript
复制
target = remote("github.com", 9000)

If you want to run a target binary:

代码语言:javascript
复制
target = process("./challenge")

If you want to attach the gdb debugger to a process:

代码语言:javascript
复制
gdb.attach(target)

If we want to attach the gdb debugger to a process, and also immediately pass a command to gdb to set a breakpoint at main:

代码语言:javascript
复制
gdb.attach(target, gdbscript='b *main')

Now for actual I/O. If we want to send the variable x to the target (target can be something like a process, or remote connection established by pwntools):

代码语言:javascript
复制
target.send(x)

If we wanted to send the variable x followed by a newline character appended to the end:

代码语言:javascript
复制
target.sendline(x)

If we wanted to print a single line of text from target:

代码语言:javascript
复制
print target.recvline()

If we wanted to print all text from target up to the string out:

代码语言:javascript
复制
print target.recvuntil("out")

Now one more thing, ELFs store data via least endian, meaning that data is stored with the least significant byte first. In a few situations where we are scanning in an integer, we will need to take this into account. Luckily pwntools will take care of this for us.

To pack the integer y as a least endian QWORD (commonly used for x64):

代码语言:javascript
复制
p64(x)

To pack the integer y as a least endian DWORD (commonly used for x86):

代码语言:javascript
复制
p32(x)

It can also unpack values we get. Let’s say we wanted to unpack a least endian QWORD and get it’s integer value:

代码语言:javascript
复制
u64(x)

To unpack a DWORD:

代码语言:javascript
复制
u32(x)

Lastly if just wanted to interact directly with target:

代码语言:javascript
复制
target.interactive()

This is only a small bit of the functionality pwntools has. You will see a lot more of the functionality later. If you want to see more of pwntools, it has some great docs: http://docs.pwntools.com/en/stable/

  • send(payload) 发送payload
  • sendline(payload) 发送payload,并进行换行(末尾\n
  • sendafter(some_string, payload) 接收到 some_string 后, 发送你的 payload
  • recvn(N) 接受 N(数字) 字符
  • recvline() 接收一行输出
  • recvlines(N) 接收 N(数字) 行输出
  • recvuntil(some_string) 接收到 some_string 为止

IDA Pro

https://xz.aliyun.com/t/4205 IDA Pro7.0使用技巧总结 其他的慢慢看 IDA 权威指南吧

IDA Pro 逆向速参 https://juejin.im/post/6844903550460362766

a:将数据转换为字符串

f5:一键反汇编

esc:回退键,能够倒回上一部操作的视图(只有在反汇编窗口才是这个作用,如果是在其他窗口按下esc,会关闭该窗口)

shift+f12:可以打开string窗口,一键找出所有的字符串,右击setup,还能对窗口的属性进行设置

ctrl+w:保存ida数据库

ctrl+s:选择某个数据段,直接进行跳转

ctrl+鼠标滚轮:能够调节流程视图的大小

x:对着某个函数、变量按该快捷键,可以查看它的交叉引用

g:直接跳转到某个地址

n:更改变量的名称

y:更改变量的类型

/ :在反编译后伪代码的界面中写下注释

\:在反编译后伪代码的界面中隐藏/显示变量和函数的类型描述,有时候变量特别多的时候隐藏掉类型描述看起来会轻松很多

;:在反汇编后的界面中写下注释

ctrl+shift+w:拍摄IDA快照

u:undefine,取消定义函数、代码、数据的定义

配置

Disassembly
代码语言:javascript
复制
OPCODE_BYTES            = 6   // 机器码字节数,默认0
INDENTION               = 0   // 指令缩进,默认16,设为0代码会整洁一些
COMMENTS_INDENTION      = 30  // 注释缩进,默认40
MAX_TAIL                = 16  // 交叉参考的深度,默认16
MAX_XREF_LENGTH         = 80  // Maximal length of line with cross-references
MAX_DATALINE_LENGTH     = 100  // Data directives (db,dw, etc):
                              //   max length of argument string
SHOW_AUTOCOMMENTS       = NO  // Display comments for every instruction
                              // Advanced users will turn this off
                              // Please note that there is another definition
                              // for IBM PC below
SHOW_BASIC_BLOCKS       = NO  // Generate an empty line at the end of a basic block
SHOW_BORDERS            = YES // Borders between data/code
SHOW_EMPTYLINES         = YES // Generate empty line to make disassembly more readable
SHOW_LINEPREFIXES       = YES // Show line prefixes (like 1000:0000)
SHOW_XREFS              = 15   	// 显示大量的交叉参考信息,默认2
SHOW_ORIGINS            = NO 	// Generate 'org' directives
ASCII strings & names

Options => ASCII String styles

中文

IDA 从 7.0 版本开始正式支持中文字符串的显示,但仍需要配置 ida.cfg。

在 IDA \ CFG 目录下新建一个文件 Chinese.clt,内容如下。(好像默认就有了)

代码语言:javascript
复制
u2000..u206F,
u2F00..u2FDF,
u3000..u303F,
u31C0..u31EF,
u3400..u4DBF,
u4E00..u9FFF,
uF900..uFAFF,
uFE30..uFE4F,
u20000..u2A6DF,
u2A700..u2BA7F,
u2B740..u2B81F,
u2F800..u2FA1F;

导航条

  • 蓝色:.text section
    • 深蓝:用户自己写的函数编译后的代码区
    • 浅蓝:编译器自己添加的函数,像启动函数,异常函数等(我自己猜的,不一定百分百正确)
  • 粉红色:.idata section 有关输入表的一些数据信息
  • 军绿色:.rdata section 纯数据,只读
  • 灰色:为了段对齐而留下的空隙
  • 黑色:禁区,不存在任何数据

ghidra

GDB

gdb 还有其他一些小技巧,可以参考awesome-cheatsheets/tools/gdb.txt中的列表。该列表最初由韦神创建,我时不时也会添加一些上去。当然为了方便大家的查阅,这里直接给出汇总表格附录:

启动 GDB

命令

含义

备注

gdb object

正常启动,加载可执行

gdb object core

对可执行 + core 文件进行调试

gdb object pid

对正在执行的进程进行调试

gdb

正常启动,启动后需要 file 命令手动加载

gdb -tui

启用 gdb 的文本界面(或 ctrl-x ctrl-a 更换 CLI/TUI)

帮助信息

命令

含义

备注

help

列出命令分类

help running

查看某个类别的帮助信息

help run

查看命令 run 的帮助

help info

列出查看程序运行状态相关的命令

help info line

列出具体的一个运行状态命令的帮助

help show

列出 GDB 状态相关的命令

help show commands

列出 show 命令的帮助

断点

命令

含义

备注

break main

对函数 main 设置一个断点,可简写为 b main

break 101

对源代码的行号设置断点,可简写为 b 101

break basic.c:101

对源代码和行号设置断点

break basic.c:foo

对源代码和函数名设置断点

break *0x00400448

对内存地址 0x00400448 设置断点

info breakpoints

列出当前的所有断点信息,可简写为 info break

delete 1

按编号删除一个断点

delete

删除所有断点

clear

删除在当前行的断点

clear function

删除函数断点

clear line

删除行号断点

clear basic.c:101

删除文件名和行号的断点

clear basic.c:main

删除文件名和函数名的断点

clear *0x00400448

删除内存地址的断点

disable 2

禁用某断点,但是部删除

enable 2

允许某个之前被禁用的断点,让它生效

rbreak {regexpr}

匹配正则的函数前断点,如 ex_* 将断点 ex_ 开头的函数

tbreak function/line

临时断点

hbreak function/line

硬件断点

ignore {id} {count}

忽略某断点 N-1 次

condition {id} {expr}

条件断点,只有在条件生效时才发生

condition 2 i == 20

2号断点只有在 i == 20 条件为真时才生效

watch {expr}

对变量设置监视点

info watchpoints

显示所有观察点

catch exec

断点在exec事件,即子进程的入口地址

运行程序

命令

含义

备注

run

运行程序

run {args}

以某参数运行程序

run < file

以某文件为标准输入运行程序

run < <(cmd)

以某命令的输出作为标准输入运行程序

run <<< $(cmd)

以某命令的输出作为标准输入运行程序

Here-String

set args {args} ...

设置运行的参数

show args

显示当前的运行参数

cont

继续运行,可简写为 c

step

单步进入(si 执行一行汇编),碰到函数会进去。

step {count}

单步多少次

next

单步跳过(ni 执行一行汇编),碰到函数不会进入。

next {count}

单步多少次

CTRL+C

发送 SIGINT 信号,中止当前运行的程序

attach {process-id}

链接上当前正在运行的进程,开始调试

detach

断开进程链接

finish

结束当前函数的运行

until

持续执行直到代码行号大于当前行号(跳出循环)

until {line}

持续执行直到执行到某行

kill

杀死当前运行的函数

栈帧

命令

含义

备注

bt

打印 backtrace

frame

显示当前运行的栈帧

up

向上移动栈帧(向着 main 函数)

down

向下移动栈帧(远离 main 函数)

info locals

打印帧内的相关变量

info args

打印函数的参数

代码浏览

命令

含义

备注

list 101

显示第 101 行周围 10行代码

list 1,10

显示 1 到 10 行代码

list main

显示函数周围代码

list basic.c:main

显示另外一个源代码文件的函数周围代码

list -

重复之前 10 行代码

list *0x22e4

显示特定地址的代码

cd dir

切换当前目录

pwd

显示当前目录

search {regexpr}

向前进行正则搜索

reverse-search {regexp}

向后进行正则搜索

dir {dirname}

增加源代码搜索路径

dir

复位源代码搜索路径(清空)

show directories

显示源代码路径

浏览数据

命令

含义

备注

print {expression}

打印表达式,并且增加到打印历史

print /x {expression}

十六进制输出,print 可以简写为 p

print array[i]@count

打印数组范围

print $

打印之前的变量

print *$->next

打印 list

print $1

输出打印历史里第一条

print ::gx

将变量可视范围(scope)设置为全局

print 'basic.c'::gx

打印某源代码里的全局变量,(gdb 4.6)

print /x &main

打印函数地址

x *0x11223344

显示给定地址的内存数据

x /nfu {address}

打印内存数据,n是多少个,f是格式,u是单位大小

x /10xb *0x11223344

按十六进制打印内存地址 0x11223344 处的十个字节

x/x &gx

按十六进制打印变量 gx,x和斜杆后参数可以连写

x/4wx &main

按十六进制打印位于 main 函数开头的四个 long

x/gf &gd1

打印 double 类型

help x

查看关于 x 命令的帮助

info locals

打印本地局部变量

info functions {regexp}

打印函数名称

info variables {regexp}

打印全局变量名称

ptype name

查看类型定义,比如 ptype FILE,查看 FILE 结构体定义

whatis {expression}

查看表达式的类型

set var = {expression}

变量赋值

set *address = value

可将 * 换成 char / short / long 分别设定 1/2/8 byte

set {int}0x600000 = 1337

display {expression}

在单步指令后查看某表达式的值

undisplay

删除单步后对某些值的监控

info display

显示监视的表达式

show values

查看记录到打印历史中的变量的值 (gdb 4.0)

info history

查看打印历史的帮助 (gdb 3.5)

文件操作

命令

含义

备注

file {object}

加载新的可执行文件供调试

file

放弃可执行和符号表信息

symbol-file {object}

仅加载符号表

exec-file {object}

指定用于调试的可执行文件(非符号表)

core-file {core}

加载 core 用于分析

信号控制

命令

含义

备注

info signals

打印信号设置

handle {signo} {actions}

设置信号的调试行为

handle INT print

信号发生时打印信息

handle INT noprint

信号发生时不打印信息

handle INT stop

信号发生时中止被调试程序

handle INT nostop

信号发生时不中止被调试程序

handle INT pass

调试器接获信号,不让程序知道

handle INT nopass

调试起不接获信号

signal signo

继续并将信号转移给程序

signal 0

继续但不把信号给程序

线程调试

命令

含义

备注

info threads

查看当前线程和 id

thread {id}

切换当前调试线程为指定 id 的线程

break {line} thread all

所有线程在指定行号处设置断点

thread apply {id..} cmd

指定多个线程共同执行 gdb 命令

thread apply all cmd

所有线程共同执行 gdb 命令

set schedule-locking ?

调试一个线程时,其他线程是否执行

set non-stop on/off

调试一个线程时,其他线程是否运行

set pagination on/off

调试一个线程时,分页是否停止

set target-async on/off

同步或者异步调试,是否等待线程中止的信息

进程调试

命令

含义

备注

info inferiors

查看当前进程和 id

inferior {id}

切换某个进程

kill inferior {id...}

杀死某个进程

set detach-on-fork on/off

设置当进程调用fork时gdb是否同时调试父子进程

set follow-fork-mode parent/child

设置当进程调用fork时是否进入子进程

汇编调试

命令

含义

备注

info registers

打印普通寄存器

info all-registers

打印所有寄存器

print/x $pc

打印单个寄存器

stepi

指令级别单步进入

si

nexti

指令级别单步跳过

ni

display/i $pc

监控寄存器(每条单步完以后会自动打印值)

x/x &gx

十六进制打印变量

info line 22

打印行号为 22 的内存地址信息

info line *0x2c4e

打印给定内存地址对应的源代码和行号信息

disassemble {addr}

对地址进行反汇编,比如 disassemble 0x2c4e

其他命令

命令

含义

备注

show commands

显示历史命令 (gdb 4.0)

info editing

显示历史命令 (gdb 3.5)

ESC-CTRL-J

切换到 Vi 命令行编辑模式

set history expansion on

允许类 c-shell 的历史

break class::member

在类成员处设置断点

list class:member

显示类成员代码

ptype class

查看类包含的成员

/o可以看成员偏移,类似pahole

print *this

查看 this 指针

define command ... end

定义用户命令

<return>

直接按回车执行上一条指令

shell {command} [args]

执行 shell 命令

source {file}

从文件加载 gdb 命令

quit

退出 gdb

pwndbg

用法特性:https://github.com/pwndbg/pwndbg/blob/dev/FEATURES.md

分屏

peda

代码语言:javascript
复制
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit

Ollydbg

PE 类工具

masm32

Immunitydebugger

pwndbg

z3

strings

file

binwalk

Reference

https://guyinatuxedo.github.io/

https://adworld.xctf.org.cn/task REVERSE或者PWN或者MOBILE三个方向合计完成任意9题

http://reversing.kr/ 5题

http://pwnable.kr/ 6题

https://pwnable.tw/ 4题

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/10/07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 每天学点新东西
  • Assembly
    • Intel vs AT&T
      • 程序模板
        • 寄存器
          • 数据类型
            • 寻址模式
              • 直接内存寻址
              • 寄存器间接寻址
            • 常用指令
              • 控制转移
          • Clang
            • static
            • Reverse
              • 要求
                • 常规逆向流程
                  • 定位关键代码 tips
                    • 逆向 tips
                      • 动态分析
                        • 算法和数据结构识别
                          • 代码混淆
                            • 保护壳
                              • 反调试
                                • 非常规逆向思路
                                  • 前期准备
                                  • 找工具
                                • 寻找主入口(main函数)
                                • Stack Overflow
                                  • Basic
                                    • 调用约定
                                  • 类型
                                  • Format Strings
                                  • Array Indexing
                                  • Bad Seed
                                  • Z3 & Symbolic Execution(angr)
                                  • ROP
                                    • Partial Overwrite
                                      • Stack Pivoting
                                        • SIGROP(SROP)
                                          • ret2csu
                                            • ret2system
                                            • Heap Exploitation
                                              • Double Frees
                                                • Heap Consolidation
                                                  • Use after Frees
                                                    • Protostar: heap0
                                                      • protostar: heap1
                                                        • protostar: heap2
                                                          • unlink() Exploitation
                                                            • Heap Grooming
                                                              • Fastbin Attack
                                                                • Unsortedbin Attack
                                                                  • Largebin Attack
                                                                    • GLibc Tcache
                                                                      • House of Spirit
                                                                        • House of Lore
                                                                          • House of Force
                                                                            • House of Einherjar
                                                                              • House of Orange
                                                                                • Miscellaneous
                                                                                • Grab Bag
                                                                                  • Shell coding
                                                                                    • Patching
                                                                                      • .NET
                                                                                      • Security Protection Mechanism
                                                                                        • NX
                                                                                          • RELRO
                                                                                            • Stack (Canary)
                                                                                              • PIE
                                                                                                • FORTIFY
                                                                                                  • Bypass
                                                                                                  • Virus
                                                                                                    • DOS
                                                                                                      • COM 简介
                                                                                                      • COM 覆盖型病毒
                                                                                                      • COM 伴随型病毒
                                                                                                      • COM 寄生型病毒
                                                                                                    • 隐藏技术
                                                                                                      • 变形技术
                                                                                                        • 反跟踪、反调试、反分析
                                                                                                          • 驻留内存
                                                                                                            • 其他
                                                                                                            • Executable
                                                                                                              • ELF
                                                                                                                • PE
                                                                                                                • Tools
                                                                                                                  • pwntools
                                                                                                                    • Installation
                                                                                                                    • Using it
                                                                                                                  • IDA Pro
                                                                                                                    • 配置
                                                                                                                    • 导航条
                                                                                                                  • ghidra
                                                                                                                    • GDB
                                                                                                                      • 启动 GDB
                                                                                                                      • 帮助信息
                                                                                                                      • 断点
                                                                                                                      • 运行程序
                                                                                                                      • 栈帧
                                                                                                                      • 代码浏览
                                                                                                                      • 浏览数据
                                                                                                                      • 文件操作
                                                                                                                      • 信号控制
                                                                                                                      • 线程调试
                                                                                                                      • 进程调试
                                                                                                                      • 汇编调试
                                                                                                                      • 其他命令
                                                                                                                    • pwndbg
                                                                                                                      • peda
                                                                                                                        • Ollydbg
                                                                                                                          • PE 类工具
                                                                                                                            • masm32
                                                                                                                              • Immunitydebugger
                                                                                                                                • pwndbg
                                                                                                                                  • z3
                                                                                                                                    • strings
                                                                                                                                      • file
                                                                                                                                        • binwalk
                                                                                                                                        • Reference
                                                                                                                                        领券
                                                                                                                                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档