IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 中职网络安全省赛逆向PE01程序静态分析 -> 正文阅读

[网络协议]中职网络安全省赛逆向PE01程序静态分析

开始

将PE01程序拖入到ida工具中
在这里插入图片描述

1.对靶机服务器场景桌面上的PE01.exe二进制文件进行荆条调试,将main函数的入口作为Flag提交;

现在我们进入到程序中,可以发现左上角的主函数名中第一个为main函数。

在这里插入图片描述

双击main函数,可以看见下面为main函数的入口地址
在这里插入图片描述

Flag:0x0000000140001000

2.对靶机服务器场景桌面上的PE01.exe二进制文件进行静态调试,将该二进制文件中检查许可证的关键函数作为Flag值提交;

程序在进行判断的时候要么是正确的回显要么是错误的回显,类似c语言的if语句的判断。在PE01.exe程序中,输入字符出现了"wrong…"的错误信息

按空格键来到汇编代码窗口中
在这里插入图片描述

按Alt加t键,搜索关键字符串

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

我们在这里点击wrong左上角的主函数,可以发现上面jnz指令跳转的为这个黄色主函数。call指令为回调地址,也就是说jnz跳转主函数后回调地址sub_1400016A0

在这里插入图片描述

按F5键查看伪代码,由于ida并不是能完整的复现伪代码的所有真实数据,在这里可以发现if语句对sub_1400016A0函数进行判断。

在这里插入图片描述

我们继续双击sub_1400016A0函数,来到了另一个伪代码中,在这里可以发现这是一些算法加上for循环语句进行if判断,这更加证明了sub_1400016A0函数就是检查许可证的关键函数

在这里插入图片描述

点击汇编代码窗口,双击sub_1400016A0回调函数,可以看见它的入口地址为:00000001400016A0

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Flag:0x00000001400016A0

3.对靶机服务器场景桌面上的PE01.exe二进制文件进行静态调试,找到Flag值提交;

我们根据题目他提示继续分析Flag可能会出现的地方,双击main的函数,并在当前页面下按F5查看伪代码。

在这里插入图片描述

在这里我们可以看见有两个函数地址,分别是sub_140001250和sub_140001920,双击sub_140001920函数,可以发现这里有些字符串的提示语句:“你好!也许秘密就藏在背景图片中”

在这里插入图片描述

根据提示,联想到exe程序中默认是可以进行解压的,那么PE01.exe程序里的背景也是可以通过这种方式进行解压出来,我们将程序解压到PE01文件夹中,在.rsrc\2052\BITMAP的路径中发现了这张图片。

在这里插入图片描述

在这里插入图片描述

将图片拖入到HxD工具中,在图片十六进制的末尾可以发现有一些可以可疑的十六进制值,尝试猜解一些字符串,验证想法是正确的,编写一个脚本获取flag值

在这里插入图片描述

在这里插入图片描述

脚本如下:

import re
str ='04 06 06 0C 06 01 06 07 03 01 07 0B 06 03 04 00 04 0E 07 04 05 0F 03 05 06 05 05 0F 06 0D 04 05 07 0D'

result = str.replace(' ','')
len_r = len(result)
flag = "" 
shiliu = ""

for j in range(1,len_r,2): 
    shiliu += (result[j])  
result1 = re.findall('.{2}',shiliu) 

for i in result1: 
    flag += (chr(int(i,16)))
print(flag) 

Flag:Flag1{c@Nt_5e_mE}

5.对靶机场景桌面上的PE01.exe二进制文件进行静态调试,将激活所需的许可证码作为Flag值提交;

我们在第2题得知sub_1400016A0函数就是检查许可证的关键函数,那么我们返回到这个函数的伪代码进行分析。

__int64 __fastcall sub_1400016A0(const WCHAR *a1)
{
  int i; // [rsp+20h] [rbp-28h]
  int v3; // [rsp+24h] [rbp-24h]
  _DWORD *v4; // [rsp+28h] [rbp-20h]

  v3 = lstrlenW(a1);
  v4 = malloc(saturated_mul(v3, 4ui64));
  for ( i = 0; i < v3 && i < 17; ++i )
  {
    v4[i] = (char)sub_1400017B0(LOBYTE(a1[i]));
    v4[i] = -v4[i];
    v4[i] ^= i + dword_140005044;
    if ( dword_140005000[i] != v4[i] )
      return 0i64;
  }
  return 1i64;
}

