游客

PWN指北

一言准备中...

欢迎

Pwn(读作“砰”,拟声词)⼀词起源于⽹络游戏社区,原本表⽰成功⼊侵了计算机系统,在 CTF 中则是⼀种题⽬⽅向:通过构造恶意输⼊达到泄漏信息甚⾄劫持⼏乎整个系统(getshell)的⽬的。其实在 CTF ⽐赛发展初期,赛题通常只与⼆进制安全相关,因此 Pwn 是 CTF 领域最原始的⽅向。在这⾥,你能深⼊计算机系统最底层,感受纯粹的计算机科学。

前置知识

鉴于本⼈水平有限,不敢妄⾔,但是 Pwn 的前置知识绝对算得上很多,从开始⼊⻔,到拿到你⼈⽣的第⼀个 flag 还需要⼀段时间,但请耐⼼沉淀,你可能很长一段时间得不到任何结果,这种枯燥和寂静会劝退很多人。
可以先去看看前置知识之Linux操作系统

学会如何提问

当搜索引擎+AI都没办法解决你的问题的时候,可以考虑去询问他⼈。但是请注意,每个⼈都有⾃⼰要做的事情,回答你的问题并不是他们的义务。所以提问的时候最重要的⼀点就是要信息详细,说清楚你的思路、你已经做过的尝试、你卡在哪⼀个点或者对于AI给出的回答有什么疑问,⽽不是让回答者去猜测,⽩⽩浪费时间。
请务必深刻理解《提问的艺术》

计算机数据表示

Pwn 属于⼆进制(binary)安全,为什么说是“⼆进制”?因为计算机只处理和存储⼆进制信息。与我们⽇常使⽤的⼗进制“逢⼗进⼀”不同,“逢⼆进⼀”的⼆进制世界只有“0”和“1”。⼀位⼆进制信息称为⽐特(bit),8 ⽐特为 1 字节(byte),字节通常是计算机处理信息的最⼩单位,计算机中的信息通常是连续的字节。⼈类输⼊给计算机的任何信息(⽂字、图像、⾳频等)都可编码为数字信息(⼆进制⽐特流)进⾏处理,需要输出时再解码为原形式。

不同进制间可相互转换,你需要熟悉进制转换⽅式,其中最重要的是⼆进制、⼗进制、⼗六进制间的转换。对于 Pwn,我们通常希望轻松阅读内存中的原始数据。为简化⼆进制表达便于⼈类理解,我们通常将计算机中⼆进制数据⽤⼗六进制表⽰:⼀位⼗六进制数正好为 4 ⽐特,两位⼗六进制数为 1 字节。有时为⽅便数据类型转换和运算,计算机存储数字时,数字在内存中的⾼低位与⼈类阅读的⾼低位相反,这种数据存储⽅式叫“⼩端存储”。你需要知道⼤端序(big-endian)和⼩端序(little-endian)的概念,能够区分它们,并能做到相互转换。关于这⼀⽅⾯的知识,其实可以归结到计算机基础中,这⾥为你推荐南京⼤学的⼀⻔《计算机系统基础》课程,这⾥链接给出的仅仅是(⼀),你不必急于看完,知识的获取不是⼀蹴⽽就的,慢慢来,后续还可以在MOOC中搜索(⼆)(三)进⾏观看。

程序设计

既然 Pwn 涉及逆向程序逻辑,我们需要看懂程序究竟在做什么并寻找其漏洞,那么我们⾸先得有能⼒“正向”写出⼀般的程序吧。电脑⽆法读懂⼈类语⾔,我们必须得⽤程序设计语⾔编写程序,并编译(详⻅下⽂“编译与汇编”)成电脑能“读懂”并执⾏的机器码。正在阅读这篇⽂档的你很可能没有任何编程基础,这很正常。你也许曾了解过 Visual Basic、JavaScript... 但是对于 Pwn 学习初期,我们⼀般⾯对 Linux 环境下的 C 语⾔。

现在你已经逐渐进⼊实操阶段了,实操过程中最重要的是善⽤搜索引擎(以及⼀些 AI ⼤模型),推荐使⽤必应或⾕歌。在接下来的旅程中,你⼤概需要先配置好“科学上⽹”⼯具。

