去年参加了几场工控CTF比赛,基本都在坐牢。闲暇之余对工控CTF中常见的题型进行学习。
工控CTF题目主要以流量分析、无线电分析、组态分析、梯形图等方向为主,偶尔有逆向分析、日志分析等相关分析题目。 相关赛事较少,赛事主办方以政府为主,常见的有每年的ICSC/IISC国赛及其各省的选拔赛/省赛。 线下赛有工业网络渗透实战、工业应急响应等赛制,主要考察渗透和运维能力。
常见的工控协议有:Modbus、MMS、MQTT、COTP、IEC104、IEC61850、S7COMM、OMRON等。由于工控技术起步较早但是统一的协议规范制定较晚,所以许多工业设备都有自己的协议。 题目考点主要以工控流量和恶意流量为主,主要考察Wireshark使用和找规律,部分难度较高的题目主要考察协议定义和特征。
Modbus协议是工控领域最常见的协议之一,也算是工控CTF中最常见题型。
1. Modbus/RTU从机地址1B+功能码1B+数据字段xB+CRC值2B
最大长度256B,所以数据字段最大长度252B
2. Modbus/ASCII由Modbus/RTU衍生,采用`0123456789ABCDEF`表示原本的从机地址、功能码、数据字段,并添加开始结束标记,所以长度翻倍
开始标记`:`1B+从机地址2B+功能码2B+数据字段xB+LRC值2B+结束标记`\r\n`2B
最大长度513B,因为数据字段在RTU中是最大252B,所以在ASCII中最大504B
3. Modbus/TCP不再需要从机地址,改用UnitID;不再需要CRC/LRC,因为TCP自带校验
题目中最常见的是Modbus/TCP协议,主要原因是抓包方便。 Modbus常见功能码:
传输标识符2B+协议标识符2B+长度2B+从机ID 1B+功能码1B+数据字段xB1:读线圈
2:读离散输入
3:读保持
4:读输入
5:写单个线圈
6:写单个保持
15:写多个线圈
16:写多个保持
题目要求:分析文件找出flag
1. 首先依次筛选常见功能码,筛选到功能码为3的返回包:可以选择筛选返回包中的来源ip地址,来筛选出response包
((modbus) && (modbus.func_code == 3)) && (ip.src == 192.168.161.2)
1. 因为功能码显示read,所以判断看返回包,发现有报错的数据包。
通过筛选byte count字段,筛选出有数据的响应包
(((modbus) && (modbus.func_code == 3)) && (ip.src == 192.168.161.2)) && (modbus.byte_cnt)
1. 查看响应包数据,发现响应包每条会增加一些字符
1. 将值复制出来
#[email protected]%&$&#=!!%!!$! "=$&$!""#!"@[email protected]!'% $$#
但是发现复制的值中间有欠缺,所以复制hex16进制,然后找过字符的开头和结尾进行去除,然后转码
0023003d0024004000250026002400260023003d00210021002500210021001f0024001f002100200022003d0024002600240021002200220023001f0021001e00220040002400400021002700250020002400240023
1. 以下步骤目的是为了将00去除
第一步:将hex转换
第二步:将值转换成hex,并设置一行2个bytes
第三步:使用take bytes将字节取不是00的第二位 并设置为一行2个
第四步:然后再转换为hex,得出完整的字符串
#[email protected]%&$&#=!!%!!.$.! "=$&$!""#.!."@[email protected]!'% $$#
第五步:将字符串转换为10进制,发现61 64
第六步:转换为16进制 得到5a6d78685a33733161324a68634451304d6d3972665
第七步:得到的5a6d78685a33733161324a68634451304d6d3972665疑似16进制字符串,然后再进行hex解码得到ZmxhZ3s1a2JhcDQ0Mm9rf.
第八步:base64解码获取flag
MMS主要有2种类型:
1. initiate(可以理解为握手)
initiate-RequestPDU
initiate-ResponsePDU
1. confirmed(可以理解为交互)
confirmed-RequestPDU
confirmed-ResponsePDU
通常情况为:
1. 1轮initiate
即发送1个initiate-RequestPDU,接收1个initiate-ResponsePDU
1. n轮confirmed,直到会话主动关闭或被动断开
即confirmed-RequestPDU和confirmed-ResponsePDU交替发送和接收
交互时的指令称为confirmedService
1. 对象操作
getNameList (1)
read (4)
write (5)
getVariableAccessAttributes (6)
getNamedVariableListAttributes (12)
1. 文件操作
fileOpen (72)
fileRead (73)
fileClose (74)
fileDirectory (77)
题目要求:分析文件找出flag
1. 根据题目名称过滤出MMS数据包,发现前两个包为请求握手,观察第三个包发现read为4
1. 过滤read不是4的包,发现没有。证明全是4
(mms) && (mms.confirmedServiceRequest != 4)
1. 然后再找其他数据段发现itemId数据不一样,仔细观察都是LLN0开头
1. 过滤LLN0开头的数据
选中过滤器
(mms) && mms.itemId contains "LLN0"
1. 然后过滤一下非FFNO的数据,发现三条数据
(mms) && mms.itemId &&!(mms.itemId contains "LLN0")
1. 通过观察比较发现数据疑似ascii码,因为ascii码中f为66、l为6c
itemId: LLN666i5250356j4249 itemId: LLN616732557968356j itemId: LLAy7sxCA9wSYrVLCbr
1. 将字符串中的字母部分转换,构建为666c为flag的fl开头
• 所以使用正则先将字母提取出来,然后进行减法,让i变为c发现减6变成c
• 然后使用merge合并,转成hex发现得到flRP5mBIag2Uyh5m
• 观察发现应该为2个字节换了下一段 flRP5mBI ag2Uyh5m
1. 拼接后flag为:
1. 子协议
IEC 101(任务相关)
IEC 102(电量相关)
IEC 103(保护相关)
IEC 104(101的网络版)
IEC ASDU(基于101/104的应用服务数据单元传输)
1. 主要技巧
筛选`iec60870_asdu`
关注IOA的值
可尝试用type进行分类
1. 过滤协议发现有错误的数据包,并且随便点数据包,发现分组不同说明建立了很多不同的连接
1. 过滤分组为0的数据包,这样得到的为同一个连接的数据包,数据也是连贯的
iec60870_asdu && tcp.stream == 0
1. 然后筛选有IOA Value值的数据
1. 然后再去筛选TypeId: M_ME_TD_1 (34)发现对应的ioa的值,无规则,并且右下角数据包过多
1. 继续筛选除去TypeId: M_ME_TD_1 (34)后的包,发现TypeId: M_ME_TD_1 (9)也有100多数据包,然后除去34和9,之后发现只剩18条数据
(((iec60870_asdu && tcp.stream == 0) && (iec60870_asdu.normval)) && !(iec60870_asdu.typeid == 34)&& !(iec60870_asdu.typeid == 9))
1. 将值提取,base64解码后发现为乱码
Mzhx3ZKtTOTJ0VadnNYdVSnlUUBNQf==
1. 分析发现两个字节组成一个数据,猜测为颠倒数据(两字节一数据有可能为颠倒的)
1. 调换位置获取flag
mZhx3ZKtTOTJ0VadnNYdVSnlUUBNQf== ZmxhZ3tKOTJTV0daNndYSVlnUUNBfQ== flag{J92SWGZ6wXIYgQCA}
主要数据交互的消息类型为PUBLISH
• 筛选mqtt.msgtype == 3
服务端有若干个主题(topic)可供客户端订阅
• 客户端订阅后可以收到来自服务端关于这个主题的消息(message)
• 一个主题可以持续产生消息
首先查看协议占比,大致判断为mqtt的题目
1、筛选mqtt.msgtype == 3的时候有数据
(mqtt) && (mqtt.msgtype == 3)
2、依次尝试复制出明文进行hex转码,发现为无用数据
3、直到发现504B0304的一段数据内容,hex之后为PK的头,504B0304一般为zip文件的头
放入010粘粘hex,然后保存为rar,解压发现文件损坏
4、猜测该rar不完整,然后发现该rar的数据是在f
中的数据包
5、拼凑为flag,依次提取数据包的内容,然后粘贴到010保存为rar,发现需要密码
6、尝试使用数据包中的字符串当作密码,发现成功解压出flag文件
6、发现flag图片损坏
使用其他工具,发现只显示了一半二维码,猜测需要更改高度
使用010更改高度为260
保存打开发现还是不全
7、使用Stegsolve打开 浏览发现Red、Green、Blue 0的时候上方都有数据显示
然后使用数据提取,将RGB为0勾选
然后点击preview
最后save bin保存出png图片,发现为后半段的二维码
拼接扫描二维码得到LSB_is_easy} 最后拼接上半段flag最终得到 flag{21png_LSB_is_easy}
• COTP可以理解为基于TCP的工控TCP
• COTP主要有五种类型:CR Connect Request (0x0e)
CC Connect Confirm (0x0d)
DT Data (0x0f)
UD User Data (0x04)
ED Expedited Data (0x01)
• CR和CC只在建立连接时由双方发送,发起方发送CR,被动方发送CC,后续数据主要走DT
• 因为协议类似于TCP,较为底层,所以没有其他比较有用的协议字段可供解题
题目:找到黑客流量,flag为后90字节的16进制 1、过滤cotp流量,发现第一个流量包没有请求握手流量,反而直接是数据传输
2、过滤掉分组0,查看其他分组cotp && tcp.stream != 0
发现是一个完整的请求
3、然后尝试提取字节16进制,提交flag。最后发现该数据包为黑客流量
31312d31424535312d30584230203b56332e308240001505323b32383882410003000300a20000000072010000
1. S7基于COTP
2. 主要有3种类型(ROSCTR)
• Mode-transition (0)
• Programmer commands (1)
• Block functions (3)
• CPU functions (4)
• Security (5)
• Time functions (7)
• Setup communication (0xf0)
• Read Var (0x04)
• Write Var (0x05)
• 下载
• 上传
• PI-Service (0x28)
• Request download (0x1a)
• Download block (0x1b)
• Download ended (0x1c)
• Start upload (0x1d)
• Upload (0x1e)
• End upload (0x1f)
• Job (1) - Ack_Data (3) / Ack (2)10种功能(Function)
• Userdata (7)6种功能组(Function group)
题目:通过协议分析获取flag 1、查看协议占比发现该题考察点为s7comm,然后通过筛选发现read中data没有flag的痕迹
2、发现在write中data数据为01开头
3、提取hex并转换二进制,发现为f
依次提取write中的data转换为flag
011001100110110001100001011001110111101101100110011011000110000101100111010111110110100101110011010111110110100001100101011100100110010101111101
Command CODE比较多,关注点主要在读写,如:
Memory Area Read (0x0101)
Memory Area Write (0x0102)
Multiple Memory Area Read (0x0104)
Memory Area Transfer (0x0105)
Parameter Area Read (0x0201)
Parameter Area Write (0x0202)
Data Link Table Read (0x0220)
Data Link Table Write (0x0221)
Program Area Read (0x0306)
Program Area Write (0x0307)
打开压缩包发现key
1、打开数据包过滤command。发现全为read,没有write
2、然后再筛选response,发现数据包比较多
3、通过长度排序,然后发现了加密字符串数据
得到U2FsdGVkX1/bWSZYUeFDeonQhK0AUHr9Tm7Ic20PRXxlPvlwG6a4fQ== 4、观察发现开头为U2Fsd 因U2Fsd疑似网站https://www.sojson.com
的特征,并且压缩包里存在key:jnds 因此使用aes算法解密,发现失败,尝试tripledes解密成功,获取flag
基于各类数据传输协议的数据传输功能,实现的数据传输都可以称为隧道。 如:基于TCP的隧道、基于UDP的隧道、基于ICMP的隧道。
1、通过大致翻阅,发现查询了奇怪的域名
2、筛选出所有的流量
(dns) && (dns.resp.name contains ".in-addr.arpa")
3、全选该数据,使用正则提取
然后0x去掉,得到16进制
然后转hex发现有flag痕迹
然后猜测为shellcod,解码发现需改为32位,并且出现多处push
将push数据提取出来 from hex之后为 X9RTM1QTMxkWYs9WYk1SZklmbtcmbplXLuFWdo1iZ0NWdz5WYnt3ZhxmZ 将数据进行反转进行base64转码得到flag:
某行业特有的一些通信协议,比较少见。
题目要求:找到卡车司机的身份信息 下载文件附件t808_info,为交通运输行业标准和流量包
导入流量包发现wireshark筛选不到该t808协议,但t808基于tcp 使用wireshark筛选带有数据的tcp数据包 规则使用长度比0大(tcp.len > 0)
通过查找数据包内容0702发现数据包
发现驾驶员身份信息采集上报的消息ID为0702,找到该数据包
提取hex
7e070240eb010000000001777064121100720120062709485600b48af896b850e7964d543d8af89640646996b850e77f3d85a9985876a4802876a4773e52ab963f621176a46167963f4ea676a4621154c6515c964d56a47957610d76a48fe695cd773e76a496404ea6805e5ba354a48fe652ab85a956c9610d805e980876a4585e8fe676a48ae64ea652ab4ea676a495cd985876a454a44fee95cd85a956a45ba376a4621183e983e976a48fe6805e8ae65a464ea6805e76a4963f85a96240985859827a7a5982598256d176a456d131313031303131393939303530353132313500000cb9e3b6abcaa1bdbbcda8ccfc20300505131182198502039877a67e
提取出姓名的16进制 然后from hex发现乱码。使用magic功能尝试发现得到了类似与佛论禅的编码, 因magic显示不全,所以使用具体的utf-16BE进行解码
然后通过base64解码,发现全是大写的。再使用base32得到flag
工控CTF中常见的逆向分析题型主要围绕工控概念为主,其中出现较多的为工控程序分析、固件分析、无线电中频谱、波形以及编解码分析等题目。
ida打开发现该地址会执行下载操作,访问发现该地址已失效
查看sub_401041发现执行了windows的api操作,打开http连接,发送请求和接收响应,然后写文件。
执行完之后返回,查看是否执行成功,成功的话继续执行下一步操作 否则成功直接退出。
将该http地址改为本机127.0.0.1,构造下载请求后,程序执行shellcode,获取flag
将hex进行修改
将ip改为127.0.0.1 多余部分使用00填充,然后应用更改
更改成功
最后编辑-修补程序-修补程序应用到输入文件
然后本地搭建http服务,并将题目中的sc.jpg放入后运行
获取flag
题目中说APP会进行加密操作,所以打开jadx搜索加密算法关键字 比如:encode、encrypt
发现/sdcard/encrypt.jpg 并且题目里有encrypt.jpg 进去发现了aes_key
查看调用aes_key的具体函数,发现打开了一个文件,然后使用AES_key当作密钥去进行加密
然后将加密后的图片encrypt.jpg放入cyberchef,输入APK里的aes_key MyDifficultPassw 因未发现IV,选择空,mode选择ECB(没有偏移)。输出后,先查看1字节文件内容
发现为base64编码
经过3轮base64解码后,发现文件头为JFIF
然后转为图片,发现手机号
题目为bin文件,使用7zip打开解压该文件,发现为固件包目录
需要寻找后门程序 一般后门会在web、bin、sbin目录, 按修改日期寻找发现tmp目录下有个backdoor文件
导入010发现为ELF格式文件, 将该文件导入ida发现函数特别少,怀疑是加了壳。 然后再导入010发现upx关键字
使用upx脱壳
.\upx.exe -d .\backdoor
再次放入ida后shift+F12查看字符串,发现存在域名的3个地址
查看该域名,并追踪调用的方法
追踪发现commServer函数
继续追踪发现v3=36667 在return处返回连接请求的域名+端口。所以端口为36667
flag{ZWNoby5ieWV0dDx.com:36667}
出题点主要以频谱分析、波形分析和编解码为主
题目给出文件为ppt。 首先使用010打开文件,发现是有规律的16进制
然后尝试使用Audacity打开文件
使用默认配置导入后,发现波形图没有异常。 然后改成频谱图
缩小发现flag
鼠标点左右键,缩小放大,获取全部flag
看起来比较模糊,可以使用频谱图设置更改参数,获取较为清晰的flag
题目给出为mp3文件 使用工具导入音频文件
听出是发电报的声音,分析为莫斯电码。将波形转成0和1
将0替换成. 1替换成-
11100 11 00000 00111 11100 001 101 11000 00001 0000 11000 10000
然后摩斯电码进行转换,得到8M528UK74H76
发现该字符串不对,后分析发现音频结尾的声音在最前面,猜测可能为倒序排列 转换为43H63KD285M2,发现也不对,改成小写字母提交正确
题目为mp3文件,因题目名为隐信道。并且mp3能正常播放。在不影响音频正常播放的前提下,能修改的地方也只有私有位private bit正常为0 将文件拖入010查看,发现私有位private bit存在为1的情况。
将文件私有位进行提取 也就是FRAME中的mpeg_hdr中的private_bit 1、首先观察发现FRAME前面有一段数据,先将该数据删除 (选中会发现文件为115128bytes)
2、将该mp3文件拖入cyberchef删除0到115128bytes
3、删除后发现开头的数据和010对应,都为FRAME的数据。然后to hex转成16进制,提取16进制中private_bit对应的字节
4、观察发现private_bit对应的值在第六个字节中显示
5、然后提取该字节内容,发现可成功提取出0
6、然后进行"应用每一行"
7、将该数据转成2进制,发现flag
1、全局搜索关键文本,如flag 2、打开组态项目后优先查看窗口内容、组态命名、用户名/密码、组态脚本等适合用来放置flag的功能 3、窗口中flag可能会故意被图片或者其他组件挡住,需要注意窗口中所有组件的位置是否正常 4、用户密码通常以星号显示,可以使用各类星号查看器去获取密码
题目给出PCZ文件 打开发现为油气集输首站.PCZ文件,使用力控恢复,发现失败 解压该文件后,利用力控的搜索功能选中文件夹然后选择开发。 打开查看主窗口未发现flag
查看功能处的用户管理,发现admin密码
使用星号查看器读取密码[email protected]
题目为工艺.jfif,发现压缩文件
将解压后的文件放入010,发现BCAF271C的头为疑似为7z文件
载入正常的7z文件,头为377abcaf27
将377A插入,
改成377A
然后即可解压
然后使用SIMATIC WinCC打开PDT后缀的文件 或者载入.mcp后缀文件 选择图形编辑器,发现文本栏有flag
查看下一个图形编辑器,发现flag
1、需要熟悉常用的算数运算、位运算、逻辑运算。 2、了解计算机各类型数据的存储方式,如整数型、实数型、逻辑型。 3、了解类型转换时强制转换和等价转换的区别。 4、稍微了解梯形图中的一些常见元器件的含义,如开关。 5、安装常用的仿真软件,如博图、西门子、autothink、ispsoft等。 算数运算: 加+ADD、减-SUB、乘*MUL、除/DIV、余%MOD 开方SQRT 正弦SIN、余弦COS、正切TAN、余切COT、正割SEC、余割CSC 反正弦ASIN/ARCSIN、反余弦ACOS/ARCSIN、反正切ATAN/ARCTAN、反余切ACOT/ARCCOT、反正割ASEC/ARCSEC、反余割ACSC/ARCCSC 位运算 反~NOT 、 与&AND 、 或|OR 、 异或^XOR 逻辑运算 大于> 、 小于< 、 等于= 、大于等于 >= 、 小于等于<= 、 不等于!=/<>
打开题目,发现为ap16的文件,使用TIA博图打开
打开程序块的main
选择启动仿真、监视并运行
题目中说IN1接口数据为886,所以填写数据到IN1中
然后发现out口输出了数据
发现文件存在Untitled2.hpf,使用autothink打开
然后点击仿真和运行并根据题目将IW2的值输入13600
根据题目要求求出IW4的值,发现IW4乘以3.09=V2
V2=V7减V5 (V5为固定,V7题目给出为61802.06641) 则V2= 61799.99964064 IW4乘以3.09=V2 算出IW4=19999.9998837 约等于20000
该题目为smart后缀文件
已知v2=3 v5=70 v8=-1 需要求出v6和v11的值 首先根据下图计算 v1=10+20=30 v3=v1/v2=30/3=10 v11=v5-v3=70-10=60
v12= v11整数到字节 = 60 = 00111100 v10= v12取反字节 = 11000011 v9= v10字节到整数 = 195-256 = -61 v7= v9-v8 = -61-(-1)= -60 v6= v7/v1 = -60/30 = -2
注: v12= v11整数到字节 = 60 = 00111100
v9= v10字节到整数 = 195-256 = -61
使用ispsoft软件打开
iw2=6 d10=4.65258659424 d30=1.16314665 d40=0.00589931
往期推荐
E
N
D
团队内部平台:潮汐在线指纹识别平台 | 潮听漏洞情报平台 | 潮巡资产管理与威胁监测平台 | 潮汐网络空间资产测绘 | 潮声漏洞检测平台 | 在线免杀平台 | CTF练习平台 | 物联网固件检测平台 | SRC资产监控平台 | ......
星球分享方向:Web安全 | 红蓝对抗 | 移动安全 | 应急响应 | 工控安全 | 物联网安全 | 密码学 | 人工智能 | ctf 等方面的沟通及分享
星球知识wiki:红蓝对抗 | 漏洞武器库 | 远控免杀 | 移动安全 | 物联网安全 | 代码审计 | CTF | 工控安全 | 应急响应 | 人工智能 | 密码学 | CobaltStrike | 安全测试用例 | ......
星球网盘资料:安全法律法规 | 安全认证资料 | 代码审计 | 渗透安全工具 | 工控安全工具 | 移动安全工具 | 物联网安全 | 其它安全文库合辑 | ......
扫码加入一起学习吧~