Mini Line
7 minutes to read
We are given a file called firmware.hex
that looks like this:
:100154002F6C69622F6C642D6C696E75782E736FC9
:030164002E330037
:10016800040000001400000003000000474E550082
:10017800891BDEC57F0B4D5D5D0569FF4FE7A53423
:04018800F5185E41C7
:10018C00040000001000000001000000474E550064
:10019C00000000000300000002000000000000004E
:1001AC000100000001000000010000000000000040
:0801BC0000000000000000003B
:1001C400000000000000000000000000000000002B
:1001D40000000000780300000000000003000B0092
:1001E40000000000381001000000000003001600A9
:1001F40007000000000000000000000022000000D2
:100204003C0000000000000000000000200000008E
:1002140016000000000000000000000012000000B2
:100224005800000000000000000000002000000052
:100234006700000000000000000000002000000033
:100244000100000000000000000000001200000097
:100254000061626F7274005F5F6378615F66696EEC
:10026400616C697A65005F5F6C6962635F73746176
:1002740072745F6D61696E006C6962632E736F2EB8
:100284003600474C4942435F322E34005F49544D97
:100294005F64657265676973746572544D436C6F0E
:1002A4006E655461626C65005F5F676D6F6E5F734E
:1002B400746172745F5F005F49544D5F7265676972
:1002C40073746572544D436C6F6E655461626C65F2
:0102D4000029
:1002D6000000000000000200000002000000000014
:0202E600020014
:1002E80001000100280000001000000000000000CC
:1002F8001469690D000002003200000000000000CF
:10030800080F0100170000000C0F01001700000083
:100318001C100100170000002C100100170000003D
:1003280030100100170000003C1001001700000009
:10033800201001001503000024100100150400001E
:1003480028100100150600003410010015070000F0
:100358000C10010016030000101001001605000023
:1003680014100100160600001810010016080000FD
:0C03780008402DE9270000EB0880BDE8DC
:1003840004E02DE504E09FE50EE08FE008F0BEE513
:100394006C0C010000C68FE210CA8CE26CFCBCE558
:1003A40000C68FE210CA8CE264FCBCE500C68FE292
:1003B40010CA8CE25CFCBCE500C68FE210CA8CE279
:0403C40054FCBCE544
:1003C80000B0A0E300E0A0E304109DE40D20A0E14C
:1003D80004202DE504002DE528A09FE524308FE2B8
:1003E80003A08AE020C09FE50CC09AE704C02DE571
:1003F80018309FE503309AE714009FE500009AE75C
:10040800E5FFFFEBEAFFFFEBF00B01001C0000002B
:100418002C0000003000000014309FE514209FE5F8
:1004280003308FE0022093E7000052E31EFF2F0104
:10043800DCFFFFEAD00B0100280000002C009FE53C
:100448002C309FE500008FE003308FE0000053E17F
:1004580020309FE503308FE01EFF2F0118209FE515
:10046800023093E7000053E31EFF2F0113FF2FE133
:10047800EC0B0100E80B01009C0B010024000000BC
:1004880038009FE538109FE500008FE001108FE0ED
:10049800001041E0A13FA0E1411183E024309FE535
:1004A800C110B0E103308FE01EFF2F0118209FE537
:1004B800023093E7000053E31EFF2F0113FF2FE1E3
:1004C800A80B0100A40B01004C0B01003400000034
:1004D8004C309FE54C209FE503308FE00030D3E59A
:1004E80002208FE0000053E31EFF2F1138309FE5F4
:1004F80010402DE9033092E7000053E30200000AA0
:1005080028309FE503009FE7A0FFFFEBCAFFFFEB42
:100518001C309FE50120A0E303308FE00020C3E5F5
:100528001080BDE8580B0100100B010020000000EE
:10053800280B0100180B0100D0FFFFEA04B02DE5DD
:1005480000B08DE20CD04DE20030A0E105304BE563
:1005580050309FE5003093E5FF3CC3E305205BE5A1
:100568000224A0E10210A0E138209FE5013083E1D8
:10057800003082E530309FE50528A0E3002083E5C0
:1005880028309FE50228A0E3002083E51C309FE582
:100598000127A0E3002083E50000A0E100D08BE262
:1005A80004B09DE41EFF2FE1008002E0048002E019
:1005B8000C8002E000482DE904B08DE210D04DE235
:1005C80010000BE50030A0E305304BE5080000EA19
:1005D80005305BE510201BE5033082E00030D3E5F1
:1005E8000300A0E1D4FFFFEB05305BE5013083E2B7
:1005F80005304BE505305BE510201BE5033082E054
:100608000030D3E5000053E3F0FFFF1A0000A0E13B
:100618000000A0E104D04BE20088BDE804B02DE55D
:1006280000B08DE234309FE5003093E52C209FE543
:10063800153C83E3003082E524309FE52020A0E3C9
:10064800B020C3E11C309FE51020A0E30020C3E5E3
:100658000000A0E100D08BE204B09DE41EFF2FE172
:1006680000C002E0000002E00C0002E004B02DE54A
:1006780000B08DE214D04DE20030A0E10D304BE522
:1006880068309FE58020A0E3002083E560209FE597
:100698000D305BE50338A0E12338A0E1B030C2E1BA
:1006A8000000A0E14C309FE50030D3E5FF3003E2C5
:1006B800033CA0E1433CA0E1000053E3F8FFFFAA9C
:1006C8002C309FE5B030D3E10338A0E12338A0E116
:1006D80005304BE520309FE58020A0E3002083E52E
:1006E8000000A0E100D08BE204B09DE41EFF2FE1E2
:1006F8000C8002E0080002E0040002E0048002E04E
:1007080000482DE904B08DE230D04DE26C319FE510
:1007180003308FE020C04BE20F0093E80F008CE815
:100728005C319FE524300BE558319FE503308FE0BD
:1007380034C04BE20F0093E80700ACE80030CCE58A
:1007480044319FE503308FE00300A0E198FFFFEB01
:10075800B1FFFFEB34319FE503308FE00300A0E1E8
:1007680093FFFFEB0100A0E3BFFFFFEB20319FE504
:1007780003308FE00300A0E18DFFFFEB0030A0E322
:1007880008300BE50A0000EA20204BE208301BE5A0
:10079800033082E00030D3E51A3023E2FF3003E271
:1007A8000300A0E1B0FFFFEB08301BE5013083E256
:1007B80008300BE508301BE5100053E3F1FFFFDAC2
:1007C8000030A0E30C300BE50C0000EA24204BE2DB
:1007D8000C301BE5033082E00030D3E5A330A0E104
:1007E800FF3003E2393023E2FF3003E20300A0E1E7
:1007F8009DFFFFEB0C301BE5013083E20C300BE56D
:100808000C301BE5040053E3EFFFFFDA0030A0E3F0
:1008180010300BE50C0000EA34204BE210301BE5E9
:10082800033082E00030D3E5A330A0E1FF3003E2DB
:10083800393023E2FF3003E20300A0E18AFFFFEB37
:1008480010301BE5013083E210300BE510301BE55A
:100858000D0053E3EFFFFFDA38309FE503308FE0F8
:100868000300A0E152FFFFEB0000A0E37EFFFFEBD7
:100878000030A0E30300A0E104D04BE20088BDE80B
:10088800E00200001A9614CCD402000050020000C6
:10089800500200004802000078010000F0472DE9EE
:1008A8004C609FE54C509FE506608FE005508FE057
:1008B800056046E00070A0E10180A0E10290A0E19F
:1008C800AAFEFFEB4661B0E1F087BD080040A0E357
:1008D800043095E40920A0E10810A0E10700A0E198
:1008E800014084E233FF2FE1040056E1F7FFFF1ACD
:1008F800F087BDE8540601004C0601001EFF2FE1F9
:0809080008402DE90880BDE85C
:10091000010002003A0000003D0000000A00000053
:100920003D0000000F0000003D000000240000001A
:100930003D000000320000003D0000000200000009
:100940003D000000050000003D0000001300000015
:100950003D0000000D0000003D0000000C00000004
:100960003D000000230000003D00000011000000D9
:100970003D000000260000003D00000001000000D6
:100980003D000000170000003D00000008000000CE
:100990003D000000090000003D00000000000000D4
:1009A0000000000053504920496E697469616C6908
:1009B0007A6174696F6E00005374617274206269A9
:1009C00074207365740000005472616E736D6974F5
:1009D00074696E67206461746120746F20736C6148
:1009E0007665000044617461207472616E7366659F
:1009F0007220697320636F6D706C657465640000AC
:100A0000524E5861782E68294577296E2E766945B1
:100A1000BE98AECC1412BABE103030308800000040
:100A20003A0000003D0000000A0000003D00000008
:100A30000F0000003D000000240000003D00000009
:100A4000320000003D000000020000003D000000F8
:100A5000050000003D000000130000003D00000004
:100A60000D0000003D0000000C0000003D000000F3
:100A7000230000003D000000110000003D000000C8
:100A8000260000003D000000010000003D000000C5
:100A9000170000003D000000080000003D000000BD
:100AA000090000003D000000000000000000000000
:080AB00018F9FF7F01000000AE
:040AB800000000003A
:020000021000EC
:040F080040050000A0
:040F0C00D804000005
:100F100001000000280000000C0000007803000021
:100F20000D0000000809000019000000080F010072
:100F30001B000000040000001A0000000C0F01005C
:100F40001C00000004000000F5FEFF6FAC01000073
:100F5000050000005402000006000000C40100006B
:100F60000A000000810000000B00000010000000DB
:100F70001500000000000000030000000010010048
:100F8000020000002000000014000000110000001A
:100F900017000000580300001100000008030000C3
:100FA00012000000500000001300000008000000C4
:100FB000FBFFFF6F00000008FEFFFF6FE80200006C
:100FC000FFFFFF6F01000000F0FFFF6FD60200007F
:100FD000FAFFFF6F060000000000000000000000A4
:100FE0000000000000000000000000000000000001
:100FF00000000000000000000000000000000000F1
:10100000100F010000000000000000008403000039
:10101000840300008403000084030000040900002E
:10102000000000000000000000000000A408000014
:081030000807000000000000A9
:08103800000000003C10010063
:04000003000003C82E
:00000001FF
We only know that this is the firmware of an LPC2148 microcontroller that is sending data.
Intel Hex
If we research a bit on the name of the file and the extension, we will find out that the above format is Intel HEX which conveys binary information in ASCII text form.
Looking for tools to analyze this, we can find several tools like intelhex to transform .hex
to .bin
:
# wget -q https://raw.githubusercontent.com/pda/intelhex/master/intel_hex.rb
# ruby intel_hex.rb < firmware.hex > firmware.bin
# file firmware.bin
firmware.bin: data
# xxd firmware.bin
00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000150: 0000 0000 2f6c 6962 2f6c 642d 6c69 6e75 ..../lib/ld-linu
00000160: 782e 736f 2e33 0000 0400 0000 1400 0000 x.so.3..........
00000170: 0300 0000 474e 5500 891b dec5 7f0b 4d5d ....GNU.......M]
00000180: 5d05 69ff 4fe7 a534 f518 5e41 0400 0000 ].i.O..4..^A....
00000190: 1000 0000 0100 0000 474e 5500 0000 0000 ........GNU.....
000001a0: 0300 0000 0200 0000 0000 0000 0100 0000 ................
000001b0: 0100 0000 0100 0000 0000 0000 0000 0000 ................
000001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001d0: 0000 0000 0000 0000 7803 0000 0000 0000 ........x.......
000001e0: 0300 0b00 0000 0000 3810 0100 0000 0000 ........8.......
000001f0: 0300 1600 0700 0000 0000 0000 0000 0000 ................
00000200: 2200 0000 3c00 0000 0000 0000 0000 0000 "...<...........
00000210: 2000 0000 1600 0000 0000 0000 0000 0000 ...............
00000220: 1200 0000 5800 0000 0000 0000 0000 0000 ....X...........
00000230: 2000 0000 6700 0000 0000 0000 0000 0000 ...g...........
00000240: 2000 0000 0100 0000 0000 0000 0000 0000 ...............
00000250: 1200 0000 0061 626f 7274 005f 5f63 7861 .....abort.__cxa
00000260: 5f66 696e 616c 697a 6500 5f5f 6c69 6263 _finalize.__libc
00000270: 5f73 7461 7274 5f6d 6169 6e00 6c69 6263 _start_main.libc
00000280: 2e73 6f2e 3600 474c 4942 435f 322e 3400 .so.6.GLIBC_2.4.
00000290: 5f49 544d 5f64 6572 6567 6973 7465 7254 _ITM_deregisterT
000002a0: 4d43 6c6f 6e65 5461 626c 6500 5f5f 676d MCloneTable.__gm
000002b0: 6f6e 5f73 7461 7274 5f5f 005f 4954 4d5f on_start__._ITM_
000002c0: 7265 6769 7374 6572 544d 436c 6f6e 6554 registerTMCloneT
000002d0: 6162 6c65 0000 0000 0000 0000 0200 0000 able............
000002e0: 0200 0000 0000 0200 0100 0100 2800 0000 ............(...
000002f0: 1000 0000 0000 0000 1469 690d 0000 0200 .........ii.....
...
However, the file type is not recognized. But we can see some strings:
# strings firmware.bin
/lib/ld-linux.so.3
abort
__cxa_finalize
__libc_start_main
libc.so.6v
GLIBC_2.4
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
SPI Initialization
Start bit set
Transmitting data to slave
Data transfer is completed
RNXax.h)Ew)n.viE
There is a file path /lib/ld-linux.so.3
that tells this is an ELF binary from an ARM Linux OS. If we research a bit more, we will see that Intel HEX can also be decoded to an ELF binary (more information at stackoverflow.com). We will need to use objcopy
for that.
But we must install arm-linux-gnueabihf-objcopy
because we are dealing with an ARM binary (probably coming from a Raspberry Pi):
# arm-linux-gnueabihf-objcopy --input-target=ihex --output-target=elf32-little firmware.hex firmware.elf
# file firmware.elf
firmware.elf: ELF 32-bit LSB relocatable, no machine, version 1 (SYSV), stripped
Firmware analysis
Now we can load the firmware as a binary file in Ghidra. There are several functions, but the one that looks more interesting is this one:
undefined4 FUN_00010708() {
undefined4 local_38;
undefined4 uStack_34;
undefined4 uStack_30;
undefined local_2c;
undefined4 local_28;
undefined4 local_24;
undefined4 uStack_20;
undefined4 uStack_1c;
undefined4 uStack_18;
int local_14;
int local_10;
int local_c;
local_24 = *(undefined4 *) (DAT_00010888 + 0x10720);
uStack_20 = *(undefined4 *) (DAT_00010888 + 0x10724);
uStack_1c = *(undefined4 *) (DAT_00010888 + 0x10728);
uStack_18 = *(undefined4 *) (DAT_00010888 + 0x1072c);
local_28 = DAT_0001088c;
local_38 = *(undefined4 *) (DAT_00010890 + 0x1073c);
uStack_34 = *(undefined4 *) (DAT_00010890 + 0x10740);
uStack_30 = *(undefined4 *) (DAT_00010890 + 0x10744);
local_2c = (undefined) *(undefined4 *) (DAT_00010890 + 0x10748);
FUN_000105bc(DAT_00010894 + 0x10754);
FUN_00010624();
FUN_000105bc(DAT_00010898 + 0x10768);
FUN_00010674(1);
FUN_000105bc(DAT_0001089c + 0x10780);
for (local_c = 0; local_c < 0x11; local_c = local_c + 1) {
FUN_00010674(*(byte *) ((int) &local_24 + local_c) ^ 0x1a);
}
for (local_10 = 0; local_10 < 5; local_10 = local_10 + 1) {
FUN_00010674(*(byte *) ((int) &local_28 + local_10) >> 1 ^ 0x39);
}
for (local_14 = 0; local_14 < 0xe; local_14 = local_14 + 1) {
FUN_00010674(*(byte *) ((int) &local_38 + local_14) >> 1 ^ 0x39);
}
FUN_000105bc(DAT_000108a0 + 0x1086c);
FUN_00010674(0);
return 0;
}
Actually, we are interested in the for
loops. They seem to be decrypting some buffers with a XOR cipher. The buffers are pointed to by local_24
, local_28
and local_38
.
The buffer local_24
is at address DAT_00010888 + 0x10720
, which is 0x10a00
; local_28
is at DAT_0001088c
, which is 0x1088c
; and local_38
is at DAT_00010890 + 0x1073c
, which is 0x10a10
. We know this from these global variables:
DAT_00010888 XREF[1]: FUN_00010708:00010714(R)
00010888 e0 02 00 00 undefined4 000002E0h
DAT_0001088c XREF[1]: FUN_00010708:00010728(R)
0001088c 1a 96 14 cc undefined4 CC14961Ah
DAT_00010890 XREF[1]: FUN_00010708:00010730(R)
00010890 d4 02 00 00 undefined4 000002D4h
DAT_00010894 XREF[1]: FUN_00010708:00010748(R)
00010894 50 02 00 00 undefined4 00000250h
DAT_00010898 XREF[1]: FUN_00010708:0001075c(R)
00010898 50 02 00 00 undefined4 00000250h
DAT_0001089c XREF[1]: FUN_00010708:00010774(R)
0001089c 48 02 00 00 undefined4 00000248h
DAT_000108a0 XREF[1]: FUN_00010708:00010860(R)
000108a0 78 01 00 00 undefined4 00000178h
If we go to these addresses, we have:
DAT_00010a00 XREF[1]: FUN_00010708:00010720(R)
00010a00 52 4e 58 61 undefined4 61584E52h
DAT_00010a04 XREF[1]: FUN_00010708:00010720(R)
00010a04 78 2e 68 29 undefined4 29682E78h
DAT_00010a08 XREF[1]: FUN_00010708:00010720(R)
00010a08 45 77 29 6e undefined4 6E297745h
DAT_00010a0c XREF[1]: FUN_00010708:00010720(R)
00010a0c 2e 76 69 45 undefined4 4569762Eh
DAT_00010a10 XREF[1]: FUN_00010708:0001073c(R)
00010a10 be 98 ae cc undefined4 CCAE98BEh
DAT_00010a14 XREF[1]: FUN_00010708:0001073c(R)
00010a14 14 12 ba be undefined4 BEBA1214h
DAT_00010a18 XREF[1]: FUN_00010708:0001073c(R)
00010a18 10 30 30 30 undefined4 30303010h
DAT_00010a1c XREF[1]: FUN_00010708:0001073c(R)
00010a1c 88 00 00 00 undefined4 00000088h
These are 4-byte integers, but the for
loops consider each of their bytes independently. So, we can try to decrypt this XOR cipher as follows:
#!/usr/bin/env python3
from struct import pack
local_24 = [0x61584E52, 0x29682E78, 0x6E297745, 0x4569762E]
local_28 = [0xCC14961A]
local_38 = [0xCCAE98BE, 0xBEBA1214, 0x30303010, 0x00000088]
flag = bytearray()
for d in local_24:
for b in pack('<I', d):
if b:
flag.append(b ^ 0x1a)
for d in local_28:
for b in pack('<I', d):
if b:
flag.append(b >> 1 ^ 0x39)
for d in local_38:
for b in pack('<I', d):
if b:
flag.append(b >> 1 ^ 0x39)
print(flag.decode())
Flag
If we run the above Python script, we will get the flag:
$ python3 solve.py
HTB{b4r3_m3t4ls_4r3_fun_30df1!!!}