我试图用Python生成的输入填充C中的一个简单缓冲区。这是ROP项目的实践。下面是简单的C代码:
#include <string.h>
int main(int argc, char **argv)
{
char buf[128];
strcpy(buf, argv[1]);
}
编译为:gcc -m32 -ggdb -fno-stack-protector -mpreferred-stack-boundary=2 test.c -o test
我的硬件:x86-64,Linux Mint。你知道吗
下面是python输入的一部分:
from struct import pack
p = '//bin/sh' #address 0xffffd15c
p += 'A'*28
#null terminate our string
p += pack("<I", 0x0806e67a) # pop edx ; ret
p += pack("<I", 0xffffd163) # @ "/bin/sh" + 7
p += pack("<I", 0x080bac56) # pop eax ; ret
p += pack("<I", 0xffffffff) # 0xffffffff, or could xor the instruction
p += pack("<I", 0x0807b0cf) # inc eax ; ret
p += pack("<I", 0x08099fad) # mov dword ptr [edx], eax ; ret
出于某种原因,当我将其作为argv[1]
输入时,缓冲区将正确填充到最后一行。它不是用0x08099fad
填充缓冲区,而是说0x00009fad
。这一行后面有更多的输入,但这就是出错的地方,导致其余的输入都是垃圾(不是我输入的)。你知道吗
出于某种原因,strcpy中似乎放入了一个空字节,可能提前终止了它。但我不知道空字节在哪里。当我尝试输入这个地址时,也会发生同样的情况:0x080acedc
。你知道吗
有什么想法吗?你知道吗
谢谢!你知道吗
只是为了让搜索这个答案的人得到真正的帮助。你知道吗
我今天遇到了同样的问题。 我发现的是,python本身逃避了这些字符。 如果你用C写同样的程序,它就可以工作了。 如果您像这样打印var:
将输出保存到文件并使用十六进制编辑器查看您将看到它实际打印:
当我尝试同样的方法时:
在它打印的十六进制编辑器中查看:
遗憾的是,我不知道如何使用python正确打印这些字符。 最简单的解决方案似乎是用C编写
附言:@风向标,如果有人有兴趣了解风向标在引擎盖下的工作原理,那么羞辱他又有什么意义呢? 默默无闻的安全措施(也就是不说所以没人知道)是行不通的。 有人会把它弄坏的。 最好让有兴趣的白帽知道怎么做,他们可能会试图解决这些问题。你知道吗
编辑: 多亏了弗劳恩霍夫公司的人,我找到了解决办法。 使用系统标准缓冲区.写入(ex\u str) 其中,exstr的类型必须是bytes。 首先将字符串创建为bytearray,然后将其转换为bytes类型:
你也可以使用子流程调用()或子流程运行()启动可执行文件并将其传递给bytes对象。你知道吗
希望有人觉得这个有用。你知道吗
我假定您将该字符串作为命令行参数提供给C实用程序。(顺便说一下,
test
不是实用程序的好名字,因为它是一个标准的shell函数,通常作为内置函数实现。)现在假设您要从终端调用实用程序:
显然
argv[1]
将由一个四个字符的单词组成,另一个单词放在argv[2]
中。如果希望单个参数是命令行的其余部分,则需要引用它:现在,通常当我们从一个程序中调用一个实用程序时,我们实际上不希望参数被shell解释。我们只想用带有实际参数字符串的
exec
数组来argv
进程。这样,我们就不必担心空格和shell元字符,也不必担心如何正确引用任意字符串。你知道吗但是为了受虐狂的利益,python提供了指定
shell=True
的操作系统的可能性。尽管手册明确警告不要使用这个选项,即使人们经常遇到麻烦使用它,它仍然是一个奇怪的流行选择。你知道吗顺便说一下,在生成的程序中没有空间(尽管它们可能是)。空格为0x20。但是shell将其他字节解释为空白。例如,tab是0x09。我将把它作为一个练习来计算0x0A的结果。你知道吗
相关问题 更多 >
编程相关推荐