吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7088|回复: 36
收起左侧

[CTF] 2021NCTF RE_WP

  [复制链接]
zsky 发表于 2021-11-29 15:01
本帖最后由 zsky 于 2021-11-29 15:20 编辑

NCTF2021_RE_WP

Hello せかい

记事本都能做的题.IDA打开直接看到flag

image-20211128220631446.png

flag为 NCTF{We1come_2_Reverse_Engineering}

Shadowbringer

base64换了2次表,调试起来找到表,逆回去即可

image-20211128223954505.png

image-20211129131911977.png

image-20211129131918276.png

写脚本解密

import base64

flag = "U>F2UsQXN`5sXMELT=:7M_2<X]^1ThaWF0=KM?9IUhAsTM5:T==_Ns&<Vhb!"
std_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
my_table = '#$%&\x27()*+,-.s0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[h]^_`ab'
my_table2 = 'ba`_^]h[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210s.-,+*)(\x27&%$#'

flag = flag.translate(str.maketrans(my_table2, std_table))
flag = flag.replace("!", '=').encode() # "6G074JP+s)WV:Z+T<&(Q18`Ks)WV:Y4hs9[h:YCS?&0`"
flag = base64.b64decode(flag).decode()
flag = flag.translate(str.maketrans(my_table, std_table))
print(base64.b64decode(flag))

# NCTF{H0m3_r1d1n9_h0m3_dy1n9_h0p3}

flag 为 NCTF{H0m3_r1d1n9_h0m3_dy1n9_h0p3}

鲨鲨的秘密

这个题跟西湖论剑那个第一个RE题好像

image-20211128221354110.png

loc_404E3B为执行的指令,因为每次就33条汇编,也不长,直接调试把第一轮所有的汇编拿出来分析

mov     ds:dword_404E50, 0FFFFFFFFh                                        # dword_404E50 = -1
mov     ecx, ds:I
mov     dl, [ecx+4049F8h]                                                   # flag[0]
mov     byte ptr ds:dword_404E4C, dl                                
movzx   eax, byte ptr ds:dword_404E4C
xor     eax, ds:dword_404E50                                                  dword_404E4C = (flag[0] ^ 404E50 ) & 0xFF
mov     byte ptr ds:dword_404E4C, al
movzx   ecx, byte ptr ds:dword_404E4C
and     ecx, 0FFh                                                                        dword_404E50 >>= 8
mov     byte ptr ds:dword_404E4C, cl
mov     edx, ds:dword_404E50                                                dword_404E50 ^= dword_404A38[dword_404E4C * 4]
shr     edx, 8
mov     ds:dword_404E50, edx
movzx   eax, byte ptr ds:dword_404E4C
mov     ecx, ds:dword_404E50
xor     ecx, ds:dword_404A38[eax*4]
mov     ds:dword_404E50, ecx

mov     edx, ds:I
mov     al, [edx+4049F9h]                                                # flag[1]
mov     byte ptr ds:dword_404E4C, al
movzx   ecx, byte ptr ds:dword_404E4C
xor     ecx, ds:dword_404E50                                        404E4C = flag[1] ^ 404E50
mov     byte ptr ds:dword_404E4C, cl
mov     edx, ds:dword_404E50        
shr     edx, 8                                                                        dword_404E50 >>= 8
mov     ds:dword_404E50, edx
movzx   eax, byte ptr ds:dword_404E4C
mov     ecx, ds:dword_404E50
xor     ecx, ds:dword_404A38[eax*4]                                dword_404E50 ^= dword_404A38[dword_404E4C * 4]
mov     ds:dword_404E50, ecx
mov     edx, ds:dword_404E50
xor     edx, 0FFFFFFFFh
mov     ds:dword_404E50, edx        

分析完毕,把程序中加密后的flag提取出来直接爆破

#include <stdio.h>
#include <windows.h>

