PAGalaxyLab / vxhunter

ToolSet for VxWorks Based Embedded Device Analyses

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for Cisco firmwares

rmspeers opened this issue · comments

I believe the files such as sx300_fw-14106.ros downloadable from Cisco (https://software.cisco.com/download/home/284576363/type/282463181/release/1.4.11.02) should be vxWorks but am not seeing any strings indicating that when opening, and vxhunter isn't having luck. Do you have any ideas, or have other ideas of where to obtain samples to test with?

Hi @rmspeers You can using binwalk to extract the firmware.
image

In the _sx300_fw-14112.ros.extracted folder, you can find a file named '3FC'.
This file looks like the VxWorks image.
image

Load file 3FC to Ghidra(or IDA/Radare) as arm binary with load address 0x0, find the first brunch code at 0x00000054, this should jump to usrInit function(in most case).
image

Function usrInit(offset:0x00012128) will call another function to zero out the bss segment. You can decompile and find the function below.
image

You can find bss start and end address using function parameter.
image

Now we have bss start address, you can using "bss_start_address" - firmware size to get the firmware image loading address. it's 0x013CC2E0 - 19710688 = 0x100000
image

Rebase the 3FC to 0x100000 and you can start with your research.

I haven't find the symbols and symbol file in this image, VxHunter can't automatic analyze image without VxWorks symbols. If you want test the VxHunter you can find example firmware at here

This script should extract the firmware files.

# !/usr/bin/env python3
# coding=utf-8
import struct

output_path = "./output"
source_file_data = open("sx300_fw-14112.ros", 'rb').read()

file_count = struct.unpack("<I", source_file_data[0x20:0x24])[0]
print("Found {} files in firmware".format(file_count))
print("Star extract files")
for i in range(file_count):
    file_name = source_file_data[0x50 + (i * 0x20):0x60 + (i * 0x20)]
    file_name = file_name.replace(b'\x00', b'')
    print("file_name: {}".format(file_name))
    file_offset = struct.unpack("<I", source_file_data[0x60 + (i * 0x20):0x60 + 4 + (i * 0x20)])[0]
    file_length = struct.unpack("<I", source_file_data[0x60 + 4 + (i * 0x20):0x60 + 8 + (i * 0x20)])[0]
    print("file_offset: {:#010x}".format(file_offset))
    print("file_length: {}".format(file_length))
    output_file = open("{}/{:#08x}_{}".format(output_path, file_offset, file_name.decode('utf-8'), ), 'wb')
    output_file.write(source_file_data[file_offset: file_offset + file_length])
➜  output ls -l
total 14768
-rw-r--r--  1 zhuwz  staff      107 Oct 29 14:18 0x0002d0_VER_COMP
-rw-r--r--  1 zhuwz  staff      161 Oct 29 14:18 0x00033b_DATETIME_C
-rw-r--r--  1 zhuwz  staff  4724312 Oct 29 14:18 0x0003dc_RSCODE
-rw-r--r--  1 zhuwz  staff        1 Oct 29 14:18 0x481a34_DYNAMIC
-rw-r--r--  1 zhuwz  staff   178862 Oct 29 14:18 0x481a35_CLI_FILE
-rw-r--r--  1 zhuwz  staff   771597 Oct 29 14:18 0x4ad4e3_DELSCRF
-rw-r--r--  1 zhuwz  staff  1790088 Oct 29 14:18 0x569af0_EWS_FILE
-rw-r--r--  1 zhuwz  staff    18886 Oct 29 14:18 0x71eb78_UPNP_FILE
-rw-r--r--  1 zhuwz  staff     6391 Oct 29 14:18 0x72353e_HPRM
-rw-r--r--  1 zhuwz  staff      244 Oct 29 14:18 0x724e35_SG300_SKU
-rw-r--r--  1 zhuwz  staff      245 Oct 29 14:18 0x724f29_SF300_SKU
-rw-r--r--  1 zhuwz  staff      110 Oct 29 14:18 0x72501e_EEE
-rw-r--r--  1 zhuwz  staff      160 Oct 29 14:18 0x72508c_Sx300_AC2_SKU
-rw-r--r--  1 zhuwz  staff       61 Oct 29 14:18 0x72512c_Sx300_POE+_SKU
-rw-r--r--  1 zhuwz  staff       45 Oct 29 14:18 0x725169_NONPOE_SKU
-rw-r--r--  1 zhuwz  staff       51 Oct 29 14:18 0x725196_ENV_MON_SKU
-rw-r--r--  1 zhuwz  staff      188 Oct 29 14:18 0x7251c9_ENV_MON_POE_SKU
-rw-r--r--  1 zhuwz  staff       97 Oct 29 14:18 0x725285_FAN_DIRCT_SKU
-rw-r--r--  1 zhuwz  staff      970 Oct 29 14:18 0x7252e6_MACRO_FILE
-rw-r--r--  1 zhuwz  staff       62 Oct 29 14:18 0x7256b0_PoE_pure