当前位置:   article > 正文

2022首届数字空间安全攻防大赛RE题wp_第一届数据安全大赛 wp

第一届数据安全大赛 wp

比赛是周五,上班时间没怎么打,队伍没进线下,太惨了

RE:catchme

APK里调用原生so在这里插入图片描述

核心函数是sub_8a2c和sub_a740,分别是AES加密和base64encode,密钥是a76572Rrrrs变量,解密后得到key是wonderfulday!!!
然后得到flag:
在这里插入图片描述

注意提交时需要替换成中文逗号

RE:flutter

上网找了很久的flutter逆向的工具,都不管用,然后看做出来的人还不少,想着是不是有捷径?
果然发现了出题人留的捷径:my_plugin.dll里有核心算法
在这里插入图片描述
这里的输入已经是30位flag打乱顺序后的base64编码后的字符串了
先把输入逆序,再扩展成HEX双字节,变成80字节的数据,然后进行变种的TEA加密,最后和固定串比较。
采用动态调试得到比较值4C 75 15 5C E7 81 D7 D1 73 F1 1B 50 22 B2 4D CB F5 61 5D 21 E7 9E CA 3F C7 B5 76 7C B9 8C DD C7 FA 23 0D 99 D3 1A AB 0B 32 C9 12 8E F2 BA 07 D3 23 D1 2D E5 2C 8F B6 FB E3 53 D8 BD 4E 1E 2E 89 FA 66 DD 39 65 EC FE 87 60 5E 7C 30 00 6C 0C 34
写出exp:

import struct
import base64

def decrypt(v, k):
    v0 = v[0]
    v1 = v[1]
    delta = 0x79B99E37
    x = delta*32&0xffffffff
    k0 = k[0]
    k1 = k[1]
    k2 = k[2]
    k3 = k[3]
    for i in range(32):
        v1 += ((v0 << 4) + k2) ^ (v0 + x) ^ ((v0 >> 5) + k3)
        v1 = v1 & 0xFFFFFFFF
        v0 += ((v1 << 4) + k0) ^ (v1 + x) ^ ((v1 >> 5) + k1)
        v0 = v0 & 0xFFFFFFFF
        x -= delta
        x = x & 0xFFFFFFFF
    v[0] = v0
    v[1] = v1
    return v
if __name__ == '__main__':
    enc=bytes.fromhex('4c75155ce781d7d173f11b5022b24dcbf5615d21e79eca3fc7b5767cb98cddc7fa230d99d31aab0b32c9128ef2ba07d323d12de52c8fb6fbe353d8bd4e1e2e89fa66dd3965ecfe87605e7c30006c0c34')
    encrypted=[]
    for i in range(len(enc)//4):
        encrypted.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
    key = [0xBABEC0FE, 0xDEADBEEF, 0xFACEB00C, 0xDEADC0DE]
    hexflag=''
    for i in range(len(encrypted)//2):
        decrypted = decrypt(encrypted[i*2:i*2+2], key)
        x=struct.pack('<2I',decrypted[0],decrypted[1]).hex()
        hexflag+=x[0]+x[3]+x[4]+x[7]+x[8]+x[11]+x[12]+x[15]
    x=base64.b64decode(bytes.fromhex(hexflag).decode()[::-1]).decode()
    pad='abcdefghijklmnopqrstuvwxyz1234'
    corr='a4b3c2d1ezfygxhwivjuktlsmrnqop'
    for i in range(len(pad)):
        print(x[corr.index(pad[i])],end='')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

flag为:
flag{Emp0wer_F1utter_w1th_C!!}

RE:nothing

0解题,可想而知比较难。
这题比赛的时候没时间做,不过幸亏没看,否则多给1倍的时间也不够用。
在这里插入图片描述
程序看起来没有判断flag的逻辑,其实程序利用了gcc_except_table做了异常处理,在gcc异常处理的过程中会调用.eh_frame的DWARF调试信息进行寄存器计算,输入输出寄存器均是R12-R15可以动态调试,可以在gcc库里设置断点,打印寄存器的计算过程。我的操作就是在输入字符串以后设置断点,到达以后再设置一个断点:libgcc_s.so.1:_Unwind_GetTextRelBase+1123,这里就是DWARF虚拟操作码的处理部分,如下图: 在这里插入图片描述
多跑几遍就可以了解大致的逻辑,可以根据需要继续在每种操作上设置其他的断点进行记录
在这里插入图片描述
然后经过大量的IDA调试和信息输出,通过人肉得到大致逻辑(过程很痛苦,浪费了一个周末的时间):
R12的入参是形如050703FB04020100070603的8字节数值,而返回R12是偏移量,比如1,如果上次R12输入的是FB04020100070603,则下次R12的值就是03FB040201000706,就是右移的字节数
R13是一个计数器,相当于for 循环的i,每次增加0x5477d63e117fac13,从0开始
R14、R15初始的时候分别是输入flag前半部分和后半部分,再输出加密后的R14和R15,实际加密处理是根据R13数值得到的一个值进行异或。
由于是简单的异或,所以key可以根据输入和输出计算出来。
最后是EXP:

import sys
k3=[0x63be9781a14ac750,0xb8366dbda1abfa4b,0xcae43fee60afd26,0x61261a3a6269c000,0xb59df07bafc8f32d,0xa15c6b4a32fe9d6,0x5e8d9cf46488c6d3,0xb3057331e5e993ef,0x77d49729c4920fa,0x5bf51faebcabd5e1,0xb06cf5ef1b0a8acd,0x4e4cc28676a2fda,0x595ca268eac63417,0xadd478a5ae27810c,0x24c4ee629873e3e,0x56c42522eae53b41,0xab3bfb60674488a4,0xffb3d1a3dba44d9f,0x542ba7df381c2293,0xa8a37e1e587d9674,0xfd1b5459f9dd5d79,0x51932a99693f1861,0xa60b00d42a9e9704]
index=0x050703FB04020100070603

x,y=0xfcbf957dff20a9ca,0xc9867e171b17b6bd
#x,y=0x7cd65ad3bc8e919a,0xdc5caf27c9896237
k1,k2=0xc34c7a039b8fd712,0x25abe38011b4b716
x=x^k1
y=y^k2
for j in range(22,-1,-1):
    #print(hex(x),hex(y))
    x,y=y,x
    x=x^k3[j]
print(hex(x^k1),hex(y^k2))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

验证结果在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/445507
推荐阅读
相关标签
  

闽ICP备14008679号