闰咄阅 发表于 2025-12-6 15:15:00

2024江西省振兴杯工控CTF

协议分析

被攻击的电机

思路:
过滤一下 modbus 协议,看 func_code == 5 时,Data 的 10 进制数据是大于 3000 的,但是提交 hex 数据错误modbus.func_code == 5https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112840678-1797475590.png
然后看 func_code == 6 刚好,Data 为 5000 很可疑,提交一下正常,其实就是硬找https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112840969-342020497.png
flag:flag{c90a00000006030600721388}
omron

思路:
过滤 omron 协议。然后追踪一下 tcp 流https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112841232-44822150.png
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112841516-2033205585.png
然后在第二个流发现 base64 字符,尝试解码,就是 flaghttps://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112841861-1691170016.png
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112842067-1740242746.png
flag: flag{guoqingcdgl923}



应急处置

工程被加密了

思路:
下载 组态王7.5SP1软件,打开后发现要密码
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112839855-2014325682.png
猜测为弱密码,123456,进去
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112840136-1607952312.png
然后点击操作记录就能看到 flag
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112840365-2029875378.png
flag: flag{fujka8899}
时间炸弹

题目:
产线中运行的PLC程序中被供应商埋入了“时间炸弹”,时间条件满足后触发,PLC的自动运行功能被锁定从而致使生产停摆,只能通过手动进行简单操作,生产效率将大幅降低,需要输入密码进行程序解锁。请分析找出解锁密码,密码即为flag。提交格式:flag{xxxxxxxx}。



固件分析

固件后门分析

思路:
解压文件后找到 tmp 目录打开https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112842323-122097430.png
看到了 runs.py 和 ce.pyc,将 ce.pyc 反编译一下https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112842789-1731741319.png
flag: flag{www.1sdfa4sdfdsgbnm098d8342kflgb.com:38209}


组态编程

西门子组态分析

题目:
请对西门子组态程序进行分析:按照原来的设计思路,按下启动按钮A后设备运行指示灯C应该点亮,但是C并没有亮,请根据程序,判断出还需要按下X(按钮)持续D(秒)以上得到F(点位)=G(数值)才能使得C亮。flag格式为flag{X_D_F_G}。题目同时提供了组态源程序的附件和程序代码段的截图。
思路:
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112839588-1547967890.png
从prog.png可以看到完整的PLC梯形图程序,包含4个程序段,如下
程序段1:主控逻辑
%M10.0 ——||—— %M10.4 ——||—— ( %M10.3 )    A            D            C

[*]逻辑:A AND D → C
[*]含义:启动按钮A 且 条件D 同时满足时,指示灯C点亮
程序段2:备用控制
%M10.1 ——||—— ( %M10.3 )    B            C

[*]逻辑:B → C
[*]含义:按钮B可以直接控制指示灯C
程序段3:定时器1
%M10.1 ——||—— —— ( %M10.4 )    B         %DB2 T#12S      D

[*]逻辑:B触发12秒定时器,输出到D
[*]含义:按下B按钮12秒后,D条件满足
程序段4:定时器2(关键)
%M10.3 ——|/|—— %M10.2 ——||—— —— ( %M10.4 )    C            E         %DB1 T#10S      D

[*]逻辑:NOT C AND E 触发10秒定时器,输出到D
[*]含义:当C未点亮且E按钮按下时,10秒后D条件满足
问题分析如下:
题目描述中提到"按下启动按钮A后设备运行指示灯C应该点亮,但是C并没有亮"。
从程序段1可以看出,要使C点亮需要满足:A AND D

[*]A = %M10.0(启动按钮)✓ 已按下
[*]D = %M10.4(某个条件)✗ 未满足
问题核心:D条件不满足,导致C无法点亮。
payload:
要使D (%M10.4) 为真,有两种方式:

[*]方式1(程序段3) :按下B按钮12秒
[*]方式2(程序段4) :按下E按钮10秒(推荐)
选择方式2的原因:

[*]初始状态下C=0,所以NOT C = 1(条件已满足)
[*]只需要按下E按钮即可触发定时器
[*]定时时间更短(10秒 vs 12秒)
操作步骤:

