Firmware validation (WIP)
The logic to validate the firmware bundle begins at: libupg_validate_firmware_mem
.
This is called from libupg_upgrade_mem
that is subsequently called from the command upgrade
in the psbl
terminal.
This can be seen from the upgrade
command handler:
int upgrade(int argc,char **argv)
{
int iVar1;
undefined4 *param2;
if ((argc == 2 || argc == 4) && ((argc != 4 || (iVar1 = strcmp(argv[1],"-i"), iVar1 == 0)))) {
*argv = "upgrade";
argv[argc] = "/dev/ram";
param2 = (undefined4 *)tftp(argc + 1,argv); // [1]
if (0 < (int)param2) {
iVar1 = libupg_upgrade_mem((astruct *)0xb4500000,param2); // [2]
return iVar1;
}
}
else {
upgrade_usage();
}
return -1;
}
A couple of things to note from this snippet:
- [1] Shows the data is being obtained through
tftp
(wtf) - We can see the address [2]
0xb4500000
being passed intolibupg_upgrade_mem
. This will be the location that the firmware is either downloaded to or where we will begin flashing.
libupg_validate_firmware_mem
The function starts by taking two arguments:
int libupg_validate_firmware_mem(byte *param1,uint param2)
[...]
-
param1
is the pointer into RAM discussed above (0xb4500000
) -
param2
is the result fromtftp
(Looks like it is being used as a data length)
The function begins by validating the firmware's header.
Header validation
The header validation can be found in function validate_firmware_header
.
The function starts by taking a structure (we're going to call it firmware_header_struct
). Maybe this is a buffer stream?
The function contains two stages:
- Digest validation
- Randseq validation
If we search for "Randseq" as it seems custom to Cisco we come across a handy Github repo (https://github.com/BigNerd95/paytonImageEditor). Tool is cool but the interesting section is the "Firmware header" section:
Firmware Header
Size (byte) | Type | Name | Description |
---|---|---|---|
16 | Byte array | Magic | Eg: SkOsMo5 fIrMwArE |
32 | Byte array | Signature | Not used |
16 | Byte array | Digest | MD5 of Firmware Header + Modules Headers |
16 | Byte array | Randseq | Not so random |
4 | Unsigned BE Int | Firmware Header Size | Eg: 136 |
4 | Unsigned BE Int | Module Header Size | Eg: 128 |
4 | Unsigned BE Int | Firmware size | Entire firmware image size |
32 | Byte array | Version | Eg: 1.4.1 |
4 | Unsigned BE Int | Modules number | Number of modules present in this firmware image |
Comparing to our firmware header:
We can extract from this the Digest and Randseq
- Digest:
05B910ECA58C1B6275E78185F3FAC6FC
- Randseq:
68974CEF8CE0F0318587EC50083155C0
Alongside:
- Firmware header size:
0x80
- Module (?) header size:
0x40
- Entire firmware size:
0x43162c
(4.19 MB)
- Version:
7.6.2g
- Number of modules:
0x4F