不一样的flag

ida F5得到伪代码

image-20200427142729388

查看字符串,得到一串特殊字符

image-20200427142748004

长度为25,综合考虑了一下,发现考点为”迷宫”

*1111
01000
01010
00010
1111#

输入一下代码

222441144222

可以得到

image-20200427144407701

flag为:flag{222441144222}

CrackRTF

首先分析一下sub_40100A函数

image-20200429090809250

打开后发现调用的是sub_401230函数,接下来分析sub_401230函数

image-20200429090905109

// 主要函数 
BOOL CryptCreateHash(
  HCRYPTPROV hProv,
  ALG_ID     Algid,  // 指定加密的密码 这里 0x8004 指定的是sha1
  HCRYPTKEY  hKey,
  DWORD      dwFlags,
  HCRYPTHASH *phHash
);


对照表如下

0x00006603 CALG_3DES
0x00006609 CALG_3DES_112
0x00006611 CALG_AES
0x0000660e CALG_AES_128
0x0000660f CALG_AES_192
0x00006610 CALG_AES_256
0x0000aa03 CALG_AGREEDKEY_ANY
0x0000660c CALG_CYLINK_MEK
0x00006601 CALG_DES
0x00006604 CALG_DESX
0x0000aa02 CALG_DH_EPHEM
0x0000aa01 CALG_DH_SF
0x00002200 CALG_DSS_SIGN
0x0000aa05 CALG_ECDH
0x0000ae06 CALG_ECDH_EPHEM
0x00002203 CALG_ECDSA
0x0000a001 CALG_ECMQV
0x0000800b CALG_HASH_REPLACE_OWF
0x0000a003 CALG_HUGHES_MD5
0x00008009 CALG_HMAC
0x0000aa04 CALG_KEA_KEYX
0x00008005 CALG_MAC
0x00008001 CALG_MD2
0x00008002 CALG_MD4
0x00008003 CALG_MD5
0x00002000 CALG_NO_SIGN
0xffffffff CALG_OID_INFO_CNG_ONLY
0xfffffffe CALG_OID_INFO_PARAMETERS
0x00004c04 CALG_PCT1_MASTER
0x00006602 CALG_RC2
0x00006801 CALG_RC4
0x0000660d CALG_RC5
0x0000a400 CALG_RSA_KEYX
0x00002400 CALG_RSA_SIGN
0x00004c07 CALG_SCHANNEL_ENC_KEY
0x00004c03 CALG_SCHANNEL_MAC_KEY
0x00004c02 CALG_SCHANNEL_MASTER_HASH
0x00006802 CALG_SEAL
0x00008004 CALG_SHA
0x00008004 CALG_SHA1
0x0000800c CALG_SHA_256
0x0000800d CALG_SHA_384
0x0000800e CALG_SHA_512
0x0000660a CALG_SKIPJACK
0x00004c05 CALG_SSL2_MASTER
0x00004c01 CALG_SSL3_MASTER
0x00008008 CALG_SSL3_SHAMD5
0x0000660b CALG_TEK
0x00004c06 CALG_TLS1_MASTER
0x0000800a CALG_TLS1PRF

所以密码1可爆破,但是直接找个在线的网站也解出来了,爆破截包如下:

import hashlib

for i in range(100000,999999):
    if hashlib.sha1((str(i) + '@DBApp').encode('utf-8')).hexdigest().upper() == '6E32D0943418C2C33385BC35A1470250DD8923A9':
        print(str(i))

// 123321   密码1为 123321

继续往下分析,密码2为6位,未指定范围,sub_401019函数也是个hash加密,指向的是MD5加密,可以爆破可见字符.

image-20200429092130004

硬盘够大,时间够多的情况下还是可以的。

image-20200429093343379

无奈,只能继续往下分析

image-20200429093453782

这里sub_40100F函数使用了密码2,而且会根据密码2来判断是否退出程序,所以,应该是解出密码2的关键点。

image-20200429093701931

分析一波函数

