STM32在CTF中的应用和快速解题

题目给的是bin文件,基本上就是需要我们手动修复的固件逆向。

如果给的是hex文件,我们可能需要使用MKD进行动态调试

主要还是以做题为目的

详细的可以去看文档:https://pdf1.alldatasheet.com/datasheet-pdf/view/201596/STMICROELECTRONICS/STM32F103C8T6.html

SVD文件下载:https://github.com/posborne/cmsis-svd

image

本文参考了网上多篇文章,最终汇总在一篇,对这道新的STM32题进行解题。

IDA分析设置

1、基础设置

STM32主要信息:

  • 内核:ARM32位Cortex-M3 CPU
  • ARM Little-endian
  • Cortex-M架构属于ARMv7-M

IDA32位打开

image​​​

ARM little-endian

image

image

点击ok之后进入

  • flash的映射地址是 0x08000000 ~ 0x0807ffff (512KB)

flash就是我们装代码的地方,也是STM32入口

image

下面这张图来自STM32中文参考手册

image

从这张表中,可以了解的信息是,在偏移4的位置存储的是RESET,并且是固定的。

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

Reset就是充电就会执行并进入的地方,因此将其当做固件入口

image

在IDA偏移为4的地方,按下“D”键进行转换

得到了RESET的地址:0x80004D1

可以看到为奇数,说明是thumb指令

按下 “G” 键进行跳转

image

然后神奇的一幕发生了

image

自动识别了很多函数

image

其实这没有固定的套路,我们跟踪跳转,一步一步的分析,最终会到达关键步骤

image

分析函数 :sub_8000260

image

发现爆红了,需要我们手动添加一些段

  • Flash Memory: 0x8000000 ~ 0x801FFFF (128K)
  • SRAM: 0x20000000 ~ 0x20004FFF (20K)
  • Peripherals: 0x40000000 ~ 0x40023400

2、添加段-SRAM

image​​

单片机内存被总分为flash(rom)和sram(ram),flash里面的数据掉电可保存,sram中的数据掉电就丢失,sram的执行速度要快于flash,flash容量大于sram

单片机的程序存储分为code(代码存储区)、RO-data(只读数据存储区)、RW-data(读写数据存储区) 和 ZI-data(零初始化数据区)
Flash 存储 code和RO-data
Sram 存储 RW-data 和ZI-data

所以,SRAM段需要我们自己添加

[0x20000000,0x2000ffff]
SRAM: 0x20000000 ~ 0x20004FFF (20K) 存放程序动态执行时的变量

image

image​​

3、添加段-Peripherals

Peripherals: 0x40000000 ~ 0x400234ff    #这里还是改为了0x400234ff 而不是 0x40023400 在实战中发现多有多余的爆红,因此范围扩大总没错
外设寄存器的映射地址,程序通过读写这些内存地址实现对外围设备的控制

Peripherals 段中包含了我们要了解的寄存器

image

4、恢复中断向量表

地址0x8000000​-0x80000eb​ 存储了中断向量表的相关信息

使用python脚本,主要功能是删除旧的分析,添加dword类型分析

for i in range(0x8000000,0x80000eb,1): del_items(i)
for i in range(0x8000000,0x80000eb,4): create_dword(i)
print("ok")

image

可以看到均已恢复

image

修复完成后,发现了很多重复的地址,比如:0x8000519 这些函数并没有定义

image

跳转过去,将其全部生成对应的函数,使用(P 键)

image

官方图:

image

5、恢复符号

bindiff来恢复符号表

如果有闲工夫或者是对stm32的开发非常上手,就可以自己写一个demo,尽可能多的使用到各种库函数,然后编译出一个axf文件。我这里的话,由于好久没有用stm32了,开发起来有些生疏,所以就不自己手写了,我选择捡现成的项目,编译出axf文件

可以多选几个例程,能涵盖更多的库函数,将这些axf文件用IDA打开,然后生成idb文件。然后在我们的目标bin文件中,使用bindiff加载idb文件。

image

网上随便找一个,下载axf文件

image

选择一个idb文件,然后会出现这样一个比较界面:

image

选取similarity大的函数导入到bin文件中

image

导入之后实际上就能恢复大部分的函数名了。

image

6、恢复外设

导入SVD文件,恢复外设结构

在IDA7.5以后,就自带SVD文件加载插件了,如下图:

image

打开之后如下:

我们可以自行下载相应的SVD文件,或者加载GitHub上的仓库,我这里选择自行下载然后在本地加载。

下载链接是这个:

stm32-svd-main.zip

image

选中想要加载的svd文件之后,IDA就会自动恢复bin文件中的外设结构,体现在伪代码中就是这样:

image

image

(在这题中好像没什么用)

2、解题

基本上做完上面的操作后

STM32就能看了

进入main函数

image

继续分析

image

image​​

题目说的是要找key

image

但是发现Key没有值。。。也就是说要么动调要么爆破,给了密文,就差了key

image

因此写出解密脚本

先转换一下

