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"}

posted @ 2023-10-30 18:02  wgf4242  阅读(141)  评论(0编辑  收藏  举报