HRSRC FindResourceA(
  HMODULE hModule, 
  LPCSTR  lpName,
  LPCSTR  lpType
); // 在程序的资源列表里打开类型为lpType,名称为lpName的资源。

分析程序得到

image-20200429094408594

关键点在sub_401005函数,分析它:

image-20200429094527735

表示将资源的数据逐字节的与(密码二+密码一[email protected])循环xor。

查看资源,0x65 = 101

image-20200429094834994

资源有了,密码2为6位由用户输入,该输入啥呢。

可以看到因为创建的文件为rtf格式,所以文件头是固定的,所以,可以查看rtf的文件头格式,只需要前6位,搜索得到文件头前六位为7B5C72746631与资源的前6个字节xor得到密码二[email protected]

密码1: 123321

密码2: [email protected]

解密得到文件,打开即是flag{N0_M0re_Free_Bugs}

简单注册器

image-20200429103020976

输入长度为32
第31个为a
第一个为b
第0+第2 - 48 = 56

继续往下分析,发现用户输入的只是用来更改flag标志,并没有参与flag加密,所以直接copy代码

public class A {
    public static void main(String[] args) {
        char[] x = "dd2940c04462b4dd7c450528835cca15".toCharArray();
        x[2] = (char) ((x[2] + x[3]) - 50);
        x[4] = (char) ((x[2] + x[5]) - 48);
        x[30] = (char) ((x[31] + x[9]) - 48);
        x[14] = (char) ((x[27] + x[28]) - 97);
        for (int i = 0; i < 16; i++) {
            char a = x[31 - i];
            x[31 - i] = x[i];
            x[i] = a;
        }
        System.out.println("flag{" + String.valueOf(x) + "}");
    }
}

// flag{59acc538825054c7de4b26440c0999dd}

[GXYCTF2019]luck_guy

└> file luck_guy
luck_guy: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=38f6b7066f73e3b41dca3ab5b6da405f8edf2ec5, not stripped

64位,Linux可执行文件

image-20200429104857439

  1. 输入数字调用patch_me

    image-20200429105043506

  2. 分析patch_me,输入为偶数调用get_flag

    image-20200429105113603

  3. 输入偶数试试,发现他在骗我…

    image-20200429105203757

  4. 分析get_flag

    image-20200429105334001

    循环四次,由随机数分发,有一定几率拿到flag。

    在分支1中是可以得到flag的:flag由f1和f2组成。

    在分支2和分支3中都是错误的。

    在分支4中给f2赋值。

    在分支5中操作f2。

    默认输出错误。

  5. 由此,可以推断,执行流,4,5,1.

    In [1]: flag = '7F666F6067756369'
    
    In [2]: s = ''
       ...: for i in range(0,len(flag),2):
       ...:     s += chr(int(flag[i:i+2],16))
       ...:
    
    In [3]: s = list(s)
    
    In [4]: s.reverse()
    
    In [5]: s
    Out[5]: ['i', 'c', 'u', 'g', '`', 'o', 'f', '\x7f']
    
    In [6]: flag = ''
       ...: pre = 'GXY{do_not_'
       ...: for i in range(0,8):
       ...:     if i % 2 == 1:
       ...:         flag += chr(ord(s[i]) - 2)
       ...:     else:
       ...:         flag += chr(ord(s[i]) - 1)
       ...: print(pre+flag)
    GXY{do_not_hate_me}
    

Youngter-drive

查壳,upx壳

image-20200429111813488

脱壳

image-20200429111944821

分析,反调试还挺多的

image-20200429112224296

分析程序Source是全局变量,由用户输入

image-20200429113115925

用户输入的数据copy到Dest,创建了两个线程StartAddress和sub_41119F

image-20200429113203312

查看线程StartAddress

主要作用是对Source加密

image-20200429125136740

查看线程sub_41119F

image-20200429125239913

对数字dword_418008进行减一操作

回过头看加密函数

反编译,发现堆栈不平衡错误,修复之后

