首页
论坛
专栏
课程

[原创]2018看雪CTF第十二题WP

jackandkx
6
2018-7-10 01:06 605

命令行参数

直接打开CM,程序闪退。用命令行打开,CM会输出一句话然后退出。

λ Desktop\kanxueCTF2018\12\CrackMe\CrackMe.exe
input like this:crackme.exe mykey

原来要用命令行参数的形式输入flag。(IDA调试时,在Debugger->Process Option->Parameter处输入)

λ Desktop\kanxueCTF2018\12\CrackMe\CrackMe.exe 123456
registration failed

随便传了一个flag,回显失败就退出了。

IDA反编译

main函数中:

if ( argc == 2 )
{
  sub_14000E55C(key, 260i64, (char *)argv[1], 260i64);
  sub_140002E00(&retaddr);
  result = 0;
}

sub_14000E55C作用是把我们输入的flag(argv[1]指向的)复制到全局变量key处。
第二个call是验证函数。

 

这里值得一提的是,else分支中有大量的垃圾代码(验证函数中也有大量的垃圾代码,其实是一些常量经过各种变换,生成另一些常量,作用是阻挠分析,分析时需要无视它们),比如以下:

else
  {
    v30 = (unsigned __int16)((((dword_140038020 << 16) + (unsigned __int16)(HIWORD(dword_140038020) - dword_140038020) + (unsigned __int16)(7 - (HIWORD(dword_140038020) - dword_140038020)) - (unsigned int)(unsigned __int16)(HIWORD(dword_140038020) - dword_140038020)) >> 16) - (HIWORD(dword_140038020) - dword_140038020 + 7 - (HIWORD(dword_140038020) - dword_140038020) - (HIWORD(dword_140038020) - dword_140038020)) * (HIWORD(dword_140038020) - dword_140038020 + 7 - (HIWORD(dword_140038020) - dword_140038020) - (HIWORD(dword_140038020) - dword_140038020))) + (((dword_140038020 << 16) + (unsigned __int16)(HIWORD(dword_140038020) - dword_140038020) + (unsigned __int16)(7 - (HIWORD(dword_140038020) - dword_140038020)) - (unsigned __int16)(HIWORD(dword_140038020) - dword_140038020)) << 16);
    v31 = 31 * ((unsigned __int16)((BYTE1(dword_140038024) << 8) - 7 + (unsigned __int8)(101 * dword_140038024 + 51)) + ((unsigned __int16)(-7 * (unsigned __int8)(35 - 101 * BYTE2(dword_140038024)) - 1792 * (unsigned __int8)(101 * HIBYTE(dword_140038024) + 108) + 35) << 16)) - 961;
    v32 = (unsigned __int16)((((unsigned __int16)(((unsigned __int16)(7 * ((unsigned __int8)dword_140038028 + (BYTE1(dword_140038028) << 8)) - 35) >> 8) - 31 + ((unsigned __int8)(7 * dword_140038028 - 40) << 8)) + ((unsigned int)(unsigned __int16)(((unsigned __int16)-HIWORD(dword_140038028) >> 8) + ((unsigned __int8)(-7 * BYTE2(dword_140038028)) << 8)) << 16)) >> 16) - (((unsigned __int16)(7 * ((unsigned __int8)dword_140038028 + (BYTE1(dword_140038028) << 8)) - 35) >> 8) - 31 + ((unsigned __int8)(7 * dword_140038028 - 40) << 8)) * (((unsigned __int16)(7 * ((unsigned __int8)dword_140038028 + (BYTE1(dword_140038028) << 8)) - 35) >> 8) - 31 + ((unsigned __int8)(7 * dword_140038028 - 40) << 8))) + (((unsigned __int16)(((unsigned __int16)(7 * ((unsigned __int8)dword_140038028 + (BYTE1(dword_140038028) << 8)) - 35) >> 8) - 31 + ((unsigned __int8)(7 * dword_140038028 - 40) << 8)) + ((unsigned __int16)(((unsigned __int16)-HIWORD(dword_140038028) >> 8) + ((unsigned __int8)(-7 * BYTE2(dword_140038028)) << 8)) << 16)) << 16);
    v3 = ((((unsigned __int16)(-31 * HIWORD(dword_14003802C)) >> 8) - abs((char)(-31 * BYTE2(dword_14003802C)))) & 0xFF) - 7936 * HIWORD(dword_14003802C);
    v4 = (unsigned __int8)(4 * dword_14003802C + dword_14003802C - 35) + (BYTE1(dword_14003802C) << 8);
    v5 = (v4 << 8) + (((v4 >> 8) - v4 * v4) & 0xFF);
    v6 = -7936 * v5 - 31 * (((v5 >> 8) - v5 * v5) & 0xFF) + 7;
    v7 = (unsigned __int8)(76 - 7 * ((unsigned __int16)(5 * ((unsigned __int8)(5 - HIBYTE(v6)) + ((unsigned __int8)(-7 * v6 - 1) << 8))) >> 8)) - (unsigned __int8)(-58 - 111 * (76 - 7 * ((unsigned __int16)(5 * ((unsigned __int8)(5 - HIBYTE(v6)) + ((unsigned __int8)(-7 * v6 - 1) << 8))) >> 8))) - ((unsigned __int8)(76 - 7 * ((unsigned __int16)(5 * ((unsigned __int8)(5 - HIBYTE(v6)) + ((unsigned __int8)(-7 * v6 - 1) << 8))) >> 8)) + ((unsigned __int8)(-81 * (5 - HIBYTE(v6)) - 96) << 8)) + 7;
    v8 = v7 + (unsigned __int8)(v7 - 7) - (unsigned __int8)v7;
    v33 = (unsigned __int16)((v8 << 8) + (((v8 >> 8) - abs((char)(v7 - 7))) & 0xFF)) + ((unsigned __int16)(-31 * (1280 * v3 + ((((unsigned __int16)(5 * v3) >> 8) - abs((char)(5 * (((unsigned __int16)(-31 * HIWORD(dword_14003802C)) >> 8) - abs(-31 * BYTE2(dword_14003802C)))))) & 0xFF))) << 16);
    v41 = dword_140038030;
    v34 = 5 * ((unsigned __int16)(1 - dword_140038030) + ((unsigned __int16)(HIWORD(dword_140038030) - 5) << 16));
    _mm_storeu_si128((__m128i *)&v38, _mm_load_si128((const __m128i *)&xmmword_140024850));
    v37 = 0;
    sub_140002720(&v37, &v30, 17i64);
    v26 = (unsigned __int16)((unsigned __int8)(59 * dword_140038010 + 63) + (BYTE1(dword_140038010) << 8)) + ((unsigned __int16)(25 * (((unsigned __int8)(5 - HIBYTE(dword_140038010)) << 8) + BYTE2(dword_140038010)) - 155 + (unsigned __int8)(5 - (25 * BYTE2(dword_140038010) + 101)) - (unsigned __int8)(25 * BYTE2(dword_140038010) + 101)) << 16);
    v9 = 31 - ((unsigned __int8)(BYTE2(dword_140038014) - 5) << 8) - ((unsigned __int16)(HIWORD(dword_140038014) - 5) >> 8);
    v10 = abs((((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) >> 8) - ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) * ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8))) & 0xFF));
    v11 = (unsigned __int16)((((unsigned __int16)((((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) >> 8) - ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) * ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8))) & 0xFF)) + ((unsigned int)v9 << 16)) >> 16) - v10);
    v12 = (((unsigned __int16)((((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) >> 8) - ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) * ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8))) & 0xFF)) + (v9 << 16)) << 16) + v11;
    v13 = v12 + (unsigned __int16)((((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) >> 8) - ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) * ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8))) & 0xFF)) - (unsigned __int16)v12;
    v14 = 7 * ((v13 << 16) + (unsigned __int16)(((v12 + (unsigned __int16)((((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) >> 8) - ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) * ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8))) & 0xFF)) - (unsigned int)(unsigned __int16)v12) >> 16) - v13 * v13));
    v15 = 7 * ((v14 << 16) + (unsigned __int16)(HIWORD(v14) - abs(7 * (((v12 + (unsigned __int16)((((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) >> 8) - ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) * ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8))) & 0xFF)) - (unsigned int)(unsigned __int16)v12) >> 16) - v13 * v13))));
    v27 = 7 * ((v15 << 16) + (unsigned __int16)(HIWORD(v15) - v15 * v15));
    v41 = dword_140038018;
    v16 = (unsigned __int16)-((7 - ((unsigned __int16)dword_140038018 + (dword_140038018 & 0xFFFF0000))) >> 16) + (((unsigned __int8)(7 - dword_140038018) + ((unsigned __int8)-((unsigned __int16)(7 - dword_140038018) >> 8) << 8)) << 16);
    v28 = 5 * (((v16 + 4 * v16 - 1) << 16) + (unsigned __int16)(((unsigned int)(v16 + 4 * v16 - 1) >> 16) - (v16 + 4 * v16 - 1) * (v16 + 4 * v16 - 1)));
    v17 = ((unsigned __int16)(dword_14003801C - 31) << 16) + (unsigned __int16)(HIWORD(dword_14003801C) - 1);
    v18 = (v17 << 16) + (unsigned __int16)(HIWORD(v17) - v17 * v17);
    v19 = (((unsigned __int8)(BYTE2(v17) - v17 * v17) + ((unsigned __int8)-BYTE1(v18) << 8)) << 16) + (unsigned __int16)((v18 >> 16) - 1);
    v20 = (v19 << 16) + (unsigned __int16)(HIWORD(v19) - v19 * v19);
    v21 = 7 * (unsigned __int16)v20 - 7 * (v20 + (unsigned __int16)(31 * ((unsigned __int8)(11 * (BYTE2(v19) - v19 * v19) - 5) + ((unsigned __int8)(96 - 35 * ((unsigned __int16)(HIWORD(v19) - v19 * v19) >> 8)) << 8)))) + 31;
    LOWORD(v20) = -256 * ((unsigned __int8)(7 * v20 - 7 * (v20 + 31 * (11 * (BYTE2(v19) - v19 * v19) - 5)) + 31) + ((7 * v20 - 7 * (v20 + 31 * ((unsigned __int8)(11 * (BYTE2(v19) - v19 * v19) - 5) + ((unsigned __int8)(96 - 35 * ((unsigned __int16)(HIWORD(v19) - v19 * v19) >> 8)) << 8))) + 31) & 0xFF00)) + ((((unsigned __int16)-(signed __int16)((unsigned __int8)(7 * v20 - 7 * (v20 + 31 * (11 * (BYTE2(v19) - v19 * v19) - 5)) + 31) + ((7 * v20 - 7 * (v20 + 31 * ((unsigned __int8)(11 * (BYTE2(v19) - v19 * v19) - 5) + ((unsigned __int8)(96 - 35 * ((unsigned __int16)(HIWORD(v19) - v19 * v19) >> 8)) << 8))) + 31) & 0xFF00)) >> 8) + (unsigned __int8)(7 * v20 - 7 * (v20 + 31 * (11 * (BYTE2(v19) - v19 * v19) - 5)) + 31) + ((7 * v20 - 7 * (v20 + 31 * ((unsigned __int8)(11 * (BYTE2(v19) - v19 * v19) - 5) + ((unsigned __int8)(96 - 35 * ((unsigned __int16)(HIWORD(v19) - v19 * v19) >> 8)) << 8))) + 31) & 0xFF00)) & 0xFF);
    v29 = v21 + (unsigned __int16)(v20 + (unsigned __int8)(-101 - 5 * v20) - (unsigned __int8)v20) - (unsigned __int16)v21;
    _mm_storeu_si128((__m128i *)&v36, _mm_load_si128((const __m128i *)&xmmword_140024850));
    v35 = 0;
    sub_140002720(&v35, &v26, 16i64);
    v22 = (_QWORD *)sub_1400011A0(&v40, &v35, &v37);
    v23 = v22[2];
    if ( v22[3] >= 0x10ui64 )
      v22 = (_QWORD *)*v22;
    v24 = sub_140001340(&qword_140039930, v22, v23);
    sub_1400018B0(v24);
    sub_140001FD0(&v40);
    sub_140001FD0(&v35);
    sub_140001FD0(&v37);
    result = -1;
  }

