2023工业信息安全技能大赛—钢铁锦标赛 WriteUp
04.异常的交互流量
tshark -r 8.pcap -Y "modbus.func_code ==03 and ip.dst==172.16.236.128" -T fields -e modbus.regval_uint16 > data.txt
Register 7中的值为0 正常不应该为0
05.easy_vm
ops = [1, 1, 0, 1, 2, 0, 2, 1, 5, 5, 1, 3, 0, 3, 8, 4, 1, 4, 0, 2, 2, 1, 6, 20, 7, 3, 8, 0, 0, 0, 0];
box = 'sundosnapxnsodkshgds'
print(f'''.data
box db '{box}', 0
''')
print('main proc')
ar = [1, 2, 3, 4, 5, 6]
enc = [None] * 14
printa = lambda x: print(' ' + x)
def mov():
ops_ori = [*ops]
op = ops.pop(0)
if op == 2:
printa('lea rax, [box + rcx]')
elif op == 3:
printa('lea rbx, [input + ecx]')
elif op == 4:
printa('mov byte ptr [enc + rcx], rax')
elif op == 1:
val = ops[0]
printa(f'mov rcx, {val}')
else:
printa(ops)
raise "ERROR, mov"
ops.pop(0)
def add():
v1 = ops.pop(0)
v2 = ops.pop(0)
if v1 == 1:
printa(f'lea rax, [rax+{v2}]')
elif v1 == 2:
printa(f'lea rcx, [rcx+{v2}]')
def sub():
t = ops.pop(0)
printa(f'lea rbx, [rbx-{t}]')
def xor():
printa(f'xor rax,rbx')
def jl():
rip = ops.pop(0)
printa('jle __start')
def cmp():
rip = ops.pop(0)
printa(f'cmp {rip},rcx')
def not1():
printa(f'not ax')
def foo():
v2 = 0
op = ops.pop(0)
match op:
case 1:
mov()
case 2:
add()
case 3:
sub()
case 4:
xor()
case 5:
not1()
case 6:
cmp()
case 7:
jl()
case 8:
v2 = 1
case _:
v2 = 1
return v2
while not foo():
pass
print('main endp')
print('end main')
print()
print()
print()
得到
.data
box db 'sundosnapxnsodkshgds', 0
main proc
mov rcx, 0
lea rax, [box + rcx]
lea rax, [rax+5]
not ax
lea rbx, [input + ecx]
lea rbx, [rbx-8]
xor rax,rbx
mov byte ptr [enc + rcx], rax
lea rcx, [rcx+1]
cmp 20,rcx
jle __start
main endp
end main
大概看一下。写个脚本解密
box = b'sundosnapxnsodkshgds'
enc = [0xD9, 0xE1, 0xD5, 0xC9, 0xF8, 0xB8, 0xD5, 0xFD, 0xD3, 0xF2, 0xFD, 0xD0, 0xB6, 0xCF, 0xE4, 0xF6, 0x8B, 0xDD, 0xD3, 0xF2];
l = len(enc)
# enc[i] = ~(box[i] + 5) ^ (input[i] - 8)
for i in range(l):
xff_ = ~(box[i] + 5) & 0xff
print(chr((enc[i] ^ xff_) + 8), end='')
# flag{Galaxy_Easy!VM}
07.reverse_mips
两次输入
BOOL __fastcall rc2(int a1)
{
BOOL result; // $v0
int i; // [sp+1Ch] [+1Ch]
for ( i = 0; ; ++i )
{
result = i < a1;
if ( i >= a1 )
break;
enc1[i] = *((_BYTE *)&Str + i) ^ rc1();
}
return result;
}
// rc4 小改取值。
int rc1()
{
char tmp; // [sp+7h] [+7h]
int i; // [sp+8h] [+8h]
int v3; // [sp+Ch] [+Ch]
int j; // [sp+10h] [+10h]
int x; // [sp+14h] [+14h]
unsigned int y; // [sp+18h] [+18h]
if ( !Gi )
{
for ( i = 0; i < 256; ++i )
SBox[i] = i;
LOBYTE(v3) = key[K];
if ( ++K >= 16 )
K = 0;
for ( j = 0; j < 256; ++j )
{
v3 = (unsigned __int8)(109 * v3 + 57);
tmp = SBox[j];
SBox[j] = SBox[v3];
SBox[v3] = tmp;
}
}
Gi = (Gi + 1) % 256;
x = SBox[Gi];
y = SBox[(unsigned __int8)(Gi + x)];
return (unsigned __int8)(16 * (HIBYTE(x) ^ HIBYTE(y))) | (unsigned __int8)((x ^ y) >> 4);
}
拿到每一轮的rc1()返回值和enc1 进行异或 得到第一部分。
然后第一次输入的值和第二部分 enc2 进行异或得到第二部分。
"""
.text:00400930 # 25: x = SBox[RCDATA];
.text:00400930 lui $v0, 0x4A # 'J'
.text:00400934 lw $v1, Gi
.text:00400938 li $v0, SBox
.text:00400940 addu $v0, $v1, $v0
.text:00400944 lb $v0, 0($v0) # 这里有个坑,有符号数操作赋值, 比如 0xA0 变为 0xFFFFFF00 | 0xA0 = 0xFFFFFFA0, 容易踩坑
.text:00400948 sw $v0, 0x24+x($fp)
"""
def uint(x):
if x > 0x80:
return x | 0xffffff00
return x
def crypt(data, key):
n = 0
box = list(range(256))
v3 = key[n % 16]
n += 1
for i in range(256):
v3 = (109 * v3 + 57) & 0xff
x = v3
box[i], box[x] = box[x], box[i]
Gi = 1
for i in range(16):
x = box[Gi]
y = box[Gi + x]
x = uint(x)
y = uint(y)
v = x ^ y
v = (v << 4 | v >> 4) & 0xff
print(f'0x{v:02x},', end='')
Gi = (Gi + 1) % 256
stdata = ''
key = bytearray([0x79, 0x8B, 0xD8, 0xBA, 0x2C, 0x0E, 0x18, 0xD4, 0xE8, 0xB0, 0x38, 0x0A, 0xC6, 0x95, 0x71, 0xF2])
result = crypt(data=stdata, key=key)
# 0xf0,0xf8,0x50,0x40,0x11,0xa4,0xf8,0x81,0x56,0xe5,0xd0,0x41,0x95,0xc5,0xf8,0xf8
# 不补符号位错误值为 [0xf0, 0x28, 0x50, 0x40, 0x11, 0xa4, 0x78, 0x81, 0x56, 0xe5, 0xd0, 0x41, 0x95, 0xc5, 0xf8, 0xe8] 解出 flag 为 f'ag{J.stEncIt!m 还是能拼出来正确的flag的
e1 = [0xf0, 0xf8, 0x50, 0x40, 0x11, 0xa4, 0xf8, 0x81, 0x56, 0xe5, 0xd0, 0x41, 0x95, 0xc5, 0xf8, 0xf8]
r1 = bytes.fromhex('B782123464EE91B40CD5B72DCCB2B68E')
for a, b in zip(e1, r1):
print(chr(a ^ b), end='')
print()
# GzBtuJi5Z0glYwNv
key1 = b'GzBtuJi5Z0glYwNv'
r2 = bytes.fromhex('211623130E001C462E75090F10036F0B')
for a, b in zip(key1, r2):
print(chr(a ^ b), end='')
# flag{JustEncIt!}
08.ropmaster
"""
input[x] ^= 0x53u;
input[x] += 17;
input[x] = cip[x]
"""
cip = bytes.fromhex('46504345397C7576487B7341418F434678738F774176488F424373428F71467C737B7643487477417C3F')
for i, ch in enumerate(cip):
print(chr((ch - 17) ^ 0x53), end='')
09.simeple_re
box = b'SRzLZlKvlYHJqBqASzSqNgGXTGcKXoDe'
box = bytes.fromhex('0D542D7D7B5A7D656659517E7D42214B687F60694175')
keys = """ 040A223A0E0B063C2A302E06060E04331935291E1A32
23273523111A381E3F031D082B3B28240A0E3C023620
211B2F000F3E2337161F0B12353B3D233E1010202600
271A09250E343A1B2D0F2C3D3313100516373A180B14
11050B001B04380209290D031E210216180C38260135
3610321C390D1C3827030C0D150E15073E361B000F10
1B040B222B2606323B1B070121233D34010C32291813
1C102D36161929311614032833282B371C111F39010E
061A29260C153D061B3C113D360D382E272E09372C3E
3D3023290C0724102912380121160805261C3F23390F
17261D29330902102E130C3D32263A3336192B100A0D
311C1E393503251A091D0C2529151F08042018021C28
30181B16312224183C0D0B033A28162A1D0E323B3425
141539280E2929303F321C2E262D14140A3D31282105
073A1B2232382305292A0538252E1D31302A0721183D
3F10110D281F07221E1C2206022E063710141132000E
6B384C1A00081333362F3B2B04314578290811071908
311F1C3B2308121D2B3412011A083322262E173D0501
1139152E1F0F0901011E3A3F2029350F3A0C0237201F
"""
for key in keys.strip().splitlines():
enc = bytes.fromhex(key)
s = ''
for i, c in enumerate(enc):
values = chr(c ^ box[i])
s += values
print(s)
if s.startswith('flag'):
print(key)
exit(0)
# '6B384C1A00081333362F3B2B04314578290811071908'
"""
Looking for GNU DWARF file at "/usr/lib/debug/.build-id/e9/9d68f49ba574430a41fb8c0e12b9375cac49e8.debug"... no.
8j6VZdXEZvsaus49zrBvWo
Welcome peskyPup8
Checking safebox.....
Flag is : flag{RnVPvjUysd3AwqnX}
"""
key = bytes.fromhex('6B384C1A00081333362F3B2B04314578290811071908')
print('key' + key.decode())
box = b'SRzLZlKvlYHJqBqASzSqNgGXTGcKXoDe'
print(box)
for a, b in zip(key, box):
print(chr(a ^ b), end='')
赛题三
分别导出各类数据, 4693 返回数据长度不对
10.控制程序修复
找到备注“控制炼钢工艺模拟量”
11.工业现场的应急处置
进程中 shell.exe 较为可疑, 用户名中 test\(可疑, 尝试组合后去掉\)提交成
功
flag{"shell.exe"/"test"}