int main() {int  v19[8] = { 0 };v19[0] = 0xF4DD0F64;v19[1] = 0x5173B9F8;v19[2] = 0xC7D238B2;v19[3] = 0x9B9FCA8;v19[4] = 0x286D3C51;v19[5] = 0x429DE399;v19[6] = 0x8084307B;LOWORD(v19[7]) = 0x9175;for (size_t i = 0; i < 8; i++){for (size_t j = 0; j < 4; j++){printf("%02x ", (v19[i] >> 8 * j)&0xff);}}return 0;
}

写出解密脚本:

from itertools import product
from Crypto.Cipher import ARC4
xorkey ="flag{tH14.l4_F@kKkEeeE---f41g}"
enc = bytearray([0x64,0x0f,0xdd,0xf4,0xf8,0xb9,0x73,0x51,0xb2,0x38,0xd2,0xc7,0xa8,0xfc,0xb9,0x09,0x51,0x3c,0x6d,0x28,0x99,0xe3,0x9d,0x42,0x7b,0x30,0x84,0x80,0x75,0x91])
l = list(range(0x20,0x7f))
for k in product(l, repeat=4):key = bytearray(k)res = ARC4.new(key).decrypt(xorkey.encode())if res == enc:print('get')print(key)exit(0)

使用C语言爆破会更快

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>#include <openssl/arc4.h>#define XOR_KEY "flag{tH14.l4_F@kKkEeeE---f41g}"
#define ENC_SIZE 29int main() {uint8_t enc[ENC_SIZE] = {0x64, 0x0f, 0xdd, 0xf4, 0xf8, 0xb9, 0x73, 0x51, 0xb2, 0x38, 0xd2, 0xc7, 0xa8, 0xfc, 0xb9, 0x09, 0x51, 0x3c, 0x6d, 0x28, 0x99, 0xe3, 0x9d, 0x42, 0x7b, 0x30, 0x84, 0x80, 0x75, 0x91};int l[] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f};int l_size = sizeof(l) / sizeof(int);uint8_t key[4];uint8_t dec[ENC_SIZE];for (int i = 0; i < l_size; i++) {for (int j = 0; j < l_size; j++) {for (int k = 0; k < l_size; k++) {for (int m = 0; m < l_size; m++) {key[0] = l[i];key[1] = l[j];key[2] = l[k];key[3] = l[m];ARC4_CTX ctx;ARC4_set_key(&ctx, 4, key);ARC4(&ctx, ENC_SIZE, enc, dec);if (memcmp(dec, XOR_KEY, ENC_SIZE) == 0) {printf("get\n");printf("%c%c%c%c\n", key[0], key[1], key[2], key[3]);exit(0);}}}}}return 0;
}

爆破出秘钥:

d4@d

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Crow:基于req.rul查找路由Rule对象及匹配参数

