zoukankan      html  css  js  c++  java
  • BUUCTF RE Youngterdrive

    BUUCTF RE Youngter-drive

    1.查壳


    upx的 去kali脱壳

    2.IDA

    int __cdecl main_0(int argc, const char **argv, const char **envp)
    {
      HANDLE v4; // [esp+D0h] [ebp-14h]
      HANDLE hObject; // [esp+DCh] [ebp-8h]
    
      ((void (*)(void))sub_4110FF)();
      ::hObject = CreateMutexW(0, 0, 0);
      j_strcpy(Destination, &Source);
      hObject = CreateThread(0, 0, StartAddress, 0, 0, 0);
      v4 = CreateThread(0, 0, sub_41119F, 0, 0, 0);
      CloseHandle(hObject);
      CloseHandle(v4);
      while ( dword_418008 != -1 )
        ;
      sub_411190();
      CloseHandle(::hObject);
      return 0;
    }
    

    可以看到创建了两个进程
    hObject = CreateThread(0, 0, StartAddress, 0, 0, 0);
    v4 = CreateThread(0, 0, sub_41119F, 0, 0, 0);

    查看SrartAddress函数

    void __stdcall StartAddress_0(int a1)
    {
      while ( 1 )
      {
        WaitForSingleObject(hObject, 0xFFFFFFFF);
        if ( dword_418008 > -1 )
        {
          sub_41112C(&Source, dword_418008);
          --dword_418008;
          Sleep(0x64u);
        }
        ReleaseMutex(hObject);
      }
    }
    

    继续跟进sub_41112c函数

    char *__cdecl sub_411940(int a1, int a2)
    {
      char *result; // eax
      char v3; // [esp+D3h] [ebp-5h]
    
      v3 = *(_BYTE *)(a2 + a1);
      if ( (v3 < 97 || v3 > 122) && (v3 < 65 || v3 > 90) )
        exit(0);
      if ( v3 < 97 || v3 > 122 )
      {
        result = off_418000[0];
        *(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 38];
      }
      else
      {
        result = off_418000[0];
        *(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 96];
      }
      return result;
    }
    

    97 122是小学ascii字符a-z
    这就是一个判断大小写字符,对字符进行表替换。off_418000[0]的值为QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbn

    查看另一函数 sub_411B10(int a1)

    void __stdcall sub_411B10(int a1)
    {
      while ( 1 )
      {
        WaitForSingleObject(hObject, 0xFFFFFFFF);
        if ( dword_418008 > -1 )
        {
          Sleep(0x64u);
          --dword_418008;
        }
        ReleaseMutex(hObject);
      }
    }
    

    这里少了对我们输入字符的操作函数,就仅仅对dword_418008变量进行减1操作。

    回到主函数最后有个sub_411190函数,打开

    int sub_411880()
    {
      int i; // [esp+D0h] [ebp-8h]
    
      for ( i = 0; i < 29; ++i )
      {
        if ( Source[i] != off_418004[i] )
          exit(0);
      }
      return printf("\nflag{%s}\n\n", Destination);
    }
    
    

    然后就可以写脚本解题了。一开始索引dword_418008为29的时候要加密,那么索引i为0的时候不解密,为1的时候解密。
    阅读sub_411940可以得知,我们要找到最后与Dest相比较的字符串off_418004的每一位字符在加密函数中的字符串off_418000中出现的位置,
    再根据索引的奇偶,和位置+38是否大于等于65来判断是否进行解密以及如何解密。
    注意off_418004字符串只有29位,而我们需要30位,所以最后要添加一位。(根据答案,最后一位字符解密后为’E’)

     1 test = "TOiZiZtOrYaToUwPnToBsOaOapsyS"
      2 test1 = "TOiZiZtOrYaToUwPnToBsOaOapsySy" # 随便添加一位(说随便其实也不随便)
      3 key = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasd"
      4 Source=""
      5 for i in range(0,30):
      6     if i%2==1: # 加密
      7         # x = key.find(test[d]) # 会报错,out of range,test只有29位
      8         x = key.find(test1[i])
      9         if x+38 >= 65: 
     10             Source+=chr(x+38)
     11         else: 
     12             Source+=chr(x+96)
     13     else: # 不加密
     14         Source+=test1[i]
     15 print(Source)
    

    flag{ThisisthreadofwindowshahaIsESE}

  • 相关阅读:
    javablogs
    Android学习笔记WIFI设备
    线程
    初次尝试Chrome扩展开发——以幻灯片方式显示网页内的图片
    could not find the main class, Program will exit(已解决)
    tomcat6.0配置(含配置视频下载)
    Windows下JDK1.6.0+Tomcat6.0的安装配置
    Java学习
    【翻译】在没有安装ASP.NET MVC3的服务器上运行ASP.NET MVC3的程序scottgu
    AForge.NET框架的使用
  • 原文地址:https://www.cnblogs.com/socialbiao/p/15681044.html
Copyright © 2011-2022 走看看