unsigned char byte_404A38[] =
{
  0x00, 0x00, 0x00, 0x00, 0x96, 0x30, 0x07, 0x77, 0x2C, 0x61,
  0x0E, 0xEE, 0xBA, 0x51, 0x09, 0x99, 0x19, 0xC4, 0x6D, 0x07,
  0x8F, 0xF4, 0x6A, 0x70, 0x35, 0xA5, 0x63, 0xE9, 0xA3, 0x95,
  0x64, 0x9E, 0x32, 0x88, 0xDB, 0x0E, 0xA4, 0xB8, 0xDC, 0x79,
  0x1E, 0xE9, 0xD5, 0xE0, 0x88, 0xD9, 0xD2, 0x97, 0x2B, 0x4C,
  0xB6, 0x09, 0xBD, 0x7C, 0xB1, 0x7E, 0x07, 0x2D, 0xB8, 0xE7,
  0x91, 0x1D, 0xBF, 0x90, 0x64, 0x10, 0xB7, 0x1D, 0xF2, 0x20,
  0xB0, 0x6A, 0x48, 0x71, 0xB9, 0xF3, 0xDE, 0x41, 0xBE, 0x84,
  0x7D, 0xD4, 0xDA, 0x1A, 0xEB, 0xE4, 0xDD, 0x6D, 0x51, 0xB5,
  0xD4, 0xF4, 0xC7, 0x85, 0xD3, 0x83, 0x56, 0x98, 0x6C, 0x13,
  0xC0, 0xA8, 0x6B, 0x64, 0x7A, 0xF9, 0x62, 0xFD, 0xEC, 0xC9,
  0x65, 0x8A, 0x4F, 0x5C, 0x01, 0x14, 0xD9, 0x6C, 0x06, 0x63,
  0x63, 0x3D, 0x0F, 0xFA, 0xF5, 0x0D, 0x08, 0x8D, 0xC8, 0x20,
  0x6E, 0x3B, 0x5E, 0x10, 0x69, 0x4C, 0xE4, 0x41, 0x60, 0xD5,
  0x72, 0x71, 0x67, 0xA2, 0xD1, 0xE4, 0x03, 0x3C, 0x47, 0xD4,
  0x04, 0x4B, 0xFD, 0x85, 0x0D, 0xD2, 0x6B, 0xB5, 0x0A, 0xA5,
  0xFA, 0xA8, 0xB5, 0x35, 0x6C, 0x98, 0xB2, 0x42, 0xD6, 0xC9,
  0xBB, 0xDB, 0x40, 0xF9, 0xBC, 0xAC, 0xE3, 0x6C, 0xD8, 0x32,
  0x75, 0x5C, 0xDF, 0x45, 0xCF, 0x0D, 0xD6, 0xDC, 0x59, 0x3D,
  0xD1, 0xAB, 0xAC, 0x30, 0xD9, 0x26, 0x3A, 0x00, 0xDE, 0x51,
  0x80, 0x51, 0xD7, 0xC8, 0x16, 0x61, 0xD0, 0xBF, 0xB5, 0xF4,
  0xB4, 0x21, 0x23, 0xC4, 0xB3, 0x56, 0x99, 0x95, 0xBA, 0xCF,
  0x0F, 0xA5, 0xBD, 0xB8, 0x9E, 0xB8, 0x02, 0x28, 0x08, 0x88,
  0x05, 0x5F, 0xB2, 0xD9, 0x0C, 0xC6, 0x24, 0xE9, 0x0B, 0xB1,
  0x87, 0x7C, 0x6F, 0x2F, 0x11, 0x4C, 0x68, 0x58, 0xAB, 0x1D,
  0x61, 0xC1, 0x3D, 0x2D, 0x66, 0xB6, 0x90, 0x41, 0xDC, 0x76,
  0x06, 0x71, 0xDB, 0x01, 0xBC, 0x20, 0xD2, 0x98, 0x2A, 0x10,
  0xD5, 0xEF, 0x89, 0x85, 0xB1, 0x71, 0x1F, 0xB5, 0xB6, 0x06,
  0xA5, 0xE4, 0xBF, 0x9F, 0x33, 0xD4, 0xB8, 0xE8, 0xA2, 0xC9,
  0x07, 0x78, 0x34, 0xF9, 0x00, 0x0F, 0x8E, 0xA8, 0x09, 0x96,
  0x18, 0x98, 0x0E, 0xE1, 0xBB, 0x0D, 0x6A, 0x7F, 0x2D, 0x3D,
  0x6D, 0x08, 0x97, 0x6C, 0x64, 0x91, 0x01, 0x5C, 0x63, 0xE6,
  0xF4, 0x51, 0x6B, 0x6B, 0x62, 0x61, 0x6C, 0x1C, 0xD8, 0x30,
  0x65, 0x85, 0x4E, 0x00, 0x62, 0xF2, 0xED, 0x95, 0x06, 0x6C,
  0x7B, 0xA5, 0x01, 0x1B, 0xC1, 0xF4, 0x08, 0x82, 0x57, 0xC4,
  0x0F, 0xF5, 0xC6, 0xD9, 0xB0, 0x65, 0x50, 0xE9, 0xB7, 0x12,
  0xEA, 0xB8, 0xBE, 0x8B, 0x7C, 0x88, 0xB9, 0xFC, 0xDF, 0x1D,
  0xDD, 0x62, 0x49, 0x2D, 0xDA, 0x15, 0xF3, 0x7C, 0xD3, 0x8C,
  0x65, 0x4C, 0xD4, 0xFB, 0x58, 0x61, 0xB2, 0x4D, 0xCE, 0x51,
  0xB5, 0x3A, 0x74, 0x00, 0xBC, 0xA3, 0xE2, 0x30, 0xBB, 0xD4,
  0x41, 0xA5, 0xDF, 0x4A, 0xD7, 0x95, 0xD8, 0x3D, 0x6D, 0xC4,
  0xD1, 0xA4, 0xFB, 0xF4, 0xD6, 0xD3, 0x6A, 0xE9, 0x69, 0x43,
  0xFC, 0xD9, 0x6E, 0x34, 0x46, 0x88, 0x67, 0xAD, 0xD0, 0xB8,
  0x60, 0xDA, 0x73, 0x2D, 0x04, 0x44, 0xE5, 0x1D, 0x03, 0x33,
  0x5F, 0x4C, 0x0A, 0xAA, 0xC9, 0x7C, 0x0D, 0xDD, 0x3C, 0x71,
  0x05, 0x50, 0xAA, 0x41, 0x02, 0x27, 0x10, 0x10, 0x0B, 0xBE,
  0x86, 0x20, 0x0C, 0xC9, 0x25, 0xB5, 0x68, 0x57, 0xB3, 0x85,
  0x6F, 0x20, 0x09, 0xD4, 0x66, 0xB9, 0x9F, 0xE4, 0x61, 0xCE,
  0x0E, 0xF9, 0xDE, 0x5E, 0x98, 0xC9, 0xD9, 0x29, 0x22, 0x98,
  0xD0, 0xB0, 0xB4, 0xA8, 0xD7, 0xC7, 0x17, 0x3D, 0xB3, 0x59,
  0x81, 0x0D, 0xB4, 0x2E, 0x3B, 0x5C, 0xBD, 0xB7, 0xAD, 0x6C,
  0xBA, 0xC0, 0x20, 0x83, 0xB8, 0xED, 0xB6, 0xB3, 0xBF, 0x9A,
  0x0C, 0xE2, 0xB6, 0x03, 0x9A, 0xD2, 0xB1, 0x74, 0x39, 0x47,
  0xD5, 0xEA, 0xAF, 0x77, 0xD2, 0x9D, 0x15, 0x26, 0xDB, 0x04,
  0x83, 0x16, 0xDC, 0x73, 0x12, 0x0B, 0x63, 0xE3, 0x84, 0x3B,
  0x64, 0x94, 0x3E, 0x6A, 0x6D, 0x0D, 0xA8, 0x5A, 0x6A, 0x7A,
  0x0B, 0xCF, 0x0E, 0xE4, 0x9D, 0xFF, 0x09, 0x93, 0x27, 0xAE,
  0x00, 0x0A, 0xB1, 0x9E, 0x07, 0x7D, 0x44, 0x93, 0x0F, 0xF0,
  0xD2, 0xA3, 0x08, 0x87, 0x68, 0xF2, 0x01, 0x1E, 0xFE, 0xC2,
  0x06, 0x69, 0x5D, 0x57, 0x62, 0xF7, 0xCB, 0x67, 0x65, 0x80,
  0x71, 0x36, 0x6C, 0x19, 0xE7, 0x06, 0x6B, 0x6E, 0x76, 0x1B,
  0xD4, 0xFE, 0xE0, 0x2B, 0xD3, 0x89, 0x5A, 0x7A, 0xDA, 0x10,
  0xCC, 0x4A, 0xDD, 0x67, 0x6F, 0xDF, 0xB9, 0xF9, 0xF9, 0xEF,
  0xBE, 0x8E, 0x43, 0xBE, 0xB7, 0x17, 0xD5, 0x8E, 0xB0, 0x60,
  0xE8, 0xA3, 0xD6, 0xD6, 0x7E, 0x93, 0xD1, 0xA1, 0xC4, 0xC2,
  0xD8, 0x38, 0x52, 0xF2, 0xDF, 0x4F, 0xF1, 0x67, 0xBB, 0xD1,
  0x67, 0x57, 0xBC, 0xA6, 0xDD, 0x06, 0xB5, 0x3F, 0x4B, 0x36,
  0xB2, 0x48, 0xDA, 0x2B, 0x0D, 0xD8, 0x4C, 0x1B, 0x0A, 0xAF,
  0xF6, 0x4A, 0x03, 0x36, 0x60, 0x7A, 0x04, 0x41, 0xC3, 0xEF,
  0x60, 0xDF, 0x55, 0xDF, 0x67, 0xA8, 0xEF, 0x8E, 0x6E, 0x31,
  0x79, 0xBE, 0x69, 0x46, 0x8C, 0xB3, 0x61, 0xCB, 0x1A, 0x83,
  0x66, 0xBC, 0xA0, 0xD2, 0x6F, 0x25, 0x36, 0xE2, 0x68, 0x52,
  0x95, 0x77, 0x0C, 0xCC, 0x03, 0x47, 0x0B, 0xBB, 0xB9, 0x16,
  0x02, 0x22, 0x2F, 0x26, 0x05, 0x55, 0xBE, 0x3B, 0xBA, 0xC5,
  0x28, 0x0B, 0xBD, 0xB2, 0x92, 0x5A, 0xB4, 0x2B, 0x04, 0x6A,
  0xB3, 0x5C, 0xA7, 0xFF, 0xD7, 0xC2, 0x31, 0xCF, 0xD0, 0xB5,
  0x8B, 0x9E, 0xD9, 0x2C, 0x1D, 0xAE, 0xDE, 0x5B, 0xB0, 0xC2,
  0x64, 0x9B, 0x26, 0xF2, 0x63, 0xEC, 0x9C, 0xA3, 0x6A, 0x75,
  0x0A, 0x93, 0x6D, 0x02, 0xA9, 0x06, 0x09, 0x9C, 0x3F, 0x36,
  0x0E, 0xEB, 0x85, 0x67, 0x07, 0x72, 0x13, 0x57, 0x00, 0x05,
  0x82, 0x4A, 0xBF, 0x95, 0x14, 0x7A, 0xB8, 0xE2, 0xAE, 0x2B,
  0xB1, 0x7B, 0x38, 0x1B, 0xB6, 0x0C, 0x9B, 0x8E, 0xD2, 0x92,
  0x0D, 0xBE, 0xD5, 0xE5, 0xB7, 0xEF, 0xDC, 0x7C, 0x21, 0xDF,
  0xDB, 0x0B, 0xD4, 0xD2, 0xD3, 0x86, 0x42, 0xE2, 0xD4, 0xF1,
  0xF8, 0xB3, 0xDD, 0x68, 0x6E, 0x83, 0xDA, 0x1F, 0xCD, 0x16,
  0xBE, 0x81, 0x5B, 0x26, 0xB9, 0xF6, 0xE1, 0x77, 0xB0, 0x6F,
  0x77, 0x47, 0xB7, 0x18, 0xE6, 0x5A, 0x08, 0x88, 0x70, 0x6A,
  0x0F, 0xFF, 0xCA, 0x3B, 0x06, 0x66, 0x5C, 0x0B, 0x01, 0x11,
  0xFF, 0x9E, 0x65, 0x8F, 0x69, 0xAE, 0x62, 0xF8, 0xD3, 0xFF,
  0x6B, 0x61, 0x45, 0xCF, 0x6C, 0x16, 0x78, 0xE2, 0x0A, 0xA0,
  0xEE, 0xD2, 0x0D, 0xD7, 0x54, 0x83, 0x04, 0x4E, 0xC2, 0xB3,
  0x03, 0x39, 0x61, 0x26, 0x67, 0xA7, 0xF7, 0x16, 0x60, 0xD0,
  0x4D, 0x47, 0x69, 0x49, 0xDB, 0x77, 0x6E, 0x3E, 0x4A, 0x6A,
  0xD1, 0xAE, 0xDC, 0x5A, 0xD6, 0xD9, 0x66, 0x0B, 0xDF, 0x40,
  0xF0, 0x3B, 0xD8, 0x37, 0x53, 0xAE, 0xBC, 0xA9, 0xC5, 0x9E,
  0xBB, 0xDE, 0x7F, 0xCF, 0xB2, 0x47, 0xE9, 0xFF, 0xB5, 0x30,
  0x1C, 0xF2, 0xBD, 0xBD, 0x8A, 0xC2, 0xBA, 0xCA, 0x30, 0x93,
  0xB3, 0x53, 0xA6, 0xA3, 0xB4, 0x24, 0x05, 0x36, 0xD0, 0xBA,
  0x93, 0x06, 0xD7, 0xCD, 0x29, 0x57, 0xDE, 0x54, 0xBF, 0x67,
  0xD9, 0x23, 0x2E, 0x7A, 0x66, 0xB3, 0xB8, 0x4A, 0x61, 0xC4,
  0x02, 0x1B, 0x68, 0x5D, 0x94, 0x2B, 0x6F, 0x2A, 0x37, 0xBE,
  0x0B, 0xB4, 0xA1, 0x8E, 0x0C, 0xC3, 0x1B, 0xDF, 0x05, 0x5A,
  0x8D, 0xEF, 0x02, 0x2D
};

