首页
论坛
专栏
课程

[原创]看雪CTF2019晋级赛Q2第六题《消失的岛屿》解题wp

2019-6-14 12:28 151

[原创]看雪CTF2019晋级赛Q2第六题《消失的岛屿》解题wp

2019-6-14 12:28
151

程序的流程:


IDA伪代码:

int __cdecl main()
{
  int v0; // eax@3
  _BYTE v2[3]; // [sp+11h] [bp-3Fh]@1
  const char *v3; // [sp+48h] [bp-8h]@3
  char *v4; // [sp+4Ch] [bp-4h]@3

  __main();
  printf("please enter Serial:");
  scanf(" %s", v2);
  if ( strlen(v2) > 0x31 )
    puts("error");
  v4 = (char *)calloc(1u, 0x400u);
  v0 = strlen(v2);
  base64_encode(v2, v4, v0);
  v3 = "!NGV%,$h1f4S3%2P(hkQ94==";
  if ( !strcmp("!NGV%,$h1f4S3%2P(hkQ94==", v4) )
    puts("Success");
  else
    puts("Please Try Again");
  free(v4);
  system("pause");
  return 0;
}

这里是程序的算法:


跟进去看看


IDA伪代码:

int __cdecl base64_encode(const uint8_t *bindata, char *base64, int binlength)
{
  int v3; // eax@2
  char *v4; // ebx@2
  int v5; // eax@3
  int v6; // ST0C_4@3
  char *v7; // ebx@3
  int v8; // eax@3
  int v9; // eax@4
  char *v10; // ebx@4
  int v11; // eax@5
  int v12; // eax@6
  char *v13; // ebx@6
  uint8_t current; // [sp+Bh] [bp-Dh]@2
  uint8_t currenta; // [sp+Bh] [bp-Dh]@4
  int j; // [sp+Ch] [bp-Ch]@1
  int ja; // [sp+Ch] [bp-Ch]@2
  int jb; // [sp+Ch] [bp-Ch]@4
  int i; // [sp+10h] [bp-8h]@1

  i = 0;
  j = 0;
  while ( i < binlength )
  {
    v3 = j;
    ja = j + 1;
    v4 = &base64[v3];
    *v4 = charEncrypt((bindata[i] >> 2) & 0x3F);
    current = 16 * bindata[i] & 0x30;
    if ( i + 1 >= binlength )
    {
      v5 = ja;
      v6 = ja + 1;
      v7 = &base64[v5];
      *v7 = charEncrypt(current);
      base64[v6] = '=';
      v8 = v6 + 1;
      j = v6 + 2;
      base64[v8] = '=';
      break;
    }
    v9 = ja;
    jb = ja + 1;
    v10 = &base64[v9];
    *v10 = charEncrypt((bindata[i + 1] >> 4) | current);
    currenta = 4 * bindata[i + 1] & 0x3C;
    if ( i + 2 >= binlength )
    {
      base64[jb] = charEncrypt(currenta);
      v11 = jb + 1;
      j = jb + 2;
      base64[v11] = '=';
      break;
    }
    base64[jb] = charEncrypt((bindata[i + 2] >> 6) | currenta);
    v12 = jb + 1;
    j = jb + 2;
    v13 = &base64[v12];
    *v13 = charEncrypt(bindata[i + 2] & 0x3F);
    i += 3;
  }
  base64[j] = 0;
  return j;
}

这里看到base64必备的编码变换函数:


跟进去看看,找到字符表


OD定位,查看里面的存储数据,这里也能用IDA直接看,但是我还是习惯用OD来定位。


到这里,就可以参考网上的base64,来写出对应的解密算法


int __cdecl base64_decode(char *base64, char *bindata, int binlength)
{
  int t = 0, x = 0, y = 0, i = 0;
  unsigned char c = 0;
  int g = 3;
 
  while (base64[x] != 0) {
    // 需要解码的数据对应的ASCII值对应base64_suffix_map的值
    c = charUnEncrypt(base64[x]);
    x++;
    if (c == 255) return -1;// 对应的值不在转码表中
    if (c == 253) continue;// 对应的值是换行或者回车
    if (c == 254) { c = 0; g--; }// 对应的值是'='
    t = (t << 6) | c; // 将其依次放入一个int型中占3字节
    if (++y == 4) {
      bindata[i++] = (unsigned char)((t >> 16) & 0xff);
      if (g > 1) bindata[i++] = (unsigned char)((t >> 8) & 0xff);
      if (g > 2) bindata[i++] = (unsigned char)(t & 0xff);
      y = t = 0;
    }
  }
  return i;
}

得出flag


程序解密完整源码如下:

#include "pch.h"
#include <iostream>
#include <locale>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string>
#include <windows.h>
char aTuvwxtulmnopqr[65] = "tuvwxTUlmnopqrs7YZabcdefghij8yz0123456VWXkABCDEFGHIJKLMNOPQRS9+/";
 
