Archive for the ‘easier said than done’ tag
Easier said than done
在看PicoWebServer的一个security flaw分析,嗯,典型的栈溢出。虽然多了一个Unicode,但是还是可以做到DoS攻击的。作者的分析也挺不错,把出现问题的地方说得清楚了。
不过末尾有一句话有点大雷了:
An attacker has full control over the device if he is able to let the overwritten return address point to a “0D F0 A0 E1″ (“MOV PC, SP”) equivalent byte sequence. Since SP is the only register pointing into the potential shellcode supplied by an attacker, the aim of an attacker is to let PC equal SP.
还好作者用的是if he is able to,还有点不确定的意思。我是老老实实地用IDA Pro搜索了整个地址空间(是的,“整个”),也没有发现有这样的序列。首先,编译器不会产生这样的代码,那么在代码段内找是徒劳的了。其次,数据段有的话,那真是纯粹巧合了,看人品,而且数据段能不能执行,还是未知之数。
所以啊,总是easier said than done,虽然现在有这样的possibility,但是实际上做不做得到,那还真是认真考证一下才清楚。
师兄也和我说了,搞个什么MessageBox出来,那是不难,但是我们的目标还是要再远一点,要有点实际的东西出来。我也挺认同的,理念上的东西,大家都清楚,但是到底能不能用,可不可以,那还真是要做过才知道。不产生实际危害的漏洞,不是好漏洞(DoS不在考虑之列,这是比较次的危害)。
提一下我们现在的问题是什么:某个软件,接收ANSI字符(0×00-0xFF),然后把接收到的字符转换成Unicode再存储到缓冲区,然后造成了缓冲区溢出。问题是,我们虽然可以改写栈上PC的值,但是这是有限制的(Unicode转换的存在)。如何把控制流改到我们注入到栈上的shellcode中,这需要很多工夫了。目前这是第一步,先不考虑shellcode是否有效,就是要把PC的值搞到栈上就OK了。
这一周基本都在考虑这个问题,也有不少的想法,但是最后都被自己否掉了。罗列如下吧:
- 把要发过去的ANSI串A看作是Unicode,先进行Unicode到ANSI的变换得到B,把B发过去,这样在Server端变换之后,就变成了A。这个想法的致命点是,ANSI只能映射Unicode的一个很小的子集,也就是说,变换过程不是满射的。而且从比例来看,只有1%左右有情况可以逆变换成功。于是有第二个想法。
- 寻找Unicode编码中的闭包子集S,发过去S中的A变换后得到的B仍然在S之内,这样可以很容易通过控制A的生成来得到理想的B。但是现在我还没有找到这样的闭包。即使找到,也只有万里长征第一步,因为这样的S估计不会很大,变换出来的编码有限的话,对于地址的选择就很有讲究了。
- 在其他段寻找如MOV PC, SP这样的序列(也就是上面文章的想法)。不用说,目前失败。
- 构造某个系统调用/API的输入,然后跳转到那个系统调用/API。要求是这个系统调用/API足够强大,可以完成很多功能。但是矛盾的地方是,功能强大的API通常参数是十分复杂的,很难构造。而且,Windows CE的calling convention中,首先使用R0-R4去传送参数,不够才使用栈。怎么让R0-R4符合API的要求?看运气?否掉。
- 从转换函数入手,当然,这个想法很烂。但是也不是说完全没有可能,先留着呗。
现在基本是能想到的都想了,但是总是有这样那样的限制,使得这些想法成为不可能。明天和师兄讨论一下,看他有没有什么其他想法吧。