首页
社区
课程
招聘
[原创] 2025-10月Solar应急响应月赛WP!
发表于: 2025-10-31 16:11 771

[原创] 2025-10月Solar应急响应月赛WP!

2025-10-31 16:11
771

1.10月月赛WP

Brainiac

题目文件结构:
图片描述

Brainiac.exe 程序文件

flag_enc.txt 加密的flag文件

分析:

图片描述

die结果,x64程序.

图片描述

运行提示输入参数.
图片描述
图片描述
图片描述
图片描述

主函数就是一个普通的命令行加密器.关键点在回调里面.

图片描述

图片描述

回调内容也不多,但是很关键.表面上是看不出什么的.

图片描述

但是能注意到,这里有个0是红色高亮的,说明要注意.这其实就是重定位会覆盖的地方,ida十分贴心地标注了.但是没见过的一看可能会不理解.还有下面那些复杂的计算,由于rax为0,ida自动优化了这些计算.所以在f5伪码中看上去,这里的传参就是0x400.这样的优化点有两处.复杂的计算只是一个选择器的代码,不必过多注意.动调起来,注意下这里的变化就真相大白了.
图片描述
看起来没有更多信息了,开始动调,断点可以直接下在回调里面.

img

设置好传入的命令行参数.

图片描述

发生异常,忽略即可.

图片描述
断下来可以发现,0已经变成了一个64位地址.

图片描述
现在按f5,得到的就是正确结果了.

图片描述

这里还有一处障眼法.既然有重定位,那么为什么没有.reloc段呢?
图片描述
图片描述
图片描述

其实只要数据目录的重定位表地址指向了正确的数据(不在文件头中),而且程序开启了动态基址,且未设置去除重定位,就一样能够解析重定位表.
图片描述

第一处可以看到,直接传入了程序基址,也就说明是修改了文件头的保护属性,第二处将基址先转成数值再加2,则开始执行的地址位于文件头后面2字节.根据题目名字Brainiac,Brain=脑=文件头中的内容,所以查看文件头偏移地址0x2处.
图片描述
图片描述

发现该位置是jmp指令.为了降低难度,直接按p即可解析.
图片描述

cfg大致是这样,加了几条跳转,不影响f5分析.
图片描述
f5可以得到关键算法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include<stdio.h>
#include<windows.h>
int main(int argc, char** argv)
{
    if (argc != 3)
    {
        printf("usage: Dec.exe <input> <output>\n");
        return 0;
    }
    char* input_path = argv[1];
    char* output_path = argv[2];
    BOOL success = FALSE;
    BYTE* file_buf = 0;
    HANDLE hInputFile = INVALID_HANDLE_VALUE;
    HANDLE hOutputFile = INVALID_HANDLE_VALUE;
    HANDLE the_heap = GetProcessHeap();
    hInputFile = CreateFile(input_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hInputFile == INVALID_HANDLE_VALUE)
    {
        goto cleanup;
    }
    DWORD filesz = GetFileSize(hInputFile, NULL);
    file_buf = (BYTE*)HeapAlloc(the_heap, HEAP_ZERO_MEMORY, filesz);
    DWORD dwBytesRead = 0;
    if (!ReadFile(hInputFile, file_buf, filesz, &dwBytesRead, NULL) || (dwBytesRead != filesz))
    {
        goto cleanup;
    }
    DWORD fsz_paded = filesz - 16;
    BYTE* tails = file_buf + fsz_paded;
    if (strncmp((char*)tails + 8, "ZXLOCKER", 8))
    {
        goto cleanup;
    }
    hOutputFile = CreateFile(output_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hOutputFile == INVALID_HANDLE_VALUE)
    {
        goto cleanup;
    }
    DWORD key = *(DWORD*)tails;
    DWORD fsz = *(DWORD*)(tails + 4) ^ key ^ 0x89abcdef;
    DWORD seed = key;
    for (DWORD i = 0; i < fsz_paded; i += 8)
    {
        DWORD* plain = (DWORD*)(file_buf + i);
        DWORD x = plain[0];
        DWORD y = plain[1];
        seed = seed * 0xfadebabe + 1919810;
        plain[1] = x ^ seed;
        seed = seed * 0xfadebabe + 1919810;
        plain[0] = y ^ seed;
    }
    DWORD dwBytesWritten = 0;
    if (!WriteFile(hOutputFile, file_buf, fsz, &dwBytesWritten, NULL) || (dwBytesWritten != fsz))
    {
        goto cleanup;
    }
    success = TRUE;
cleanup:
    if (hInputFile != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hInputFile);
    }
    if (hOutputFile != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hOutputFile);
    }
    if (file_buf)
    {
        HeapFree(the_heap, 0, file_buf);
    }
    if (success)
    {
        printf("TADA!\n");
        return 1;
    }
    else
    {
        printf("ERROR!\n");
        return 0;
    }
}

所以可以写出脚本,这里给了一个完整的命令行解密器.

解密文件,得到flag.flag见前文附件.

工控应急wp

谁把泵关了?

定位 Modbus 写单线圈(Function 0x05) 的数据帧,读取事务 ID、功能码、线圈地址。

图片描述
Transaction Identifier → 0x1a2b

Function Code → Write Single Coil (5)(即 0x05

Coil/Output Address → 0x000d 另外 Value=0x0000 表示“关”。

被写入的 NodeId

过滤 tcp.port==4840

右键任一 OPC UA 会话 → Follow TCP Stream

搜索 NodeId= 即可。
图片描述

工程站域名解析结果

找出对 engws.plant.local 的应答包,读取 A 记录

图片描述
得到

图片描述

HMI→工程站首个成功连接时间(UTC)

抓取 445/TCP首个 SYN(ACK=0)。HMI 源到工程站目的的第一帧时间即为答案(UTC 到秒)。

图片描述

将 epoch 转 ISO8601(UTC)

图片描述

得到flag
图片描述

对工程站的接口调用(Host 与 URI)

追踪TCP流发现有请求访问POST传输,然后查看发现是对接口的调用

flag为
图片描述

Ruoyi wp

为了能够看到被劫持效果,从而方便去进行排查

根据提供**配置文件(配置文件实际可以通过解压JAR提取)**进行配置数据库,这里可以用docker 快速部署

图片描述

下载ruoyi sql文件初始化数据库后即可顺利运行ruoyi

详情请参考官方部署

部署完成后通过Chrome访问 或者手机模式访问api会导致跳转到 f09K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2K6L8$3I4S2M7Y4y4W2j5%4g2J5K9i4c8&6i4K6u0W2j5$3&6Q4x3V1j5`.

图片描述

我们通过jadx分析该jar包,全局搜索162K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2K6L8$3I4S2M7Y4y4W2j5%4g2J5K9i4c8&6i4K6u0W2j5$3&6Q4x3V1j5`. ,即可发现导致跳转的相关方法

图片描述
经过测试最终preRedirect方法名是最后的答案

图片描述
假设我们仅通过静态分析,则推荐的方法是和官方版本的ruoyi进行代码比对,即可发现异常的代码。


传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回