我们拿到一个elf文件的时候,会放到linux环境,并且checksec查看有什么保护,我们做的简单的题目自然是什么保护都没有,但是稍微难一点就是给你开一个保护,这篇短文就简单讲一下遇到一个保护的时候,应该采取什么思路
核心思路:RET2LIBC / ROP 链
最简单的:checksec之后出现disable: 这意味着数据所在的内存页可以被执行

输入缓冲区 → 写入 shellcode → 覆盖返回地址 → 跳转到 shellcode → 执行

这个不细说,接下来的NX enable就是说栈不可执行:

先说最简单的情况,出现明文shellcode,我们的思路是:
覆盖返回地址为shellcode地址

高地址
+------------------------+
|        ...            |
+------------------------+
|    返回地址 (RIP)      |  <-- 我们把它改成 system("cat flag") 地址
+------------------------+
|   保存的 RBP           |  <-- 被覆盖
+------------------------+
|     局部变量           |
+------------------------+
|        buf             |  <-- 从这里开始输入
+------------------------+
低地址

payload:输入 "A"*填充 + system_cat_flag_addr

拓展一下:
如果没有system('cat ./flag')或者system('bin/bash')这种只用写他们函数执行的地址到返回地址就能getshell的函数的时候:就需要构造ROP链

高地址
+------------------------+
|        ...             |
+------------------------+
|    返回地址            |  <--rsp   #没有完整的shellcode,就拼出shellcode,返回地址改为跳转pop_rdi的地址
+------------------------+
|   保存的 RBP           |  <-- 被覆盖
+------------------------+
|     局部变量           |
+------------------------+
|        buf             |  <-- 从这里开始输入
+------------------------+
低地址

这里解释一下啊pop rdi的作用:

pop rdi  # 这条指令做两件事:
         # 1. mov rdi, [rsp]    ← 把 rsp 指向的8字节给 rdi
         # 2. add rsp, 8         ← rsp 增加8,指向下一个位置

简单来说就是把栈顶值给rdi寄存器,然后栈顶地址指向栈的下一个地址(高地址)

之所以要跳转到pop_rdi的地址,是因为system()函数需要参数,而参数需要提前放在对应的寄存器里
**64 位程序调用约定**

第1个参数 → RDI
第2个参数 → RSI
第3个参数 → RDX
第4个参数 → RCX
第5个参数 → R8
第6个参数 → R9
剩下的参数 → 压入栈

所以执行完pop rdi之后我们需要的system()里面的参数已经设置完了,下一条就应该是执行system函数

执行完pop rdi之后,下一条指令按**规定是ret**

ret: 
     mov rip, [rsp]    ; 把 rsp 指向的8字节值赋给 rip 寄存器
     add rsp, 8        ; rsp 向上移动8字节

简单来说就是栈顶指针rsp指向的地址作为下一条指令执行的地址,然后栈顶地址指向栈的下一个地址

所以只需要system_addr在binsh_addr 后面就可以执行完整shellcode

最后附图:

高地址
+---------------------------+ 
|     system_addr           | 
+---------------------------+ 
|     binsh_addr            | 
+---------------------------+ 
|     pop_rdi_addr          |  
+---------------------------+ 
|   保存的 RBP (被覆盖)      | 
+---------------------------+
|    局部变量                | 
+---------------------------+
|        buf                |
+---------------------------+
低地址