验证函数

由于是静态链接的运行库,还有大量的垃圾代码。验证函数静态并不好分析。我采用的是猜测加上调试来验证的方法。

 

下面是几个关键的判断(已去除了参杂其中的垃圾代码):

 

flag长度为30:

do
    ++v6;
while ( key[v6] );
if ( (v6 & 0xFFF) + (v529 << 12) == 30 )

flag至少有3个'9'(比较的是字符的hash值):

      v10 = key;
      do
      {
        v184 = 0;
        v11 = *v10;
        LOBYTE(v184) = v11;
        v12 = &v184;
        for ( i = -3750763034362895579i64; *(_BYTE *)v12; v11 = *(_BYTE *)v12 )
        {
          i = 1099511628211i64 * (i ^ v11);
          v12 = (__int16 *)((char *)v12 + 1);
        }
        v14 = v8 + 1;
        if ( i != -5808600853619038060i64 )
          v14 = v8;
        v8 = v14;
        ++v9;
        ++v10;
      }
      while ( v9 < v6 );
      v1 = 32i64;
      if ( v14 >= 3 )

这里用了一个hash函数(后面的判断中也被多次用到):

signed __int64 __fastcall hash(char *a1)
{
  char v1; // dl
  signed __int64 result; // rax
  signed __int64 v3; // rax

  v1 = *a1;
  for ( result = 0xCBF29CE484222325i64; *a1; result = 0x100000001B3i64 * v3 )
  {
    ++a1;
    v3 = result ^ v1;
    v1 = *a1;
  }
  return result;
}

