2020 BJDCTF Re encode

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

准备

获取信息:

  • 32位文件
  • UPX壳

IDA分析

UPX脱壳后,IDA打开

int sub_804887C()
{
  int v0; // eax
  int result; // eax
  int v2; // ecx
  unsigned int v3; // et1
  unsigned int i; // [esp+Ch] [ebp-FCh]
  unsigned int v5; // [esp+10h] [ebp-F8h]
  unsigned int v6; // [esp+14h] [ebp-F4h]
  int v7; // [esp+1Ah] [ebp-EEh]
  int v8; // [esp+1Eh] [ebp-EAh]
  int v9; // [esp+22h] [ebp-E6h]
  int v10; // [esp+26h] [ebp-E2h]
  __int16 v11; // [esp+2Ah] [ebp-DEh]
  char v12[30]; // [esp+2Ch] [ebp-DCh]
  int v13; // [esp+4Ah] [ebp-BEh]
  int v14; // [esp+4Eh] [ebp-BAh]
  int v15; // [esp+52h] [ebp-B6h]
  int v16; // [esp+56h] [ebp-B2h]
  int v17; // [esp+5Ah] [ebp-AEh]
  int v18; // [esp+5Eh] [ebp-AAh]
  int v19; // [esp+62h] [ebp-A6h]
  int v20; // [esp+66h] [ebp-A2h]
  int v21; // [esp+6Ah] [ebp-9Eh]
  int v22; // [esp+6Eh] [ebp-9Ah]
  int v23; // [esp+72h] [ebp-96h]
  int v24; // [esp+76h] [ebp-92h]
  __int16 v25; // [esp+7Ah] [ebp-8Eh]
  char v26; // [esp+7Ch] [ebp-8Ch]
  unsigned int v27; // [esp+FCh] [ebp-Ch]

  v27 = __readgsdword(0x14u);
  v7 = ‘galF‘;
  v8 = ‘ihT{‘;
  v9 = ‘_a_s‘;
  v10 = ‘galF‘;
  v11 = ‘}‘;
  v5 = strlen(&v7);
  v13 = ‘8D8E‘;
  v14 = ‘19DB‘;
  v15 = ‘A178‘;
  v16 = ‘65E1‘;
  v17 = ‘F35F‘;
  v18 = ‘9884‘;
  v19 = ‘F286‘;
  v20 = ‘4169‘;
  v21 = ‘2FA2‘;
  v22 = ‘F8BA‘;
  v23 = ‘A7DE‘;
  v24 = ‘5DFC‘;
  v25 = ‘E‘;
  printf("Please input your flag:");
  read(0, &v26, 256);
  if ( strlen(&v26) != 21 )
    exit(0);
  v0 = sub_8048AC2((int)&v26);
  strcpy((int)v12, v0);
  v6 = length(v12);
  for ( i = 0; i < v6; ++i )                    // 异或操作
    v12[i] ^= *((_BYTE *)&v7 + i % v5);
  sub_8048E24(v12, v6, &v7, v5);
  if ( !strcmp(v12, &v13) )
    exit(0);
  printf("right!");
  result = 0;
  v3 = __readgsdword(0x14u);
  v2 = v3 ^ v27;
  if ( v3 != v27 )
    sub_806FA00(v2);
  return result;
}

很多未知函数,我们能够猜出是什么函数,在代码中已改。

代码分析

在代码中,有两处函数我们不清楚作用。第一处

v0 = sub_8048AC2((int)&v26);

函数传入参数是我们输入的字符串,打开函数后