unsigned char compare[] = {
          0x5E, 0x60, 0xF6, 0xC0, 0x0A, 0x6E, 0xB1, 0x00, 0xD2, 0xA2,
          0x19, 0x33, 0xB7, 0xB7, 0xCA, 0x57, 0x9C, 0x6D, 0x64, 0x9A,
          0x26, 0x27, 0xD8, 0xBD, 0x91, 0xFB, 0x38, 0xD8, 0xB3, 0x0B,
          0xE1, 0x8D, 0xAD, 0x0D, 0x6B, 0x17, 0xEF, 0xDE, 0x5F, 0x68,
          0xB1, 0xF7, 0x1F, 0x2C, 0x96, 0x42, 0x44, 0x6C, 0x90, 0xFE,
          0x5C, 0xA1, 0x21, 0x87, 0xCD, 0x20, 0xE8, 0x7C, 0x96, 0x62,
          0xFD, 0x41, 0x16, 0x2C, 0x9A, 0x0F, 0x2D, 0x57, 0x2C, 0xDC,
          0x52, 0xAE, 0xCF, 0x7D, 0x49, 0x50, 0x4A, 0xBF, 0x6A, 0xFF
};

int main() {

        DWORD* dword_404A38 = (DWORD*)byte_404A38;
        DWORD* dwcompare = (DWORD*)compare;
        char flag[40] = {0};

        for (int k = 0; k < 40; k+=2) {
                for (int i = 32; i < 128; i++)
                {
                        for (int j = 32; j < 128; j++)
                        {
                                flag[0] = i;
                                flag[1] = j;

                                DWORD dword_404E50 = 0xFFFFFFFF;
                                DWORD dword_404E4C = (flag[0] ^ dword_404E50) & 0xFF;
                                dword_404E50 >>= 8;
                                dword_404E50 ^= dword_404A38[dword_404E4C];

                                dword_404E4C = (flag[1] ^ dword_404E50) & 0Xff;
                                dword_404E50 >>= 8;
                                dword_404E50 ^= dword_404A38[dword_404E4C];
                                dword_404E50 = 0xFFFFFFFF - dword_404E50;

                                if (dword_404E50 == dwcompare[k/2])
                                {
                                        printf("%c%c", i, j);
                                }
                        }
                }
        }

        return 0;
}

flag为 NCTF{rLdE57TG0iHA39qUnFZp6LeJyYEBcxMNL7}

狗狗的秘密

image-20211128221743368.png

前面是47进制,直接用C语言实现上面那个框中的算法,调试,输几个数试试就能试出来了

先写脚本从下往上把47进制后的flag弄出来,发现有很多种情况

byte_405018 = [
    0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0x65, 0xA2, 0x9B,
    0xF4, 0xDF, 0xAC, 0x7C, 0xA1, 0xC6, 0x16, 0xD0, 0x0F, 0xDD,
    0xDC, 0x73, 0xC5, 0x6B, 0xD1, 0x96, 0x47, 0xC2, 0x26, 0x67,
    0x4E, 0x41, 0x82, 0x20, 0x56, 0x9A, 0x6E, 0x33, 0x92, 0x88,
    0x29, 0xB5, 0xB4, 0x71, 0xA9, 0xCE, 0xC3, 0x34, 0x50, 0x59,
    0xBF, 0x2D, 0x57, 0x22, 0xA6, 0x30, 0x04, 0xB2, 0xCD, 0x36,
    0xD5, 0x68, 0x4D, 0x5B, 0x45, 0x9E, 0x85, 0xCF, 0x9D, 0xCC,
    0x61, 0x78, 0x32, 0x76, 0x31, 0xE3, 0x80, 0xAD, 0x39, 0x4F,
    0xFA, 0x72, 0x83, 0x4C, 0x86, 0x60, 0xB7, 0xD7, 0x63, 0x0C,
    0x44, 0x35, 0xB3, 0x7B, 0x19, 0xD4, 0x69, 0x08, 0x0B, 0x1F,
    0x3D, 0x11, 0x79, 0xD3, 0xEE, 0x93, 0x42, 0xDE, 0x23, 0x3B,
    0x5D, 0x8D, 0xA5, 0x77, 0x5F, 0x58, 0xDB, 0x97, 0xF6, 0x7A,
    0x18, 0x52, 0x15, 0x74, 0x25, 0x62, 0x2C, 0x05, 0xE8, 0x0D,
    0x98, 0x2A, 0x43, 0xE2, 0xEF, 0x48, 0x87, 0x49, 0x1C, 0xCA,
    0x2B, 0xA7, 0x8A, 0x09, 0x81, 0xE7, 0x53, 0xAA, 0xFF, 0x6F,
    0x8E, 0x91, 0xF1, 0xF0, 0xA4, 0x46, 0x3A, 0x7D, 0x54, 0xEB,
    0x2F, 0xC1, 0xC0, 0x0E, 0xBD, 0xE1, 0x6C, 0x64, 0xBE, 0xE4,
    0x02, 0x3C, 0x5A, 0xA8, 0x9F, 0x37, 0xAF, 0xA0, 0x13, 0xED,
    0x1B, 0xEC, 0x8B, 0x3E, 0x7E, 0x27, 0x99, 0x75, 0xAB, 0xFE,
    0xD9, 0x3F, 0xF3, 0xEA, 0x70, 0xF7, 0x95, 0xBA, 0x1D, 0x40,
    0xB0, 0xF9, 0xE5, 0xF8, 0x06, 0xBC, 0xB6, 0x03, 0xC9, 0x10,
    0x9C, 0x2E, 0x89, 0x5C, 0x7F, 0xB1, 0x1A, 0xD6, 0x90, 0xAE,
    0xDA, 0xE6, 0x5E, 0xB9, 0x84, 0xE9, 0x55, 0xBB, 0xC7, 0x0A,
    0xE0, 0x66, 0xF2, 0xD8, 0xCB, 0x00, 0x12, 0xB8, 0x17, 0x94,
    0x6A, 0x4A, 0x01, 0x24, 0x14, 0x51, 0x07, 0x65, 0x21, 0xC8,
    0x38, 0xFD, 0x8F, 0xC4, 0xF5, 0xFC
]
byte_405118 = [
    0xA7, 0x1C, 0x7E, 0xAF, 0xD9, 0xC2, 0xC0, 0xBE, 0x1F, 0x45,
    0x9A, 0x85, 0x26, 0xE3, 0x87, 0xC3, 0x21, 0xE0, 0x95, 0x10,
    0x71, 0x70, 0x02, 0x75, 0x35, 0xA5, 0x1D, 0x0D, 0x2F, 0xEE,
    0x25, 0x7B, 0xB5, 0x82, 0x66, 0x8D, 0xDB, 0x53, 0x3A, 0x29,
    0xD4, 0x43, 0x99, 0x97, 0x9D, 0xE8, 0x49, 0x00]