C语言

鉴于 C 语⾔贴近底层且灵活度⾼,⼤多数 Pwn 题⽬程序都由 C 语⾔编写,⼤多数逆向⼯具的逆向结果也是类似 C 语⾔的伪代码(详⻅下⽂“IDA 和 gdb”,后⾯将为你介绍这两个⼯具,先别急)。你需要⼊⻔学习 C 语⾔,有两种途径,⼀个是阅读书本,⼀个是通过⽹上的课程,⼀切取决于你⾃⼰更喜欢哪种学习⽅式。推荐书籍有《C Primer Plus》,以及查阅⾮教程⼯具⽹站 C 参考⼿册(中⽂)、man7.org(英⽂)。强烈建议你在 Linux 环境下编译运⾏ C 语⾔(详⻅下⽂“环境搭建”)。视频课程⽅⾯,经典的⿊⻢程序员可以作为⼀个⼿段,以及 B 站上其他的⼀些免费⽹课都是可以的,你将知道什么是 B 站⼤学(可不只是可以看番)。我们⽬前不需要完整系统地学习 C 语⾔(不代表未来不需要)。你需要关注 C 语⾔中的基础数据类型、流程控制、标准库函数(scanf、printf、puts、strcmp、system、mmap 等)、位操作和指针C 语⾔能很好地和汇编语⾔(详⻅下⽂“编译与汇编”)对应,学习两者时应相互结合,理解等效的 C 语句和汇编指令。

Python

为了能编写漏洞利⽤脚本(详⻅下⽂“Pwntools”),你还需要学习 Python 语⾔。Python 语⾔极容易上⼿,⽹上教程多如⽜⽑。你⾄少需要学会基本语法与数据类型、列表(list)与字典(dict)类型的⽤法、函数(⽅法)定义及调⽤。建议使⽤ Visual Studio Code 编辑器编写 Python 脚本。(多敲代码才是王道,纸上觉来终觉浅)

如果你对计算机科学很感兴趣想系统学习并且英语不错,我强烈建议你看 CS61A 系列课程及其配套电⼦书学习 Python。同样的,如果想看⼀些中⽂课程,不管是慕课还是哔哩哔哩,都同样有很多优质并且免费的课程等待你学习,加油!

环境搭建-GNU/Linux

Linux 是⼀种⾃由和开放源代码的类 Unix 操作系统,如今通常⽤于服务器,我们⽇常使⽤的 PC 操作系统通常是 Windows。由于 MoeCTF 以及其他 CTF ⽐赛中的 Pwn 题⽬全都在 Linux 特别是 Ubuntu(⼀个 Linux 发⾏版)环境中,为了⾄少能运⾏ Pwn 题附件的程序(详⻅下⽂“做题”),我们当然需要⼀个 Linux 环境。推荐安装⼀个 Ubuntu 虚拟机或使⽤ docker(详⻅下⽂“Pwn”),⽹上教程太多,这⾥不赘述(善⽤搜索引擎)。如果你只是想尝试 Pwn,那么 WSL2 也已经够⽤了,并且更流畅。这⾥为你推荐⼀篇 WSL2 的环境搭建⽂章,希望它能帮助到你!

环境搭建-PWN

安装好 Linux 环境后,还需继续搭建 Pwn 环境,这⾥有⼀篇⼗分详尽的⽂章。

PWN环境搭建

⽬前你⾄少需要这三样:Linux Python 环境 + 静态逆向分析⼯具(如 IDA)+ Linux 调试器(如 GDB + pwndbg)
你还需要安装更多⼯具:checksec、binutils、patchelf、LibcSearcher、glibcall-in-one、ropper、one_gadget、seccomp-tools
等,其中有很多你⽬前⽤不到,但
前两个建议先安装好(⻅上⽂ Wiki ⽂章)。
⼀个标准的 Pwn 流程是:

  1. ⽤ checksec 检查保护机制(详⻅下⽂“Linux 安全机制”)
  2. ⽤ patchelf 替换 libc、ld 等(可选)
  3. ⽤ IDA 反汇编反编译挖掘漏洞
  4. ⽤ GDB + pwndbg 调试执⾏确认漏洞
  5. ⽤ Python + pwntools 编写利⽤脚本

libc 和 ld 分别是 Linux C 标准库和动态链接器。我们⽤ C 语⾔编写程序时经常调⽤⼀些“从天⽽降”的函数(printf、scanf...),它们其实就在 libc(通常为 GNU 提供的 glibc)⾥,ld 则搭起你的程序和这些函数间的“桥梁”。(详⻅下⽂“编译与汇编”)Linux 系统中⼏乎所有软件都需要⽤到它们!

Linux的操作

既然 Pwn ⼀般在 Linux 中操作,那么学习⼀些 Linux shell 操作⾃然必要。你⾄少应该明⽩
cd、ls 、chmod、file、cat、grep、strings、man 等基础命令和管道与重定向的概
念。在这期间,你也将学到 Linux ⽤⼾与⽤⼾组及其权限管理机制。推荐这个短⽂(选
读):命令行的艺术

在计算机领域,“shell”是⼀种计算机程序,它将操作系统的服务提供给⼈类⽤⼾或其
他程序,在 Linux 中通常指命令⾏界⾯。对于 Pwn,⼀个很重要且必要的命令⾏⼯具是 Netcat(nc 命令),它能⽤来连接 Pwn 题⽬
在线环境。Netcat 是⼀个强⼤的多功能⽹络⼯具,⽬前你只需要知道⼀种⽤法:nc [ip] [端⼝]。

另外你应该学习版本控制软件 git 的基本使⽤⽅法,主要是 git clone [URL],⽤于下载各种⼯具。(git 的功能远不⽌于此)
还需要了解 Linux 常⻅的系统调⽤(syscall)——open、read、write、mmap、execve 等和⽂件描述符(file descriptor / fd)的概念:stdin - 0、stdout - 1 ...。它们是⽤⼾空间程序(我们平时运⾏的程序)和操作系统内核沟通的桥梁。你需要知道 Linux 程序运⾏时发⽣了什么(如动态链接过程,got、plt 的概念,调⽤栈结构)。

Linux ⼀切皆⽂件!希望你能从中感受到 Unix 哲学的魅⼒。之后我强烈建议你在空闲时间看看这系列视频:
计算机教育中缺失的一课

编译与汇编

当你读到这⾥时,你或许已经能⽤ C 语⾔编写并运⾏简单程序(最好在 Linux 中操作),然⽽对于 Pwn 来说,我们必须要熟悉程序编译过程和基本的汇编语句。你需要知道 ELF ⽂件格式、预处理 -> 编译 -> 汇编 -> 链接(静态 / 动态)过程、Linux 进程虚拟内存空间(栈、BSS 段、数据段、代码段等)。理解调⽤栈结构及其增⻓⽅向与数据存储增⻓⽅向相反是 Pwn 前期学习的⼀⼤重点。对于汇编语句,我们平时使⽤的和 Pwn 程序⼀般编译⾄ x86 CPU 指令集(本⽂默认 amd64),你需要学习 x86 汇编基础,⾄少应能看懂 mov、lea、add、sub、xor、call、leave、ret、cmp、jmp 及条件跳转、push、pop、nop。⼀般来说你现在可以认为 CPU 会顺序依次执⾏这些语句,但由于乱序执⾏、分⽀预测等技术,实际情况较为复杂。除了汇编语句,你需要了解 x86 CPU 寄存器,认识有特殊⽤途的寄存器(rsp、rip...)。在做 Pwn 题时,有时你需要先在适当位置填⼊ shellcode(⽤于获取 shell 的汇编码)再劫持控制流(详⻅下⽂)⾄此处以执⾏。你需要知道计算机在汇编层⾯是如何调⽤函数的。具体⽽⾔,你需要知道并牢记 amd64 System V ABI 函数调⽤规约:调⽤函数时的部分参数通过寄存器(rdi、rsi、rdx、rcx、r8、r9)传递其余通过栈传递,32 位系统直接通过栈传递参数(从右⾄左⼊栈);函数返回值也由寄存器(rax)传递。除了函数调⽤,你还需要知道 syscall 的系统调⽤号与参数的传递⽅式(rax ...),这与函数调⽤类似。(善⽤搜索引擎)