[*]按下E按钮 (%M10.2) 并保持
[*]等待10秒 定时器完成
[*]D条件满足 (%M10.4 = 1)
[*]按下A按钮 (%M10.0)
[*]指示灯C点亮 (%M10.3 = 1)
逻辑验证:

[*]初始状态:A=0, B=0, C=0, D=0, E=0
[*]按下E按钮:E=1, 触发程序段4条件 (NOT C AND E = 1 AND 1 = 1)
[*]定时器运行:%DB1定时器开始计时10秒
[*]10秒后:D=1 (%M10.4 = 1)
[*]按下A按钮:A=1, 满足程序段1条件 (A AND D = 1 AND 1 = 1)
[*]结果:C=1 (%M10.3 = 1) 指示灯点亮

flag:flag{E_10_D_1}
Smart

题目:
黑客在桌面上留下一个工程文件,经检查发现是西门子200smart plc程序,打开发现可能是一个计算程序,经分析,需要置位v22.0寄存器,获取最终VD716数值,flag为{VW502_VW600_VD716}的最终值。
思路:
使用 STEP7MicroWINSMARTV2.7.0.0 打开发现流程图,



奇怪的文件

题目:
某企业的SCADA系统主机被黑客入侵,管理员小申发现黑客上传了一个文件,我们需要帮助小申分析文件内的蛛丝马迹,找到FLAG,flag形式为 flag{}。
思路:
使用 binwalk 123.jpg 发现图片里面有个压缩包,使用 foremost 分离出来即可,观察压缩包很明显利用 crc32 进行工具,
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112834341-1299968312.png
然后使用 20251114_151839.dic 生成的字典进行字典爆破
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112834611-577965996.png
爆破得到密码 kfoudgclum5r9gx0Sv
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112834891-1732621586.png
解压得到一个 123 文件,然后 010 观察发现是一个 zip 文件,改完后缀后,观察一下,是一个力控的文件格式,可以先解压出来只有下面那个 xml 文件被加密了
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112835099-1422133507.png
然后搜索 flag 可以发现 flag
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112835424-687263286.png
然后使用力控软件(forcecontrol v7.2)恢复一下
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112835700-1392024430.png
然后选择恢复的工程,运行一下,点击用户管理
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112836214-1766007940.png
然后使用 Admin/123 登入一下,在点击修改用户
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112836722-276937937.png
可以发现有个 flag 用户,估计后半段 flag 就这里
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112837065-1277930141.png
可以使用 AsteriskPassword-星号密码查看器 查看一下密码,得到后半段 flag
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112837346-947346491.png
flag:flag{ES8-A05A-CB78-XST78-dgk8tvm9}
梯形图分析1

题目:
小朱在进行设备调试时,编写了一段模拟量转换的程序,已知IW2的值为2100,V10为2.23606801,V27为6429,请计算出V100和V200的值帮助小朱进一步分析,flag为V100与V200之和。flag格式为flag{}
思路:
给了 11.jpg ,使用 010 打开一下,发现图片尾部有个 rar 文件,
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112837653-1895933265.png
搜索一下发现是一个 AutoThink 项目文件,使用 FA-AutoThinkV3.1.9Beta1和利时PLC 这个工具打开即可
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112837926-438909340.png
现在就是求V100与V200之和,已知IW2的值为2100,V10为2.23606801,V27为6429
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112838200-1093043454.png
不会计算,后面都改 ai 分析的不知道对不对
网络 0001 - 基础运算与模运算

功能: 进行基础的算术运算,为后续计算准备中间变量
运算流程:
第一个SUB块: V2 = 88 - 23 = 65 第二个SUB块: V3 = V3 - V2 (这里V3的初值影响结果,但不影响最终目标) 第三个SUB块: V4 = %IW2 - 56 = 2100 - 56 = 2044 MUL块: V5 = %IW2 × V4 = 2100 × 2044 = 4,292,400 MOD块: V6 = V5 MOD V4 = 4,292,400 MOD 2044 = 0关键分析:

[*]V4 = 2044
[*]V5 = 4,292,400
[*]V6=0 (重要!因为V5 = %IW2 × V4,所以V5是V4的整数倍,取模结果为0)
网络 0002 - 除法与开方运算