byte_v17 = [0x52, 0xC3, 0x1A, 0xE0, 0x16, 0x5D, 0x5E, 0xE2, 0x67, 0x1F,
            0x1F, 0x06, 0x06, 0x1F, 0x17, 0x06, 0x0F, 0xF9, 0x06, 0x67,
            0x58, 0xB2, 0xE2, 0x8C, 0x0F, 0x2A, 0x06, 0x89, 0xCF, 0x2A,
            0x06, 0x1F, 0x98, 0x1A, 0x3E, 0x17, 0x67, 0x1F, 0xF7, 0x3A,
            0x44, 0xC3, 0x16, 0x33, 0x69, 0x1A, 0x75, 0x16, 0x3E, 0x17,
            0xD5, 0x69, 0x7A, 0x1B, 0x44, 0x44, 0x3E, 0x67, 0xF7, 0x89,
            0x67]
v11 = []

for v17 in byte_v17:
    for i in range(256):
        c = byte_405018[i] ^ i
        if c == v17:
            # print(hex(i))
            if i in byte_405118:
                print(byte_405118.index(i), end=" ")
    print("")

索引为

2     
0     
33 45 
44    
30    
40    
8     
23
22 11 7
37 34
37 34
19 20 43
19 20 43
37 34
24
19 20 43
31 4
29
19 20 43
22 11 7
13
5
23
41
31 4
35
19 20 43
9
14
35
19 20 43
37 34
3
33 45
10
24
22 11 7
37 34
38
1
25
0
30
6
42
33 45
36
30
10
24
21
42
26
28
25
25
10
22 11 7
38
9
22 11 7

