Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python输入缓冲区中的strcpy不正确_Python_C_Shell - Fatal编程技术网

python输入缓冲区中的strcpy不正确

python输入缓冲区中的strcpy不正确,python,c,shell,Python,C,Shell,我试图用Python生成的输入填充C中的一个简单缓冲区。这是ROP项目的实践。下面是简单的C代码: #include <string.h> int main(int argc, char **argv) { char buf[128]; strcpy(buf, argv[1]); } 由于某种原因,当我将其作为argv[1]输入时,缓冲区将正确填充,直到最后一行。它不是用0x08099fad填充缓冲区,而是说0x00009fad。这一行后面有更多的输入,但这就是出错

我试图用Python生成的输入填充C中的一个简单缓冲区。这是ROP项目的实践。下面是简单的C代码:

#include <string.h>    
int main(int argc, char **argv)
{
  char buf[128];
  strcpy(buf, argv[1]);
}
由于某种原因,当我将其作为
argv[1]
输入时,缓冲区将正确填充,直到最后一行。它不是用
0x08099fad
填充缓冲区,而是说
0x00009fad
。这一行后面有更多的输入,但这就是出错的地方,导致其余的输入都是垃圾(不是我输入的)

出于某种原因,strcpy中似乎放入了一个空字节,可能会提前终止它。但我不知道空字节在哪里。当我稍后尝试输入此地址时也会发生同样的情况:
0x080acedc

有什么想法吗


谢谢

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

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

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

./test "some thing"
现在,通常当我们从程序中调用实用程序时,我们实际上不希望shell解释参数。我们只想使用带有实际参数字符串的
argv
数组执行进程。这样,我们就不必担心空格和shell元字符,也不必为了正确引用任意字符串而烦恼

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


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

这样搜索此答案的人就可以得到实际的帮助

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

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编写

附言:@weathervane,如果有人有兴趣了解它在引擎盖下的工作原理,那么羞辱他有什么意义呢? 默默无闻的安全措施(又名不说,所以没人知道)不起作用。 有人会打破它的。 最好向有兴趣的白帽们展示如何去做,他们可能会试图解决这些问题

编辑: 多亏了弗劳恩霍夫学院的人,我找到了解决办法。 使用sys.stdout.buffer.write(ex_str) 其中ex_str的类型必须为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)
还可以使用subprocess.call()或subprocess.run()启动可执行文件并将字节对象传递给它


希望有人觉得这很有用。

也许所有这些连接都会导致字符串长度大于127。这当然很接近。慷慨地尝试使用长度为
1000
的字符串,该字符串应作为简单的
main
中的局部变量。在使用
argv[1]
之前,请检查
argc
。您好。谢谢你的回复。其目的是进行缓冲区溢出,并远远超出128字节的分配。上面的python输入只是其中的一部分。当我注释掉最后一个地址时,
0x08099fad
,其余的输入就在它刚刚好之后填充。但是这一个特别导致整个输入在写地址的过程中变得混乱。哦,这是故意利用的吗?当你设计了一些未定义的行为时,为什么还要要求解释这些行为呢?我相信,在我们生活的这个脆弱的世界里,并非只有我一个人在辱骂破坏者。我投票将这个问题作为离题来结束,因为这个网站不欢迎那些想要帮助打破我们机器的人。你们学校也开安全破解课吗,还是网络窥探技术?嗯。09和0a都在制造问题。有趣。0a会导致换行吗?但是python字符串不是让它读作地址字节,而不是ASCII符号吗?@TRP:bytes就是字节。它们没有类型。当您将一串字节传递给shell时,您只是在传递字节。你认为哪种机制会允许这些字节被“读取为地址”?不确定。但为了澄清,你认为09被解释为一个标签,而0A被解释为一个换行符?我只是好奇你的经历中为什么会这样。我是新来的。谢谢你的回复。@trp:你是如何运行C程序的?您使用的子流程模块带有
shell=True
,我错了吗?假设我是对的,那么是什么导致shell不将制表符字符视为制表符呢?您好。我目前正在gdb中运行它。我不熟悉
shell=True
语句。当我在gdb中运行它时,例如:
(gdb)r./payload.py
字符串开始复制到缓冲区中。在遇到09或0A之前,一切都正常。对我来说,这似乎有点奇怪,这似乎是唯一两个导致问题的字节,但这只是因为我对这方面相当陌生。
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)