image-20200429114403280

分析

111

所以线程一的作用为:对用户输入的字符逐字节加密,数组下标减一,睡眠0.1s

线程二的作用为:数组下标减一,睡眠0.1s

所以,综合作用就是对用户输入的字符逐字节加密,数组下标减二

111

得到加密后的字符串与off_418004出的字符串对比

脚本

dic = 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm'
res = 'TOiZiZtOrYaToUwPnToBsOaOapsyS'

flag = ''
for j in range(len(res)-1,-1,-1):
    if j % 2 == 0:
        flag += res[j]
        continue
    for i in range(64,123):
        if i < ord('Z'):
            if dic[i-38] == res[j]:
                flag += chr(i)
                break
        elif i >= ord('a'):
            if dic[i-96] == res[j]:
                flag += chr(i)
                break
flag = list(flag)
flag.reverse()
print(''.join(i for i in flag))

// ThisisthreadofwindowshahaIsES

注意:Flag为flag{ThisisthreadofwindowshahaIsESE},出题问题

题目加密部分出的很奇怪,如果我输入Z的时候,ord(‘Z’) - 38 = 52, dic[52] 会超出数组下标,程序不会会崩溃,因为他是C语言啊,作者的本意应该是输入大写字母就-97,小写字母-39,才能实现大写转成小写,小写转成大写。

总体来说:

程序输入30个字符串,从后往前每隔一位加一次密,最后与29位的字符串比较,太坑了。

相册

提取APK中完整的邮箱

image-20200429140953932

在主活动中看到程序会将调试的信息显示在终端,安装程序后启动,可以使用adb获取输出的信息,包含email地址。

image-20200429141143180

image-20200429141411297

image-20200429141539042

以上应该是非预期解

分析下程序,查找和mail相关的代码,发现了下面一段代码

image-20200429142322065

分析连接的函数

image-20200429142421602

发现配置都定义在了C0005C2中,且有些数据时在native层。

image-20200429142516081

image-20200429142750461

直接查看so库的硬编码字符串碰碰运气,可以得到邮件的base64编码

image-20200429142935213

[GWCTF 2019]pyre

反编译得到如下代码

print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
    num = ((input1[i] + i) % 128 + 128) % 128
    code += num

for i in range(l - 1):
    code[i] = code[i] ^ code[i + 1]

print code
code = [
    '\x1f',
    '\x12',
    '\x1d',
    '(',
    '0',
    '4',
    '\x01',
    '\x06',
    '\x14',
    '4',
    ',',
    '\x1b',
    'U',
    '?',
    'o',
    '6',
    '*',
    ':',
    '\x01',
    'D',
    ';',
    '%',
    '\x13']

solve

code = ['\x1f','\x12','\x1d','(','0','4','\x01','\x06','\x14','4',',','\x1b','U','?','o','6','*',':','\x01','D',';','%','\x13']
for i in range(len(code)-2,-1,-1):
    code[i] = chr(ord(code[i]) ^ ord(code[i+1]))

flag = ''
for i in range(0,len(code)):
    for j in range(0,255):
        if ((j + i) % 128 + 128) % 128 == ord(code[i]):
            flag += (chr(j))
            break
print(flag)

// GWHT{Just_Re_1s_Ha66y!}

[2019红帽杯]easyRE-藏函数