flag由'KXCTF2018'开头(也是用的hash函数来比较):

LOWORD(v183) = 0;
  LOBYTE(v183) = key[0];
  if ( hash((char *)&v183) == -5808510693665524758i64 )
  {
    LOBYTE(v183) = byte_140039301;
    if ( hash((char *)&v183) == -5808494200991101593i64 )
    {
      LOBYTE(v183) = byte_140039302;
      if ( hash((char *)&v183) == -5808519489758550446i64 )
      {
        LOBYTE(v183) = byte_140039303;
        if ( hash((char *)&v183) == -5808507395130640125i64 )
        {
          LOBYTE(v183) = byte_140039304;
          if ( hash((char *)&v183) == -5808522788293435079i64 )
          {
            LOBYTE(v183) = byte_140039305;
            if ( hash((char *)&v183) == -5808606351177179115i64 )
            {
              LOBYTE(v183) = byte_140039306;
              if ( hash((char *)&v183) == -5808608550200435537i64 )
              {
                LOBYTE(v183) = byte_140039307;
                if ( hash((char *)&v183) == -5808609649712063748i64 )
                {
                  LOBYTE(v183) = byte_140039308;
                  if ( hash((char *)&v183) == -5808599754107409849i64 )

整个flag的hash值(此处调试时无法判断,需要手动设置EIP绕过):

  if ( hash(key) == 0x4F8075587499C0FFi64 )
  {
    LODWORD(v46) = 31;
    LODWORD(v47) = 0;
  }

第一个'9'后面5个字符连接上'.DLL'为part1:

  sub_14000B7D0(&part1, 0i64, 260i64);
  v80 = (_BYTE *)sub_14000BDD8(key, "9");
  v81 = v80;
  part1 = v80[1];
  v702 = v80[2];
  v703 = v80[3];
  v704 = v80[4];
  v705 = v80[5];
  sub_14000E46C(&part1, 260i64, ".DLL");

第二个'9'和第三个'9'之间的部分为part2:

 v82 = sub_14000BDD8(v81 + 1, "9");
  v83 = v82;
  *(_BYTE *)sub_14000BDD8(v82 + 1, "9") = 0;
  sub_14000B7D0(&part2, 0i64, 260i64);
  sub_14000E55C(&part2, 260i64, (char *)(v83 + 1), 260i64);

最后的验证(伪代码表示,CM中是通过PEB来获取这些函数的地址的):

hModule = GetModuleHandle(part1);
pFunc = GetProcAddress(hModule,part2);
if(pFunc(0,30)<0)
    Success!
else
    Fail!

穷举

利用hash(flag)==0x4F8075587499C0FF来穷举:
这里比较坑。。。
1、CM中没有限定分隔符9的位置,穷举空间太大,我只能假设3个9把剩下的21的字符恰好分成2部分,第一部分长度为5,第二部分的长度为13。
2、dll名称的大小写不确定,比如GetModuleHandle("nTdlL.dll")也是能成功返回的。根据连接串'.DLL'为大写再次假设dll的名称(前5个字符)为大写的。

 

代码如下:(其中export文件为提取出来ntdll的导出表)

def f(s):
    r = 0xCBF29CE484222325
    for c in s:
        r = (0x100000001B3*(ord(c)^r))%(2**64)
    return r

path = r'\Desktop\kanxueCTF2018\12\export'

with open(path) as fp:
    data = fp.read()

l = data.split()
for a in l:
    if len(a)==13:
        s = 'KXCTF20189NTDLL9' + a + '9'
        print(s)
        if f(s)==0x4F8075587499C0FF:
            print('!!!')
            break

最后flag为KXCTF20189NTDLL9DbgUiContinue9



[防守篇]2018看雪.TSRC CTF 挑战赛(团队赛)11月1日征题开启!

最后于 2018-7-10 08:24 被jackandkx编辑 ,原因:
最新回复 (0)
返回