TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

admin 2022年4月18日23:09:26IoT工控物联网评论22 views5041字阅读16分48秒阅读模式


作者简介 /Profile/

朱文哲,平安科技银河实验室高级安全研究员,Blackhat Asia 2019 演讲者,专注于工业物联网设备及软件的漏洞挖掘。曾发现多款知名品牌工业物联网设备及软件的安全漏洞。



  • 本系列文章主要以下三个部分进行讲解:

  • · 编写调试功能的前置条件

  • · 串口调试功能设计

  • · 设计调试shellcode


0x01 前言


在上一章文章(TP-Link-WDR-7660 安全研究之固件分析)中, 我们已经通过分析固件得到了完整功能的cmd命令行。但VxWorks系统和传统的Linux系统还是有很大的差异的,在没有编入调试功能的情况下是无法对设备进行调试的。


在19年的时候我有针对另一款MIPS架构的VxWorks路由器编写过串口调试功能(详见附录),但是考虑到几年过去了TP-Link的命令行功能已经有所变化,此外当时的项目是基于python2进行编写且尚未支持ARM架构,因此就有了这篇文章。


0x02 编写调试功能的前置条件


编写调试功能首先有几个前置条件:

1. 能够直接对VxWorks的内核态内存进行直接读写(我们的目标基于VxWorks 5操作系统,而VxWorks 5系列只有内核态)。

2. 能够获取到task的寄存器值,这个步骤主要用于判断哪个task触发了断点,进入了debug loop(VxWorks的task有点像其他系统中的线程,在VxWorks 5中他们之间共享内存)。

当满足上述两个条件后,我们就可以基于这两项基础的功能进行扩展从而实现调试的设备。第一个必要条件没什么好多说的,完整功能的cmd命令行自带内存修改功能且简单好用。


TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器


第二个必要条件略微复杂一些,TP-Link的task命令输出与之前有一些变化。下图是以前的task命令输出,可以很直观的看到各个task的PC寄存器等信息。


TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器


下图是现在的task显示命令,目前已无法直接显示所有task的PC寄存器。


TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器


现在则需要使用task -c命令来获取单个task的寄存器等关键信息。


TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

这样看来虽然比之前要复杂一些,但是第二个必要条件也是可以通过分析单个task的输出来进行获取,这部分的具体实现大多是一些文本处理等工作就不进行展开了。


0x03 串口调试功能设计


串口调试功能设计与之前相同,主要就是以下几部分:


利用命令行的内存读写功能,将调试用的shellcode写入到设备内存中。

利用类似Inline Hook的技术在需要调试的代码处进行插桩,跳转执行Hook代码(调试shellcode),调试shellcode会无限循环,等待下一步的调试指令执行。

此时就可以通过命令行的指令对查看调试task的寄存器及内存等信息。

完成调试指令后,还原插桩处的代码,更新CPU缓存,跳转恢复执行。

下面是一些调试功能的示意图:

TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器



0x04 设计调试shellcode


用于调试的shellcode主要分为初始化debug栈、debug loop、Recover三个部分。初始化debug栈,主要用于申请及初始化debug调试shellcode会使用到的栈内存。debug_stack的设计如下所示:
dbg_statck:    dbg_stack_address = SP - 0x200    dbg_stack_address + 0xa4 ~ 0x200 = reserve    dbg_stack_address + 0x20 ~ 0xa0 = regs store address    dbg_stack_address + 0x1C ~ 0x1C = reserve    dbg_stack_address + 0x18 = Debug loop count    dbg_stack_address + 0x14 = Cache updated count, use to sync update status.    dbg_stack_address + 0x10 = Cache update size(Default is bp_overwrite_size)    dbg_stack_address + 0x0c = Address Need Update Cache(Default is Break PointAddress)    dbg_stack_address + 0x08 = Break Point Address + bp_overwrite_size    dbg_stack_address + 0x04 = Original $RA Value    dbg_stack_address + 0x00 = Debug Flags(0: Keep loop, 1: Recover, 2: Needupdate cache)

断点处的插桩代码如下:
def create_bp_asm(self, bp_address):    """Create breakpoint asm code    :param bp_address: break point address    :return: Breakpoint shellcode    """    # increase stack size    asm_code = '''    mov r12, sp    sub sp, sp, #0x{:x}    // save original lr value    str lr, [sp, #0x04]    // jump to dbg loop    bl 0x{:08x}    '''.format(self.dbg_stack_size, self.debugger_base_address)    self.logger.debug("asm_code: %s" % asm_code)    asm_data = self.assemble(str(asm_code), bp_address)    if not asm_data:        return None    return asm_data

