BUUCTF reverse wp 21 - 30

news2024/12/23 5:50:08

[ACTF新生赛2020]rome

在这里插入图片描述

无壳, 直接拖进IDA32
y键把v2改成char[49], n键重命名为iuput

int func()
{
  int result; // eax
  int v1[4]; // [esp+14h] [ebp-44h]
  char input[49]; // [esp+24h] [ebp-34h] BYREF

  strcpy(&input[23], "Qsw3sj_lz4_Ujw@l");
  printf("Please input:");
  scanf("%s", input);
  result = (unsigned __int8)input[0];
  if ( input[0] == 65 )
  {
    result = (unsigned __int8)input[1];
    if ( input[1] == 67 )
    {
      result = (unsigned __int8)input[2];
      if ( input[2] == 84 )
      {
        result = (unsigned __int8)input[3];
        if ( input[3] == 70 )
        {
          result = (unsigned __int8)input[4];
          if ( input[4] == 123 )
          {
            result = (unsigned __int8)input[21];
            if ( input[21] == 125 )
            {
              v1[0] = *(_DWORD *)&input[5];
              v1[1] = *(_DWORD *)&input[9];
              v1[2] = *(_DWORD *)&input[13];
              v1[3] = *(_DWORD *)&input[17];
              *(_DWORD *)&input[40] = 0;
              while ( *(int *)&input[40] <= 15 )
              {
                if ( *((char *)v1 + *(_DWORD *)&input[40]) > 64 && *((char *)v1 + *(_DWORD *)&input[40]) <= 90 )
                  *((_BYTE *)v1 + *(_DWORD *)&input[40]) = (*((char *)v1 + *(_DWORD *)&input[40]) - 51) % 26 + 65;
                if ( *((char *)v1 + *(_DWORD *)&input[40]) > 96 && *((char *)v1 + *(_DWORD *)&input[40]) <= 122 )
                  *((_BYTE *)v1 + *(_DWORD *)&input[40]) = (*((char *)v1 + *(_DWORD *)&input[40]) - 79) % 26 + 97;
                ++*(_DWORD *)&input[40];
              }
              *(_DWORD *)&input[40] = 0;
              while ( *(int *)&input[40] <= 15 )
              {
                result = (unsigned __int8)input[*(_DWORD *)&input[40] + 23];
                if ( *((_BYTE *)v1 + *(_DWORD *)&input[40]) != (_BYTE)result )
                  return result;
                ++*(_DWORD *)&input[40];
              }
              return printf("You are correct!");
            }
          }
        }
      }
    }
  }
  return result;
}

0-4位是'ACTF{'最后1位是'}'直接爆破5-20位

s = 'Qsw3sj_lz4_Ujw@l'
print(len(s))
brutestr = ''

def transchar(num):
    if num > ord('@') and num <= ord('Z'):
        return (num - ord('3')) % 26 + ord('A')
    if num > ord('`') and num <= ord('z'):
        return (num - ord('O')) % 26 + ord('a')
    return num

for i in range(16):
    for n in range(128):
        if transchar(n) == ord(s[i]):
            print(i, n)
            brutestr += chr(n)
            break

flag = 'ACTF{' + brutestr + '}'
print(len(flag), flag)

[FlareOn4]login

html写的flag checker

<!DOCTYPE Html />
<html>
    <head>
        <title>FLARE On 2017</title>
    </head>
    <body>
        <input type="text" name="flag" id="flag" value="Enter the flag" />
        <input type="button" id="prompt" value="Click to check the flag" />
        <script type="text/javascript">
            document.getElementById("prompt").onclick = function () {
                var flag = document.getElementById("flag").value;
                var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
                if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
                    alert("Correct flag!");
                } else {
                    alert("Incorrect flag, rot again");
                }
            }
        </script>
    </body>
</html>

看到rotFlag那行, 可以猜测是rot13加密, 因为对每个字母字符做+13处理
最后要等于PyvragFvqrYbtvafNerRnfl@syner-ba.pbz, 直接解密得到flag
在线网址https://rot13.com/

[2019红帽杯]easyRE

无壳, 直接分析, string定位到关键字符串

