簡體   English   中英

shellcode:在x86_64程序集中將參數傳遞給execve

[英]shellcode: pass arguments to execve in x86_64 assembly

我正在嘗試編寫一個運行execve的shellcode。 等效的c程序如下所示:

int main ()
{

  char *argv[3] = {"/bin/sh","-i", "/dev/tty", NULL};
  execve("/bin/sh", argv, NULL);

  return 0;
}

c程序運行正常。 然后我嘗試編寫我的測試程序(修改為推送null):

#include<stdio.h>
int main(){
    __asm__(
            "xor    %rdx,%rdx\n\t"   //rdx is the third argument for execve, null in this case.
            "push   %rdx\n\t"
            "mov    -8(%rbp),%rdx\n\t"
            "mov    $0x692d,%rdi\n\t" //$0x6924 is 'i-'
            "push   %rdi\n\t"         //push '-i' to the stack
            "lea    -16(%rbp),%rax\n\t"    //now rax points to '-i'
            "mov    $0x31b7f54a83,%rdi\n\t" //the address of /bin/sh
            "push   %rdi\n\t"                //push it to the stack              
            "push   %rdx\n\t"                //end the array with null
            "mov    $0x31b7e43bb3,%rdi\n\t"  //the address of "/bin/sh"
            "push   %rdi\n\t"              //push the address of "/dev/tty to the stack
            "push   %rax\n\t"              //push the address of '-i' to the stack
            "mov    $0x31b7f54a83,%rdi\n\t"
            "push   %rdi\n\t"              //push the address of /bin/sh again to the stack
            "mov    %rsp,%rsi\n\t"         //rsi now points to the beginning of the array
            "mov    -24(%rbp),%rdi\n\t"   //rdi now points to the addresss of "/bin/sh"
            "mov    $0x3b,%rax\n\t"               // syscall number = 59
            "syscall\n\t"
    );
    }

我在這里有內存中字符串的地址,我們可以假設它們不會改變。 但是我們沒有字符串'-i'的地址。 所以我在這里做的是將參數推送到堆棧中,如下所示:


Low                  ------------------------------------------------------------------             High

|addressof"/bin/sh"(rsi points to here)|addressof"-i"|addressof"/dev/ssh"|addressof"/bin/sh"(rdi points to here)|-i|

它沒用。 程序編譯正常但是當我運行該程序時,沒有任何反應。

我不熟悉匯編,我對參數的傳遞方式有一些擔憂,例如,編譯器如何知道argv參數何時在內存中結束?

編輯

感謝Niklas B的以下建議,我使用了trace來查看execve是否實際運行。 我得到execve(0x31b7f54a83, [0x31b7f54a83, "-i", 0x31b7e43bb3, 0x31b7f54a83, 0x692d], [/* 0 vars */]) = -1 EFAULT (Bad address) ,這意味着第二個參數傳遞錯誤。 我推入堆棧的所有東西都被認為是argv參數的一部分!

在我將空值推入堆棧后,strace給出execve(0x31b7f54a83, [0x31b7f54a83, "-i", 0x31b7e43bb3], [/* 0 vars */]) = -1 EFAULT (Bad address) 只有當地址是字符串時,這非常接近正確答案...

感謝Brian,我現在看到問題出在哪里。 硬編碼地址位於另一個程序的共享庫中。 因此,該程序在實際輸入該程序之前不應運行。 謝謝大家,我會盡快更新。 如果問題解決了,我會將其標記為已解決。

正如Kerrek SB和user9000在注釋中指出的那樣, argv數組需要是一個以null結尾的字符串數組。

一旦修復,獨立運行該程序仍然無法工作,因為字符串"/bin/sh""/dev/tty"可能不存在於您剛編譯的程序中的那個位置,而是存在於shell代碼旨在定位的程序中的該位置。 你需要實際將它注入到該程序中,以便它在那里執行,其中那些字符串在那些地址。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM