首页 > 其他分享 >湖南省网络攻防邀请赛 RE 题解

湖南省网络攻防邀请赛 RE 题解

时间:2023-12-03 22:33:05浏览次数:45  
标签:int 题解 ++ unsigned char RE a2 v7 邀请赛

ez_apkk

解题过程:

  • 将apk拖入jadx,查看MainActivity,发现是简单RC4加密,密钥是“55667788”,最后再将加密结果+1

    public String Encrypt(String plainText, String key) {
            int[] S = new int[256];
            byte[] K = new byte[256];
            char[] cArr = {'\n', '+', 181, '*', 225, ':', 244, 147, '\'', 182, 'J', 250, '-', 25, 135, 4, 188, '-', 230, '[', 'Q', '5', 'c', 22, 220, 25};
            char[] cArr2 = new char[26];
            Character[] keySchedul = new Character[plainText.length()];
            KSA(S, K, key);
            PRGA(S, keySchedul, plainText.length());
        //前面是RC4算法初始化
            for (int i = 0; i < plainText.length(); i++) {
                cArr2[i] = (char) ((plainText.charAt(i) ^ keySchedul[i].charValue()) + 1);//这行代码是RC4加密当前字节后 +1
            }
            for (int i2 = 0; i2 < 26; i2++) {
                if (cArr[i2] != cArr2[i2]) {
                    return "wrong!!!";
                }
            }
            return "right";
        }
    
    

解密脚本

#include <stdio.h>

