2019 安洵杯 Re WP

0x01.EasyEncryption

测试文件:https://www.lanzous.com/i7soysb

1.IDA打开

int sub_416560()
{
  int v0; // eax
  int v1; // edx
  int v2; // edx
  int v3; // ecx
  int v4; // ST08_4
  char v6[4]; // [esp+310h] [ebp-7E0h]
  char Str; // [esp+700h] [ebp-3F0h]
  int v8; // [esp+AECh] [ebp-4h]
  int savedregs; // [esp+AF0h] [ebp+0h]

  sub_41132A((int)&unk_424091);
  sub_411294(std::cout, "输入flag: ");
  sub_41113B(std::cin, &Str);
  sub_4111F4(&Str, (int)v6);                    // v6="artqkoehqpkbihv"
  if ( (unsigned __int8)sub_4112B7(v6) )
  {
    sub_41105F("you are right\n");
    system("pause");
    sub_411339(v3, v2);
  }
  else
  {
    v0 = sub_411294(std::cout, "wrong");
    sub_41114A(v0, 10);
  }
  v4 = v1;
  sub_41137A(&savedregs, &dword_416660, 0);
  return sub_411339((unsigned int)&savedregs ^ v8, v4);
}

2.代码分析

输入flag之后,首先经过sub_4111F4(&Str, (int)v6)函数处理,再经过sub_4112B7(v6)函数判断。因为v6未知,所以首先通过最后一个函数找到v6

2.1 sub_4112B7函数分析

打开sub_4112B7函数

int __cdecl sub_413980(char *Str)
{
  int v1; // edx
  int v2; // ecx
  int v3; // edx
  int v4; // ecx
  int v5; // edx
  int v6; // ecx
  char *Str1; // [esp+D0h] [ebp-8h]

  sub_41132A((int)&unk_42405B);
  Str1 = (char *)sub_4112D5(Str);               // Base64
  if ( !j_strcmp(Str1, "YXJ0cWtvZWhxcGtiaWh2") )
  {
    free(Str1);
    sub_411339(v6, v5);
  }
  else
  {
    free(Str1);
    sub_411339(v2, v1);
  }
  return sub_411339(v4, v3);
}

通过分析得到,sub_4112D5函数是Base6加密,因此这个函数实际上就是将Str进行Base64加密,得到字符串Str1与"XJ0cWtvZWhxcGtiaWh2"比较。将"XJ0cWtvZWhxcGtiaWh2"进行Base64解密,得到Str,即v6="artqkoehqpkbihv"

2.2 sub_4111F4函数分析

接着,打开sub_4111F4函数,太长了,就不贴出来了。这个函数,分为三个部分:

0x01 第一部分:

 for ( i = 0; byte_41EC80[i]; ++i )
  {
    v16 = (unsigned __int8)byte_41EC80[i] - 97;
    v2 = j_abs(v16);
    v15[i] = v2;
  }

byte_41EC80已知,可以写出脚本变换,得到v15

Serial = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

Li = []