然后写脚本,从一头开始试,因为如果一头稍微一改,打印的字符串前面变化很大的话,说明改对了,因为数据高位一改,整个数字变化才大,然后long_to_bytes后对应的字符也变换很大了,如果从低位改,数据变化不大,long_to_bytes后头部的字符变化也不大了, 就这样一点点改,flag就一点点的显示出来了

可能描述的有点抽象,举个例子就很容易懂了

image-20211129132600731.png

对应的解密脚本

from Crypto.Util.number import *
compare = [2,
           0,
           45,
           44,
           30,
           40,
           8,
           23,
           11,
           37,
           34,
           43,
           43,
           37,
           24,
           19,
           4,
           29,
           19,          # 19 20 43
           22,            # 22 11 7
           13,
           5,
           23,
           41,
           4,           # 31  4
           35,
           20,          # 19 20 43
           9,
           14,
           35,
           43,          # 19 20 43
           37,          # 37 34
           3,
           33,          # 33 45
           10,
           24,
           22,           # 22 11 7
           37,      # 37 34
           38,
           1,
           25,
           0,
           30,
           6,
           42,
           45,          # 33 45
           36,
           30,
           10,
           24,
           21,
           42,
           26,
           28,
           25,
           25,
           10,
           7,
           38,
           9,
           11]

sum = 0
re_compare = compare[::-1]
for i in range(len(compare)):
    tmp = re_compare[i] * pow(47, i)
    sum += tmp

print(long_to_bytes(sum))
# NCTF{ADF0E239-D911-3781-7E40-A575A19E5835}

flag为 NCTF{ADF0E239-D911-3781-7E40-A575A19E5835}

easy_mobile

JEB打开分析

image-20211129133043672.png

