pwn 学习总结

0x00 记录下学习过程

首先,安天实验室几个pwn专题的实验不错。学习了下,当做入门。

入门之后,找到了练手的好地方:http://pwnable.kr/,这个网站的题目真的很不错。先做简单的,一般都能从网上搜到思路。然后,自己分析写写exp。

接下来,我记录下pwnable.kr上的几个简单题目。

0x01 bof

最简单的栈溢出,源码都给了:

不过还是看ida比较好,可以精确知道overflowmekey分别到栈底(ebp)之间的距离。精确覆盖即可。
可以看到:

因此两者之间的距离为34h(也就是52字节)。接下来就是精确覆盖了,简单Payload为:

0x02 fd

linux下0代表标准输入:

0x03 uaf

这个题目让我初步理解了use after free漏洞,这个题目还涉及到c++内存布局中的虚函数知识,不好讲清楚。请参考这个链接: http://www.cnblogs.com/bizhu/archive/2012/09/25/2701691.html

这里记录下我对uaf的一个测试代码:

上述代码的运行结果为:

内存分配会优先在刚释放的内存区域进行。

0x04 echo1

刚入门,这个题目很不错。 这是个64位程序,扔到ida中,F5慢慢看~ 阅读代码时基本功吧~
很容易能找到溢出点:

变量s在bp-20h处,而我们可以输入128字节的数据。栈上足以让我们写个shellcode。

现在缺少的是如何控制eip,跳转到我们栈上去执行shellcode。

思路:

  • 栈的地址,是不知道的~需要找方法泄露。 这题有点困难~~

  • 找个全局变量,使其存储jmp rsp汇编指令。然后,将栈的返回地址指向它~(全局变量地址是不变的)

刚好有个id变量存储着我们输入进去的name,具体可以用gdb调调看看。然后就好说了:

  • 全局变量id存储jmp rsp汇编指令。
  • 栈返回地址覆盖为id的地址
  • 栈的返回地址以上都是我们的shellcode。(rsp现在就指向这里)

Payload如下:

echo2

echo2接着echo1,看到了fsbuaf。根据名字猜测,是格式化字符串漏洞use after free结合。

漏洞点:

  • 格式化字符串漏洞:

这里需要用它来泄露栈地址。

  • use after free漏洞

在我们为选择确定退出之前,下面cleanup()函数已经free(o)了。然后,在echo3函数中,再次使用它。

变量s指针,重新在堆中分配的一块内存,在原来释放变量o的地方。

我们只能输入32字节到内存中。所以只能触发echo3的第1个语句*(o+3)()(把shellcode地址放在第4个位置)。o_QWORD类型,即它是8字节指针,+3则加了24个字节。

shellcode 存储位置

现在我们就可以控制程序调到某个地址去执行。就缺shellcode了~
echo1中全局变量id可以存储,但只有2字节。无法存储一段shellcode。

因此,只能讲shellcode存在栈的上。找到了输入名字处的局部变量v7。

这里v7位于bp-20h处。在汇编代码中,可以看到可以输入24字节到v7中。这样足以存储一段shellcode。

fsb泄露栈地址

万事俱备,只欠东风。现在只剩下最后一个问题:shellcode在栈上~而栈地址我们是不知道的,如何获取?

fsb在这里就发挥作用了,在格式化字符串漏洞处打断点。可以看到:

可以在栈上看到可以泄露出一个ffffe420的栈地址。因为%x是输出无符号整数,所以只输出32位。从rsp到这个栈地址就有10的距离了。可以使用%10$x直接输出。

再找找我们输入的名字在哪:在ffffe400处,两者的相对地址为20h。因此,溢出这个地址,就可以得到我们的shellcode地址了。

payload

整理的payload为:

simple login

这个题目帮助我理解ebp,esp,eip中的关系。看漏洞点:


input最多有12字节的空间。而v4bp-8h,刚好能覆盖前一栈帧的ebp

这里可以控制ebp,能干啥事情呢?

先来看看函数开头和结尾的汇编代码:

覆盖ebp到可控全局变量(这里使用input)地址。此时ebp所指向的栈(input内存块)状态为:

函数执行完成后,会执行mov ebp,esp;。esp此时会执行栈底(即上图ebp的位置)。

pop ebp; esp便指向了返回地址处(这里存储system('/bin/sh')语句地址)。
pop eip eip便跳到shell处执行命令了。

payload很简单:

dragon

这里有uaf漏洞和一个整数溢出漏洞

  • 当我们胜利打败dragon后,会产生一个uaf漏洞,eip直接跳到我们输入的地址。
  • 如何打败dragon~ dragon的血量只有一字节,一直防守,使其产生整数溢出。自爆~~

对应代码为:

具体看Payload:

brain fuck

漏洞点:

  • 我们可以通过控制指针来读写内存中有限范围内地址的内容。

利用:

  • 改变原有函数的got表(认准.got.plt),使其指向我们特定的函数。例如:system('/bin/sh')

本地我们产生这样的效果:

payload 如下:

这里需要使程序再次回到main函数中,所以将putchar函数覆盖为main函数地址。

有疑问,测试过程中发现:

只能最后对putchar赋值为main函数地址?
猜测:putchar()和getchar()之间有关联。