signed __int64 __fastcall sub_4009C6(double a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8)
{
  double v8; // xmm4_8
  double v9; // xmm5_8
  signed __int64 result; // rax
  __int64 v11; // ST10_8
  __int64 v12; // ST18_8
  __int64 v13; // ST20_8
  __int64 v14; // ST28_8
  __int64 v15; // ST30_8
  __int64 v16; // ST38_8
  __int64 v17; // ST40_8
  __int64 v18; // ST48_8
  __int64 v19; // ST50_8
  __int64 v20; // ST58_8
  int i; // [rsp+Ch] [rbp-114h]
  char v22; // [rsp+60h] [rbp-C0h]
  char v23; // [rsp+61h] [rbp-BFh]
  char v24; // [rsp+62h] [rbp-BEh]
  char v25; // [rsp+63h] [rbp-BDh]
  char v26; // [rsp+64h] [rbp-BCh]
  char v27; // [rsp+65h] [rbp-BBh]
  char v28; // [rsp+66h] [rbp-BAh]
  char v29; // [rsp+67h] [rbp-B9h]
  char v30; // [rsp+68h] [rbp-B8h]
  char v31; // [rsp+69h] [rbp-B7h]
  char v32; // [rsp+6Ah] [rbp-B6h]
  char v33; // [rsp+6Bh] [rbp-B5h]
  char v34; // [rsp+6Ch] [rbp-B4h]
  char v35; // [rsp+6Dh] [rbp-B3h]
  char v36; // [rsp+6Eh] [rbp-B2h]
  char v37; // [rsp+6Fh] [rbp-B1h]
  char v38; // [rsp+70h] [rbp-B0h]
  char v39; // [rsp+71h] [rbp-AFh]
  char v40; // [rsp+72h] [rbp-AEh]
  char v41; // [rsp+73h] [rbp-ADh]
  char v42; // [rsp+74h] [rbp-ACh]
  char v43; // [rsp+75h] [rbp-ABh]
  char v44; // [rsp+76h] [rbp-AAh]
  char v45; // [rsp+77h] [rbp-A9h]
  char v46; // [rsp+78h] [rbp-A8h]
  char v47; // [rsp+79h] [rbp-A7h]
  char v48; // [rsp+7Ah] [rbp-A6h]
  char v49; // [rsp+7Bh] [rbp-A5h]
  char v50; // [rsp+7Ch] [rbp-A4h]
  char v51; // [rsp+7Dh] [rbp-A3h]
  char v52; // [rsp+7Eh] [rbp-A2h]
  char v53; // [rsp+7Fh] [rbp-A1h]
  char v54; // [rsp+80h] [rbp-A0h]
  char v55; // [rsp+81h] [rbp-9Fh]
  char v56; // [rsp+82h] [rbp-9Eh]
  char v57; // [rsp+83h] [rbp-9Dh]
  char v58[32]; // [rsp+90h] [rbp-90h]
  int v59; // [rsp+B0h] [rbp-70h]
  char v60; // [rsp+B4h] [rbp-6Ch]
  char v61; // [rsp+C0h] [rbp-60h]
  char v62; // [rsp+E7h] [rbp-39h]
  char v63; // [rsp+100h] [rbp-20h]
  unsigned __int64 v64; // [rsp+108h] [rbp-18h]

  v64 = __readfsqword(0x28u);
  v22 = 73;
  v23 = 111;
  v24 = 100;
  v25 = 108;
  v26 = 62;
  v27 = 81;
  v28 = 110;
  v29 = 98;
  v30 = 40;
  v31 = 111;
  v32 = 99;
  v33 = 121;
  v34 = 127;
  v35 = 121;
  v36 = 46;
  v37 = 105;
  v38 = 127;
  v39 = 100;
  v40 = 96;
  v41 = 51;
  v42 = 119;
  v43 = 125;
  v44 = 119;
  v45 = 101;
  v46 = 107;
  v47 = 57;
  v48 = 123;
  v49 = 105;
  v50 = 121;
  v51 = 61;
  v52 = 126;
  v53 = 121;
  v54 = 76;
  v55 = 64;
  v56 = 69;
  v57 = 67;
  memset(v58, 0, sizeof(v58));
  v59 = 0;
  v60 = 0;
  sub_4406E0(0LL, v58);
  v60 = 0;
  if ( sub_424BA0(v58) == 36 )
  {
    for ( i = 0; i < sub_424BA0(v58); ++i ) // xor运算
    {
      if ( (v58[i] ^ i) != *(&v22 + i) )
      {
        result = 4294967294LL;
        goto LABEL_13;
      }
    }
    sub_410CC0("continue!");
    memset(&v61, 0, 0x40uLL);
    v63 = 0;
    sub_4406E0(0LL, &v61);
    v62 = 0;
    if ( sub_424BA0(&v61) == 39 )
    {
      v11 = sub_400E44(&v61);
      v12 = sub_400E44(v11);
      v13 = sub_400E44(v12);
      v14 = sub_400E44(v13);
      v15 = sub_400E44(v14);
      v16 = sub_400E44(v15);
      v17 = sub_400E44(v16);
      v18 = sub_400E44(v17);
      v19 = sub_400E44(v18);
      v20 = sub_400E44(v19);
      if ( !sub_400360(v20, off_6CC090) ) // base64运算
      {
        sub_410CC0("You found me!!!");
        sub_410CC0("bye bye~");
      }
      result = 0LL;
    }
    else
    {
      result = 4294967293LL;
    }
  }
  else
  {
    result = 0xFFFFFFFFLL;
  }
LABEL_13:
  if ( __readfsqword(0x28u) != v64 )
    sub_444020(a1, a2, a3, a4, v8, v9, a7, a8);
  return result;
}
  1. 第一处加密得到的结果

    Info:The first four chars are `flag`
    
  2. 第二处加密得到的结果

    https://bbs.pediy.com/thread-254172.htm
    
  3. 都没啥太大的意义

    一番查看,发现了在初始化段存在另外一处程序不运行的函数。

    image-20200430101131336

    __int64 __fastcall sub_400D35(double a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8)
    {
      double v8; // xmm4_8
      double v9; // xmm5_8
      __int64 result; // rax
      unsigned __int64 v11; // rt1
      unsigned int v12; // [rsp+Ch] [rbp-24h]
      signed int i; // [rsp+10h] [rbp-20h]
      signed int j; // [rsp+14h] [rbp-1Ch]
      unsigned int v15; // [rsp+24h] [rbp-Ch]
      unsigned __int64 v16; // [rsp+28h] [rbp-8h]
    
      v16 = __readfsqword(0x28u);
      v12 = sub_43FD20() - qword_6CEE38;
      for ( i = 0; i <= 1233; ++i )
      {
        sub_40F790(v12);
        sub_40FE60();
        sub_40FE60();
        v12 = sub_40FE60() ^ 0x98765432;
      }
      v15 = v12;
      if ( (v12 ^ byte_6CC0A0[0]) == 102 && (HIBYTE(v15) ^ byte_6CC0A3) == 103 )
      {
        for ( j = 0; j <= 24; ++j )
          sub_410E90((byte_6CC0A0[j] ^ *(&v15 + j % 4)));
      }
      v11 = __readfsqword(0x28u);
      result = v11 ^ v16;
      if ( v11 != v16 )
        sub_444020(a1, a2, a3, a4, v8, v9, a7, a8);
      return result;
    }
    

    byte_6CC0A0与byte_6CC0A3数据如下

    .data:00000000006CC0A0     byte_6CC0A0     db 40h                  ; DATA XREF: sub_400D35+95↑r
    .data:00000000006CC0A0                                             ; sub_400D35+C1↑r
    .data:00000000006CC0A1                     db  35h ; 5
    .data:00000000006CC0A2                     db  20h
    .data:00000000006CC0A3     byte_6CC0A3     db 56h                  ; DATA XREF: sub_400D35+A6↑r
    .data:00000000006CC0A4                     db  5Dh ; ]
    .data:00000000006CC0A5                     db  18h
    .data:00000000006CC0A6                     db  22h ; "
    .data:00000000006CC0A7                     db  45h ; E
    .data:00000000006CC0A8                     db  17h
    .data:00000000006CC0A9                     db  2Fh ; /
    .data:00000000006CC0AA                     db  24h ; $
    .data:00000000006CC0AB                     db  6Eh ; n
    .data:00000000006CC0AC                     db  62h ; b
    .data:00000000006CC0AD                     db  3Ch ; <
    .data:00000000006CC0AE                     db  27h ; '
    .data:00000000006CC0AF                     db  54h ; T
    .data:00000000006CC0B0                     db  48h ; H
    .data:00000000006CC0B1                     db  6Ch ; l
    .data:00000000006CC0B2                     db  24h ; $
    .data:00000000006CC0B3                     db  6Eh ; n
    .data:00000000006CC0B4                     db  72h ; r
    .data:00000000006CC0B5                     db  3Ch ; <
    .data:00000000006CC0B6                     db  32h ; 2
    .data:00000000006CC0B7                     db  45h ; E
    .data:00000000006CC0B8                     db  5Bh ; [
    .data:00000000006CC0B9                     db    0
    .data:00000000006CC0BA                     db    0
    .data:00000000006CC0BB                     db    0
    .data:00000000006CC0BC                     db    0
    .data:00000000006CC0BD                     db    0
    .data:00000000006CC0BE                     db    0
    .data:00000000006CC0BF                     db    0
    

    主要代码如下

    v15 = v12;
    if ( (v12 ^ byte_6CC0A0[0]) == 'f' && (HIBYTE(v15) ^ byte_6CC0A3) == 'g' ){
        for ( j = 0; j <= 24; ++j )
            sub_410E90((byte_6CC0A0[j] ^ *(&v15 + j % 4)));
    }
    
    假设 v12 = 0xAABBCCDD
    则v12 ^ byte_6CC0A0[0] == 0xDD ^ byte_6CC0A0[0]
      HIBYTE(v15) ^ byte_6CC0A3 == 0xAA ^ byte_6CC0A3 // HIBYTE 提取16bit数的高8bit
    

    前面提示了flag的前四位为flag

    所以

    Byte_6CC0A0 ^ v15 == flag…..

    In [5]: a = [0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x
       ...: 62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5B]
    
    In [6]: v15 = [a[0] ^ ord('f'),a[1] ^ ord('l'),a[2] ^ ord('a'),a[3] ^ ord('g')]
    
    In [7]: flag = ''
       ...: for i in range(len(a)):
       ...:     flag += chr(a[i] ^ v15[i%4])
       ...:
    
    In [8]: flag
    Out[8]: 'flag{Act1ve_Defen5e_Test}'
    

[SUCTF2019]SignIn

image-20200430103624213

在线提取pq

image-20200430103400951

代码如下

import base64

p= 282164587459512124844245113950593348271
q= 366669102002966856876605669837014229419
e= 65537
c= 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
n= 103461035900816914121390101299049044413950405173712170434161686539878160984549
def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)
def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m
d=modinv(e,(p-1)*(q-1))
print 'd=',d
m=pow(c,d,n)
print hex(m)[2:len(hex(m))-1].decode('hex')