发现check_flag 的算法在对应的so文件里

image-20211129133838003.png

IDA打开找到Java_com_example_rectf_MainActivity_checkflag 函数

image-20211129133146870.png

哇塞,看这优美的图形,是OLLVM,从网上找来各种脚本平坦化,要么是失败,要么是去了还不如不去容易看

我一共试了这2个脚本

https://github.com/cq674350529/deflat (成功去除,基址设置为0X400000,比如check_flag是0X7900,然后 就运行

python deflat.py -f libnative-lib.so --addr 0x407900,但是去了后我感觉更难看了)

https://github.com/pcy190/deobfuscator (这个我去除失败,可能是qiling版本的问题)

好吧,直接硬刚OLLVM,真机调试

如何搭建真机调试环境可以参考我写的这篇文章

https://zzzzsky.com/2021/11/29/IDA%E7%9C%9F%E6%9C%BA%E8%B0%83%E8%AF%95%E5%AE%89%E5%8D%93so%E6%96%87%E4%BB%B6/

image-20211129134112254.png

在下面每个框中第一条指令下断点,尤其是这种大的块肯定是有用的,先审视一下这种大的块

image-20211129134233317.png

发现在这个位置调用了strlen,然后与0X18对比 猜测是验证flag的长度,继续审视其他块

image-20211129134438579.png

在这个位置发现了一些类似密钥的字符串,还调用了一个函数,进入这个sub_7D30F1E260 函数

image-20211129134631372.png

根据<< 4 >>5 0X12345678等特征,发现这是一种个TEA算法,delta改为了0X12345678

继续审视,在这个位置发现了一些明文

image-20211129134810778.png
F5,发现这里还有一些加减乘除的一些操作

image-20211129135242278.png

开始调试,直接在上面对应的位置下断点,flag先输入12345试试,一点点来到strlen的位置,发现果然是验证flag的长度

image-20211129135058075.png

继续F9,发现即没有到达加减乘除那个块,也没有到达TEA算法那里就显示NO了,我么输入flag为 123456789012345678901234

image-20211129135555940.png

好,程序断在了加减乘除那个块那里,直接一点点单步调试

image-20211129140054267.png

在mul之前停下,观察寄存器,发现X1指向的是最后8个字符,然后来到X16寄存器指向的内存位置,稍微整理整理

image-20211129140156055.png

发现系统初始化了16个字符  PRST0123789: "#$ ,然后下面紧跟着flag 的前16位,猜测flag是分开验证的16 + 8

跳过乘法,再看内存

image-20211129140515888.png

最终调试到memcpy的位置

image-20211129140714060.png

dword_7CD3B3E14C 处的数据为

image-20211129140754349.png

而刚才0007FD020C630处的数据已经变为了

image-20211129141049519.png

于是猜测是flag的前16位根据PRST0123789: "#$ 加减乘除后 与dword_7CD3B3E14C进行对比,然后flag 的后8位是那个tea算法

这里一点点调试,发现

['3', '4', '5', '6'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] = [1687, 1824, 1912, 2002]
['9', '0', '1', '2'] * ['0', '1', '2', '3'] + ['P', 'R', 'S', 'T'] = [2816, 2434, 2533, 2634]
['5', '6', '7', '8'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] = [1751, 1892, 1982, 2074]
['1', '2', '3', '4'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] = [1623, 1756, 1842, 1930]

写脚本解密得到flag的前16个字符

a = [3287, 1688, 3452, 1786,    
     3255, 1994, 1947, 2002,   
     2384, 2777, 2783, 5286,   
     3319, 1824, 1842, 2038]   

mul1 = [ord(i) for i in "0123"]

mul2 = [ord(i) for i in ' "#$']

add1 = [ord(i) for i in "PRST"]

add2 = [ord(i) for i in "789:"]

flag = []

flag1 = [(a[:4][i]-add2[i])/mul2[i] for i in range(4)]
flag2 = [(a[4:8][i]-add2[i])/mul2[i] for i in range(4)]
flag3 = [(a[8:12][i]-add1[i])/mul1[i] for i in range(4)]
flag4 = [(a[12:][i]-add2[i])/mul2[i] for i in range(4)]

print(flag1)
print(flag2)
print(flag3)
print(flag4)

flag = flag1 + flag2 + flag3 + flag4
flag = [chr(int(i)) for i in flag]
print("".join(flag))
# [101.0, 48.0, 97.0, 48.0]
# [100.0, 57.0, 54.0, 54.0]
# [48.0, 55.0, 54.0, 102.0]
# [102.0, 52.0, 51.0, 55.0]
# e0a0d966076ff437

然后flag输入e0a0d966076ff437ABCD1234重新调试,果然程序断在了TEA算法的位置

image-20211129142112345.png

image-20211129142119304.png

发现果然是对flag的后8个字符进行TEA加密,直接运行到加密完成

