<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    picture-lock

    安卓題,和加密勒索軟件的套路有點像,輸入一個文件,輸出其加密后的結果。目標是將某個加密后的文件解密出來,flag 就在里面。

    java 層基本沒東西,算一下簽名的md5,將原本文件、加密后文件、md5帶入 native。

    沒有init_array,沒有JNI_OnLoad,直接看JNI 方法。

    一進來先初始化了 AES 的 SBox,比較騷的地方在于他初始化了2組 AES 的 SBox,也就是相當于有2個 AES_Cipher,使用的 key 不同,這部分其實我看不大懂,只是調試時候發現的。

        if ( new_fd )
        {
          old_file_buffer = (char *)malloc(0x100u);
          newFile = (char *)old_fd;
          bbb_1024 = malloc(0x100u);
          for ( i = 0; ; ++i )
          {
            v26 = md5String[i & 0x1F];
            nextChar = fread(old_file_buffer, 1u, md5String[i & 0x1F], (FILE *)newFile);
            dataLen = nextChar;
            if ( !nextChar )
              goto done;
            if ( nextChar <= 0xF )
            {
              v29 = &old_file_buffer[nextChar];
              if ( 16 != (dataLen & 0xF) )
              {
                _aeabi_memset(v29, 16 - (dataLen & 0xF), 16 - (dataLen & 0xF));
                v29 = &old_file_buffer[16 - (dataLen & 0xF) + dataLen];
              }
              newFile = (char *)old_fd;
              dataLen = 16;
              *v29 = 0;
            }

    然后開始讀文件,每次讀取 md5[i&0x1F]個字節,如果長度小于16,就 PKCS5 到16字節。

            left_or_right = (int **)&g_buf_0x180_p0x30;
            if ( !(v26 & 1) )
              left_or_right = &g_buf_0x180;
            if ( dataLen >= 0x11 )
            {
              kk = 16;
              p_md5String_1 = md5String;
              do
              {
                bbb_1024[kk] = old_file_buffer[kk] ^ p_md5String_1[kk % 32];
                ++kk;
              }
              while ( kk < dataLen );
            }
            if ( fwrite(bbb_1024, 1u, dataLen, new_fd) != dataLen )
              break;

    16字節以后的, plain[index]逐位 xor上 md5[index] 。之后將這些 byte 寫到加密后的文件里。

    寫一點 testcase 驗證一下我們的猜想,發現是正確的,下文是解密的 python 腳本。

    from Crypto.Cipher import AES
    
    md5 = "f8c49056e4ccf9a11e090eaf471f418d"
    odd_key = "1e090eaf471f418d"
    even_key = "f8c49056e4ccf9a1"
    
    odd_cipher = AES.new(odd_key, AES.MODE_ECB)
    even_cipher = AES.new(even_key, AES.MODE_ECB)
    
    with open('/Users/leadroyal/CTF/2018/qwb/assets/flag.jpg.lock') as f:
        data = f.read()
    
    offset = 0
    i = 0
    output = ""
    count = 0
    while True:
        count += 1
        current = data[offset:offset + ord(md5[i])]
        if current == '':
            break
        offset += ord(md5[i])
        if ord(md5[i]) % 2 == 0:
            left = even_cipher.decrypt(current[0:16])
            output += left
        else:
            left = odd_cipher.decrypt(current[0:16])
            output += left
        for j in range(16, len(current)):
            output += chr(ord(current[j]) ^ ord(md5[j % 32]))
        i += 1
        i %= 32
    
    
    print len(data)
    print len(output)
    
    # print output.encode('hex')
    with open('/tmp/flag.jpg', 'wb') as fd:
        fd.write(output)

    本文章首發在 網安wangan.com 網站上。

    上一篇 下一篇
    討論數量: 0
    只看當前版本


    暫無話題~
    亚洲 欧美 自拍 唯美 另类