Crow::run()会调用Crow::validate(),而后者会调用router_.validate(); void validate() {//Take all the routes from the registered blueprints and add them to `all_rules_` to be processed.detail::middleware_indices blueprint_mw;validate_bp(blueprints_, blueprin…

五、Java核心数组篇

1.数组 概念&#xff1a; ​ 指的是一种容器&#xff0c;可以同来存储同种数据类型的多个值。 ​ 但是数组容器在存储数据的时候&#xff0c;需要结合隐式转换考虑。 比如&#xff1a; ​ 定义了一个int类型的数组。那么boolean。double类型的数据是不能存到这个数组中的&…

23.Java程序设计--基于SSM框架的移动端家庭客栈管理系统的设计与实现

第一章&#xff1a;引言 1.1 背景 客栈业务背景移动端应用需求增长趋势 1.2 研究动机 移动端管理系统的需求SSM框架的选择和优势 1.3 研究目的与意义 提高家庭客栈管理效率移动端解决方案的创新 第二章&#xff1a;相关技术和理论综述 2.1 SSM框架简介 Spring框架Spri…

如何在Go中使用Flag包

引言 命令行实用工具很少能在没有额外配置的情况下开箱即用。好的默认值很重要,但有用的工具需要接受用户的配置。在大多数平台上,命令行实用程序接受标志来定制命令的执行。标志是添加在命令名称之后的键值分隔的字符串。Go允许你使用标准库中的flag包来构建接受标志的命令…

swagger的ApiModelProperty设置字段的顺序

需求 让前端可以直接通过swagger就能知道各个字段是什么意思 如何配置 比如&#xff0c;我们设置了ApiModelProperty ApiModelProperty("用户主键")private Long userId;在swagger页面能直接看到注释 但是这个顺序是按照字母排序的&#xff0c;明显不符合我们的要…

在IDEA中使用Git 、远程仓库克隆工程到本地

4.1 在IDEA中配置Git 安装好IntelliJ IDEA后&#xff0c;如果Git安装在默认路径下&#xff0c;那么idea会自动找到git的位置&#xff0c;如果更改了Git的安装位置则需要手动配置下Git的路径。 选择File→Settings打开设置窗口&#xff0c;找到Version Control下的git选项&…

Java 基础学习(十)包装类、异常

1 包装类 1.1 包装类概述 1.1.1 什么是包装类 在进行类型转换时&#xff0c;有一种特殊的转换&#xff1a;将 int 这样的基本数据类型转换为对象&#xff0c;如下图所示&#xff1a; 所有基本类型都有一个与之对应的类&#xff0c;即包装类&#xff08;wrapper&#xff09;。…

使用ldflags为Go应用程序设置版本信息

引言 在将应用程序部署到生产环境中时,使用版本信息和其他元数据构建二进制文件将通过添加标识信息来帮助跟踪构建过程,从而改进监视、日志记录和调试过程。这个版本信息通常可以包括高度动态的数据,例如构建时间、构建二进制文件的机器或用户、构建二进制文件时使用的版本…

MATLAB基础应用精讲-【数模应用】神经网络(补充篇)

目录 前言 几个相关概念 反向传播 梯度下降 损失函数 优化函数

机器学习--归一化处理

归一化 归一化的目的 归一化的一个目的是&#xff0c;使得梯度下降在不同维度 θ \theta θ 参数&#xff08;不同数量级&#xff09;上&#xff0c;可以步调一致协同的进行梯度下降。这就好比社会主义&#xff0c;一小部分人先富裕起来了&#xff0c;先富带后富&#xff0c…

源码赏析: 数据结构转换工具 configor (一)

一、configor 先贴地址 configor&#xff0c;先看configor的特性&#xff1a; Header-only & STL-likeCustom type conversion & serializationComplete Unicode supportASCII & Wide-character support 说白了&#xff0c;这个工具用于自定义类型的转换和序列化…

微服务 Nacos服务注册与发现

一、Nacos 功能介绍 在微服务架构下&#xff0c;一个业务服务会被拆分成多个微服务&#xff0c;各个服务之间相互通信完成整体的功能。另外&#xff0c;为了避免单点故障&#xff0c;微服务都会采取集群方式的高可用部署&#xff0c;集群规模越大&#xff0c;性能也会越高&…

Flask 中的跨域难题:定义、影响与解决方案深度解析

跨域&#xff08;Cross-Origin&#xff09;是指在浏览器中&#xff0c;一个页面的脚本试图访问另一个页面的内容时发生的安全限制。Flask 作为一种 Web 应用框架&#xff0c;也涉及到跨域问题。本文将详细介绍跨域的定义、影响以及解决方案&#xff0c;涵盖如何在 Flask 中处理…

为什么需要分库分表,如何实现?

本文我们主要讲解“为什么需要分库分表&#xff0c;如何实现”。 在前文中讲到了读写分离&#xff0c;读写分离优化了互联网读多写少场景下的性能问题&#xff0c;考虑一个业务场景&#xff0c;如果读库的数据规模非常大&#xff0c;除了增加多个从库之外&#xff0c;还有其他…

WaitGroup并发控制原理及底层源码实现

WaitGroup并发控制原理及底层源码实现 1.1实现原理 1.2底层源码 type WaitGroup struct {noCopy noCopy// 64-bit value: high 32 bits are counter, low 32 bits are waiter count.// 64-bit atomic operations require 64-bit alignment, but 32-bit// compilers only guaran…

MSSQL存储过程的功能和用法

MSSQL&#xff08;Microsoft SQL Server&#xff09;的存储过程是一组SQL语句的集合&#xff0c;这些语句被预先编译并存储在数据库中&#xff0c;用于执行复杂的数据操作。以下是MSSQL存储过程的一些主要功能和用法&#xff1a; 功能&#xff1a; 数据操作&#xff1a;存储过程…

MySQL升级PostgreSQL遇到的常见问题及其解决方案

CRUD问题 选择 id 在的逗号分隔的字符串所表示的数组中的行 如果要将字符串用于连接条件&#xff0c;则需要将字符串转换为适当的整数数组。 Select * from table_name where id any(string_to_array(?, ,)::int[]);string_to_array(?, ,)::int[] 这部分代码的作用是将一…

态势感知是什么?在网络安全中有什么作用

态势感知是一种基于环境的、动态的、全面的洞察安全风险的能力。它以安全大数据为基础&#xff0c;从全局的角度&#xff0c;提高对安全威胁的发现识别、理解分析和处理反应能力。目的在于在大规模网络环境下&#xff0c;对能够引起网络态势变化的安全要素进行获取、理解、显示…

L1-041:寻找250

题目描述 对方不想和你说话&#xff0c;并向你扔了一串数…… 而你必须从这一串数字中找到“250”这个高大上的感人数字。 输入格式&#xff1a; 输入在一行中给出不知道多少个绝对值不超过1000的整数&#xff0c;其中保证至少存在一个“250”。 输出格式&#xff1a; 在一行中…

程序员视角体验快速搭建智能客服中心

本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 目录 前言基本概念工作原理浅试体验体验收获最后 前言 Amazon Connect是亚马逊云科技…