操作系统

这个属于⽐较进阶的基础知识了,你不必在⼀开始就学习,但是,想要成为⼀个优秀的 Pwn ⼈,操作系统绝对是不可或缺的,未来学校也会为你开设操作系统课,⾜以说明其重要性。如果你等不及的话,这⾥也为你推荐⼀⻔宝藏课程,来⾃南京⼤学蒋岩炎⽼师的操作系统课(当你的基础还没有那么牢固的时候,可能会看不懂,所以这⾥的区域请以后再来探索)。

学习路线

终于正式开始 Pwn 了。以上前置知识不⽤先学完,最好边学边做。学习 Pwn ⼀定不能⼀直读书,这并不能让你“基础扎实”,反⽽会让你被庞⼤的前置知识劝退,学习起来没有任何的反馈感,⽹络安全是⼗分重实践的领域。我的经验是多做题,多看其他师傅(通称)的 Writeup(赛后复盘),当出现看不懂的知识的时候,就去查询,⼀层层的递归学习。另外,尽量看在线资源,书籍信息⼀般具有滞后性。

常⻅漏洞和利⽤⽅法

以下列举出⼀些⼊⻔常⻅的漏洞和利⽤⽅法,限于篇幅只能⼀句话概括且不够准确严谨。你必须通过 CTF Wiki 等资料(详⻅下⽂“推荐资料”)具体学习,这⾥仅提供学习⽅向。(“⭐”数代表针对⼊⻔学习的重要性)

  • 整数溢出 —— 数学世界整数有⽆穷多,但由于内存限制,计算机中补码表⽰的“整数”有上下限。通过输⼊超⼤数字溢出或者利⽤有符号整数(负数)强转为⽆符号整数可以构造超⼤数字,从⽽绕过检查或越界写⼊。⭐⭐⭐

  • 栈缓冲区溢出 —— 最经典的漏洞,通过越界写⼊修改函数返回地址或栈指针从⽽实现劫持控制流和栈迁移(篡改栈基址 rbp)。⭐⭐⭐⭐

  • 字符串 \0 结尾 —— C ⻛格字符串以零字节(“⼆进制”的 \0 ⽽⾮ ASCII 数字 0)结尾。如果破坏或中途输⼊这⼀标记则可泄漏信息或绕过检查(如绕过 strcmp)。这是很多漏洞的“万恶之源”。⭐⭐⭐

  • 返回导向编程(ROP)—— 这是 Pwn 前期学习重点。其中包含 ret2text、ret2libc、ret2syscall、ret2system、ret2shellcode、ret2csu、SROP 等,这也是栈缓冲区溢出的主要⽬的。进阶:通过 ropper 或者ROPgadget等⼯具寻找程序中 gadgets(ROP ⽚段,以 ret 结尾)结合栈缓冲区溢出构造调⽤链控制程序执⾏流,甚⾄能执⾏⼏乎任意⾏为(通常 open、read、write)。⭐⭐⭐⭐⭐

  • 竞争条件 —— 程序并⾏访问共享资源时,由于各线/进程执⾏顺序不定,有可能绕过检查或破坏数据。⭐

Linux的安全机制

  • NX(No eXecute)—— 通过将栈内存权限设置为不可执⾏,使栈上机器码不可执⾏,从⽽⽆法简单地在栈上布置 shellcode。⼀般所有题⽬都会开启,可⽤栈迁移

  • 或修改可执⾏位等⽅法绕过。⭐⭐⭐

  • Canary —— 在栈上栈指针和返回地址前设置⼀个随机值(canary),通过⽐对函数返回前和执⾏前该值是否相等来检测栈缓冲区溢出攻击。通过直接越界读泄漏、劫持 scanf 特殊输⼊或爆破等⽅法绕过。⭐⭐⭐⭐

  • ASLR / PIE —— 通过随机化程序的内存布局(地址),使得攻击者难以预测程序的内存结构,从⽽增加攻击难度。设法泄漏基址或爆破等从⽽绕过。⭐⭐

  • RELRO —— 通过将动态链接程序的全局偏移量表(GOT)在程序启动后设置为只读,防⽌通过修改其中数据结构进⾏攻击。⭐

  • Seccomp —— ⼀种沙箱保护机制,可以限制程序能够使⽤的 syscall。⭐

  • CFI(IBT / SHSTK)—— 控制流完整性保护,可以阻⽌ ROP 攻击,抑制 COP、JOP 攻击。