__int64 sub_4009C6()
{
  __int64 result; // rax
  int i; // [rsp+Ch] [rbp-114h]
  __int64 v2; // [rsp+10h] [rbp-110h]
  __int64 v3; // [rsp+18h] [rbp-108h]
  __int64 v4; // [rsp+20h] [rbp-100h]
  __int64 v5; // [rsp+28h] [rbp-F8h]
  __int64 v6; // [rsp+30h] [rbp-F0h]
  __int64 v7; // [rsp+38h] [rbp-E8h]
  __int64 v8; // [rsp+40h] [rbp-E0h]
  __int64 v9; // [rsp+48h] [rbp-D8h]
  __int64 v10; // [rsp+50h] [rbp-D0h]
  __int64 v11; // [rsp+58h] [rbp-C8h]
  char v12[13]; // [rsp+60h] [rbp-C0h] BYREF
  char v13[4]; // [rsp+6Dh] [rbp-B3h] BYREF
  char v14[19]; // [rsp+71h] [rbp-AFh] BYREF
  char v15[32]; // [rsp+90h] [rbp-90h] BYREF
  int v16; // [rsp+B0h] [rbp-70h]
  char v17; // [rsp+B4h] [rbp-6Ch]
  char v18[72]; // [rsp+C0h] [rbp-60h] BYREF
  unsigned __int64 v19; // [rsp+108h] [rbp-18h]

  v19 = __readfsqword(0x28u);
  qmemcpy(v12, "Iodl>Qnb(ocy", 12);
  v12[12] = 127;
  qmemcpy(v13, "y.i", 3);
  v13[3] = 127;
  qmemcpy(v14, "d`3w}wek9{iy=~yL@EC", sizeof(v14));
  memset(v15, 0, sizeof(v15));
  v16 = 0;
  v17 = 0;
  sub_4406E0(0LL, v15, 37LL);
  v17 = 0;
  if ( sub_424BA0(v15) == 36 )
  {
    for ( i = 0; i < (unsigned __int64)sub_424BA0(v15); ++i )
    {
      if ( (unsigned __int8)(v15[i] ^ i) != v12[i] )
      {
        result = 4294967294LL;
        goto LABEL_13;
      }
    }
    sub_410CC0("continue!");
    memset(v18, 0, 0x40uLL);
    v18[64] = 0;
    sub_4406E0(0LL, v18, 64LL);
    v18[39] = 0;
    if ( sub_424BA0(v18) == 39 )
    {
      v2 = sub_400E44(v18);
      v3 = sub_400E44(v2);
      v4 = sub_400E44(v3);
      v5 = sub_400E44(v4);
      v6 = sub_400E44(v5);
      v7 = sub_400E44(v6);
      v8 = sub_400E44(v7);
      v9 = sub_400E44(v8);
      v10 = sub_400E44(v9);
      v11 = sub_400E44(v10);
      if ( !(unsigned int)sub_400360(v11, off_6CC090) )
      {
        sub_410CC0("You found me!!!");
        sub_410CC0("bye bye~");
      }
      result = 0LL;
    }
    else
    {
      result = 4294967293LL;
    }
  }
  else
  {
    result = 0xFFFFFFFFLL;
  }
LABEL_13:
  if ( __readfsqword(0x28u) != v19 )
    sub_444020();
  return result;
}

盲猜base64, 提取数据

from idaapi import *

bytes_addr = 0x00000000004A23A8
bytes_size = 0x00000000004A2690 - 0x00000000004A23A8
data = get_bytes(bytes_addr,bytes_size) 
print(data)

连续base64解码10次得到一个地址https://bbs.pediy.com/thread-254172-3.htm
进去之后看评论区, 得到flag (= =

非预期解属于是, 正解是定位到下面的一串字符串的交叉引用函数sub_400D35

unsigned __int64 sub_400D35()
{
  unsigned __int64 result; // rax
  unsigned int v1; // [rsp+Ch] [rbp-24h]
  int i; // [rsp+10h] [rbp-20h]
  int j; // [rsp+14h] [rbp-1Ch]
  unsigned int v4; // [rsp+24h] [rbp-Ch]
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  v1 = sub_43FD20(0LL) - qword_6CEE38;
  for ( i = 0; i <= 1233; ++i )
  {
    sub_40F790(v1);
    sub_40FE60();
    sub_40FE60();
    v1 = sub_40FE60() ^ 0x98765432;
  }
  v4 = v1;
  if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 102 && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 103 )
  {
    for ( j = 0; j <= 24; ++j )
      sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));
  }
  result = __readfsqword(0x28u) ^ v5;
  if ( result )
    sub_444020();
  return result;
}

就是异或处理, 查看byte_6CC0A0的数据, 就是刚刚base 字符串幌子的下面的一串数据
在这里插入图片描述
就是用flag作为已知明文求出密钥, 然后用密钥与输入进行异或得到的值, 与这arr一串数据比较

from idaapi import *

addr = 0x00000000006CC0A0
sizes = 0x00000000006CC0C0 - 0x00000000006CC0A0
data = get_bytes(addr, sizes)
print(data)

arr = []
for i in data:
    arr.append(i)
print(arr)

解密

#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;