功能: 进行除法运算、开方运算和数据类型转换
运算流程:
DIV块: V8 = V6 ÷ V7 = 0 ÷ V7 = 0 (只要V7≠0) SQRT块: V10 = √V8 = √0 = 0 (理论计算) REAL_TO_INT块: V30 = INT(V10) = INT(2.23606801) = 2关键分析:

[*]V8=0 (因为V6=0,所以无论V7为何值,V8都等于0)
[*]题目给出V10 = 2.23606801,这可能是程序运行中的实际值
[*]V30=2 (对V10进行向零取整)
网络 0003 - 计算V100

功能: 通过减法、开方和幂运算计算目标变量V100
运算流程:
SUB块: V28 = V7 - V8 = V7 - 0 = V7 SQRT块: V29 = √V28 = √V7 EXPT块: V100 = V29^V8 = (√V7)^0 = 1关键分析:

[*]V28 = V7 (但V7的具体值不影响最终结果)
[*]V29 = √V7
[*]V100=1 (任何非零数的0次方都等于1,0^0在大多数PLC中也定义为1)
网络 0004 - 计算V200

功能: 通过模运算、幂运算和三角函数计算目标变量V200
运算流程:
MOD块: V36 = V27 MOD V30 = 6429 MOD 2 = 1 SUB块: V31 = V8 - V7 = 0 - V7 = -V7 EXPT块: V37 = V31^V36 = (-V7)^1 = -V7 COS块: V200 = COS(V37) = COS(-V7) = COS(V7)关键分析:

[*]V36 = 6429 MOD 2 = 1 (6429是奇数)
[*]V31 = -V7
[*]V37 = -V7 (因为指数为1)
[*]由于题目未给出V7的值,且程序中未对V7进行赋值,按PLC变量初始化规则,V7 = 0
[*]V200=COS(0)   =1
数学计算验证

关键计算步骤


[*]模运算验证:
V5 = 2100 × 2044 = 4,292,400 V6 = 4,292,400 MOD 2044 = 0 证明: 4,292,400 ÷ 2044 = 2100 (整除)
[*]实数取整验证:
V10 = 2.23606801 V30 = REAL_TO_INT(2.23606801) = 2
[*]幂运算验证:
V100 = (任意数)^0 = 1 V200 = COS(0) = 1
最终结果计算


[*]V100 = 1
[*]V200 = 1
[*]Flag = V100 + V200 = 1 + 1 = 2

exp:
import mathdef solve_plc_problem():    # 已知条件    IW2 = 2100    V10 = 2.23606801    V27 = 6429    V7 = 0# 默认初始值      print("=== 工控梯形图分析求解过程 ===")    print(f"已知: IW2={IW2}, V10={V10}, V27={V27}")      # 网络0001    print("\n--- 网络0001 ---")    V4 = IW2 - 56    V5 = IW2 * V4    V6 = V5 % V4    print(f"V4 = {IW2} - 56 = {V4}")    print(f"V5 = {IW2} × {V4} = {V5}")    print(f"V6 = {V5} MOD {V4} = {V6}")      # 网络0002    print("\n--- 网络0002 ---")    V8 = V6 // V7 if V7 != 0 else 0# 避免除零    V30 = int(V10)    print(f"V8 = {V6} ÷ {V7} = {V8}")    print(f"V30 = INT({V10}) = {V30}")      # 网络0003    print("\n--- 网络0003 ---")    V28 = V7 - V8    V29 = math.sqrt(abs(V28)) if V28 >= 0 else 0    V100 = V29 ** V8 if V8 != 0 else 1    print(f"V28 = {V7} - {V8} = {V28}")    print(f"V29 = √{V28} = {V29}")    print(f"V100 = {V29}^{V8} = {V100}")      # 网络0004    print("\n--- 网络0004 ---")    V36 = V27 % V30    V31 = V8 - V7    V37 = V31 ** V36    V200 = math.cos(V37)    print(f"V36 = {V27} MOD {V30} = {V36}")    print(f"V31 = {V8} - {V7} = {V31}")    print(f"V37 = {V31}^{V36} = {V37}")    print(f"V200 = COS({V37}) = {V200}")      # 最终结果    print("\n=== 最终结果 ===")    print(f"V100 = {V100}")    print(f"V200 = {V200}")    flag_value = V100 + V200    print(f"Flag = V100 + V200 = {flag_value}")    print(f"答案: flag{{{int(flag_value)}}}")      return int(flag_value)if __name__ == "__main__":    result = solve_plc_problem()flag:flag{2}
扫雷