Glibc相关利用

  • fmt_str —— 若 printf 等格式化字符串函数中“格式(” format)参数为⽤⼾输⼊,则可被利⽤,从⽽达到任意地址读写等⽬的。⭐⭐⭐

  • one_gadget —— 将程序指针修改⾄ glibc 中的⼀些特殊位置(one_gadgets)同时满⾜少量条件即可直接 getshell。⭐

  • Heap / _IO_FILE / ... —— Pwn 永⽆⽌境 ..

pwn college

这⾥推荐⼀个学习 Pwn 的宝藏⽹站 Pwn college:https://pwn.college/ 简单介绍⼀下,这个是⼀个由亚利桑那⼤学(University of Arizona)⽹络安全研究团队开发的、⾯向初学者和进阶者的免费在线 PWN 学习平台,其中包含了课程、靶场等,相当于他们学校的本科⽣和研究⽣修 pwn 的课程所⽤的实验平台,稍微了解怎么⽤之后,其实很简单,这⾥为⼤家介绍⼀下它主要的模块和⽤法,⾸先是上⾯的 dojo(道场),这是主要的题⽬模块,其中包含上⾯的⼊⻔模块和下⾯的核⼼模块,Getting Started 中主要是教你怎么使⽤这个⽹站,Linux Luminarium 中则是包含了很多 Linux的基础知识,是⼀个上⼿ Linux 的模块,能很快的通过⼀个个的 challenge 模块对 Linux 的使⽤进⾏快速了解,Computing 101 中主要是对汇编语⾔进⾏了⼀个学习,最后⼀个⼦ module 甚⾄让你⽤汇编语⾔搭建⼀个简易 Web server,对该模块的学习能让你很快的掌握汇编语⾔的使⽤,Playing With Programs 模块中,则包含了⼀些与程序的交互,下⾯的核⼼模块中,Program Securiy更贴近于我们前期的 ROP 学习,推荐前⾯的基础模块⼊⻔后,优先选择该核⼼模块进⾏学习。

推荐资料

以下资料不是全都要看完,只需⾃⾏挑选⼀些最适合⾃⼰的即可。

  • 《深⼊理解计算机系统》—— CSAPP
  • 《程序员的⾃我修养:链接、装载与库》
  • CTF-All-In-One
  • 《CTF 权威指南(Pwn 篇)》
  • CS ⾃学指南——计算机科学(Computer Science)⾃学指南。
  • 《IDA Pro 权威指南》

以下推荐⼀些视频课,帮助⼀些不是很喜欢看书的同学有效的学习

  • CSE365,是pwn college中针对新⽣开设的⼀堂课,将带领新⼊⻔的学⽣⾛进pwn的世界。
  • CSE466,是pwn college中进阶的课程,你将学习程序安全、系统安全等进阶知识。
  • 你有多想 pwn,B 站上国资社畜师傅针对 pwn 的⼀个课程,相⽐前⾯的英⽂课程,这个中⽂课程更为友好⼀些。
  • 南⼤计算机基础,了解计算机基础的⼀⻔好课,基础不牢地动⼭摇!
  • 本文作者:Junius
  • 本文链接: https://enc.edu.pl/?post=21
  • 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。
文章很赞!支持一下吧 还没有人为TA充电
为TA充电
还没有人为TA充电
1
1
  • 支付宝打赏
    支付宝扫一扫
  • 微信打赏
    微信扫一扫
感谢支持
文章很赞!支持一下吧
关于作者
20
0
1
0
内卷太严重,已躺平...

线性代数的角度求解数列通项公式

上一篇

宴席

下一篇
评论区
内容为空

这一切,似未曾拥有

  • 复制图片
按住ctrl可打开默认菜单