C/C++教程

BUUCTF reverse26-30 WP

本文主要是介绍BUUCTF reverse26-30 WP,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

写脚本技术很菜,所以和其他wp相比看起来比较麻烦
笔记是按照当时的题目排序写的,顺序可能有出入
做题是从0开始做起,所以前面部分也会尽可能写的详细一点
只要能记录并且了解到怎么做即可,所以就没有去在意排版
遇到不会的函数尽可能去百度了解

题目:[SUCTF2019]SignIn、相册、[BJDCTF2020]easy、[ACTF新生赛2020]usualCrypt、[MRCTF2020]Transform

26.[SUCTF2019]SignIn
得到的 flag 请包上 flag{} 提交。

查壳,无壳,IDA打开,查看main函数
在这里插入图片描述
稍微看了一下,发现用到Pow就觉得不对劲,然后看到了65537,加上gmpz,就猜想是一道RSA题目。
翻阅https://gmplib.org/manual/发现猜想正确
所以得到c,n,e

c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
e = 65537

首先分解N,用的是http://www.factordb.com
得到

q = 282164587459512124844245113950593348271
p = 366669102002966856876605669837014229419

然后写脚本

import gmpy2
import binascii

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

L = (q-1)*(p-1)
d = gmpy2.invert(e,L)
m = gmpy2.powmod(c,d,n)

print(binascii.unhexlify(hex(m)[2:]))

得到flag
在这里插入图片描述

flag{Pwn_@_hundred_years}

27.相册
你好,这是上次聚会相片,你看看(病毒,不建议安装到手机,提取完整邮箱即为flag) 注意:得到的 flag 请包上 flag{} 提交

apk逆向,GDA打开,不会em,以后学了补充。

28.[BJDCTF2020]easy
得到的 flag 请包上 flag{} 提交。来源:https://github.com/BjdsecCA/BJDCTF2020

IDA打开,看main函数
在这里插入图片描述
运行一下
在这里插入图片描述
应该在别的函数里,首先看的就是main函数上面的ques,看了之后感觉挺像的,先从这入手

int ques()
{
  int v0; // edx
  int result; // eax
  int v2[50]; // [esp+20h] [ebp-128h]
  int v3; // [esp+E8h] [ebp-60h]
  int v4; // [esp+ECh] [ebp-5Ch]
  int v5; // [esp+F0h] [ebp-58h]
  int v6; // [esp+F4h] [ebp-54h]
  int v7; // [esp+F8h] [ebp-50h]
  int v8; // [esp+FCh] [ebp-4Ch]
  int v9; // [esp+100h] [ebp-48h]
  int v10; // [esp+104h] [ebp-44h]
  int v11; // [esp+108h] [ebp-40h]
  int v12; // [esp+10Ch] [ebp-3Ch]
  int j; // [esp+114h] [ebp-34h]
  __int64 v14; // [esp+118h] [ebp-30h]
  int v15; // [esp+124h] [ebp-24h]
  int v16; // [esp+128h] [ebp-20h]
  int i; // [esp+12Ch] [ebp-1Ch]

  v3 = 2147122737;
  v4 = 140540;
  v5 = -2008399303;
  v6 = 141956;
  v7 = 139457077;
  v8 = 262023;
  v9 = -2008923597;
  v10 = 143749;
  v11 = 2118271985;
  v12 = 143868;
  for ( i = 0; i <= 4; ++i )
  {
    memset(v2, 0, sizeof(v2));
    v16 = 0;
    v15 = 0;
    v0 = *(&v4 + 2 * i);
    LODWORD(v14) = *(&v3 + 2 * i);
    HIDWORD(v14) = v0;
    while ( SHIDWORD(v14) > 0 || v14 >= 0 && (_DWORD)v14 )
    {
      v2[v16++] = ((SHIDWORD(v14) >> 31) ^ (((unsigned __int8)(SHIDWORD(v14) >> 31) ^ (unsigned __int8)v14)
                                          - (unsigned __int8)(SHIDWORD(v14) >> 31)) & 1)
                - (SHIDWORD(v14) >> 31);
      v14 /= 2LL;
    }
    for ( j = 50; j >= 0; --j )
    {
      if ( v2[j] )
      {
        if ( v2[j] == 1 )
        {
          putchar('*');
          ++v15;
        }
      }
      else
      {
        putchar(' ');
        ++v15;
      }
      if ( !(v15 % 5) )
        putchar(' ');
    }
    result = putchar(10);
  }
  return result;
}