char __cdecl charEncrypt(int data)
{
  int dataa; // [esp+18h] [ebp+8h]
 
  dataa = aTuvwxtulmnopqr[data];
  if (dataa > 64 && dataa <= 90)
    return 155 - dataa;
  if (dataa > 96 && dataa <= 122)
    return dataa - 64;
  if (dataa > 47 && dataa <= 57)
    return dataa + 50;
  if (dataa == 43)
    return 119;
  if (dataa == 47)
    dataa = 121;
  return dataa;
}
 
char __cdecl charUnEncrypt(int data)
{
  int i;
  if (data == 121) {
    data = 47;
  }
  else if (data == 119) {
    data = 43;
  }
  else if (data > 47 + 50 && data <= 57 + 50) {
    data = data - 50;
  }
  else if (data > 96 - 64 && data <= 122 - 64) {
    data = data + 64;
  }
  else if (data >= 155 - 90 && data < 155 - 64) {
    data = 155 - data;
  }
  for (i = 0; i < 64; i++) {
    if (data == aTuvwxtulmnopqr[i])
      return i;
  }
  return 254;
}
 
int __cdecl base64_decode(char *base64, char *bindata, int binlength)
{
  int t = 0, x = 0, y = 0, i = 0;
  unsigned char c = 0;
  int g = 3;
 
  while (base64[x] != 0) {
    // 需要解码的数据对应的ASCII值对应base64_suffix_map的值
    c = charUnEncrypt(base64[x]);
    x++;
    if (c == 255) return -1;// 对应的值不在转码表中
    if (c == 253) continue;// 对应的值是换行或者回车
    if (c == 254) { c = 0; g--; }// 对应的值是'='
    t = (t << 6) | c; // 将其依次放入一个int型中占3字节
    if (++y == 4) {
      bindata[i++] = (unsigned char)((t >> 16) & 0xff);
      if (g > 1) bindata[i++] = (unsigned char)((t >> 8) & 0xff);
      if (g > 2) bindata[i++] = (unsigned char)(t & 0xff);
      y = t = 0;
    }
  }
  return i;
}
 
int __cdecl base64_encode(char *bindata, char *base64, int binlength)
{
  int v3; // eax
  char *v4; // ebx
  int v5; // eax
  int v6; // ST0C_4
  char *v7; // ebx
  int v8; // eax
  int v9; // eax
  char *v10; // ebx
  int v11; // eax
  int v12; // eax
  char *v13; // ebx
  uint8_t current; // [esp+Bh] [ebp-Dh]
  uint8_t currenta; // [esp+Bh] [ebp-Dh]
  int j; // [esp+Ch] [ebp-Ch]
  int ja; // [esp+Ch] [ebp-Ch]
  int jb; // [esp+Ch] [ebp-Ch]
  int i; // [esp+10h] [ebp-8h]
 
  i = 0;
  j = 0;
  while (i < binlength)
  {
    v3 = j;
    ja = j + 1;
    v4 = &base64[v3];
    *v4 = charEncrypt((bindata[i] >> 2) & 0x3F);
    current = (bindata[i] << 4) & 0x30;
    if (i + 1 >= binlength)
    {
      v5 = ja;
      v6 = ja + 1;
      v7 = &base64[v5];
      *v7 = charEncrypt(current);
      base64[v6] = '=';
      v8 = v6 + 1;
      j = v6 + 2;
      base64[v8] = '=';
      break;
    }
    v9 = ja;
    jb = ja + 1;
    v10 = &base64[v9];
    *v10 = charEncrypt((bindata[i + 1] >> 4) | current);
    currenta = 4 * bindata[i + 1] & 0x3C;
    if (i + 2 >= binlength)
    {
      base64[jb] = charEncrypt(currenta);
      v11 = jb + 1;
      j = jb + 2;
      base64[v11] = 61;
      break;
    }
    base64[jb] = charEncrypt((bindata[i + 2] >> 6) | currenta);
    v12 = jb + 1;
    j = jb + 2;
    v13 = &base64[v12];
    *v13 = charEncrypt(bindata[i + 2] & 0x3F);
    i += 3;
  }
  base64[j] = 0;
  return j;
}
char * wchar2char(const wchar_t* wchar)//wchar转换为char
{
	char * m_char;
	int len = WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), NULL, 0, NULL, NULL);
	m_char = new char[len + 1];
	WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), m_char, len, NULL, NULL);
	m_char[len] = '\0';
	return m_char;
}

int main()
{
  //goto lbtest;
  int i = 0;
  char buf[256] = { 0 };
  char buf1[256] = { 0 };
  const wchar_t* code = L"!NGV%,$h1f4S3%2P(hkQ94==";
  char* as = wchar2char(code);
  //base64_encode(as, buf, 1);
  base64_decode(as, buf1, 16);
  printf(buf1);
}



[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

上传的附件:
最新回复 (0)
游客
登录 | 注册 方可回帖
返回