x86_64执行外壳代码失败:

2024-10-04 15:29:56 发布

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

我在64位Linux上使用python2.7。我有下面的Python脚本,它应该执行一个简单的helloworld外壳代码。在

import urllib2
import ctypes

shellcode = "\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\xbe\xd8\x00\x60\x00\x00\x00\x00\xba\x0e\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05"


#Create buffer in memory
shellcode_buffer = ctypes.create_string_buffer(shellcode, len(shellcode))

#Funktionszeiger
shellcode_func  = ctypes.cast(shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p))

#Shellcode execute
shellcode_func()

如果我运行python Scriptname.py我会得到一个内存访问错误。有人知道我的剧本为什么不起作用吗?在

编辑: 原始ASM代码:

^{pr2}$

Tags: 代码import脚本linuxbufferctypeshelloworldfunc
1条回答
网友
1楼 · 发布于 2024-10-04 15:29:56

您将需要python代码,使shell代码在具有读/写/执行权限的内存位置运行。因为shell代码的内存不在可执行内存中。您可以创建一个为您完成此操作的函数(testshellcode.py):

import ctypes, mmap, sys

# Convert string to bytes object. Differs between Python2 and Python3
if sys.version_info >= (3, 0):
    def b(string, charset='latin-1'):
        if isinstance(string, bytes) and not isinstance(string, str):
            return (string)
        else:
            return bytes(string, charset)
else:
    def b(string):
        return bytes(string)

def create_shellcode_function (shellcode_str):
    shellcode_bytes = b(shellcode_str)

    # Allocate memory with a RWX private anonymous mmap
    exec_mem = mmap.mmap(-1, len(shellcode_bytes),
                         prot = mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,
                         flags = mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE)

    # Copy shellcode from bytes object to executable memory
    exec_mem.write(shellcode_bytes)

    # Cast the memory to a C function object
    ctypes_buffer = ctypes.c_int.from_buffer(exec_mem)
    function = ctypes.CFUNCTYPE( ctypes.c_int64 )(ctypes.addressof(ctypes_buffer))
    function._avoid_gc_for_mmap = exec_mem

    # Return pointer to shell code function in executable memory
    return function

# linux machine code
shellcode = "shell code string here"

# Create a pointer to our shell code and execute it with no parameters
create_shellcode_function(shellcode)()

该代码应该可以与Python2.7+和Python3一起使用


即使您将shell代码字符串插入上面的测试程序中的byte对象,它也将失败。您的shell代码字符串似乎缺少字符串本身(hello);似乎没有正确编码,您依赖于text标签的静态内存位置。你需要一个与职位无关的地址。在

要修复代码使其与位置无关,可以使用RIP相对寻址。将字符串放在代码段后面的.text内,完全忘掉.data。{cd6>这个版本应该足够了:

^{pr2}$

使用OBJDUMP将shell代码程序转换为shell代码字符串可能会有问题。我写了一篇Stackoverflow Answer讨论OBJDUMP方法的一些缺陷。如果要创建一个可执行文件来独立测试shell代码,那么最好将其汇编并链接到可执行文件;使用OBJCOPY将可执行文件转换为二进制文件,然后使用某种方法(如hextump)将二进制文件转换为shell代码字符串。以下命令应该有效:

nasm -f elf64 shellcode.asm -o shellcode.o 
ld shellcode.o -o shellcode
objcopy -O binary shellcode shellcode.bin

如果运行独立的二进制文件shellcode,它应该输出:

Hello

然后,可以使用以下命令将shellcode.bin转换为shell代码字符串:

hexdump -v -e '"\\""x" 1/1 "%02x" ""' shellcode.bin

输出如下所示:

\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\x8d\x35\x13\x00\x00\x00\xba\x06\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05\x48\x65\x6c\x6c\x6f\x0a

然后,您可以在上面的python程序中插入这个shell代码字符串(testshellcode.py),用上面的字符串替换shell code string here。您可以使用以下命令运行上面的脚本:

python testshellcode.py

输出应为:

Hello


这是更高级的,并且有一些shell代码教程解释了避免字符串中的\x00字节的许多技巧。在

通常,在shell代码中,您希望消除NUL(\x00)字节来进行真正的字符串攻击。执行此操作的shellcode.asm版本可能类似于:

section .text
    global _start

_start:
    jmp afterdata
    text db "Hello",10
text_len EQU $-text

afterdata:
    ;syscall sys_write(1, text, text_len)
    xor eax, eax
    inc eax
    mov edi, eax
    lea rsi, [rel text]
    xor edx, edx
    mov dl, text_len
    syscall

    ;syscall sys_exit(0)
    xor eax, eax
    mov al, 60
    xor edi, edi
    syscall

如果使用前面提到的命令创建shell代码字符串,HEXDUMP应该生成如下内容:

\xeb\x06\x48\x65\x6c\x6c\x6f\x0a\x31\xc0\xff\xc0\x89\xc7\x48\x8d\x35\xed\xff\xff\xff\x31\xd2\xb2\x06\x0f\x05\x31\xc0\xb0\x3c\x31\xff\x0f\x05

这个版本的操作与您的代码相同,但是请注意字符串中没有\x00字节。运行时,它也应打印:

Hello

相关问题 更多 >

    热门问题