## 二进制漏洞的发现与利用 在我们日常的生活中已经越来越离不开软件的使用,这也促生了挖洞这一行业,对于pwn的入门要求还是比较高的,首先需要熟悉汇编语言,然后要有一定的数据结构和操作系统的知识,有时涉及到协议攻击的话,还需要我们掌握各种基本的通信协议。 ### 保护措施 在开始接触二进制之前,先要了解他们的一些保护措施。 #### ASLR aslr是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的的一种技术。也就是说程序每次执行时,栈、堆、库的位置都不一样。 ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。据研究表明ASLR可以有效的降低缓冲区溢出攻击的成功率,如今Linux、FreeBSD、Windows等主流操作系统都已采用了该技术。 #### DEP 数据执行保护,默认栈的权限是可读、可写、不可执行。 #### PIE PIE(position-independent executable, 地址无关可执行文件)技术就是一个针对代码段.text, 数据段.*data,.bss等固定地址的一个防护技术。同ASLR一样,应用了PIE的程序会在每次加载时都变换加载基址。 #### Stack Guard 编译器对栈溢出的一种保护机制,在函数执行时,先在栈上放置一个随机标识符,函数返回前会先检查标识符是否被修改,如果被修改则直接触发中断来中止程序,可以有效的防止栈溢出攻击。 #### RELRO relro 是一种用于加强对 binary 数据段的保护的技术。 接下来站长介绍一些主流的漏洞。 ### 栈溢出 ```c++ // gcc -no-pie -fno-stack-protector stack.c -o stack #include #include int backdoor(){ system("/bin/sh"); } int main() { char buf[0x10]; scanf("%s", buf); puts(buf); return 0; } ``` 在这里栈的大小只有`0x10`,但是却没有对用户数据的长度进行限制,导致了栈溢出,我们可以修改`main`函数的返回地址到`backdoor`函数,这样就能拿到靶机的shell。 ### 格式化字符串 ```c++ // gcc -no-pie -z lazy fmt.c -o fmt #include #include int backdoor(){ system("/bin/sh"); } int main() { char buf[0x100]; fgets(buf, 0x100-1, stdout); printf(buf); exit(0); } ``` 这里用户可以直接控制`fmt`参数,所以可以利用`printf`函数的`%n`特性来修改`exit`的`got`地址为后门地址,这样在执行`exit`的时候,便能拿到shell。 这里仅举这两个简单的例子。 其他的还有: * 整数溢出 * 堆的利用 * House of 漏洞系统 * IO_FILE 的利用 * 条件竞争 * 内核PWN ### 推荐学习网站 * [ctf-wiki](https://ctf-wiki.github.io/ctf-wiki/introduction/resources/) ### 靶机网站 * [pwnable.tw](https://pwnable.tw) * [pwnable.kr](http://pwnable.kr/) * [PWN Challenge](http://pwn.eonew.cn)