Skip to main content

Firmware validation

Firmware validation

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 into libupg_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 from tftp (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