找回密码
 立即注册
首页 业界区 安全 2024江西省振兴杯工控CTF

2024江西省振兴杯工控CTF

闰咄阅 昨天 15:15
协议分析

被攻击的电机

思路:
  1. 过滤一下 modbus 协议,看 func_code == 5 时,Data 的 10 进制数据是大于 3000 的,但是提交 hex 数据错误
复制代码
  1. modbus.func_code == 5
复制代码
  1. 然后看 func_code == 6 刚好,Data 为 5000 很可疑,提交一下正常,其实就是硬找
复制代码

flag:flag{c90a00000006030600721388}
omron

思路:
  1. 过滤 omron 协议。然后追踪一下 tcp 流
复制代码

  1. 然后在第二个流发现 base64 字符,尝试解码,就是 flag
复制代码


flag: flag{guoqingcdgl923}



应急处置

工程被加密了

思路:
下载 组态王7.5SP1软件,打开后发现要密码

猜测为弱密码,123456,进去

然后点击操作记录就能看到 flag

flag: flag{fujka8899}
时间炸弹

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



固件分析

固件后门分析

思路:
  1. 解压文件后找到 tmp 目录打开
复制代码
  1. 看到了 runs.py 和 ce.pyc,将 ce.pyc 反编译一下
复制代码

flag: flag{www.1sdfa4sdfdsgbnm098d8342kflgb.com:38209}


组态编程

西门子组态分析

题目:
请对西门子组态程序进行分析:按照原来的设计思路,按下启动按钮A后设备运行指示灯C应该点亮,但是C并没有亮,请根据程序,判断出还需要按下X(按钮)持续D(秒)以上得到F(点位)=G(数值)才能使得C亮。flag格式为flag{X_D_F_G}。题目同时提供了组态源程序的附件和程序代码段的截图。
思路:

从prog.png可以看到完整的PLC梯形图程序,包含4个程序段,如下
程序段1:主控逻辑
  1. %M10.0 ——|  |—— %M10.4 ——|  |—— ( %M10.3 )    A              D              C
复制代码

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

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

  • 逻辑:B触发12秒定时器,输出到D
  • 含义:按下B按钮12秒后,D条件满足
程序段4:定时器2(关键)
  1. %M10.3 ——|/|—— %M10.2 ——|  |—— [TON] —— ( %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 进行工具,

然后使用 20251114_151839.dic 生成的字典进行字典爆破

爆破得到密码 kfoudgclum5r9gx0Sv

解压得到一个 123 文件,然后 010 观察发现是一个 zip 文件,改完后缀后,观察一下,是一个力控的文件格式,可以先解压出来只有下面那个 xml 文件被加密了

然后搜索 flag 可以发现 flag

然后使用力控软件(forcecontrol v7.2)恢复一下

然后选择恢复的工程,运行一下,点击用户管理

然后使用 Admin/123 登入一下,在点击修改用户

可以发现有个 flag 用户,估计后半段 flag 就这里

可以使用 AsteriskPassword-星号密码查看器 查看一下密码,得到后半段 flag

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 文件,

搜索一下发现是一个 AutoThink 项目文件,使用 FA-AutoThinkV3.1.9Beta1和利时PLC 这个工具打开即可

现在就是求V100与V200之和,已知IW2的值为2100,V10为2.23606801,V27为6429

不会计算,后面都改 ai 分析的不知道对不对
网络 0001 - 基础运算与模运算

功能: 进行基础的算术运算,为后续计算准备中间变量
运算流程:
  1. 第一个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 - 除法与开方运算

功能: 进行除法运算、开方运算和数据类型转换
运算流程:
  1. 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
运算流程:
  1. 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
运算流程:
  1. 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
数学计算验证

关键计算步骤


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


  • V100 = 1
  • V200 = 1
  • Flag = V100 + V200 = 1 + 1 = 2

exp:
  1. 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,发现如下

双击文件定位到关键位置,就能发现密文

密文如下,根据 U2FsdG 头知道这是一个用 js 前端加密库解密的密文,一般都需要 key,看到这个文件名猜测就是密钥,jdgf
U2FsdGVkX1/MRLx94+KHoo9xb0iO9g2swJLVNYD38y7yMYhDpciH6pK0F5HHMY+Qj4XACALNZBY=
解密一下,得到 flag

在线Triple DES加密 | Triple DES解密- 在线工具 用在线的也许,就是要多试一下解密方式

flag:flag{Revitalization_Cup@578790336}


恶意程序分析

勒索病毒分析

枢网智盾线上赛Writeup - FreeBuf网络安全行业门户
题目:
客团伙利用工控系统的RCE漏洞投递了一款勒索病毒,导致系统重大量重要文件被加密,管理员经过排查已修复相关漏洞,并找到了勒索病毒样本,但无法恢复被加密的文件。你能通过分析恶意样本,协助管理员解密被加密的文件吗?请解密flag.txt.encrypt文件,获取flag。
思路:
ida 反汇编报错

可以发现 401D48 这个位置失败,先双击跟进一下这个函数,然后按 f5 ,可以发现这个函数可以反汇编,然后再回到 mian 函数 f5 也能反汇编了



exp:
  1. # 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}
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册