# suctf{[email protected]_hundred_years}

涉及的GNU高精度算法库

https://gmplib.org/manual/

[V&N2020 公开赛]strangeCpp-藏数据

主体作用就是输出系统信息,看了半天不知道数据在哪里加密的,查看wp后,知道了

__int64 __fastcall sub_140013AA0(__int64 a1, __int64 a2, __int64 *a3)
{
  char *v3; // rdi
  signed __int64 i; // rcx
  __int64 v5; // rax
  __int64 v6; // rax
  __int64 v7; // rax
  __int64 v8; // rax
  char v10; // [rsp+0h] [rbp-20h]
  struct _SYSTEM_INFO SystemInfo; // [rsp+28h] [rbp+8h]
  __int64 *j; // [rsp+78h] [rbp+58h]
  __int64 v13; // [rsp+98h] [rbp+78h]
  __int64 *v14; // [rsp+1A0h] [rbp+180h]

  v14 = a3;
  v3 = &v10;
  for ( i = 94i64; i; --i )
  {
    *v3 = -858993460;
    v3 += 4;
  }
  sub_1400110AA(&unk_140027033);
  GetSystemInfo(&SystemInfo);
  putchar(unk_140021004[0]);
  putchar(unk_140021004[1]);
  putchar(unk_140021004[2]);
  putchar(unk_140021004[3]);
  putchar(unk_140021015[4]);
  putchar(unk_140021015[5]);
  putchar(unk_140021004[1]);
  putchar(10);
  puts("Let me have a look at your computer...");
  for ( j = v14; *j; ++j )
  {
    v13 = *j;
    sub_140011226("%s\n", v13);
  }
  std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140011127);
  dword_140021190 = SystemInfo.dwNumberOfProcessors;
  sub_140011226("now system cpu num is %d\n", SystemInfo.dwNumberOfProcessors);
  if ( dword_140021190 >= 8 )
  {
    puts("Are you in VM?");
    _exit(0);
  }
  if ( GetUserNameA(Str1, &unk_140021000) )
  {
    v5 = sub_140011172(std::cout, "this is useful");
    std::basic_ostream<char,std::char_traits<char>>::operator<<(v5, sub_140011127);
  }
  v6 = std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_140011127);
  v7 = sub_140011172(v6, "ok,I am checking...");
  std::basic_ostream<char,std::char_traits<char>>::operator<<(v7, sub_140011127);
  if ( !j_strcmp(Str1, "cxx") )
  {
    v8 = sub_140011172(std::cout, "flag{where_is_my_true_flag?}");
    std::basic_ostream<char,std::char_traits<char>>::operator<<(v8, sub_140011127);
    _exit(0);
  }
  system("pause");
  sub_1400113E3(&v10, &unk_14001DE50);
  return 0i64;
}