for i in Serial:
    Li.append(abs(ord(i) - 97)

0x02 第二部分

 v10 = j_strlen(Str);
  if ( v10 % i <= 0 )
  {
    v3 = v10 % i;                               // 余数
    v9 = v10 / i;                               // 商
  }
  else
  {
    v3 = v10 % i;
    v9 = v10 / i + 1;
  }

0x03 第三部分

  for ( j = 0; j < v9; ++j )
  {
    for ( k = 0; k < i; ++k )
    {
      if ( Str[v14] )                           // 输入的字符值不能为0
      {
        if ( Str[v14] < 97 || Str[v14] > 122 )  // 输入只能是小写字母
          exit(1);
        if ( (Str[v14] + v15[k] - 97) % 26 + 97 > 122 )
          v4 = (Str[v14] + v15[k] - 97) % 26 + 71;
        else
          v4 = (Str[v14] + v15[k] - 97) % 26 + 97;
        v8 = v4;
        v3 = v14 + a2;
        *(_BYTE *)(v14++ + a2) = v8;
      }
    }
  }

第二部分,第三部分和v6,结合分析,可以得到输入的flag应该是15,那么v9=1,v3=15,而第三部分实际上就是一个根据输入字符,进行选择变换得到v14(即v6),因为输入只能是小写字母,那我逆向变换的时候,只要得到的是小写字母,那就行了

3.脚本解密

Serial = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

Li = []

for i in Serial:
    Li.append(abs(ord(i) - 97))
print(Li)

t1 = len(Li) - 1

enc = "artqkoehqpkbihv"
v10 = len(enc)
v14 = 0
Str = ‘‘
for j in range(1):
    for k in range(v10):
        for n in range(10):
            tmp1 = ord(enc[v14]) - 71 + 26 * n + 97 - Li[k]
            tmp2 = ord(enc[v14]) - 97 + 26 * n + 97 - Li[k]
            if tmp1 >= 97 and tmp1 <= 122:
                print ("SUCCESS!")
                Str += chr(tmp1)
                break
            elif tmp2 >= 97 and tmp2 <= 122:
                print ("SUCCESS!")
                Str += chr(tmp2)
                break
            else:
                print("ERROR!")
        v14 = v14 + 1
print (Str)

4.get flag!

flag{umpnineissogood}

0x02 crackme

测试文件:https://www.lanzous.com/i7sucre

1.函数定位

首先定位到起始的函数sub_412AB0

int __stdcall sub_412AB0(int a1, int a2, int a3, int a4)
{
  size_t i; // [esp+D8h] [ebp-8h]

  for ( i = 0; i < j_strlen(BASE64_table_41A080); ++i )
  {
    if ( BASE64_table_41A080[i] <= 122 && BASE64_table_41A080[i] >= 97 )
    {
      BASE64_table_41A080[i] -= 32;
    }
    else if ( BASE64_table_41A080[i] <= 90 && BASE64_table_41A080[i] >= 65 )
    {
      BASE64_table_41A080[i] += 32;
    }
  }
  MessageBoxA(0, "hooked", "successed", 0);
  AddVectoredExceptionHandler(0, Handler);
  return 0;
}

2.程序分析

根据起始函数,这里首先对Base64的序列进行的变换,将大小写进行对换。

#include <iostream>
#include <string>

using namespace std;

string Str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int main()
{
    char v2;

    size_t i; // [esp+D8h] [ebp-8h]

    for (i = 0; i < Str.length(); ++i)
    {
        if (Str[i] <= 122 && Str[i] >= 97)
        {
            Str[i] -= 32;
        }
        else if (Str[i] <= 90 && Str[i] >= 65)
        {
            Str[i] += 32;
        }
    }

    cout << Str << endl;

    system("PAUSE");
    return 0;
}

SetUnhandledExceptionFilter()函数:https://baike.baidu.com/item/SetUnhandledExceptionFilter/2334228?fr=aladdin

AddVectoredExceptionHandler()函数:https://www.cnblogs.com/suanguade/p/6674232.html

这道就是将base64的表置换,重排“1UTAOIkpyOSWGv/mOYFY4R!!”,用base64来加密重排字符串,在经过一次sm4加密

对Base64的“添加了异常VEH向量”还有疑问,明天看下...

原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11972774.html

时间: 2024-08-30 11:42:38

2019 安洵杯 Re WP的相关文章

刷题记录:[安洵杯 2019]easy_serialize_php

目录 刷题记录:[安洵杯 2019]easy_serialize_php 知识点 PHP反序列化 刷题记录:[安洵杯 2019]easy_serialize_php 题目复现链接:https://buuoj.cn/challenges 参考链接:第二届安洵杯2019部分writeup 知识点 PHP反序列化 payload为_SESSION[phpflag]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==&quo

[安洵杯 2019]easy_web

0x00 知识点 md5强类型的绕过 方法比较固定: POST: a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 &b=%4d%c9%68%ff%0e%e3%

[安洵杯 2019]easy_serialize_php

0x00 知识点 PHP反序列化的对象逃逸 任何具有一定结构的数据,只要经过了某些处理而把自身结构改变,则可能会产生漏洞. 参考链接: https://blog.csdn.net/a3320315/article/details/104118688/ 过滤函数分为两种情况 第一种为关键词数增加 例如: where->hacker,这样词数由五个增加到6个. 第二种为关键词数减少 例如:直接过滤掉一些关键词,例如这道题目中. 过滤函数filter()是对serialize($_SESSION)进行

Upload To rce 安洵杯2019 这不是上传

0X0A 首先我们大致审计一下 三个源码文件 upload.php 上传页面 inlculde了helper extend了里面的helper 类型 大致是一个上传文件的函数 判断文件是否上传成功 如果失败则重新上传 再来看看helper里面的函数 看到了经典的反序列化magic _destruct()调用了 view_files 方法 view_file里面file_get_content函数可以造成rce或者任意文件读取 那么调用在哪里呐?? https://www.kancloud.cn/

2019红帽杯部分wp

xx 程序首先取输入的前4个字符作为xxtea加密的密钥之后进行xxtea加密.接着进行位置置换操作,然后又进行了以3个为一组的异或 首先逆向解出xxtea加密之后的结果 #include<stdio.h> #include<Windows.h> int main() { int count = 0; int b[24]; int a[] = { 0xCE, 0xBC, 0x40, 0x6B, 0x7C, 0x3A, 0x95, 0xC0, 0xEF, 0x9B, 0x20, 0x

【 Ex 2019 】 WinSrv 2019 安裝 Ex 2019

由於這個是測試環境,你還是需要準備:IP段.域名等. 1.Windows Server 2019 創建 域(略)其實跟Windows Server 2016的方法一致,有時間我會再做一個教程出來. 2.下載 Exchange 2019(體驗版)http://blog.51cto.com/happynews/2153851 3.客戶端加入 域(略)其實跟你以往的經驗一致,有時間我會再做一個. 4.管理員啟動PowerShell 5.運行IIS的安裝命令( Install-WindowsFeatur

Windows 2019 安裝 VMware tools

1.VMware Workstation 安裝 VMware Tools(類似微軟 Hyper-V 的增強型驅動) 2.D:\setup.exe 3. 4.選擇 SetupX64.exe 5. 6. 7.選擇完整安裝,下一步 8.開始安裝 9. 10.習慣性動作,重啟 10.1.重啟過程與啟動過程,略. 11.安裝完成后,會有一個VM的圖標 12.設備管理器沒有感歎號,任務完成. 原文地址:http://blog.51cto.com/happynews/2154287

【 Ex 2019 】 WinSrv 2019 安裝 Ex 2019(三)

1.插入Exchange2019的ISO文件,直接雙擊2.由於是測試環境,我們選擇不更新,下一步3.4.下一步5.同意,下一步6.默認,下一步7.黃色標記,下一步(由於我只有一台AD,所以直接選擇這兩個選項,邊緣傳輸服務器,你需要部署另外一台DC才可以,其實微軟公司是不建議我們AD上安裝任何的東西,由於是測試環境,無所謂啦~)8.默認下一步9.否,下一步(因為我的虛擬機沒有設置連接外網,所以不選擇這個)10.安裝11.檢查結果12.正式開始安裝,這個過程就要看你的硬件配置了--13.我以為它掛了

【 Ex 2019 】 WinSrv 2019 安裝 Ex 2019(二)

1.Install-WindowsFeature RSAT-ADDS2.利用Exchange擴展AD架構,從Exchange2013開始,我發現只要通過UI的嚮導去拓展這個AD架構是100%失敗,所以微軟公司的產品,還是好大的Bug,直接差評,哈哈哈哈,好吧,我們直接PowerShell吧!( .\Setup.exe /PrepareSchema /IAcceptExchangeServerLicenseTerms )Done3.( .\setup /IAcceptExchangeServerL