WriteUp-i春秋-溯源

Posted cloud-tree

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WriteUp-i春秋-溯源相关的知识,希望对你有一定的参考价值。

一个简单的逆向qwq

技术图片

 

 叫你输入key,给出提示信息

--技术图片

 

 无壳

C++编写

老规矩:拖IDA

搜索fail找到了main函数

技术图片

 

 技术图片

 

 这个main流程有点复杂qwq

我们看看它的伪代码:

技术图片

 

全代码:

技术图片
  1 _DWORD *__fastcall sub_401D90(_DWORD *a1, _DWORD *a2)
  2 {
  3   _DWORD *v2; // esi
  4   _DWORD *v3; // ebx
  5   int v4; // eax
  6   signed int v5; // edi
  7   int v6; // ecx
  8   int v7; // eax
  9   void (__thiscall ***v8)(_DWORD, signed int); // eax
 10   bool v9; // cf
 11   _BYTE *v10; // eax
 12   int v11; // ecx
 13   int v12; // eax
 14   unsigned int v13; // edi
 15   int i; // eax
 16   char v15; // dl
 17   unsigned int v16; // edi
 18   _DWORD *v17; // eax
 19   _DWORD *v18; // eax
 20   int v19; // eax
 21   bool v20; // zf
 22   int v21; // eax
 23   int v22; // ecx
 24   int v24; // [esp+0h] [ebp-4Ch]
 25   int v25; // [esp+4h] [ebp-48h]
 26   int v26; // [esp+8h] [ebp-44h]
 27   int v27; // [esp+Ch] [ebp-40h]
 28   char v28; // [esp+10h] [ebp-3Ch]
 29   int v29; // [esp+14h] [ebp-38h]
 30   _DWORD *v30; // [esp+18h] [ebp-34h]
 31   char v31; // [esp+1Ch] [ebp-30h]
 32   int v32; // [esp+20h] [ebp-2Ch]
 33   int v33; // [esp+24h] [ebp-28h]
 34   _DWORD *v34; // [esp+28h] [ebp-24h]
 35   int v35; // [esp+2Ch] [ebp-20h]
 36   int v36; // [esp+30h] [ebp-1Ch]
 37   int v37; // [esp+34h] [ebp-18h]
 38   int v38; // [esp+38h] [ebp-14h]
 39   int *v39; // [esp+3Ch] [ebp-10h]
 40   int v40; // [esp+40h] [ebp-Ch]
 41   int v41; // [esp+44h] [ebp-8h]
 42   int v42; // [esp+48h] [ebp-4h]
 43 
 44   v39 = &v24;
 45   v2 = a2;
 46   v3 = a1;
 47   v34 = a1;
 48   v4 = *a1;
 49   v5 = 0;
 50   v32 = 0;
 51   HIBYTE(v38) = 0;
 52   v30 = a1;
 53   v6 = *(_DWORD *)((char *)a1 + *(_DWORD *)(v4 + 4) + 56);
 54   if ( v6 )
 55     (*(void (**)(void))(*(_DWORD *)v6 + 4))();
 56   v42 = 0;
 57   v31 = std::basic_istream<char,std::char_traits<char>>::_Ipfx(v3, 0);
 58   v42 = 1;
 59   if ( v31 )
 60   {
 61     v7 = std::ios_base::getloc((char *)v3 + *(_DWORD *)(*v3 + 4), &v28);
 62     LOBYTE(v42) = 2;
 63     v33 = sub_401940(v7);
 64     LOBYTE(v42) = 3;
 65     if ( v29 )
 66     {
 67       v8 = (void (__thiscall ***)(_DWORD, signed int))(*(int (**)(void))(*(_DWORD *)v29 + 8))();
 68       if ( v8 )
 69         (**v8)(v8, 1);
 70     }
 71     v9 = v2[5] < 0x10u;
 72     v2[4] = 0;
 73     if ( v9 )
 74       v10 = v2;
 75     else
 76       v10 = (_BYTE *)*v2;
 77     *v10 = 0;
 78     LOBYTE(v42) = 4;
 79     v11 = *(_DWORD *)(*v3 + 4);
 80     v12 = *(_DWORD *)((char *)v3 + v11 + 36);
 81     v13 = *(_DWORD *)((char *)v3 + v11 + 32);
 82     v37 = *(_DWORD *)((char *)v3 + v11 + 32);
 83     if ( v12 >= 0 && (v12 > 0 || v13) && (v36 = v12, v13 < 0xFFFFFFFE) )
 84     {
 85       v36 = v12;
 86     }
 87     else
 88     {
 89       v13 = -2;
 90       v37 = -2;
 91     }
 92     for ( i = std::basic_streambuf<char,std::char_traits<char>>::sgetc(*(_DWORD *)((char *)v3 + v11 + 56));
 93           ;
 94           i = std::basic_streambuf<char,std::char_traits<char>>::snextc(*(_DWORD *)((char *)v3
 95                                                                                   + *(_DWORD *)(v19 + 4)
 96                                                                                   + 56)) )
 97     {
 98       v15 = i;
 99       v36 = i;
100       if ( !v13 )
101         break;
102       if ( i == -1 )
103       {
104         v5 = 1;
105         goto LABEL_38;
106       }
107       if ( *(_BYTE *)(*(_DWORD *)(v33 + 12) + 2 * (unsigned __int8)i) & 0x48 )
108         break;
109       if ( (unsigned int)~v2[4] <= 1 )
110         sub_401780();
111       v16 = v2[4] + 1;
112       if ( v2[4] == -1 )
113       {
114         v9 = v2[5] < 0x10u;
115         v2[4] = 0;
116         if ( v9 )
117           *(_BYTE *)v2 = 0;
118         else
119           *(_BYTE *)*v2 = 0;
120       }
121       else
122       {
123         if ( v2[5] < v16 )
124         {
125           sub_401790(v2, v16);
126           v15 = v36;
127         }
128         if ( v2[5] < 0x10u )
129           v17 = v2;
130         else
131           v17 = (_DWORD *)*v2;
132         *((_BYTE *)v17 + v2[4]) = v15;
133         v9 = v2[5] < 0x10u;
134         v2[4] = v16;
135         if ( v9 )
136           v18 = v2;
137         else
138           v18 = (_DWORD *)*v2;
139         *((_BYTE *)v18 + v16) = 0;
140       }
141       v19 = *v3;
142       v13 = v37 - 1;
143       HIBYTE(v38) = 1;
144       --v37;
145     }
146     v5 = 0;
147 LABEL_38:
148     v42 = 1;
149   }
150   v20 = HIBYTE(v38) == 0;
151   v21 = *(_DWORD *)(*v3 + 4);
152   *(_DWORD *)((char *)v3 + v21 + 32) = 0;
153   *(_DWORD *)((char *)v3 + v21 + 36) = 0;
154   if ( v20 )
155     v5 |= 2u;
156   std::basic_ios<char,std::char_traits<char>>::setstate(
157     (char *)v3 + *(_DWORD *)(*v3 + 4),
158     v5,
159     0,
160     v24,
161     v25,
162     v26,
163     v27,
164     *(_DWORD *)&v28,
165     v29,
166     v30,
167     *(_DWORD *)&v31,
168     v32,
169     v33,
170     v34,
171     v35,
172     v36,
173     v37,
174     v38,
175     v39,
176     v40,
177     v41,
178     v42);
179   v42 = 6;
180   v22 = *(_DWORD *)((char *)v30 + *(_DWORD *)(*v30 + 4) + 56);
181   if ( v22 )
182     (*(void (**)(void))(*(_DWORD *)v22 + 8))();
183   return v3;
184 }
View IDA Code

 