通过观察可以发现,许可证必须的等于v4[i]才能回显正确,那么我们求v4[i]的值等于求许可证的值,所以现在第一个目标是求v4[i],进行反编写脚本获取它的许可证码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zCGeaLw9-1665923129735)(C:/Users/admin/Desktop/逆向/笔记/PE01逆向/img/image-20221016104946574.png)]

可以发现求许可证的核心关键是for循环,那么我们只要关注for循环里的内容就好了,既然是逆向,逆向的脚本应该也是逆着来的,我们从后面开的函数分析。双击dword_140005000。

在这里可以发现这个变量里的数组有17个值。

在这里插入图片描述

这个我们先不管,返回到伪代码窗口,继续向上分析,双击该变量名,跳转到该地址的数据段,在这里我们可以看见类似上面变量名的xxh这是汇编语言中的十六进制的表示符。

在这里插入图片描述

在这里插入图片描述

现在我们知道这个变量名的数据段的值为那些十六进制,为了方便认识,按n键修改变量名字,将dword_140005044修改为key,v4修改为num。

在这里插入图片描述

在这里插入图片描述

其中为了求出许可证我们知道num[i]必须恒等于dword_140005000[i],所以dword_140005000数据段里的17个十六进制值要等于num的变量名中的数组里的值。我们继续点击dword_140005000变量来到数据段里分析其中的十六进制值,为了方便认识,把它们都转为十进制。

在这里插入图片描述

这里涉及到了十六进制转负数的知识点,如果直接进行进制转换可以发现有些数值是很大的,这不符合了十进制和ascii直之间的转换(0-127)。我们要判断十六进制是否为负数,只需要知道16进制首位是否大于8,大于8为负数,小于8为正数。

例如,在上图中dword_14000500变量里的数据段第一个十六进制值0FFFFFF9Ch,把它转为负数该如何进行操作?

  • 在汇编语言中为了避免将16进制数误认为是指令,需要在前面添加一个0

    • 所以0FFFFFF9Ch -> FFFFFF9Ch -> FFFFFF9C(前面讲解过h为十六进制标识符,这里不解释了)
  • 由于我们知道16进制首位大于8为负数,为了简单运算只留下一个F就够了

    • 所以 FFFFFF9C -> F9C
  • F9C 的二进制位为1111 1001 1100,这里由涉及了一个知识点十六进制转负数,简单来说就是求该二进制的补码就行。

  • 简单一个实验案例十六进制转负数

    • 1111 1001 1100 原码:为十六进制转为二进制的值
      0000 0110 0011 反码就是把原码的0和1改为相反数(原码求补码的过程要经历反码)
      1000 0110 0100 补码在最高位加1,证明它是负数,并且在最低为加1
      
      所以 F9C等于1000 0110 0100 (前面的1只是证明负数,运算的时候不理)
      -> 0110 0100 (转为十进制,注意添加符号,前面证明了是负数)-> -100
      

现在我们了解了那么多的信息,用python定义两个了变量

num =[-100,72,-98,-103,78,-118,61,-91,83,-74,-128,6,39,-93,117,-103,-65]

key = 65

继续分析上面的伪代码,其中-num[i]不理,后面编写逆向照着写就好了。在伪代码的左边可以发现chr函数,它的意义是转为ASCII值,num变量最后会经历ASCII的转码,这个时候ASCII输出的值也就是flag。我们双击sub_1400017B0,在这其中可以发现返回了一些算法的信息。其中a1是什么变量?根据伪代码a1[i]可以猜测出a1=num,其中0xFu中在十六进制不存在,所以编写脚本的时候应该改为0xF即可。

在这里插入图片描述

在这里插入图片描述

我们来到分析最后一行关键代码,可以看见是一个for循环,这有两种理解方式,一个是ida自动生成的伪代码并不标准,中间不可能出现与运算。二是因为我们知道num的数组有17位,那么for循环从零开始到16,遍历17次,所以这行代码应该理解为:

for ( i = 0; i < 17; ++i )

在这里插入图片描述

最终用python脚本获取flag:

num =[-100,72,-98,-103,78,-118,61,-91,83,-74,-128,6,39,-93,117,-103,-65]
key = 65
flag = ""

for i in range (len(num)):
    num[i] ^= (i + key)
    num[i] = -num[i]
    num[i] = chr(16 * (num[i] & 15) | (num[i] >> 4) & 15)
    flag += num[i]
print(flag)

Flag:2o22_Ch1n@Ski1ls!

结尾

我也不是很会,有什么错的请指正

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:53:48  更:2022-10-22 21:56:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:52:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码