题目:
自动化专家老吴通过PLC编程开发了一款小游戏——扫雷,通关后可获得flag,flag格式为:flag{}。
思路:
想让我通关不可以的,解压出来是 扫雷_V16.ap16 文件,很明显的用S7-1200 博途软件V16 打开,然后 crtl + f 搜索 flag,发现如下
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112838548-1414020530.png
双击文件定位到关键位置,就能发现密文
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112838817-2057811792.png
密文如下,根据 U2FsdG 头知道这是一个用 js 前端加密库解密的密文,一般都需要 key,看到这个文件名猜测就是密钥,jdgf
U2FsdGVkX1/MRLx94+KHoo9xb0iO9g2swJLVNYD38y7yMYhDpciH6pK0F5HHMY+Qj4XACALNZBY=
解密一下,得到 flag
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112839095-1029472547.png
在线Triple DES加密 | Triple DES解密- 在线工具 用在线的也许,就是要多试一下解密方式
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112839368-838736996.png
flag:flag{Revitalization_Cup@578790336}


恶意程序分析

勒索病毒分析

枢网智盾线上赛Writeup - FreeBuf网络安全行业门户
题目:
客团伙利用工控系统的RCE漏洞投递了一款勒索病毒,导致系统重大量重要文件被加密,管理员经过排查已修复相关漏洞,并找到了勒索病毒样本,但无法恢复被加密的文件。你能通过分析恶意样本,协助管理员解密被加密的文件吗?请解密flag.txt.encrypt文件,获取flag。
思路:
ida 反汇编报错
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112843264-232898759.png
可以发现 401D48 这个位置失败,先双击跟进一下这个函数,然后按 f5 ,可以发现这个函数可以反汇编,然后再回到 mian 函数 f5 也能反汇编了
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112843531-1779732601.png
https://img2024.cnblogs.com/other/3176340/202512/3176340-20251205112834112-1873299789.png

exp:
# coding: utf-8"""勒索病毒解密脚本 - ChaCha20 算法"""from Crypto.Cipher import ChaCha20# 加密数据(明文标记之前的部分)data = bytes([    0x0B, 0xB0, 0xB5, 0x4E, 0x89, 0x4E, 0x9D, 0x03, 0x93, 0x1D, 0x5B, 0xE5,    0x10, 0xE2, 0xEA, 0x13, 0x10, 0xBE, 0x60, 0x09, 0xD8, 0x16, 0x4A, 0xF0,    0x4B, 0xF8, 0xCB, 0xC6, 0x49, 0x39, 0x88, 0x10, 0x72, 0x00, 0x28, 0xB6,    0x0D, 0x5A, 0xCB, 0x49, 0xFB, 0x3D])# ChaCha20 密钥和 Noncekey = bytes([    0x75, 0x2b, 0xcb, 0x44, 0x8b, 0xd1, 0x70, 0x53, 0xe6, 0xb5, 0x5c, 0xc4,    0xe6, 0xba, 0x1b, 0xe8, 0x75, 0x6d, 0x2d, 0xbb, 0x03, 0x89, 0x9e, 0xb6,    0x5e, 0xf5, 0xa7, 0xef, 0xf6, 0xde, 0x5e, 0xe7])nonce = bytes([    0x4b, 0xf6, 0x5b, 0x44, 0xe2, 0x79, 0x81, 0x1c, 0x36, 0x7f, 0x94, 0xcc])# 初始化 ChaCha20 并设置计数器为 1(偏移 64 字节)cipher = ChaCha20.new(key=key, nonce=nonce)cipher.seek(64)# 解密并输出decrypted = cipher.decrypt(data)print(decrypted.decode('utf-8'))# FLAG: flag{e26e86af-bb71-4bf5-9dec-e845b4f7b1c3}
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

巨耗 发表于 5 天前

感谢发布原创作品,程序园因你更精彩

抑卞枯 发表于 前天 18:19

收藏一下   不知道什么时候能用到
页: [1]
查看完整版本: 2024江西省振兴杯工控CTF