int main() {
    int arr[] = {64, 53, 32, 86, 93, 24, 34, 69, 23, 47, 36, 110, 98, 60, 39, 84, 72, 108, 36, 110, 114, 60, 50, 69, 91};
    string str0 = "flag";
    int key[5] = {0};
    cout << sizeof(arr) / sizeof(arr[0]) << endl;

    for (int i = 0; i < 4; ++i) {
        key[i] = str0[i] ^ arr[i];
    }

    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i) {
        cout << char(arr[i] ^ key[i % 4]);
    }
    cout << endl;
}

[GUET-CTF2019]re

在这里插入图片描述

upx脱壳, 拖入IDA

_BOOL8 __fastcall sub_4009AE(char *a1)
{
  if ( 1629056 * *a1 != 166163712 )
    return 0LL;
  if ( 6771600 * a1[1] != 731332800 )
    return 0LL;
  if ( 3682944 * a1[2] != 357245568 )
    return 0LL;
  if ( 10431000 * a1[3] != 1074393000 )
    return 0LL;
  if ( 3977328 * a1[4] != 489211344 )
    return 0LL;
  if ( 5138336 * a1[5] != 518971936 )
    return 0LL;
  if ( 7532250 * a1[7] != 406741500 )
    return 0LL;
  if ( 5551632 * a1[8] != 294236496 )
    return 0LL;
  if ( 3409728 * a1[9] != 177305856 )
    return 0LL;
  if ( 13013670 * a1[10] != 650683500 )
    return 0LL;
  if ( 6088797 * a1[11] != 298351053 )
    return 0LL;
  if ( 7884663 * a1[12] != 386348487 )
    return 0LL;
  if ( 8944053 * a1[13] != 438258597 )
    return 0LL;
  if ( 5198490 * a1[14] != 249527520 )
    return 0LL;
  if ( 4544518 * a1[15] != 445362764 )
    return 0LL;
  if ( 3645600 * a1[17] != 174988800 )
    return 0LL;
  if ( 10115280 * a1[16] != 981182160 )
    return 0LL;
  if ( 9667504 * a1[18] != 493042704 )
    return 0LL;
  if ( 5364450 * a1[19] != 257493600 )
    return 0LL;
  if ( 13464540 * a1[20] != 767478780 )
    return 0LL;
  if ( 5488432 * a1[21] != 312840624 )
    return 0LL;
  if ( 14479500 * a1[22] != 1404511500 )
    return 0LL;
  if ( 6451830 * a1[23] != 316139670 )
    return 0LL;
  if ( 6252576 * a1[24] != 619005024 )
    return 0LL;
  if ( 7763364 * a1[25] != 372641472 )
    return 0LL;
  if ( 7327320 * a1[26] != 373693320 )
    return 0LL;
  if ( 8741520 * a1[27] != 498266640 )
    return 0LL;
  if ( 8871876 * a1[28] != 452465676 )
    return 0LL;
  if ( 4086720 * a1[29] != 208422720 )
    return 0LL;
  if ( 9374400 * a1[30] == 515592000 )
    return 5759124 * a1[31] == 719890500;
  return 0LL;
}

直接解就行