可以发现,最后的时候会在指定位置分别打印空格和*号,根据Can you find me,可以知道我们需要想办法进入ques函数
用OD,改time的地址为ques的地址(因为time没啥用)
在这里插入图片描述
在这里插入图片描述

flag{HACKIT4FUN}

29.[ACTF新生赛2020]usualCrypt
得到的 flag 请包上 flag{} 提交。

(题目名字是crypt,文件名字叫base,先猜测一波换表base)
查壳,发现无壳
在这里插入图片描述

IDA打开,找到main函数,F5大法
在这里插入图片描述

首先查看第一个while,双击byte_40E0E4
在这里插入图片描述

……结果显而易见了,换表base和密文都给了,尝试解码,但是发现解不出来(啊这)
去研究一下main函数,之前进入的函数是判断函数,所以这次进入sub_401080加密函数

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)
                                            + (((signed int)*(unsigned __int8 *)(a1 + v3 - 2) >> 4) & 0xF)];
      *(_BYTE *)(v8 + a3 - 1) = byte_40E0A0[4 * (*(_BYTE *)(a1 + v3 - 2) & 0xF)
                                          + (((signed 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[((signed 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((const char *)a3);
}

首先查看sub_401000函数
在这里插入图片描述
其中,byte_40E0AA是

KLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

byte_40E0A0是

ABCDEFGHIJ

研究此循环,发现是将表中QRSTUVWXY和GHIJKLMNO进行了交换
(因为可以将此表拼接起来成为ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 然后又分开看,可以发现40E0AA是从K开始,40E0A0是从A开始,所以是这样换的表)
手动替换一下

ABCDEFQRSTUVWXYPGHIJKLMNOZabcdefghijklmnopqrstuvwxyz0123456789+/

然后吧,中间就是base过程,但是最后有个函数(sub_401030)
在这里插入图片描述
明显的大小写转换,在线转一下

string = 'zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'.swapcase() #sub_401030()
print (string)

在这里插入图片描述
得到之后再在线换表转一下

在这里插入图片描述

flag{bAse64_h2s_a_Surprise}

30.[MRCTF2020]Transform
得到的 flag 请包上 flag{} 提交。
感谢天璇战队供题。
天璇战队平台:http://ctf.merak.codes/

在这里插入图片描述
IDA64
在这里插入图片描述
要求长度33,然后进入循环,最后进行判断
判断是将byte_40E640与byte_414040进行判断,v6是我们输入的flag,在循环里会将其打乱之后赋值给byte_414040,然后byte_414040与我们输入的flag进行异或,现在已经给出了异或之后的值(byte_40F0E0中),可以写脚本了

enc = [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]#3F dup(0)是3F是0的意思
chg = [9, 10, 15, 23, 7, 24, 12, 6, 1, 16, 3, 17, 32, 29, 11,30, 27, 22, 4, 13, 19, 20, 21, 2, 25, 5, 31, 8, 18,26, 28, 14,0] #同理8 dup(0)是8个0的意思
tmp = ''
flag = ['']*len(enc)
for i in range(len(enc)):
    tmp += chr(enc[i]^chg[i]) #byte_414040
#print(tmp)
for i in range(len(tmp)):
    flag[chg[i]] += chr(ord(tmp[i]))
print(''.join(flag))

在这里插入图片描述

flag{Tr4nsp0sltiON_Clph3r_1s_3z}

这篇关于BUUCTF reverse26-30 WP的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!