第一次玩工控…
.NET开发的软件,直接放dnSpy
,题目给了hint:分析Modbus协议,找出触发flag的特殊事件
粗略看了下,知道这是一个客户端,所以需要整一个服务端来交互,找了个测试工具
https://github.com/study4coder/HslCommunicationDemo
开了服务端,就可以用WireShark抓包了,然而这并不是流量分析题,回到re上
下面找flag触发点
dnSpy反编译的代码并不是太好,换ILSpy
逻辑很清楚,只要combined数组(大小为9)元素都不为NULL或空,就能触发flag事件。然而并不知道text
是什么
用dnSpy动态调试下,可以看到text其实是每个**AnalogValueDisplay**
控件的属性,并且有上下限
到这里我就没了思路…算是半吊子的工控逆向探索。到比赛结束这题都还是0,等官方出WP再补上吧..
2021-05-24
等了好久,还是没有官方的WP出来,也许是我太天真了把… 只好自己继续冲了。
花了近一天时间(中途上课去了),终于找到了规律,花了大半个小时爆出了flag….(题是真的….)
讲一下规律把,之前以为他是0.0001一点点加上去的,想了想不可能,时间复杂度算下来,就算是超算也算不出来。
于是再次上dnSpy动态调试了一番,看到调用堆栈,瞬间找到了突破点
反复分析一下AdvancedHMIControls.dll!AdvancedHMIControls.SubscriptionHandler.SubscribedDataReturned
就能发现它的规律:0.00305和0.0153交替出现,而且分别对应控件的PLCAddress
一番调试过后,总结出以下规律
这里需要注意的是,num就是PLC中的寄存器的值,而且是乘法,所以需要取到范围内能够被Step整除的最小值
如AnalogValueDisplay3:Math.Ceil(52.8 / 0.00305) * 0.00305
即 52.8016
如此,时间复杂度大幅度降低,可以考虑爆破了
但是,用什么语言实现是一个头疼的问题,试了试使用Python爆破,慢的离谱….
写了份Go来爆破。事实证明,Go真香(花的时间依旧在40分钟左右,CPU环境:Intel i5 -10200H)
挂上代码(tips:强迫症,挂上了自己写的控制台美化模块,可能会造成性能损失,换成普通的fmt速度应该还能更快)
Go接触的时间不多,可能会有效率更高的方法,或是代码存在缺陷或BUG,如果您有什么更好的方式或意见,欢迎师傅们和我交流。
最后挂个爆出来的图?
/
/
AdvancedHMIControls.AnalogValueDisplay
using System;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
private void UpdateText()
{
string text
=
"";
string text2
=
"";
double result;
if
(m_ShowValue)
{
text
=
m_Value;
if
(!string.IsNullOrEmpty(m_NumericFormat))
{
if
(double.TryParse(Value, out result))
{
try
{
text
=
result.ToString(m_NumericFormat);
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
Exception ex2
=
ex;
text
=
"Check Numeric Format"
;
ProjectData.ClearProjectError();
}
}
}
else
{
text
=
Value;
}
}
if
(!string.IsNullOrEmpty(m_Prefix))
{
text
=
m_Prefix
+
text;
}
if
(!string.IsNullOrEmpty(m_Suffix))
{
text
+
=
m_Suffix;
}
base.Text
=
text;
if
(double.TryParse(Value, out result))
{
if
(result > m_ValueLimitUpper)
{
base.ForeColor
=
m_ForeColorOverLimit;
return
;
}
if
(result < m_ValueLimitLower)
{
base.ForeColor
=
m_ForeColorUnderLimit;
return
;
}
base.ForeColor
=
m_ForeColorInLimits;
}
if
(PLCAddressValue !
=
null &&
int
.TryParse(PLCAddressValue.PLCAddress, out var result2))
{
if
((result2
=
=
41049
) & (Strings.
Len
(text) <
30
))
{
combined[
0
]
=
text;
}
if
(result2
=
=
41048
)
{
combined[
1
]
=
text;
}
if
(result2
=
=
41047
)
{
combined[
2
]
=
text;
}
if
(result2
=
=
41050
)
{
combined[
3
]
=
text;
}
if
(result2
=
=
41053
)
{
combined[
4
]
=
text;
}
if
(result2
=
=
41054
)
{
combined[
5
]
=
text;
}
if
(result2
=
=
41052
)
{
combined[
6
]
=
text;
}
if
(result2
=
=
41051
)
{
combined[
7
]
=
text;
}
}
int
num
=
0
;
int
num2
=
0
;
do
{
if
(string.IsNullOrEmpty(combined[num2]))
{
num
=
1
;
break
;
}
num2
=
checked(num2
+
1
);
}
while
(num2 <
=
7
);
if
(num
=
=
0
)
{
text2
=
GetHash(string.Join(
","
, combined));
Console.WriteLine(
"Booooooooooooooooom!"
);
if
(Operators.CompareString(text2.Substring(
0
,
10
),
"F0B278CCB9"
, TextCompare: false)
=
=
0
)
{
Console.WriteLine(
"CISCN{"
+
text2
+
"}"
);
}
}
}
/
/
AdvancedHMIControls.AnalogValueDisplay
using System;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
private void UpdateText()
{
string text
=
"";
string text2
=
"";
double result;
if
(m_ShowValue)
{
text
=
m_Value;
if
(!string.IsNullOrEmpty(m_NumericFormat))
{
if
(double.TryParse(Value, out result))
{
try
{
text
=
result.ToString(m_NumericFormat);
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
Exception ex2
=
ex;
text
=
"Check Numeric Format"
;
ProjectData.ClearProjectError();
}
}
}
else
{
text
=
Value;
}
}
if
(!string.IsNullOrEmpty(m_Prefix))
{
text
=
m_Prefix
+
text;
}
if
(!string.IsNullOrEmpty(m_Suffix))
{
text
+
=
m_Suffix;
}
base.Text
=
text;
if
(double.TryParse(Value, out result))
{
if
(result > m_ValueLimitUpper)
{
base.ForeColor
=
m_ForeColorOverLimit;
return
;
}
if
(result < m_ValueLimitLower)
{
base.ForeColor
=
m_ForeColorUnderLimit;
return
;
}
base.ForeColor
=
m_ForeColorInLimits;
}
if
(PLCAddressValue !
=
null &&
int
.TryParse(PLCAddressValue.PLCAddress, out var result2))
{
if
((result2
=
=
41049
) & (Strings.
Len
(text) <
30
))
{
combined[
0
]
=
text;
}
if
(result2
=
=
41048
)
{
combined[
1
]
=
text;
}
if
(result2
=
=
41047
)
{
combined[
2
]
=
text;
}
if
(result2
=
=
41050
)
{
combined[
3
]
=
text;
}
if
(result2
=
=
41053
)
{
combined[
4
]
=
text;
}
if
(result2
=
=
41054
)
{
combined[
5
]
=
text;
}
if
(result2
=
=
41052
)
{
combined[
6
]
=
text;
}
if
(result2
=
=
41051
)
{
combined[
7
]
=
text;
}
}
int
num
=
0
;
int
num2
=
0
;
do
{
if
(string.IsNullOrEmpty(combined[num2]))
{
num
=
1
;
break
;
}
num2
=
checked(num2
+
1
);
}
while
(num2 <
=
7
);
if
(num
=
=
0
)
{
text2
=
GetHash(string.Join(
","
, combined));
Console.WriteLine(
"Booooooooooooooooom!"
);
if
(Operators.CompareString(text2.Substring(
0
,
10
),
"F0B278CCB9"
, TextCompare: false)
=
=
0
)
{
Console.WriteLine(
"CISCN{"
+
text2
+
"}"
);
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)