a1 = chr(166163712 // 1629056)
a2 = chr(731332800 // 6771600)
a3 = chr(357245568 // 3682944)
a4 = chr(1074393000 // 10431000)
a5 = chr(489211344 // 3977328)
a6 = chr(518971936 // 5138336)
a8 = chr(406741500 // 7532250)
a9 = chr(294236496 // 5551632)
a10 = chr(177305856 // 3409728)
a11 = chr(650683500 // 13013670)
a12 = chr(298351053 // 6088797)
a13 = chr(386348487 // 7884663)
a14 = chr(438258597 // 8944053)
a15 = chr(249527520 // 5198490)
a16 = chr(445362764 // 4544518)
a17 = chr(981182160 // 10115280)
a18 = chr(174988800 // 3645600)
a19 = chr(493042704 // 9667504)
a20 = chr(257493600 // 5364450)
a21 = chr(767478780 // 13464540)
a22 = chr(312840624 // 5488432)
a23 = chr(1404511500 // 14479500)
a24 = chr(316139670 // 6451830)
a25 = chr(619005024 // 6252576)
a26 = chr(372641472 // 7763364)
a27 = chr(373693320 // 7327320)
a28 = chr(498266640 // 8741520)
a29 = chr(452465676 // 8871876)
a30 = chr(208422720 // 4086720)
a31 = chr(515592000 // 9374400)
a32 = chr(719890500 // 5759124)

print (a1,a2,a3,a4,a5,a6,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32)

最后差个a7, 爆破服务器得到1

[WUSTCTF2020]level1

在这里插入图片描述

无壳直接分析

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int i; // [rsp+4h] [rbp-2Ch]
  FILE *stream; // [rsp+8h] [rbp-28h]
  char ptr[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v7; // [rsp+28h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  stream = fopen("flag", "r");
  fread(ptr, 1uLL, 0x14uLL, stream);
  fclose(stream);
  for ( i = 1; i <= 19; ++i )
  {
    if ( (i & 1) != 0 )
      printf("%ld\n", (unsigned int)(ptr[i] << i));
    else
      printf("%ld\n", (unsigned int)(i * ptr[i]));
  }
  return 0;
}

i = 1 ~ 19, 奇数时左移i位, 偶数时乘上i; 结合output.txt

198
232
816
200
1536
300
6144
984
51200
570
92160
1200
565248
756
1474560
800
6291456
1782
65536000

写逆

#include<stdlib.h>

int main () {
    long long arr[] = {198, 232, 816, 200, 1536, 300,
                    6144, 984, 51200, 570, 92160,
                    1200, 565248, 756, 1474560,
                    800, 6291456, 1782, 65536000
                    };

    for (int i = 1; i <= 19; ++i) {
        if ( (i & 1) != 0 )
            printf("%c", (arr[i - 1] >> i));
        else
            printf("%c", (arr[i - 1] / i));
    }
}   

[SUCTF2019]SignIn

直接逆

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  char v4[16]; // [rsp+0h] [rbp-4A0h] BYREF
  char v5[16]; // [rsp+10h] [rbp-490h] BYREF
  char v6[16]; // [rsp+20h] [rbp-480h] BYREF
  char v7[16]; // [rsp+30h] [rbp-470h] BYREF
  char v8[112]; // [rsp+40h] [rbp-460h] BYREF
  char v9[1000]; // [rsp+B0h] [rbp-3F0h] BYREF
  unsigned __int64 v10; // [rsp+498h] [rbp-8h]

  v10 = __readfsqword(0x28u);
  puts("[sign in]");
  printf("[input your flag]: ");
  __isoc99_scanf("%99s", v8);
  sub_96A(v8, v9);
  __gmpz_init_set_str(v7, "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL);
  __gmpz_init_set_str(v6, v9, 16LL);
  __gmpz_init_set_str(v4, "103461035900816914121390101299049044413950405173712170434161686539878160984549", 10LL);
  __gmpz_init_set_str(v5, "65537", 10LL);
  __gmpz_powm(v6, v6, v5, v4);
  if ( (unsigned int)__gmpz_cmp(v6, v7) )
    puts("GG!");
  else
    puts("TTTTTTTTTTql!");
  return 0LL;
}

输入的数经过sub_96A, 执行 x 65537 % 103461035900816914121390101299049044413950405173712170434161686539878160984549 x^{65537} \% 103461035900816914121390101299049044413950405173712170434161686539878160984549 x65537%103461035900816914121390101299049044413950405173712170434161686539878160984549运算后与ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35比较
归约到RSA大数分解问题
M = ?
E = 65537
C = ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
N = 103461035900816914121390101299049044413950405173712170434161686539878160984549
分解N得到
P = 282164587459512124844245113950593348271
Q = 366669102002966856876605669837014229419

可以写解密脚本

import gmpy2
import binascii

n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
e = 65537
p = 282164587459512124844245113950593348271
q = 366669102002966856876605669837014229419
c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35

d = gmpy2.invert(e,(p-1)*(q-1))
m = gmpy2.powmod(c,d,n)
print(binascii.unhexlify(hex(m)[2:]).decode(encoding="utf-8"))

[MRCTF2020]Transform

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Str[104]; // [rsp+20h] [rbp-70h] BYREF
  int j; // [rsp+88h] [rbp-8h]
  int i; // [rsp+8Ch] [rbp-4h]

  sub_402230(argc, argv, envp);
  sub_40E640("Give me your code:\n");
  sub_40E5F0("%s", Str);
  if ( strlen(Str) != 33 )                      // 32 bytes length
  {
    sub_40E640("Wrong!\n");
    system("pause");
    exit(0);
  }
  for ( i = 0; i <= 32; ++i )
  {
    byte_414040[i] = Str[dword_40F040[i]];
    byte_414040[i] ^= LOBYTE(dword_40F040[i]);  // byte_414040[i] = Str[dword_40F040[i]] ^ dword_40F040[i]
  }
  for ( j = 0; j <= 32; ++j )
  {
    if ( byte_40F0E0[j] != byte_414040[j] )
    {
      sub_40E640("Wrong!\n");
      system("pause");
      exit(0);
    }
  }
  sub_40E640("Right!Good Job!\n");
  sub_40E640("Here is your flag: %s\n", Str);
  system("pause");
  return 0;
}

rev

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

unsigned char indexs[] =
{
    9,   0,   0,   0,  10,   0,   0,   0,  15,   0, 
    0,   0,  23,   0,   0,   0,   7,   0,   0,   0, 
   24,   0,   0,   0,  12,   0,   0,   0,   6,   0, 
    0,   0,   1,   0,   0,   0,  16,   0,   0,   0, 
    3,   0,   0,   0,  17,   0,   0,   0,  32,   0, 
    0,   0,  29,   0,   0,   0,  11,   0,   0,   0, 
   30,   0,   0,   0,  27,   0,   0,   0,  22,   0, 
    0,   0,   4,   0,   0,   0,  13,   0,   0,   0, 
   19,   0,   0,   0,  20,   0,   0,   0,  21,   0, 
    0,   0,   2,   0,   0,   0,  25,   0,   0,   0, 
    5,   0,   0,   0,  31,   0,   0,   0,   8,   0, 
    0,   0,  18,   0,   0,   0,  26,   0,   0,   0, 
   28,   0,   0,   0,  14,   0,   0,   0,   0,   0
};

unsigned char testvalues[] =
{
  103, 121, 123, 127, 117,  43,  60,  82,  83, 121, 
   87,  94,  93,  66, 123,  45,  42, 102,  66, 126, 
   76,  87, 121,  65, 107, 126, 101,  60,  92,  69, 
  111,  98,  77,   0,   0,   0,   0,   0,   0,   0
};

int main(int argc, char **argv) 
{
    char flag[33] = "\x00";
    int i = 0;
    for (i = 0; i < 32; ++i) 
    {
        int pos = indexs[i*4];
        // printf("%d\n", indexs[i*4]);
        flag[pos] = indexs[i*4] ^ testvalues[i];  
        // printf("%d %c\n", flag[pos], flag[pos]); 
    }
    printf("flag: %s\n", flag + 1);
}

[WUSTCTF2020]level2

在这里插入图片描述

脱壳,拉进IDA, shift + f12
在这里插入图片描述

完事

[ACTF新生赛2020]usualCrypt

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // esi
  int v5[3]; // [esp+8h] [ebp-74h] BYREF
  __int16 v6; // [esp+14h] [ebp-68h]
  char v7; // [esp+16h] [ebp-66h]
  char v8[100]; // [esp+18h] [ebp-64h] BYREF

  sub_403CF8(&unk_40E140);
  scanf("%s", v8);
  memset(v5, 0, sizeof(v5));
  v6 = 0;
  v7 = 0;
  sub_401080(v8, strlen(v8), v5);
  v3 = 0;
  while ( *((_BYTE *)v5 + v3) == byte_40E0E4[v3] )
  {
    if ( ++v3 > strlen((const char *)v5) )
      goto LABEL_6;
  }
  sub_403CF8(aError);
LABEL_6:
  if ( v3 - 1 == strlen(byte_40E0E4) )
    return sub_403CF8(aAreYouHappyYes);
  else
    return sub_403CF8(aAreYouHappyNo);
}

int __cdecl sub_401080(int a1, int a2, int a3)
{
  int v3; // edi
  int v4; // esi
  int v5; // edx
  int v6; // eax
  int v7; // ecx
  int v8; // esi
  int v9; // esi
  int v10; // esi
  int v11; // esi
  _BYTE *v12; // ecx
  int v13; // esi
  int v15; // [esp+18h] [ebp+8h]

  v3 = 0;
  v4 = 0;
  sub_401000();
  v5 = a2 % 3;
  v6 = a1;
  v7 = a2 - a2 % 3;
  v15 = a2 % 3;
  if ( v7 > 0 )
  {
    do
    {
      LOBYTE(v5) = *(_BYTE *)(a1 + v3);
      v3 += 3;
      v8 = v4 + 1;
      *(_BYTE *)(v8 + a3 - 1) = byte_40E0A0[(v5 >> 2) & 0x3F];
      *(_BYTE *)(++v8 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(a1 + v3 - 3) & 3)
                                            + (((int)*(unsigned __int8 *)(a1 + v3 - 2) >> 4) & 0xF)];
      *(_BYTE *)(++v8 + a3 - 1) = byte_40E0A0[4 * (*(_BYTE *)(a1 + v3 - 2) & 0xF)
                                            + (((int)*(unsigned __int8 *)(a1 + v3 - 1) >> 6) & 3)];
      v5 = *(_BYTE *)(a1 + v3 - 1) & 0x3F;
      v4 = v8 + 1;
      *(_BYTE *)(v4 + a3 - 1) = byte_40E0A0[v5];
    }
    while ( v3 < v7 );
    v5 = v15;
  }
  if ( v5 == 1 )
  {
    LOBYTE(v7) = *(_BYTE *)(v3 + a1);
    v9 = v4 + 1;
    *(_BYTE *)(v9 + a3 - 1) = byte_40E0A0[(v7 >> 2) & 0x3F];
    v10 = v9 + 1;
    *(_BYTE *)(v10 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(v3 + a1) & 3)];
    *(_BYTE *)(v10 + a3) = 61;
LABEL_8:
    v13 = v10 + 1;
    *(_BYTE *)(v13 + a3) = 61;
    v4 = v13 + 1;
    goto LABEL_9;
  }
  if ( v5 == 2 )
  {
    v11 = v4 + 1;
    *(_BYTE *)(v11 + a3 - 1) = byte_40E0A0[((int)*(unsigned __int8 *)(v3 + a1) >> 2) & 0x3F];
    v12 = (_BYTE *)(v3 + a1 + 1);
    LOBYTE(v6) = *v12;
    v10 = v11 + 1;
    *(_BYTE *)(v10 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(v3 + a1) & 3) + ((v6 >> 4) & 0xF)];
    *(_BYTE *)(v10 + a3) = byte_40E0A0[4 * (*v12 & 0xF)];
    goto LABEL_8;
  }
LABEL_9:
  *(_BYTE *)(v4 + a3) = 0;
  return sub_401030(a3);
}

经过sub_401080处理后, 与硬编码数据比较

int sub_401000()
{
  int result; // eax
  char v1; // cl

  for ( result = 6; result < 15; ++result )
  {
    v1 = byte_40E0AA[result];
    byte_40E0AA[result] = byte_40E0A0[result];
    byte_40E0A0[result] = v1;
  }
  return result;
}

会进行base64变表, 然后base64编码, 再转换大小写

int __cdecl sub_401030(const char *a1)
{
  __int64 v1; // rax
  char v2; // al

  v1 = 0i64;
  if ( strlen(a1) )
  {
    do
    {
      v2 = a1[HIDWORD(v1)];
      if ( v2 < 97 || v2 > 122 )
      {
        if ( v2 < 65 || v2 > 90 )
          goto LABEL_9;
        LOBYTE(v1) = v2 + 32;
      }
      else
      {
        LOBYTE(v1) = v2 - 32;
      }
      a1[HIDWORD(v1)] = v1;
LABEL_9:
      LODWORD(v1) = 0;
      ++HIDWORD(v1);
    }
    while ( HIDWORD(v1) < strlen(a1) );
  }
  return v1;
}

REV

import base64
import string

changelist = list('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')
origintable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
testValue = 'zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'

for i in range(6, 15):
    changelist[i], changelist[i+10] = changelist[i+10], changelist[i]

changetable = ''.join(changelist)
testValue = testValue.swapcase()
flag = base64.b64decode(testValue.translate(str.maketrans(changetable, origintable)))
print(flag)

Youngter-drive

在这里插入图片描述

如果运行时报错缺少dll, 或者0xc000007b错误, 去dll修复 / 检查system的dll文件版本(32bits / 64bits)解决
注意看文档, 32bit dll放在syswow64, 64bit dll放在system32, 不要想当然乱放
参考:
https://blog.csdn.net/VeryDelicious/article/details/119278996
https://blog.csdn.net/qq_16645423/article/details/83743220
https://www.dll-files.com/download/d57e2eda325bac8081fd054209d736ae/msvcr100d.dll.html?c=OWhmSFQ4MDZnTnpQQjE0Y2MyUHBqZz09

脱壳, 拖进IDA32

int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  void *v3; // ecx
  HANDLE Thread; // [esp+D0h] [ebp-14h]
  HANDLE hObject; // [esp+DCh] [ebp-8h]

  j_Inputs(v3);
  ::hObject = CreateMutexW(0, 0, 0);
  j_strcpy(Destination, Source);
  hObject = CreateThread(0, 0, StartAddress, 0, 0, 0);
  Thread = CreateThread(0, 0, sub_41119F, 0, 0, 0);
  CloseHandle(hObject);
  CloseHandle(Thread);
  while ( cnt != -1 )
    ;
  j_testfunc();
  CloseHandle(::hObject);
  return 0;
}

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);
}

// positive sp value has been detected, the output may be wrong!
char *__cdecl sub_411940(int a1, int a2)
{
  char *result; // eax
  char v3; // [esp+D3h] [ebp-5h]

  v3 = *(_BYTE *)(a2 + a1);
  if ( (v3 < 'a' || v3 > 122) && (v3 < 65 || v3 > 90) )// check upper & lower chars
    exit(0);
  if ( v3 < 97 || v3 > 122 )                    // not lower chars
  {
    result = off_418000[0];
    *(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 38];
  }
  else                                          // lower chars
  {
    result = off_418000[0];
    *(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 96];
  }
  return result;
}

根据大小写字母相对QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm的位置进行置换, 输入串长度为30(坑点, 最后比较的串只有29长, 最后一位理论上是随意输入都可以通过, 不过BUU这里是E, 只能说程序写的有问题)
同时注意该程序是多线程编程, 两个线程一个有process函数, 一个没有, 单纯是cnt--, 所以是奇数序数处理, 偶数维持不变
REV

#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

void revfunc(string source, int cnt, const string changetable, char *flag) {
    char v3 = source[cnt];
    if ( (v3 < 97 || v3 > 122) && (v3 < 65 || v3 > 90) ) {
        // check upper & lower chars
        cout << v3 << endl;
        cout << "invalid char" << endl;
        exit(0);
    }
    cout << v3 << changetable.find(v3) << endl;
    if ( v3 < 97 || v3 > 122 ) { // not lower chars
        flag[cnt] = changetable.find(v3) + 96;
    }
    else { // lower chars
        flag[cnt] = changetable.find(v3) + 38;
    }
}

int main() {
    string testValues = "TOiZiZtOrYaToUwPnToBsOaOapsySE"; // 29 length but 30 actually
    string changetable = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
    char flag[31] = "TOiZiZtOrYaToUwPnToBsOaOapsySE"; // last char is E on BUUCTF = =
    cout << testValues.size() << endl;
    for (int i = 28; i >= 0; --i)
        if (i % 2 == 1)
            revfunc(testValues, i, changetable, flag);   

    cout << sizeof(flag) << ' ' << flag << endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1051422.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【知识点】JavaScript中require的一些理解

以下内容源自个人理解&#xff0c;若有错误欢迎指出。 猜想 多个文件中require同一个文件时&#xff0c;对于首次出现的require&#xff0c;会去读取文件并执行一遍&#xff0c;然后加入缓存&#xff1b;之后当再次require到这个文件时&#xff0c;只会指向这个缓存&#xff0c…

使用 Velocity 模板引擎的 Spring Boot 应用

使用 Velocity 模板引擎的 Spring Boot 应用 模板引擎是构建动态内容的重要工具&#xff0c;特别适用于生成HTML、邮件内容、报告和其他文本文档。Velocity是一个强大的模板引擎&#xff0c;它具有简单易用的语法和灵活性。本文将介绍如何在Spring Boot应用中使用Velocity模板…

2023-9-29 JZ27 二叉树的镜像

题目链接&#xff1a;二叉树的镜像 import java.util.*;/** public class TreeNode {* int val 0;* TreeNode left null;* TreeNode right null;* public TreeNode(int val) {* this.val val;* }* }*/public class Solution {/*** 代码中的类名、方法名、参数…

【算法基础】一文掌握十大排序算法,冒泡排序、插入排序、选择排序、归并排序、计数排序、基数排序、希尔排序和堆排序

目录 1 冒泡排序&#xff08;Bubble Sort&#xff09; 2 插入排序&#xff08;Insertion Sort&#xff09; 3 选择排序&#xff08;Selection Sort&#xff09; 4. 快速排序&#xff08;Quick Sort&#xff09; 5. 归并排序&#xff08;Merge Sort&#xff09; 6 堆排序 …

力扣 -- 44. 通配符匹配

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:bool isMatch(string s, string p) {int ms.size();int np.size();//为了调整映射关系s s;p p;//多开一行多开一列vector<vector<bool>> dp(m1,vector<bool>(n1,false));//初始化//dp[0]…

uniapp 实现下拉筛选框 二次开发定制

前言 最近又收到了一个需求&#xff0c;需要在uniapp 小程序上做一个下拉筛选框&#xff0c;然后找了一下插件市场&#xff0c;确实有找到&#xff0c;但不过他不支持搜索&#xff0c;于是乎&#xff0c;我就自动动手&#xff0c;进行了二开定制&#xff0c;站在巨人的肩膀上&…

asp.net core mvc 文件上传,下载,预览

//文件上传用到了IformFile接口 1.1文件上传视图 <form action"/stu/upload" method"post" enctype"multipart/form-data"><input type"file" name"img" /><input type"submit" value"上传&…

分类预测 | Matlab实现BES-ELM秃鹰搜索算法优化极限学习机分类预测

分类预测 | Matlab实现BES-ELM秃鹰搜索算法优化极限学习机分类预测 目录 分类预测 | Matlab实现BES-ELM秃鹰搜索算法优化极限学习机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 Matlab实现BES-ELM秃鹰搜索算法优化极限学习机分类预测&#xff08;完整源码和数…

深度学习算法在工业视觉落地的思考

0.废话 距离上次的栈板识别的思考已经过去3个月&#xff0c;中间根据客户的需求和自己的思考&#xff0c;对软件又重新做了调整。但是整体上还是不满意。 0.1 老生常谈的工业视觉落地架构 对于软件架构&#xff0c;我实在没有太多的参考。没办法&#xff0c;公司根本不关心软…

react+IntersectionObserver实现页面丝滑帧动画

实现效果&#xff1a; 加入帧动画前&#xff1a; 普通的静态页面 加入帧动画后&#xff1a; 可以看到&#xff0c;加入帧动画后&#xff0c;页面效果还是比较丝滑的。 技术实现 加入animation动画类 先用 **scss **定义三种动画类&#xff1a; .withAnimation {.fade1 {ani…

学会这些,QtIFW制作安装包不再是难题

一文看懂如何利用QtIFW制作安装包&#xff0c;小白也能看懂且学会的软件安装包制作教程&#xff1b;&#xff08;本文不基于Qt工程&#xff09; 1 前言 1.1 安装包制作工具的选择 安装程序生成工具就是将应用程序和依赖的文件打包到一个可执行的安装程序种&#xff0c;可以简…

HTML之如何下载网页中的音频(二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【算法】莫队

这篇博客起源于本人把一道 p o w ( 2 , n ) pow(2,n) pow(2,n) 的问题考虑成求组合数前缀和的问题qwq&#xff0c;于是接触到了这个新算法来总结一下 参考自这篇文章&#xff0c;写得太好了 首先是一道模板题 题目意思是&#xff0c;给出一个数组a&#xff0c;再给出多个区…

What is an HTTP Flood DDoS attack?

HTTP 洪水攻击是一种针对 Web 和应用程序服务器的第 7 层分布式拒绝服务 &#xff08;DDoS&#xff09; 攻击。HTTP 洪水攻击通过使用 HTTP GET 或 HTTP POST 请求执行 DDoS 攻击。这些请求是有效的&#xff0c;并且针对可用资源&#xff0c;因此很难防范 HTTP 洪水攻击。 匿名…

特斯拉——使用人工智能制造智能汽车

特斯拉(Tesla)是电动汽车开发和推广的先驱。特斯拉对自动驾驶汽车的未来寄予厚望--实际上&#xff0c;每一辆特斯拉汽车都有可能通过软件升级成为自动驾驶汽车。该公司还生产和销售高级电池和太阳能电池板。 汽车的自动驾驶是按从1~5的等级划分的。自适应巡航控制和自动停车系…

论文笔记(整理):轨迹相似度顶会论文中使用的数据集

0 汇总 数据类型数据名称数据处理出租车数据波尔图 原始数据&#xff1a;2013年7月到2014年6月&#xff0c;170万条数据 ICDE 2023 Contrastive Trajectory Similarity Learning with Dual-Feature Attention 过滤位于城市&#xff08;或国家&#xff09;区域之外的轨迹 过…

【SSL】用Certbot生成免费HTTPS证书

1. 实验背景 服务器&#xff1a;CentOS7.x 示例域名&#xff1a; www.example.com 域名对应的web站点目录&#xff1a; /usr/local/openresty/nginx/html 2. 安装docker # yum -y install yum-utils# yum-config-manager --add-repo https://download.docker.com/linux/ce…

采集SEO方法-优化内链与外链建设

采集大量的文章数据&#xff0c;要想批量做SEO优化添加内链外链方法&#xff0c;可以使用简数采集器的处理规则实现。 简数采集器的一个处理规则&#xff0c;可以包含多种SEO方法&#xff0c;还可自由组合&#xff0c;强大灵活方便。 优化内链外链的SEO技巧&#xff1a; 1&a…

基于PYQT5的GUI开发系列教程【二】QT五个布局的介绍与运用

目录 本文概述 作者介绍 创建主窗口 水平布局 垂直布局 栅格布局 分裂器水平布局 分裂器垂直布局 自由布局 取消原先控件的布局的方法 尾言 本文概述 PYQT5是一个基于python的可视化GUI开发框架&#xff0c;具有容易上手&#xff0c;界面美观&#xff0c;多平台…

基于SpringBoot的教学资源库系统的设计与实现

目录 前言 一、技术栈 二、系统功能介绍 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 社会的进步&#xff0c;教育行业发展迅速&#xff0c;人们对教育越来越重视&#xff0c;在当今网络普及的情况下&#xff0c;教学模式也开始逐渐网络化&#xff0c;各大…