简单分析一下可以看出:

sub_401D90这个函数是获取输入的(疑似有处理)

sub_401300是处理输入的

sub_401120也有点关系

后面有简单的处理与验证(暂时不管qwq)

 

先看看sub_401D90:

技术图片
_DWORD *__fastcall sub_401D90(_DWORD *a1, _DWORD *a2)
{
  _DWORD *v2; // esi
  _DWORD *v3; // ebx
  int v4; // eax
  signed int v5; // edi
  int v6; // ecx
  int v7; // eax
  void (__thiscall ***v8)(_DWORD, signed int); // eax
  bool v9; // cf
  _BYTE *v10; // eax
  int v11; // ecx
  int v12; // eax
  unsigned int v13; // edi
  int i; // eax
  char v15; // dl
  unsigned int v16; // edi
  _DWORD *v17; // eax
  _DWORD *v18; // eax
  int v19; // eax
  bool v20; // zf
  int v21; // eax
  int v22; // ecx
  int v24; // [esp+0h] [ebp-4Ch]
  int v25; // [esp+4h] [ebp-48h]
  int v26; // [esp+8h] [ebp-44h]
  int v27; // [esp+Ch] [ebp-40h]
  char v28; // [esp+10h] [ebp-3Ch]
  int v29; // [esp+14h] [ebp-38h]
  _DWORD *v30; // [esp+18h] [ebp-34h]
  char v31; // [esp+1Ch] [ebp-30h]
  int v32; // [esp+20h] [ebp-2Ch]
  int v33; // [esp+24h] [ebp-28h]
  _DWORD *v34; // [esp+28h] [ebp-24h]
  int v35; // [esp+2Ch] [ebp-20h]
  int v36; // [esp+30h] [ebp-1Ch]
  int v37; // [esp+34h] [ebp-18h]
  int v38; // [esp+38h] [ebp-14h]
  int *v39; // [esp+3Ch] [ebp-10h]
  int v40; // [esp+40h] [ebp-Ch]
  int v41; // [esp+44h] [ebp-8h]
  int v42; // [esp+48h] [ebp-4h]

  v39 = &v24;
  v2 = a2;
  v3 = a1;
  v34 = a1;
  v4 = *a1;
  v5 = 0;
  v32 = 0;
  HIBYTE(v38) = 0;
  v30 = a1;
  v6 = *(_DWORD *)((char *)a1 + *(_DWORD *)(v4 + 4) + 56);
  if ( v6 )
    (*(void (**)(void))(*(_DWORD *)v6 + 4))();
  v42 = 0;
  v31 = std::basic_istream<char,std::char_traits<char>>::_Ipfx(v3, 0);
  v42 = 1;
  if ( v31 )
  {
    v7 = std::ios_base::getloc((char *)v3 + *(_DWORD *)(*v3 + 4), &v28);
    LOBYTE(v42) = 2;
    v33 = sub_401940(v7);
    LOBYTE(v42) = 3;
    if ( v29 )
    {
      v8 = (void (__thiscall ***)(_DWORD, signed int))(*(int (**)(void))(*(_DWORD *)v29 + 8))();
      if ( v8 )
        (**v8)(v8, 1);
    }
    v9 = v2[5] < 0x10u;
    v2[4] = 0;
    if ( v9 )
      v10 = v2;
    else
      v10 = (_BYTE *)*v2;
    *v10 = 0;
    LOBYTE(v42) = 4;
    v11 = *(_DWORD *)(*v3 + 4);
    v12 = *(_DWORD *)((char *)v3 + v11 + 36);
    v13 = *(_DWORD *)((char *)v3 + v11 + 32);
    v37 = *(_DWORD *)((char *)v3 + v11 + 32);
    if ( v12 >= 0 && (v12 > 0 || v13) && (v36 = v12, v13 < 0xFFFFFFFE) )
    {
      v36 = v12;
    }
    else
    {
      v13 = -2;
      v37 = -2;
    }
    for ( i = std::basic_streambuf<char,std::char_traits<char>>::sgetc(*(_DWORD *)((char *)v3 + v11 + 56));
          ;
          i = std::basic_streambuf<char,std::char_traits<char>>::snextc(*(_DWORD *)((char *)v3
                                                                                  + *(_DWORD *)(v19 + 4)
                                                                                  + 56)) )
    {
      v15 = i;
      v36 = i;
      if ( !v13 )
        break;
      if ( i == -1 )
      {
        v5 = 1;
        goto LABEL_38;
      }
      if ( *(_BYTE *)(*(_DWORD *)(v33 + 12) + 2 * (unsigned __int8)i) & 0x48 )
        break;
      if ( (unsigned int)~v2[4] <= 1 )
        sub_401780();
      v16 = v2[4] + 1;
      if ( v2[4] == -1 )
      {
        v9 = v2[5] < 0x10u;
        v2[4] = 0;
        if ( v9 )
          *(_BYTE *)v2 = 0;
        else
          *(_BYTE *)*v2 = 0;
      }
      else
      {
        if ( v2[5] < v16 )
        {
          sub_401790(v2, v16);
          v15 = v36;
        }
        if ( v2[5] < 0x10u )
          v17 = v2;
        else
          v17 = (_DWORD *)*v2;
        *((_BYTE *)v17 + v2[4]) = v15;
        v9 = v2[5] < 0x10u;
        v2[4] = v16;
        if ( v9 )
          v18 = v2;
        else
          v18 = (_DWORD *)*v2;
        *((_BYTE *)v18 + v16) = 0;
      }
      v19 = *v3;
      v13 = v37 - 1;
      HIBYTE(v38) = 1;
      --v37;
    }
    v5 = 0;
LABEL_38:
    v42 = 1;
  }
  v20 = HIBYTE(v38) == 0;
  v21 = *(_DWORD *)(*v3 + 4);
  *(_DWORD *)((char *)v3 + v21 + 32) = 0;
  *(_DWORD *)((char *)v3 + v21 + 36) = 0;
  if ( v20 )
    v5 |= 2u;
  std::basic_ios<char,std::char_traits<char>>::setstate(
    (char *)v3 + *(_DWORD *)(*v3 + 4),
    v5,
    0,
    v24,
    v25,
    v26,
    v27,
    *(_DWORD *)&v28,
    v29,
    v30,
    *(_DWORD *)&v31,
    v32,
    v33,
    v34,
    v35,
    v36,
    v37,
    v38,
    v39,
    v40,
    v41,
    v42);
  v42 = 6;
  v22 = *(_DWORD *)((char *)v30 + *(_DWORD *)(*v30 + 4) + 56);
  if ( v22 )
    (*(void (**)(void))(*(_DWORD *)v22 + 8))();
  return v3;
}
View sub_401D90 Code

 

技术图片

 

 有……有点复杂

结合OD分析

【未完待续qwq】

 

以上是关于WriteUp-i春秋-溯源的主要内容,如果未能解决你的问题,请参考以下文章

WebShell代码分析溯源

WebShell代码分析溯源

日志分析与splunk浅谈

WebShell代码分析溯源

WebShell代码分析溯源

WebShell代码分析溯源