在作为单独代码单独运行以及与C ++代码一起运行时,shellcode调用不同的syscall [英] shellcode calls different syscall while runing alone as individiual code and while running with C++ code

查看:356
本文介绍了在作为单独代码单独运行以及与C ++代码一起运行时,shellcode调用不同的syscall的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个运行在shell中的代码:

I've such a code that run's shell:

BITS 64

global _start
_start:

  mov rax, 59

  jmp short file
  c1:
  pop rdi

  jmp short argv
  c2:
  pop rsi

  mov rdx, 0

  syscall

file:

  call c1
  db '/bin/sh',0

argv:

  call c2
  dq arg, 0

arg:

  db 'sh',0

以这种方式构建时可以使用:

It works when it's built in this way:

nasm -f elf64 shcode.asm
ld shcode.o -o shcode

Althougt,当我使用以下命令将其转换为二进制形式时:

Althougt, when I bring it into binary form with:

nasm -f bin shcode.asm

将其粘贴到以下C ++代码中:

paste it into following C++ code:

int main(void)
{

  char kod[]="\xB8\x3B\x00\x00\x00\xEB\x0B\x5F\xEB\x15\x5E\xBA\x00\x00\x00\x00\x0F\x05\xE8\xF0\xFF\xFF\xFF\x2F\x62\x69\x6E\x2F\x73\x68\x00\xE8\xE6\xFF\xFF\xFF\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x68\x00";
  reinterpret_cast<void(*)()>(kod)();

  return 0;

}

使用clang ++ texp.cpp -o texp.e -Wl,-z,execstack和execute使其执行,外壳未运行.

make it with clang++ texp.cpp -o texp.e -Wl,-z,execstack and execute, shell isn't running.

运行后

strace ./texp.e

我看到这样的内容(我用^ C停止了此过程):

I see something like this (I stopped this process with ^C):

syscall_0xffffffffffffffda(0x7ffc23e0a297, 0x7ffc23e0a2a4, 0, 0x4a0, 0x7fe1ff3039b0, 0x7fe1ff69b960) = -1 ENOSYS (Nie zaimplementowana funkcja)
syscall_0xffffffffffffffda(0x7ffc23e0a297, 0x7ffc23e0a2a4, 0, 0x4a0, 0x7fe1ff3039b0, 0x7fe1ff69b960) = -1 ENOSYS (Nie zaimplementowana funkcja)
.
.
.
syscall_0xffffffffffffffda(0x7ffc23e0a297, 0x7ffc23e0a2a4, 0, 0x4a0, 0x7fe1ff3039b0, 0x7fe1ff69b960) = -1 ENOSYS (Nie zaimplementowana funkcja)
^Csyscall_0xffffffffffffffda(0x7ffc23e0a297, 0x7ffc23e0a2a4, 0, 0x4a0,  0x7fe1ff3039b0, 0x7fe1ff69b960strace: Process 2806 detached
 <detached ...>

Nie zaimplementowana funkcja-未实现功能

Nie zaimplementowana funkcja - Function not implemented

因此程序(又名shellcode)可能正确运行了不正确的系统调用.

So the program ( aka shellcode ) is propably running improper syscall.

推荐答案

在您的C ++ shellcode调用程序中,strace显示您的execve系统调用是

In your C++ shellcode caller, strace shows your execve system call was

execve("/bin/sh", [0x34], NULL)         = -1 EFAULT (Bad address)

后面的syscall_0xffffffffffffffda(...) = -1 ENOSYS来自RAX = -EFAULT而不是59的无限循环,然后来自RAX=- ENOSYS(同样无效的呼叫号码).此循环由您的call/pop创建.

The later syscall_0xffffffffffffffda(...) = -1 ENOSYS are from an infinite loop with RAX = -EFAULT instead of 59, and then from RAX=- ENOSYS (again not a valid call number). This loop is created by your call/pop.

大概是因为您从未链接的.o或PIE可执行文件中转储了arg的绝对地址,这就是0x34作为绝对地址的方式.

Presumably because you hexdumped an absolute address for arg from an unlinked .o or from a PIE executable, which is how you got 0x34 as the absolute address.

很显然,如果要从随机堆栈地址运行且没有重定位修复程序的话,将绝对地址嵌入到您的shellcode中的整个方法将不起作用. dq arg, 0与位置无关.

Obviously the whole approach of embedding an absolute address in your shellcode doesn't work if it's going to run from a randomized stack address, with no relocation fixup. dq arg, 0 is not position-independent.

您至少需要使用指针自己构造一个argv数组(通常使用push).您也可以使用push imm32来构造arg本身.例如push 'shsh'/lea rax, [rsp+2].

You need to construct at least the argv array yourself (usually with push) using pointers. You could also use a push imm32 to construct arg itself. e.g. push 'shsh' / lea rax, [rsp+2].

或者最常见的技巧是利用特定于Linux的功能":您可以通过xor esi,esi传递argv=NULL(而不是指向NULL指针的指针).

Or the most common trick is to take advantage of a Linux-specific "feature": you can pass argv=NULL (instead of a pointer to a NULL pointer) with xor esi,esi.

(使用mov reg,0完全违反了jmp/call/pop技巧避免零字节的目的.如果允许零字节,您也可以只使用常规的RIP相对LEA.但是如果不允许,则可以跳转转发数据,然后使用具有负位移的RIP相对LEA.)

(Using mov reg,0 completely defeats the purpose of the jmp/call/pop trick for avoiding zero bytes. You might as well just use a normal RIP-relative LEA if zero bytes are allowed. But if not, you can jump forward over data then use RIP-relative LEA with a negative displacement.)

这篇关于在作为单独代码单独运行以及与C ++代码一起运行时,shellcode调用不同的syscall的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