int __cdecl sub_8048AC2(int a1)
{
  int v2; // [esp+8h] [ebp-20h]
  int v3; // [esp+Ch] [ebp-1Ch]
  int v4; // [esp+10h] [ebp-18h]
  int v5; // [esp+18h] [ebp-10h]
  int v6; // [esp+1Ch] [ebp-Ch]

  v5 = length(a1);
  if ( v5 % 3 )
    v2 = 4 * (v5 / 3 + 1);
  else
    v2 = 4 * (v5 / 3);
  v6 = sub_80597A0(v2 + 1);
  *(_BYTE *)(v2 + v6) = 0;
  v3 = 0;
  v4 = 0;
  while ( v2 - 2 > v3 )
  {
    *(_BYTE *)(v6 + v3) = a0123456789Abcd[(unsigned __int8)(*(_BYTE *)(v4 + a1) >> 2)];
    *(_BYTE *)(v6 + v3 + 1) = a0123456789Abcd[16 * (*(_BYTE *)(v4 + a1) & 3) | (unsigned __int8)(*(_BYTE *)(v4 + 1 + a1) >> 4)];
    *(_BYTE *)(v6 + v3 + 2) = a0123456789Abcd[4 * (*(_BYTE *)(v4 + 1 + a1) & 0xF) | (unsigned __int8)(*(_BYTE *)(v4 + 2 + a1) >> 6)];
    *(_BYTE *)(v6 + v3 + 3) = a0123456789Abcd[*(_BYTE *)(v4 + 2 + a1) & 0x3F];
    v4 += 3;
    v3 += 4;
  }
  if ( v5 % 3 == 1 )
  {
    *(_BYTE *)(v3 - 2 + v6) = 61;
    *(_BYTE *)(v3 - 1 + v6) = 61;
  }
  else if ( v5 % 3 == 2 )
  {
    *(_BYTE *)(v3 - 1 + v6) = 61;
  }
  return v6;
}
.rodata:080BB9A8 a0123456789Abcd db ‘0123456789+/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ‘,0

通过观察,这应该是一个变表的Base64加密

第二处

sub_8048E24((int)v10, v4, (int)&v5, v3)

unsigned int __cdecl sub_8048E24(int a1, unsigned int a2, int a3, int a4)
{
  char v4; // ST2B_1
  unsigned int result; // eax
  unsigned int v6; // et1
  int v7; // [esp+1Ch] [ebp-11Ch]
  int v8; // [esp+20h] [ebp-118h]
  unsigned int i; // [esp+24h] [ebp-114h]
  char v10[256]; // [esp+2Ch] [ebp-10Ch]
  unsigned int v11; // [esp+12Ch] [ebp-Ch]

  v11 = __readgsdword(0x14u);
  sub_8048CC2((int)v10, a3, a4);
  LOBYTE(v7) = 0;
  LOBYTE(v8) = 0;
  for ( i = 0; i < a2; ++i )
  {
    v7 = (unsigned __int8)(v7 + 1);
    v8 = (unsigned __int8)(v10[v7] + v8);
    v4 = v10[v7];
    v10[v7] = v10[v8];
    v10[v8] = v4;
    *(_BYTE *)(a1 + i) ^= v10[(unsigned __int8)(v10[v7] + v10[v8])];
  }
  v6 = __readgsdword(0x14u);
  result = v6 ^ v11;
  if ( v6 != v11 )
    sub_806FA00();
  return result;
}

这应该是一个RC4加密函数, sub_8048CC2((int)v10, a3, a4);函数是初始化函数

思路

这样整个代码的思路就很明晰了,对输入字符串进行base64加密后,再进行异或操作,最后进行RC4加密(Key = "Flag{This_a_Flag}"),并与"E8D8BD91871A1E56F53F4889682F96142AF2AB8FED7ACFD5E"比较

解密

解密网站:

http://tool.chacuo.net/cryptrc4

http://ctf.ssleye.com/rc4.html

http://tools.jb51.net/password/rc4_encode

https://gchq.github.io/CyberChef/

得到解密的字符串:23152553081a5938126a3931275b0b1313085c330b356101511f105c

# -*- coding:utf-8 -*-

from base64 import b64decode

key = ‘Flag{This_a_Flag}‘
decode_byte = ‘23152553081a5938126a3931275b0b1313085c330b356101511f105c‘

encode_base64 = ‘‘
lists = []