image-20211129142238913.png

然后进入汇编界面单步调试,注意CMP指令

image-20211129142317313.png

可以发现V0加密后应改为0XC65AEDA,  这里修改X13的值为0XC65AEDA,使其验证通过,然后再单步

image-20211129142540130.png

运行到这个位置,发现V1加密后的数据为 0xADBF8DB1

直接写脚本解密

#include <stdio.h>  
#include <stdint.h>  

//加密函数  
void encrypt(uint32_t* v, uint32_t* k) {
        uint32_t v0 = v[0], v1 = v[1], sum = 0, i;         
        uint32_t delta = 0x12345678;                   
        uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];  
        for (i = 0; i < 32; i++) {                     
                sum += delta;
                v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
                v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
        }                                             
        v[0] = v0; v[1] = v1;
}
//解密函数  
void decrypt(uint32_t* v, uint32_t* k) {
        uint32_t delta = 0x12345678;
        uint32_t v0 = v[0], v1 = v[1], sum = delta * 32, i; 
        uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];  
        for (i = 0; i < 32; i++) {                        
                v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
                v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
                sum -= delta;
        }                                          
        v[0] = v0; v[1] = v1;
}

unsigned char byte_key[] =
{
  0x71, 0x69, 0x68, 0x61, 0x68, 0x61, 0x69, 0x6E, 0x69, 0x6E,
  0x61, 0x6E, 0x61, 0x6E, 0x61, 0x6D
};

//char enc[] = { 'A', 'B', 'C', 'D', '1', '2', '3', '4' };
int main()
{
        //uint32_t* v = (uint32_t*)enc;
        uint32_t v[2] = { 0x000000000C65AEDA , 0x00000000ADBF8DB1 };
        uint32_t* k = (uint32_t*)byte_key;
        decrypt(v, k);
        printf("解密后的数据:%u %u\n", v[0], v[1]);
        return 0;
}

image-20211128222743505.png

后8位是 58af2715

拼凑得到 flag e0a0d966076ff43758af2715

1.png

验证成功


纪念AK RE, 拿了3一血,美滋滋

image-20211129143017613.png

继续加油~~

题目附件

链接:https://pan.baidu.com/s/1FaBD6_FDjKLziKpVqvGe-Q
提取码:ptjq

免费评分

参与人数 20吾爱币 +20 热心值 +19 收起 理由
dreamingctf + 1 + 1 收获很大,转载一发
Kevin52 + 1 + 1 CTF冲冲冲!
gcode + 1 + 1 谢谢@Thanks!
fengbolee + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
pandahan + 1 + 1 谢谢@Thanks!
CD3 + 1 用心讨论,共获提升!
18053317345 + 1 我很赞同!
独行风云 + 1 + 1 我很赞同!
aa530416 + 1 + 1 我很赞同!
yixi + 1 + 1 谢谢@Thanks!
笙若 + 1 + 1 谢谢@Thanks!
yunjianchenxi8 + 1 用心讨论,共获提升!
fjzry + 1 + 1 我很赞同!
EHckm + 1 + 1 热心回复!
LoveHack + 1 + 1 用心讨论,共获提升!
indian806 + 1 + 1 虽然不懂PJ,但作者好用心,大赞
m1n9yu3 + 1 + 1 我很赞同!
vethenc + 2 + 1 谢谢@Thanks!
1yttoni + 1 + 1 我很赞同!
IT_YCU + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

chenjingyes 发表于 2021-12-8 22:40
问一下楼主解那道ollvm混淆的题目,动态调试用的是deflate去除olivm混淆后的文件,还是原版文件动态调试硬杠ollvm??   


另外,怎么不考虑用ida trace来跑出程序运行流程??
 楼主| zsky 发表于 2021-12-9 09:08
chenjingyes 发表于 2021-12-8 22:40
问一下楼主解那道ollvm混淆的题目,动态调试用的是deflate去除olivm混淆后的文件,还是原版文件动态调试硬 ...

醒刚的ollvm
vethenc 发表于 2021-11-29 15:43
2733369 发表于 2021-11-29 17:34
感谢大佬分享
hjw01 发表于 2021-11-29 21:42
解密过程吗,不是很明白
zhouyaxv 发表于 2021-11-29 23:20
感谢大佬分享,太谢谢你了
xytwlh 发表于 2021-11-30 00:20
看看怎么样
douluodalu 发表于 2021-11-30 04:55
感谢大佬分享,太谢谢你了
douluodalu 发表于 2021-11-30 05:07

感谢大佬分享,太谢谢你了
头像被屏蔽
lxptyc 发表于 2021-11-30 08:07
感谢,试试看哦
wh4am1 发表于 2021-11-30 08:27
做题的时候对程序逻辑还是太不敏感了,Base64换表那个一时间没看出来
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 12:21

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表