初始化代码全部由汇编编写,具体代码如下:
###########################     Init DBG Stack     ###########################init_dbg_stack_asm_code = '''init_dbg_stack:// first save r0 to sp + 0x20, we need use r0 in debug loopstr r0, [sp, #0x{:x}]// set flag to zeromov r0, 0str r0, [sp]// clean up debug loop countstr r0, [sp, #0x18]// save current return address to stackstr lr, [sp, #0x08]// set lr to break point address and do not touch lr later.sub lr, lr, #0x{:x}// save regs to reg_store_offset + 0x04, skip r0add r0, sp, {}stmea r0!, {{R1-R11, r12, lr, pc}}// init cache update stack value to default bp address// Save cache update addressstr lr, [sp, #0x0c]mov r0, 0x{:x}// Save cache update sizestr r0, [sp, #0x10]// Init Cache updated countmov r0, 0str r0, [sp, # 0x14]'''.format(reg_store_offset, self.bp_overwrite_size, reg_store_offset + 0x04,self.bp_overwrite_size)

Debug loop,主要功能就是无限循环并根据debug flag的参数,执行断点恢复或是更新CPU缓存的功 能,具体代码如下:
###########################        DBG Loop        ###########################dbg_loop_asm_code = '''start_dbg_loop:// Update debug loop countldr r0, [sp, #0x18]add r0, 1str r0, [sp, #0x18]// Add delay 60mov r0, 60// call task_delaybl 0x{:x}// call cacheTextUpdate if flag == 0x02ldr r0, [sp]cmp r0, 2bne part_4debug_loop:// update cacheTextUpdate execute countldr r0, [sp, #0x14]add r0, 1str r0, [sp, #0x14]update_cache:// update cacheldr r0, [sp, #0x0c]// Force v7_flush_kern_cache_allmov r1, -1bl 0x{:x}// set flag to 0x00mov r0, 0str r0, [sp]// if flag != 0x01 keep looppart_4:// update dbg stack cache in each loop// mov r0, sp// mov r1, 0x{:x}// bl 0x{:x}ldr r0, [sp]cmp r0, 1bne start_dbg_loop'''.format(task_delay_addr, self.cache_update_address, self.dbg_stack_size,self.cache_update_address)

Recover,主要功能为恢复原始寄存器后跳转回断点处继续执行,具体代码如下:
###########################         Recover        ############################ load_reg_offset = reg_store_offset + (4 * 12)  # For testload_reg_offset = reg_store_offset + (4 * 14)recover_asm = '''// update dbg stack cache before recovermov r0, spmov r1, 0x{:x}bl 0x{:x}// Recover Original lrldr lr, [sp, #0x04]// recover other regsmov r0, 0add r0, sp, {}ldmea r0, {{R0-R11, sp, pc}}'''.format(self.dbg_stack_size, self.cache_update_address, load_reg_offset)asm_code += recover_asm

此处的shellcode设计与以往略有调整,主要是在这台arm架构的路由器中如果不在debug loop代码中添加task delay将会导致设备卡死,目前初步怀疑是arm的cpu可能有某些死循环的检测机制导致。

与此相对应的是否命中breakpoint机制也需要从原来的判断PC寄存器的地址改为判断traceback信息中是否包含了debug shellcode所在的地址。


0x05 效果展示


完成上述核心工作后只需要进行一些简单的辅助代码编写就可以对这台WDR-7660设备进行调试了。下图为命中断点后的效果图,可以查看断点下各个寄存器的值等各类基础信息。

TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

现在我们已经拥有了一个简易的调试工具,后面就可以利用调试工具来对设备进行动态调试了。

引用 :

bh-asia-Zhu-Dive-into-VxWorks-Based-IoT-Device-Debug-the-Undebugable-Device:

https://i.blackhat.com/asia-19/Fri-March-29/bh-asia-Zhu-Dive-into-VxWorks-Based-IoT-Device-Debug-the-Undebugable-Device.pdf


银河实验室

TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

银河实验室(GalaxyLab)是平安集团信息安全部下一个相对独立的安全实验室,主要从事安全技术研究和安全测试工作。团队内现在覆盖逆向、物联网、Web、Android、iOS、云平台区块链安全等多个安全方向。
官网:http://galaxylab.pingan.com.cn/



往期回顾


技术

TP-Link-WDR-7660 安全研究之固件分析

技术

利用DNS 反向解析执行shellcode

技术

利用图片隐写执行shellcode

技术

【干货】cobaltstrike通信协议研究


TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器
TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器
TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

长按识别二维码关注我们

微信号:PSRC_Team



TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

球分享

TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

球点赞

TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

球在看

原文始发于微信公众号(平安集团安全应急响应中心):TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月18日23:09:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  TP-Link-WDR-7660 安全研究之构造基于串口CMD的调试器 https://cn-sec.com/archives/924405.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: