IOT初尝试(PLC NOE-771)

PLC NOE-771

尝试IOT的,挑个简单的来过一遍流程,大概明白了一个固件分析的流程,感觉如果挖掘CVE的话还是FUZZ可能更加合适,直接固件分析可能带来的工作量较大!
在这里插入图片描述
过binwalk -A指令来对固件的CPU架构进行分析,此外也可以用binwalk -Y指令来调用capstone反汇编引擎来进行辅助判断,不过我实际测试下来存在一些误报的情况会把NOE 711的固件识别成arm架构的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
r1寄存器是栈指针,而r3寄存器则是第一个参数

此时指令:
lis r1,1
addi r1,r1,0 // r1置一并左移赋零,即设置r1为0x10000
lis r3,0
addi r3,r3,0
addi r1,r1,-0x10 //栈上开辟0x10空间
b loc_1E84C //跳转

根据VxWorks官网文档对对内存布局的描述,Initial Stack是usrInit函数的初始化栈,故此时跳转为usrInit函数。此时栈地址同时为固件加载地址!
在这里插入图片描述
在这里插入图片描述
此时我们需要查看符号表是否包含符号表,如果包含即需要手动加载!
在这里插入图片描述
在这里插入图片描述
基于符号表特征也可得出符号表结尾地址!

# coding=utf-8
from idaapi import *
import time

symbol_interval = 16# 符号表间隔
load_address = 0x10000# 固件内存加载地址
symbos_table_start = 0x32d514 + load_address#符号表在内存中的起始地址
symbol_table_end = 0x356e70 + load_address# 符号表在内存中结尾地址
symbol_item_counts = 0x2996# 符号表项数
# 在IDA 中rebase 程序到加载地址
# 修改基地址
rebase_program(load_address, 0x0008)
#autoWait()#调用IDA的自动分析功能

i = symbos_table_start
while i < symbol_table_end:
    offset = 4 # 每4个字节为一组数据
    #MakeStr(Dword(i + offset),BADADDR)# 将函数名指针位置的数据转化为字符串
    sName = GetString(Dword(i + offset), -1, ASCSTR_C)# 将函数名赋值给变量sName
    print(sName)
    if sName:
        # 开始修复函数名
        eaFunc = Dword(i + offset + 4)
        MakeName(eaFunc, sName)
        MakeCode(eaFunc)
        MakeFunction(eaFunc,BADADDR)
    i += symbol_interval

在这里插入图片描述
但此时IDA7.0发生TypeError: in method ‘create_strlit’, argument 2 of type 'size_t’错误!此为脚本二次传参错误bug(MakeStr 在7.0版本中使用会报错)
解决方法

IDA 7.0\python\idc_bc695.py
中,113行的
def MakeStr(ea, endea): return create_strlit(ea, 0 if (endea) == ida_idaapi.BADADDR else endea-ea)
屏蔽掉,然后修正添加如下即可
def MakeStr(ea, endea): return create_strlit(ea, endea)
最后reload下idc模块即可

经过一次又一次的尝试,因为ida版本不一,故idapython的函数具体实现不一样,故引发错误,导致无法正确恢复符号表
如下为正确脚本,(总算好了

#coding=utf-8
from idaapi import *
from idc import *

symbol_interval = 16 #符号表间隔
load_address = 0x10000 #固件内存加载基址
symbol_table_start = 0x301e64 + load_address   #符号表起始地址
symbol_table_end = 0x3293a4 + load_address #符号表结束地址
ea = symbol_table_start
eaEnd = symbol_table_end

while ea < eaEnd:
   offset = 0   #4个字节为一组数据
   #将函数名指针位置的数据转换为字符串
   create_strlit(get_wide_dword(ea-offset), BADADDR)
   #将函数名赋值给变量sName
   sName = get_strlit_contents(get_wide_dword(ea))
   print(sName)
   if sName:
       #将bytes转为str
       sName = str(sName,encoding="utf-8")
       #开始修复函数名
       eaFunc = get_wide_dword(ea - offset +4)
       set_name(eaFunc, sName)
       create_insn(eaFunc)
       ida_funcs.add_func(eaFunc, BADADDR)
   ea += symbol_interval

在这里插入图片描述
通过调用关系_sysInit -> usrInit -> usrKernelInit -> usrRoot -> usrAppInit

在这里插入图片描述

参考链接
固件恢复idapython脚本
idapython

posted @ 2022-03-22 19:59  望权栈  阅读(44)  评论(0编辑  收藏  举报  来源