for i in range(len(decode_byte)//2):
    lists.append(int(decode_byte[i*2:(i+1)*2],16))
# for i in range(0,len(decode_byte),2):
#     lists.append(int(decode_byte[i:i+2],16))

print (lists)
for i in range(len(lists)):
    encode_base64 += chr(lists[i] ^ ord(key[i%len(key)]))

t = ‘0123456789+/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=‘
table = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=‘
table = str.maketrans(t, table)
flag = b64decode(encode_base64.translate(table))
print(flag)

get flag!

BJD{0v0_Y0u_g07_1T!}

E8D8BD91871A1E56F53F4889682F96142AF2AB8FED7ACFD5E

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

时间: 2024-11-09 00:35:15

2020 BJDCTF Re encode的相关文章

20170427报错UnicodeEncodeError: ‘gbk’ codec can’t encode character ‘\xa0’ in position

今天写python,将网上数据流编写进文件里时遇到的,网上搜到结果并正确的进行了处理,把原文解决方法拷过来了,嘿嘿 使用Python写文件的时候,或者将网络数据流写入到本地文件的时候,大部分情况下会遇到:UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position - 这个问题. 网络上有很多类似的文件讲述如何解决这个问题,但是无非就是encode,decode相关的,这是导致该问题出现的真正原因吗?不是的.

Python之encode与decode浅析

 Python之encode与decode浅析 在 python 源代码文件中,如果你有用到非ASCII字符,则需要在文件头部进行字符编码的声明,声明如下: # code: UTF-8 因为python 只检查 #.coding 和编码字符串,为了美观等原因可以如下写法: #-*-coding:utf-8-*- 常见编码介绍: GB2312编码:适用于汉字处理.汉字通信等系统之间的信息交换. GBK编码:是汉字编码标准之一,是在 GB2312-80 标准基础上的内码扩展规范,使用了双字节编码.

文章标题 fzu 2020

Problem 2020 组合 Accept: 623 Submit: 1533 Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Description 给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数.例如C(5,2) = 10, C(4,2) = 6.可是当n,m比较大的时候,C(n,m)很大!于是xiaobo希望你输出 C(n,m) mod p的值! Input 输入数据第一行是一个正整数T,表示数据组数 (T <=

XTU1154:Encode

题目描述 行程编码是一种常见的无损压缩方式.比如针对于纯英文小写字符我们可以按以下方式进行编码:每个字节的低5位表示英文小写字母的序号(从0到25),高3位表示此字母连续的次数-1(0到7依次表示连续1到8次).比如说一个字节的二进制为00100001,其表示字符串bb.给你一个字符串,试将字符串编码为对应的行程编码,并将编码字节的16进制输出. 输入 第一行是一个整数K,表示样例的个数.以后每行是一个待编码的小写英文字母组成的字符串,其长度不超过1000个字符. 输出 每行输出一个编码的16进

UnicodeEncodeError: &#39;ascii&#39; codec can&#39;t encode character u&#39;\u5728&#39; in position 1

s = "图片picture"print chardet.detect(s) for c in s.decode('utf-8'): print c UnicodeEncodeError: 'ascii' codec can't encode character u'\u5728' in position 1 解决方案: reload(sys) sys.setdefaultencoding("utf8") UnicodeEncodeError: 'ascii' co

ural 2020 Traffic Jam in Flower Town

2020. Traffic Jam in Flower Town Time limit: 1.0 secondMemory limit: 64 MB Having returned from Sun City, Dunno told all his friends that every shorty may have a personal automobile. Immediately after that so many citizens took a fancy of becoming ro

URL地址中中文乱码详解(javascript中encodeURI和decodeURI方法、java.net.URLDecoder.encode、java.net.URLDecoder.decode)

引言: 在Restful类的服务设计中,经常会碰到需要在URL地址中使用中文作为的参数的情况,这种情况下,一般都需要正确的设置和编码中文字符信息.乱码问题就此产生了,该如何解决呢?且听本文详细道来. 1.  问题的引出 在Restful的服务设计中,查询某些信息的时候,一般的URL地址设计为: get /basic/service? keyword=历史 , 之类的URL地址. 但是,在实际的开发和使用中,确是有乱码情况的发生,在后台的读取keyword信息为乱码,无法正确读取. 2. 乱码是如

距离2020年一月30号还剩。。。

<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <style> #con { width: 500px; height: 200px; border: 2px solid fuchsia; margin: 30px auto; } #con1 { width: 500px; height: 100px; line-

UnicodeEncodeError: &#39;ascii&#39; codec can&#39;t encode characters in position 0-13: ordinal not i│ n range(128)

python保持网页文件遇到的错误,归根结底还是编码问题,改一下要保存的数据为utf-8就好了. 如下最简单: import sys reload(sys) sys.setdefaultencoding('utf-8') 更详细一些的python编码可以见下面文章: http://python.jobbole.com/85482/ 其实更好的解决方式是使用Python3,哼 UnicodeEncodeError: 'ascii' codec can't encode characters in