与flag相关的数据都没用,简直脑洞

welcome数据中夹杂其他数据

image-20200430125512331

点击查看数据

image-20200430125528305

使用交叉引用定位函数

image-20200430125551975

主要是for循环处,byte xor 直接爆破

In [1]: flag = [0x26, 0x2C, 0x21, 0x27, 0x3B, 0x0D, 0x04, 0x75, 0x68, 0x34, 0x28, 0x25,
   ...:  0x0E, 0x35, 0x2D, 0x69, 0x3D]

In [2]: for i in range(0,256):
   ...:     s = ''
   ...:     for j in flag:
   ...:         s += chr(i^j)
   ...:     print s

...
flag{MD5(theNum)}
...

theNum为知,可能是需要计算dword_140021190

sub_140011384(dword_140021190) = 0x242EE21A

signed __int64 __fastcall sub_140013890(int a1)
{
  __int64 *v1; // rdi
  signed __int64 i; // rcx
  signed __int64 result; // rax
  __int64 v4; // [rsp+0h] [rbp-20h]
  int v5; // [rsp+24h] [rbp+4h]
  int v6; // [rsp+44h] [rbp+24h]
  unsigned int v7; // [rsp+64h] [rbp+44h]
  int v8; // [rsp+160h] [rbp+140h]

  v8 = a1;
  v1 = &v4;
  for ( i = 82i64; i; --i )
  {
    *v1 = -858993460;
    v1 = (v1 + 4);
  }
  sub_1400110AA(&unk_140027033);
  v5 = v8 >> 12;
  v6 = v8 << 8;
  v7 = (v8 << 8) ^ (v8 >> 12);
  v7 *= 291;
  if ( v7 )
    result = v7;
  else
    result = 0x3DBi64;
  return result;
}

主要代码

v7 = (v8 << 8) ^ (v8 >> 12);
v7 *= 291;

v7 == 0x242EE21A

代码如下

In [9]: for i in range(0,9999999999):
   ...:     if (((i << 8) ^ (i >> 12)) * 291) & 0xffffffff == 0x242EE21A:
   ...:         print i
   ...:         break
   ...:
123456

MD5加密

┌[bufsnake☮ bufsnake.com]-(~)
└> echo '123456\c' | md5
e10adc3949ba59abbe56e057f20f883e

Flag: flag{e10adc3949ba59abbe56e057f20f883e}



reverse      buuctf

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!