Python 和 Bash 处理十六进制(shellcode)的方式不同?不一致?
Python and Bash handle hex (shellcode) differently? Inconsistent?
所以我一直在研究一个简单的格式字符串漏洞,在过去的 3 个小时左右,我一直在抨击 table 想知道为什么我的十六进制值没有出现在堆栈中.
谁能赐教,不胜感激
1.
最初我在做这些挑战时使用 python 编写脚本,特别是对于这个例子:
python -c 'print "AAAAA\xcc\xd5\xff\x4f"' > a
然后在 GDB 中查看堆栈:
format string>
0xffffd550: 0xffffd584 0xf7ffdab8 0x41f95300 0x41414141
0xffffd560: 0x95c38cc3 0x0a4fbfc3 0xf7e2ec00 0xf7f8f820
现在它似乎没有出现在 "AAAAA" 之后(使用 5,因为没有对齐)。
2.
但是,当我使用之前使用过的另一个地址时:
python -c 'print "AAAAA\x5c\x57\x55\x56"' > a
我得到:
format string>
0xffffd550: 0xffffd584 0xf7ffdab8 0x41f95300 0x41414141
0xffffd560: 0x5655575c 0x0000000a 0xf7e2ec69 0xf7f8f820
看起来还不错?
3.
此外,当我使用类似的东西时:
echo -en "AAAAA\xcc\xd5\xff\x4f" > b
我可以这样正确地将值设置到堆栈中:
format string>
0xffffd550: 0xffffd584 0xf7ffdab8 0x41f95300 0x41414141
0xffffd560: 0x4fffd5cc 0x00000000 0xf7e2ec69 0xf7f8f820
下面分别是 a 和 b 文件的输出:
AAAAA���O
AAAAAÌÕÿO
第一个示例的问题是您的字符串包含大于 0x7F 的值。当 Python 输出字符串时,它决定(根据您的系统和语言设置)它应该以 UTF-8 格式写出字符。
UTF-8 将字符 0x7F 及更低的字符表示为它们自己,因此 A
和 x4f
字符将原封不动地写出。但是,UTF-8 将值大于 0x7F 的字符表示为多个字节的序列。在这种情况下,大于 0x7F 的字符是 \xcc
、\xd5
和 \xff
。这些字符的 UTF-8 编码分别为 0xC3 0x8C
、0xC3 0x95
和 0xC3 BF
。这些是显示在您的内存转储中的值。
您可以通过强制 Python 使用处理 0x7F 以上值的编码发出字符串来解决这个问题,方法是将它们作为自身传递,而不进行转换。 "latin1"就是这样一种编码,所以你可以使用这个命令:
python 'print u"AAAAA\xcc\xd5\xff\x4f".encode("latin1")'
但这很丑
此外,Python 版本总是在字符串末尾发出一个换行符 (0x0A)。它显示在您的内存转储中,位于您打算传递的值之后的单词中。您可以通过以下方式解决该问题:
python -c 'import sys; sys.stdout.write(u"AAAAA\xcc\xd5\xff\x4f".encode("latin1"))'
但这更丑陋。
我忘记尝试为此使用 Python 单线并坚持使用 echo -ne
方法。
所以我一直在研究一个简单的格式字符串漏洞,在过去的 3 个小时左右,我一直在抨击 table 想知道为什么我的十六进制值没有出现在堆栈中.
谁能赐教,不胜感激
1.
最初我在做这些挑战时使用 python 编写脚本,特别是对于这个例子:
python -c 'print "AAAAA\xcc\xd5\xff\x4f"' > a
然后在 GDB 中查看堆栈:
format string>
0xffffd550: 0xffffd584 0xf7ffdab8 0x41f95300 0x41414141
0xffffd560: 0x95c38cc3 0x0a4fbfc3 0xf7e2ec00 0xf7f8f820
现在它似乎没有出现在 "AAAAA" 之后(使用 5,因为没有对齐)。
2.
但是,当我使用之前使用过的另一个地址时:
python -c 'print "AAAAA\x5c\x57\x55\x56"' > a
我得到:
format string>
0xffffd550: 0xffffd584 0xf7ffdab8 0x41f95300 0x41414141
0xffffd560: 0x5655575c 0x0000000a 0xf7e2ec69 0xf7f8f820
看起来还不错?
3.
此外,当我使用类似的东西时:
echo -en "AAAAA\xcc\xd5\xff\x4f" > b
我可以这样正确地将值设置到堆栈中:
format string>
0xffffd550: 0xffffd584 0xf7ffdab8 0x41f95300 0x41414141
0xffffd560: 0x4fffd5cc 0x00000000 0xf7e2ec69 0xf7f8f820
下面分别是 a 和 b 文件的输出:
AAAAA���O
AAAAAÌÕÿO
第一个示例的问题是您的字符串包含大于 0x7F 的值。当 Python 输出字符串时,它决定(根据您的系统和语言设置)它应该以 UTF-8 格式写出字符。
UTF-8 将字符 0x7F 及更低的字符表示为它们自己,因此 A
和 x4f
字符将原封不动地写出。但是,UTF-8 将值大于 0x7F 的字符表示为多个字节的序列。在这种情况下,大于 0x7F 的字符是 \xcc
、\xd5
和 \xff
。这些字符的 UTF-8 编码分别为 0xC3 0x8C
、0xC3 0x95
和 0xC3 BF
。这些是显示在您的内存转储中的值。
您可以通过强制 Python 使用处理 0x7F 以上值的编码发出字符串来解决这个问题,方法是将它们作为自身传递,而不进行转换。 "latin1"就是这样一种编码,所以你可以使用这个命令:
python 'print u"AAAAA\xcc\xd5\xff\x4f".encode("latin1")'
但这很丑
此外,Python 版本总是在字符串末尾发出一个换行符 (0x0A)。它显示在您的内存转储中,位于您打算传递的值之后的单词中。您可以通过以下方式解决该问题:
python -c 'import sys; sys.stdout.write(u"AAAAA\xcc\xd5\xff\x4f".encode("latin1"))'
但这更丑陋。
我忘记尝试为此使用 Python 单线并坚持使用 echo -ne
方法。