【问题标题】:Shellcode with restrictions有限制的Shellcode
【发布时间】:2016-03-10 16:00:37
【问题描述】:

对于一个任务,我需要创建简单的 shellcode,但不允许它包含 \x80。

注意:要在 linux 上进行系统调用,例如 write 或 exit,您需要以下行:int 0x80,最终将生成包含 \x80 的 shellcode。

尽管如此,我需要进行系统调用,所以我现在的想法是使用一个变量作为中断向量号。比如0x40,然后乘以2,所以最后shellcode中会有\x40而不是\x80。

问题是 int 没有将变量作为参数,我试过这个进行测试:

section .data

nr db 0x80

section .text

global _start

_start:

xor eax, eax
inc eax

xor ebx, ebx
mov ebx, 0x1

int [nr]

然后得到

错误:操作码和操作数的组合无效

我怎样才能让我的想法发挥作用?或者您对这个问题有不同的解决方案?

PS。 sysenter 和 syscall 不工作 -> 非法指令

我在 x86-32 位机器上使用 nasm。

【问题讨论】:

  • 是否允许自修改代码?
  • int 不占用内存操作数。只是即时值。见x86.renejeschke.de/html/file_module_x86_id_142.html
  • 只是好奇,但在正常情况下,值为 0x00 的 shell 代码会产生问题。好奇是什么设计考虑使 0x80 成为问题?
  • 作为 Ross Ridge 提到的内容的扩展,您可以在 32 位 Linux 上通过 call near [gs:10H] 进行操作。这是通过 gs:0x10 地址的间接跳转,该地址通常是 VDSO 系统调用蹦床地址。
  • 是否有可能将整条指令(如 int 0x80)压入堆栈并执行堆栈中的指令?不就是这样做的吗? int 0x80 究竟是如何执行的?会被压入栈吗?

标签: linux assembly nasm system-calls shellcode


【解决方案1】:

也许是这样,但千万不要在严肃的代码中使用它!

format ELF executable
use32
entry start

segment executable  writeable
  start:
  ;<some code>
  inc byte [ here + 1 ] ;<or some other math>
  jmp here
  here:
  int 0x7f
segment readable  writeable

(这是fasm代码)

【讨论】:

  • 感谢您的回答,但我不明白这将如何调用 int 0x80?
  • 1.一些代码计算值 0x80 并将其写入 al, 2. a mov 在int 之后写入此值,因为它是一个 2 字节操作码:0xCD 0x80, 3. 最后执行它。
  • 啊,我明白了,谢谢!我用 nasm 试过你的代码,我得到Program received signal SIGSEGV, Segmentation fault. 在这条线上mov byte [ here + 1 ], al。但为什么?解决方案是什么?
  • @Krupuk 您的.text 部分可能不可写。您还需要在代码修改和修改后的代码之间添加jmp instruction (eg. jmp here`)。这让 CPU 知道代码已被修改,并且它应该丢弃它的任何缓存副本。
  • @PeterCordes 英特尔保证自修改代码无论距离多远,如果中间有跳转或序列化指令,都可以正常工作。请参阅 Intel 64 和 IA-32 架构软件开发人员手册,第 3 卷,8.1.3 处理自我和交叉修改代码
猜你喜欢
  • 1970-01-01
  • 2014-10-21
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多