void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k)
{
	int i = 0, j = 0;
	char k[256] = { 0 };
	unsigned char tmp = 0;
	for (i = 0; i < 256; i++) {
		s[i] = i;
		k[i] = key[i % Len_k];
	}
	for (i = 0; i < 256; i++) {
		j = (j + s[i] + k[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
	}
}
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
	unsigned char s[256];
	rc4_init(s, key, Len_k);
	int i = 0, j = 0, t = 0;
	unsigned long k = 0;
	unsigned char tmp;
	for (k = 0; k < Len_D; k++) {
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
		t = (s[i] + s[j]) % 256;
		Data[k] = Data[k] ^ s[t];
	}
}
void main()
{
	unsigned char key[] = "55667788";
	unsigned long key_len = sizeof(key) - 1;
	unsigned char data[] = {'\n', '+', 181, '*', 225, ':', 244, 147, '\'', 182, 'J', 250, '-', 25, 135, 4, 188, '-', 230, '[', 'Q', '5', 'c', 22, 220, 25};
	for (int i = 0; i < sizeof(data); i++)
	{
		data[i]-=1;
	}
	rc4_crypt(data, sizeof(data), key, key_len);
	for (int i = 0; i < sizeof(data); i++)
	{
		printf("%c", data[i]);
	}
	printf("\n");
	return;
}

运行得到flag:flag{a9k_1s_enjoy_ha6py!!}

ezdriver

解题过程:

  • IDA打开 R3-CTF.exe,发现程序调用了驱动文件 Driver_ctf.sys,用deviceIoControl函数来调用驱动程序里的功能。发送的控制代码为 0x222000

  • 逆向分析Driver_ctf.sys,发现加密代码在函数sub_1400010A0,其中里面调用的函数sub_140001590为对称加密算法,对加密数据byte_140003000再执行一次此对称加密算法即可得到原数据。

  • 但是还有一段加密算法对数据进行了加密,这里使用了求模运算,只能单字节逐个爆破

    for ( j = 1; j < 32; ++j )
          v12[j - 1] ^= ((unsigned __int8)v12[j - 1] % 0x12u + v12[j] + 5) ^ 0x41;
    
  • 我这里是使用递归算法来遍历每个可能的路径

解密算法:

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

unsigned char enc[] =
{
  0xA2, 0x23, 0x62, 0x6B, 0xDD, 0x75, 0x72, 0xD1, 0x7A, 0x88, 
  0x34, 0xD0, 0x6C, 0x23, 0xCB, 0x39, 0xAC, 0xDA, 0x76, 0x6C, 
  0x2E, 0x9B, 0x95, 0xC5, 0x79, 0x89, 0x39, 0x3C, 0x83, 0xC3, 
  0xDA, 0x1D, 0
};

void sub_140001590(unsigned int *a1, int a2)
{
  int j; // [rsp+4h] [rbp-44h]
  int i; // [rsp+8h] [rbp-40h]
  int v4; // [rsp+Ch] [rbp-3Ch] BYREF
  int *v5; // [rsp+10h] [rbp-38h]
  int v6; // [rsp+18h] [rbp-30h]
  char v7[16]; // [rsp+20h] [rbp-28h]

  v7[1] = a2 ^ 0x24;
  v7[0] = a2 ^ 0x6A;
  v7[8] = a2 ^ 0x1A;
  v7[2] = a2 ^ 0x35;
  v7[9] = a2 ^ 0x8D;
  v7[3] = a2 ^ 0x23;
  v7[11] = a2 ^ 0x9A;
  v7[4] = a2 ^ 0xCA;
  v7[5] = a2 ^ 0x4B;
  v7[6] = a2 ^ 0x21;
  v7[7] = a2 ^ 0x35;
  v7[10] = a2 ^ 0x91;
  v7[12] = a2 ^ 0x2C;
  v7[13] = a2 ^ 0xC2;
  v7[14] = a2 ^ 0x92;
  v7[15] = a2 ^ 7;
  for ( i = 0; i < 4; ++i )
  {
    v5 = &v4;
    v4 = *a1 ^ a2;
    for ( j = 0; j < 4; ++j )
    {
    	v5 = (int *)((char *)v5 + 1);
      	*((char *)v5 - 1) ^= v7[15 - (((unsigned __int8)i + (unsigned __int8)j) & 0xF)] | ((unsigned __int8)j << j) | j | 4;
    }
    v6 = ~a2 ^ v4;
    *a1++ = v6;
  }
}

void solver(int index)
{
	for(int i = index;i >= 0;i--)
	{
		unsigned char backup = enc[index - 1];
		unsigned char t = enc[i] + 5;
		for(int j = 18;j < 144;j+=0x12)
		{
			for(int k = 0;k < 0x12;k++)
			{
                //此处存在剪枝策略,若不符合限制条件则不会遍历该节点及其所有子节点
				if(((k + t) ^ 0x41 ^ (k + j)) == enc[i - 1]) 
				{
					enc[i - 1] = k+j;
					solver(index-1);
					enc[i-1] = backup; //状态回溯
				}
			}
		}
		if(index == 0)
			printf("%s\n",enc); //输出符合条件的路径
	}
}
int main()
{
	unsigned int *p = (unsigned int*)enc;
	int v6 = 0;
	do{
		sub_140001590(p, v6++); //对称算法解密
		p += 4;
	}while(v6 < 2);
	//递归算法遍历所有可能的路径
	solver(31);
}

运行后发现有四个结果,很明显第二个是正确的结果

blag{zcswelsvyioostfzjskygmojew}
flag{zcswelsvyioostfzjskygmojew}
olag{zcswelsvyioostfzjskygmojew}
墏g{zcswelsvyioostfzjskygmojew}
崅g{zcswelsvyioostfzjskygmojew}

标签:int,题解,++,unsigned,char,RE,a2,v7,邀请赛
From: https://www.cnblogs.com/S1nyer/p/17873949.html

相关文章

  • CF1692H Gambling 题解
    题意:思路:考虑离散化:枚举$x$中出现的每一个数$val$,$val$出现的次数为$cnt$,记录$val$每一次出现的索引$idx_i(1\lei\lecnt)$。设$x$中与$val$相等的数贡献为$+1$,与$val$不相等的数贡献为$-1$,那么问题转化为最大连续子段和。由......
  • ip ip-prefix
    Ip ip-prefix ip-prefix-name [index index-number {permit|deny} ipv4-address mask-length  [ match-network ] [ greater-equal greater-equal-value ][ less-equal less-equal-value ]详细说明:ip-prefix-name:前缀列表名称index-number:索引号1~4294967295pe......
  • P1004 [NOIP2000 提高组] 方格取数 题解
    题意:思路:考虑四维$dp$:设$dp[i][j][k][l]$表示两条路径分别走到$(i,j)$和$(k,l)$时所能获取的最大和,显然会超时。考虑三维$dp$:设$dp[i][j][k]$表示两条路径走了$i$步分别走到第$j$行和第$k$行时所能获取的最大和,通过当前步数$i$以及当......
  • this.$refs —— 只适用于选项式 API
    只适用于选项式API的情况下this.$refs是用于在Vue组件中访问子组件或者DOM元素的一种方式。通常,在模板中可以使用ref属性为子组件或者DOM元素指定引用,然后通过this.$refs来访问这些引用在选项式API(OptionsAPI)中,比如在methods、mounted、created等生命周......
  • vue 编辑器+使用场景+问题解决
    vue编辑器组件添加依赖"dependencies":{"@codemirror/autocomplete":"^6.4.2","@codemirror/commands":"^6.2.1","@codemirror/lang-javascript":"^6.0.2","@codemirror/lan......
  • 依赖 is already defined in a single-type import
    代码:importorg.apache.commons.lang3.StringUtils;不加依赖显示:Cannotresolvesymbol'lang3',加了依赖又显示:'com.sun.deploy.util.StringUtils'isalreadydefinedinasingle-typeimport这表明在代码或项目的其他地方已经导入了com.sun.deploy.util.StringUtils,并......
  • SP1716 GSS3 - Can you answer these queries III 题解
    题意:给定一个长度为$n$的序列$a$,$q$次操作,每次操作为以下之一:\(0\)\(x\)\(y\):将\(a_x\)修改为\(y\)\(1\)\(l\)\(r\):询问区间\([l,r]\)的最大连续子序列和思路:考虑线段树维护区间最大连续子序列和:线段树每个节点需要维护的信息:区间左端点$l$,区......
  • 一篇随笔学习React18组件通信与插槽
    了解什么是jsx->https://www.cnblogs.com/senior-shef/p/17872695.html一、了解props1、什么是propsReact支持两种组件,DOM组件和React组件。DOM组件指的是所有的HTML和SVG标签。比如说,如果我们想要使用标签,在React中,可以设置src和alt等属性。这些属性与纯HTML写法相同。在Rea......
  • Redis缓存和MySQL数据一致性方案详解
    需求起因在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MYSQL)间......
  • python报错:Pip 20.3+ break proxy connection
    参考:https://www.cnblogs.com/devilmaycry812839668/p/17872452.html   ==================================== 在proxy方式下使用pip有时候会报错。原因是某些版本pip依赖的urllib3库默认使用https方式进行网络连接,但是在proxy模式下由于大部分的proxy工具都是不支持h......