如果你不想看到最后一段-->
我在一个使用gets()
填充函数的本地1024-char*缓冲区的程序中发现了一个缓冲区溢出漏洞。它位于Sparc Solaris 5.8 (sun4u) 32位上.
要克服的第一个障碍是tch
不允许我手动输入>257个字符(如果我想要点击enter的话,可以输入256个字符);
为了绕过这一点,我一直在执行/bin/sh
和stty raw
,现在可以使用> 1095个字符有效地溢出缓冲区。(注意:我必须使用Ctrl来执行line-feed/enter,尽管我还没有研究stty raw来检查为什么会发生这种更改。
我的问题是这个:现在是时候不仅溢出缓冲区,而且在十六进制代码中写入新的返回地址/保存%fp。但是,由于我不知道如何从终端程序中手动输入十六进制代码,我想我可以找到一种使用C的方法,让它与易受攻击的程序执行/交互,并最终发送给它我的自定义缓冲区。
但是,如果我有一种手动输入/复制粘贴十六进制字节的方法,我可以做一些像这样简单的事情!
perl -e 'print "n" . "A"x1094 . "\xff\xbe\xf5\x58" . "\xff\xbe\xff\x68" . "\0"'
(如果您想知道我为什么要打印'n‘,是因为易受攻击的程序检查字符串的yes/no @ index 0)
因为我不知道如何手动粘贴这样的十六进制信息,所以我一直在用C语言尝试使用C语言,我制作了一个特殊的缓冲区,并学习了popen()
这个易受攻击的程序("w")和fput我的缓冲区,但是它充其量是不稳定的。(波彭和IPC
对我来说都是新的)
(我也尝试过piping/dup2ing
,没有得到任何结果,也没有有效的字符串输出/输入的证据)不确定出了什么问题,我对代码进行了大量的实验,后来放弃了它。
描述我的'popen‘程序的输出最好的方法是,只有在索引1096->1099处分隔缓冲区,才能在易受攻击的程序中出现分段错误,这实际上是函数的%fp
的位置,因此它似乎是正常的@ first。但是,在高于此值的索引处分隔字符串会使编程工作正常(WTF)!这种行为让我想到了WTF!!?这与手工粘贴不同,因为运行更多的字符肯定会更改seg故障->总线错误,因为我将下一个覆盖返回地址,后面是堆栈帧中任何可能重要的信息!
整根绳子是不是真的不是一声就发了?!?我从fflush()
上听到了一些关于缓冲区popen() manpage
的问题,但我不明白!!
这是我第一次使用popen()
,还有更多的行为我认为很奇怪-->如果我停止fputs()
ing数据,易受攻击的程序会进入无限循环,重复打印它通常只打印一次的最后一个输出字符串,但在这种情况下,每当我停止fput‘ing时,就会开始无限打印。现在,我希望如果我没有输出,程序不是坐着等待更多的投入,就像一只好鸭子。???显然不是。显然,它必须继续撒尿和呻吟,我需要进入下一个字符串!!这是波彭的正常行为吗?!可能是因为我的程序在实际完成之前退出并关闭了pclose() (但我原以为会有缓冲区溢出,我不知道为什么我不能像手工粘贴时那样得到它)
备注:我使用"\r\n“来指示易受攻击的程序进行‘返回’,我不确定相当于CTRL/ Enter键(输入键在原始tty中不起作用)。我也不确定在输送缓冲器时是否需要原始的tty。
然后,我想我试着变得聪明,把字符串放到一个文件中,然后通过命令行进行管道操作。我不知道你能不能把这样的管道输送到一个期望输入的程序
在这种情况下,我甚至连一个溢出都得不到!!即
printf "\r\n" > derp && perl -e 'print "n" . "A"x1025' >> derp && printf "\r\n" >> derp
cat derp | ./vuln
现在,倒带<->回到tsh,我说我有一个257字符的限制,如果我想要点击enter并让程序继续运行,我需要做的比这个少一个。所以,也许\r\n不在这里,因为那是两个字符。要么是这样,要么就是不能将cat
放入这样的程序中。但是我在我的C程序中使用\r\n来告诉易受攻击的程序我已经点击了enter,并且它们至少稍微更有功能(并不是真的),尽管仍然没有以手动粘贴垃圾缓冲区的方式溢出缓冲区。
ARGh!
另外,只使用一种或另一种:'\r‘或'\n’绝对不起作用!我是不是又错过了另一个控制点呢?这有可能是我的节目中的一个问题吗?
但基本上我的问题是,我不能‘似乎理解如何创建一个程序来运行和接口的命令行可执行,并说嗨!把这整个缓冲区放入你的gets(),我知道你会很喜欢它的!!就像我自己在终端上运行程序一样。
我也不知道用手工将十六进制代码粘贴/写入终端的方法,就是为什么我要编写一个交互程序,用C语言编写一个带有hext字节的字符串,并发送到该程序的gets()!如果您跳到这一段,我还希望您知道我正在使用/bin/bash和stty raw,这样我就可以手动输入超过257个字符(如果我能够成功地创建一个交互程序来将易受攻击的程序发送给缓冲区,我不确定是否需要继续这样做。也许以这种方式发送一个缓冲区,绕过tch的257个字符限制)
有人能帮我吗?!
发布于 2012-06-25 22:47:45
如果shell是用gets()
读取的,那么它就是在读取它的标准输入。
因此,在您的漏洞代码中,您需要生成一个适当的超长字符串。除非您使用的是expect
,否则只需将超长缓冲区写入从您的攻击程序连接到受害者标准输入的管道。您只需要确保超长字符串不包含任何换行符(CR或LF)。如果你管,你避免了变幻莫测的终端设置和控制J的控制-M等;管道是一个透明的8位传输机制。
所以,你的计划应该:
pipe()
)。dup2()
)。
您可以使用popen()
和"w"
选项简化这一点(因为父进程希望写入子进程)。
您可能需要考虑如何处理信号。同样,如果您在接收方(受害者)退出时写入管道,则会得到一个SIGPIPE信号,该信号将终止父进程。
发布于 2012-06-25 22:45:11
popen
调用可能是您想要的电话。确保在测试完成后调用pclose
,以便正确地获取子进程。
编辑 Linux手册页提到,在该模式中添加"b“对于二进制模式是可能的,但是POSIX说,除了"r”或"w“之外,其他任何东西都是未定义的。感谢丹·穆尔丁指出了这一点。
FILE *f = popen("./vuln", "w");
fwrite(buf, size, count, f);
pclose(f);
发布于 2012-06-26 13:34:15
什么都不会产生结果。
让我重点谈谈我怀疑的问题。I管道的字符串在开始时包含一个\n
,用于确认易受攻击程序的“按回车以继续”。
我继续处理的缓冲区被声明为char c[1024]
;现在我用超过1100个字节来填充这个缓冲区。我不明白;有时起作用,有时不起作用。摇摆不定的因素是如果我在gdb (在gdb中会产生更好的结果)。但有时它也不会溢出。由于这个原因,我真的认为这是关于我的缓冲区是如何传输的shell /终端设置的某种问题。但我不知道如何解决这个问题
我真的很感激大家的帮助。但我没有得到一致的结果。我做了很多事情,学到了很多粗糙的材料,但我认为现在是时候放弃这一努力了。或者,至少要等更长的时间,直到有人得到答案。
附注:安装了Expect,:)但是我无法从其中接收到溢出.
无论如何,我似乎都需要期待,因为在管道完成工作之后,我需要重新控制溪流。Expect使这个非常简单,除了这个事实,我不能让程序溢出。
我发誓这与终端外壳设置有关,但我不知道。
https://stackoverflow.com/questions/11198178
复制相似问题