[Geek Challenge 2021] Reverse赛题复现

VNCTF和HGAME属实给👴整破防了,人直接自闭了半个月

现在拿这逼极客大挑战练个手,粗略看了眼wp还是有些新东西可以学的,顺便拿其中的简单题找下自信,争取下次TQLCTF👴能成功签到

Brute_force

第一次做golang逆向,本来ida报了个这个错

以为ida抽风了,想装个golanghelper帮帮忙,然后大爹评价到

那说明本萌新觉得看起来很奇怪的反编译其实是没有问题的🥺

我们猜测main_unnamed()是另外一坨main函数,应该是得进去跑一跑的,那*(_QWORD *)(os_Args + 24) == 24LL应该是在判断flag长度是否为24

main_unnamed中,main_encode()应该是加密,main_cipher1应该是正确的flag加后的样子

然后我们在main_encode()里发现了一个函数叫crypto_md5_Sum(),我选择相信出题人(

回到main_cipher1处,我们可以发现一堆md5值

我们一个一个去网站上查

4ad50c4af2c5beda7aca217afbac9bd6 = 3_sl
5781f597ce91fb5f66057f35846bcb78 = r0g@
957a3926d4ff16d0d3bac4ed3044537b = 7h3_
ae4b9b5b2468a3d15b6b8690b761e160 = rm_1
d7bf94ada03842f20934c5605728fbc5 = g0_p
f40b339be4c5898741b8a0d2a8007bd5 = gned

剩下就是个misc题了(

SYC{7h3_g0_pr0g@rm_13_slgned}

另:正解其实应该从flag长度为24,md5有6个推出每个md5对应4字节,然后爆破md5的,这才是题目名字是Brute_force的原因,可惜出题人的网站没我的强😋

easypyc

那直接用pyinstxtractor解包

一个刚知道的小技巧:把easypyc.pyc的magic numberr替换成struct.pyc的第一行,就不用费那么大的劲去对magic number啥的了

然后用uncompyle6反编译

whatbox = [
 0] * 256

def aaaaaaa(a, b):
    k = [
     0] * 256
    t = 0
    for m in range(256):
        whatbox[m] = m
        k[m] = ord(a[(m % b)])
    else:
        for i in range(256):
            t = (t + whatbox[i] + k[i]) % 256
            temp = whatbox[i]
            whatbox[i] = whatbox[t]
            whatbox[t] = temp


def bbbbbbbbbb(a, b):
    q = 0
    w = 0
    e = 0
    for k in range(b):
        q = (q + 1) % 256
        w = (w + whatbox[q]) % 256
        temp = whatbox[q]
        whatbox[q] = whatbox[w]
        whatbox[w] = temp
        e = (whatbox[q] + whatbox[w]) % 256
        a[k] = a[k] ^ whatbox[e] ^ 102


def ccccccccc(a, b):
    for i in range(b):
        a[i] ^= a[((i + 1) % b)]
    else:
        for j in range(1, b):
            a[j] ^= a[(j - 1)]


if __name__ == '__main__':
    kkkkkkk = 'Geek2021'
    tttttt = [117, 62, 240, 152, 195, 117, 103, 74, 240, 151, 173, 162, 17, 75, 141, 165, 136, 117, 113, 33, 98, 151, 174, 4, 48, 25, 254, 101, 185, 127, 131, 87]
    ssss = input('Please input your flag:')
    inp = [0] * len(ssss)
    if len(ssss) != 32:
        print('Length Error!!!!')
        exit(0)
    for i in range(len(ssss)):
        inp[i] = ord(ssss[i])
    else:
        aaaaaaa(kkkkkkk, len(kkkkkkk))
        bbbbbbbbbb(inp, 32)
        ccccccccc(inp, 32)
        for m in range(32):
            if tttttt[m] != inp[m]:
                raise Exception('sorry your flag is wrong')
            print('success!!!!!!')
            print('your flag is {}'.format(ssss))

很容易发现是个微调rc4加个异或,写出exp即可

#include <bits/stdc++.h>
using namespace std;
void init(int *s, char *key, int len)
{
	int t[256] = {0};
	char tmp = 0;
	for (int i = 0; i < 256; ++i)
	{
		s[i] = i;
		t[i] = key[i % len];
	}
	int j = 0;
	for (int i = 0; i < 256; ++i)
	{
		j = (j + s[i] + t[i]) % 256;
		swap(s[i], s[j]);
	}
}
void crypt(int *s, char *data, int len)
{
	int i = 0, j = 0, t = 0;
	char tmp;
	for (int k = 0; k < len; ++k)
	{
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		swap(s[i], s[j]); 
		t = (s[i] + s[j]) % 256;
		data[k] ^= s[t] ^ 102;
	}
}
char data[] = {117, 62, 240, 152, 195, 117, 103, 74, 240, 151, 173, 162, 17, 75, 141, 165, 136, 117, 113, 33, 98, 151, 174, 4, 48, 25, 254, 101, 185, 127, 131, 87};
char key[2333] = "Geek2021";
int s[260];
int main()
{
	for (int i = 31; i >= 1; --i) data[i] ^= data[i - 1];
	for (int i = 31; i >= 0; --i) data[i] ^= data[(i + 1) % 32];
	int len = strlen(key);
	init(s, key, len);
	len = strlen(data);
	crypt(s, data, len);
	cout << data;
	return 0;
}

得到flag:

SYC{Just_a_Eeeeeeasy_Rc4_right?}

new_language

exeinfo查一下发现是个c#的题

dnspy打开,在new_language处可以看到源码

using System;

namespace new___language
{
	// Token: 0x02000002 RID: 2
	internal class geek
	{
		// Token: 0x06000002 RID: 2 RVA: 0x00002058 File Offset: 0x00000258
		public static int getNumFromSBox(char index)
		{
			int num = (int)(index >> 4);
			int num2 = (int)(index & '\u000f');
			return geek.sbox[num * 16 + num2];
		}

		// Token: 0x06000003 RID: 3 RVA: 0x00002080 File Offset: 0x00000280
		private static void Main(string[] args)
		{
			Console.WriteLine("input:");
			string text = Console.ReadLine();
			int[] array = new int[34];
			int[] array2 = new int[]
			{
				64,
				249,
				133,
				69,
				146,
				253,
				253,
				207,
				182,
				4,
				157,
				207,
				251,
				4,
				60,
				81,
				59,
				77,
				146,
				77,
				207,
				26,
				38,
				207,
				64,
				77,
				177,
				77,
				64,
				195,
				77,
				253,
				253
			};
			bool flag = text.Length != 38;
			if (!flag)
			{
				bool flag2 = text.Substring(0, 4) != "SYC{" || text.Substring(37, 1) != "}";
				if (!flag2)
				{
					text = text.Substring(4, 33);
					for (int i = 0; i < 33; i++)
					{
						array[i] = geek.getNumFromSBox(text[i]);
					}
					for (int j = 0; j < 33; j++)
					{
						bool flag3 = array[j] != array2[j];
						if (flag3)
						{
							return;
						}
					}
					Console.WriteLine("good");
				}
			}
		}

		// Token: 0x04000001 RID: 1
		private static int[] sbox = new int[]
		{
			99,
			124,
			119,
			123,
			242,
			107,
			111,
			197,
			48,
			1,
			103,
			43,
			254,
			215,
			171,
			118,
			202,
			130,
			201,
			125,
			250,
			89,
			71,
			240,
			173,
			212,
			162,
			175,
			156,
			164,
			114,
			192,
			183,
			253,
			147,
			38,
			54,
			63,
			247,
			204,
			52,
			165,
			229,
			241,
			113,
			216,
			49,
			21,
			4,
			199,
			35,
			195,
			24,
			150,
			5,
			154,
			7,
			18,
			128,
			226,
			235,
			39,
			178,
			117,
			9,
			131,
			44,
			26,
			27,
			110,
			90,
			160,
			82,
			59,
			214,
			179,
			41,
			227,
			47,
			132,
			83,
			209,
			0,
			237,
			32,
			252,
			177,
			91,
			106,
			203,
			190,
			57,
			74,
			76,
			88,
			207,
			208,
			239,
			170,
			251,
			67,
			77,
			51,
			133,
			69,
			249,
			2,
			127,
			80,
			60,
			159,
			168,
			81,
			163,
			64,
			143,
			146,
			157,
			56,
			245,
			188,
			182,
			218,
			33,
			16,
			255,
			243,
			210,
			205,
			12,
			19,
			236,
			95,
			151,
			68,
			23,
			196,
			167,
			126,
			61,
			100,
			93,
			25,
			115,
			96,
			129,
			79,
			220,
			34,
			42,
			144,
			136,
			70,
			238,
			184,
			20,
			222,
			94,
			11,
			219,
			224,
			50,
			58,
			10,
			73,
			6,
			36,
			92,
			194,
			211,
			172,
			98,
			145,
			149,
			228,
			121,
			231,
			200,
			55,
			109,
			141,
			213,
			78,
			169,
			108,
			86,
			244,
			234,
			101,
			122,
			174,
			8,
			186,
			120,
			37,
			46,
			28,
			166,
			180,
			198,
			232,
			221,
			116,
			31,
			75,
			189,
			139,
			138,
			112,
			62,
			181,
			102,
			72,
			3,
			246,
			14,
			97,
			53,
			87,
			185,
			134,
			193,
			29,
			158,
			225,
			248,
			152,
			17,
			105,
			217,
			142,
			148,
			155,
			30,
			135,
			233,
			206,
			85,
			40,
			223,
			140,
			161,
			137,
			13,
			191,
			230,
			66,
			104,
			65,
			153,
			45,
			15,
			176,
			84,
			187,
			22
		};
	}
}

那简简单单爆个破就行了

#include <bits/stdc++.h>
using namespace std;
char enflag[] = 
{
	64,
	249,
	133,
	69,
	146,
	253,
	253,
	207,
	182,
	4,
	157,
	207,
	251,
	4,
	60,
	81,
	59,
	77,
	146,
	77,
	207,
	26,
	38,
	207,
	64,
	77,
	177,
	77,
	64,
	195,
	77,
	253,
	253
};
char sbox[] = 
{
	99,
	124,
	119,
	123,
	242,
	107,
	111,
	197,
	48,
	1,
	103,
	43,
	254,
	215,
	171,
	118,
	202,
	130,
	201,
	125,
	250,
	89,
	71,
	240,
	173,
	212,
	162,
	175,
	156,
	164,
	114,
	192,
	183,
	253,
	147,
	38,
	54,
	63,
	247,
	204,
	52,
	165,
	229,
	241,
	113,
	216,
	49,
	21,
	4,
	199,
	35,
	195,
	24,
	150,
	5,
	154,
	7,
	18,
	128,
	226,
	235,
	39,
	178,
	117,
	9,
	131,
	44,
	26,
	27,
	110,
	90,
	160,
	82,
	59,
	214,
	179,
	41,
	227,
	47,
	132,
	83,
	209,
	0,
	237,
	32,
	252,
	177,
	91,
	106,
	203,
	190,
	57,
	74,
	76,
	88,
	207,
	208,
	239,
	170,
	251,
	67,
	77,
	51,
	133,
	69,
	249,
	2,
	127,
	80,
	60,
	159,
	168,
	81,
	163,
	64,
	143,
	146,
	157,
	56,
	245,
	188,
	182,
	218,
	33,
	16,
	255,
	243,
	210,
	205,
	12,
	19,
	236,
	95,
	151,
	68,
	23,
	196,
	167,
	126,
	61,
	100,
	93,
	25,
	115,
	96,
	129,
	79,
	220,
	34,
	42,
	144,
	136,
	70,
	238,
	184,
	20,
	222,
	94,
	11,
	219,
	224,
	50,
	58,
	10,
	73,
	6,
	36,
	92,
	194,
	211,
	172,
	98,
	145,
	149,
	228,
	121,
	231,
	200,
	55,
	109,
	141,
	213,
	78,
	169,
	108,
	86,
	244,
	234,
	101,
	122,
	174,
	8,
	186,
	120,
	37,
	46,
	28,
	166,
	180,
	198,
	232,
	221,
	116,
	31,
	75,
	189,
	139,
	138,
	112,
	62,
	181,
	102,
	72,
	3,
	246,
	14,
	97,
	53,
	87,
	185,
	134,
	193,
	29,
	158,
	225,
	248,
	152,
	17,
	105,
	217,
	142,
	148,
	155,
	30,
	135,
	233,
	206,
	85,
	40,
	223,
	140,
	161,
	137,
	13,
	191,
	230,
	66,
	104,
	65,
	153,
	45,
	15,
	176,
	84,
	187,
	22
};
int getNumFromSBox(char index)
{
	int num = (int)(index >> 4);
	int num2 = (int)(index & '\u000f');
	return sbox[num * 16 + num2];
}
int main()
{
	int len = strlen(enflag);
	for (int i = 0; i < len; ++i)
	{
		for (int c = 0; c < 127; ++c)
		{
			if (getNumFromSBox(c) == enflag[i])
			{
				putchar(c);
				break;
			}
		}
	}
	return 0;
}

得到flag:

SYC{right!!_y0u_c0mpIete_C#_reVer3e!!}

Re0

main函数没有任何代码逻辑,直接看字符串窗口就拿到了flag:

SYC{Welcome_to_Geek_challenge2021}

Re1

一个简单的异或+base64解密

#include <bits/stdc++.h>
using namespace std;
char data[233];
inline void init()
{
	data[0] = 21;
	data[1] = 113;
	data[2] = 44;
	data[3] = 4;
	data[4] = 37;
	data[5] = 113;
	data[6] = 40;
	data[7] = 16;
	data[8] = 21;
	data[9] = 44;
	data[10] = 121;
	data[11] = 40;
	data[12] = 34;
	data[13] = 45;
	data[14] = 18;
	data[15] = 38;
	data[16] = 25;
	data[17] = 45;
	data[18] = 6;
	data[19] = 58;
	data[20] = 26;
	data[21] = 20;
	data[22] = 25;
	data[23] = 112;
	data[24] = 24;
	data[25] = 114;
	data[26] = 6;
	data[27] = 57;
	data[28] = 26;
	data[29] = 22;
	data[30] = 121;
	data[31] = 112;
	data[32] = 33;
	data[33] = 7;
	data[34] = 22;
	data[35] = 38;
	data[36] = 25;
	data[37] = 45;
	data[38] = 6;
	data[39] = 58;
	data[40] = 33;
	data[41] = 24;
	data[42] = 14;
	data[43] = 38;
	data[44] = 34;
	data[45] = 114;
	data[46] = 26;
	data[47] = 38;
	data[48] = 35;
	data[49] = 45;
	data[50] = 22;
	data[51] = 114;
	data[52] = 26;
	data[53] = 24;
	data[54] = 10;
	data[55] = 58;
	data[56] = 26;
	data[57] = 24;
	data[58] = 'p';
	data[59] = '}';
}
int main()
{
	init();
	for (int i = 0; i <= 59; ++i ) data[i] ^= 0x40u, putchar(data[i]);
	// then base64decode data[]
	return 0;
}

得到flag:

SYC{XOR_and_base64_are_the_basis_of_reverse}

wasm

占坑,明天学wasm然后再填

win32

查下壳发现有upx壳,脱壳后在字符串窗口发现是个裸的base64

得到flag:

SYC{y0u_g3t_A_f1ag_by_cyberloafing_auth0r}

调试

main里面只有这玩意

好像没啥用,感觉是藏东西了?看看汇编

14A0没啥卵用,1455感觉像是在输出什么东西,那么直接把jnz patch成jz,然后尝试运行程序直接输出,就拿到了flag:

SYC{C0ngr@tuIatlOns_thls_1s_th3_r!gHt_f!ag}

刘壮桌面美化大师

是我最烦的apk :<

在desktopbeautifierConfigureActivity里面看不出来有啥加密方法,考虑去res/values/string.html(字符串文件)碰碰运气,然后得到flag。。。

SYC{We1c0m3_t0_4ndRo1d_ReV3rse!}

正解好像是Activity里面发现AppWidget方法,然后添加桌面小组件即可拿到flag

买Activity

是我最烦的apk :<

看来直接安装没啥卵用

那用jadx查看mainfest,发现与以前做的题有点不一样,这次有MainActivity和ExportedActivity两个Activity

MainActivity中看起来只是处理手机上显示的那段对话的

而Export里面onCreate函数看起来会直接打印flag

decode类中的关键代码如下

public final String getDecodedFlag() {
        String str = stringFromNative().toString();
        int length = str.length();
        String str2 = "";
        int i = 0;
        while (i < length) {
            char charAt = str.charAt(i);
            i++;
            str2 = Intrinsics.stringPlus(str2, Character.valueOf((char) (charAt ^ 16)));
        }
        return str2;
    }

而我们会发现stringFromNative()是一个native函数,我们得用ida打开so文件去找,才能拼出完整的加密代码

v24 = __readfsqword(0x28u);
  std::string::basic_string<decltype(nullptr)>(&v21, "CSD!Os!yiyO#|iU`bu1");
  std::string::basic_string<decltype(nullptr)>(&v18, "Ikxc$dFdOCBq!Oh dtm");
  std::string::basic_string<decltype(nullptr)>(&v15, &unk_2AC18);
  v1 = (char *)&v15 + 1;
  for ( i = 0LL; i != 19; ++i )
  {
    v4 = &v22;
    if ( (v21 & 1) != 0 )
      v4 = (char *)ptr;
    v5 = v4[i];
    if ( (v15 & 1) != 0 )
    {
      v6 = v16;
      v7 = (v15 & 0xFFFFFFFFFFFFFFFELL) - 1;
      if ( v16 != v7 )
        goto LABEL_8;
    }
    else
    {
      v6 = (unsigned __int64)(unsigned __int8)v15 >> 1;
      v7 = 22LL;
      if ( v6 != 22 )
      {
LABEL_8:
        if ( (v15 & 1) != 0 )
          goto LABEL_9;
        goto LABEL_12;
      }
    }
    std::string::__grow_by(&v15, v7, 1LL, v7, v7, 0LL, 0LL);
    if ( (v15 & 1) != 0 )
    {
LABEL_9:
      v8 = (char *)v17;
      v16 = v6 + 1;
      goto LABEL_13;
    }
LABEL_12:
    LOBYTE(v15) = 2 * v6 + 2;
    v8 = (char *)&v15 + 1;
LABEL_13:
    v8[v6] = v5;
    v8[v6 + 1] = 0;
    v9 = &v19;
    if ( (v18 & 1) != 0 )
      v9 = (char *)v20;
    v10 = v9[i];
    if ( (v15 & 1) != 0 )
    {
      v11 = v16;
      v12 = (v15 & 0xFFFFFFFFFFFFFFFELL) - 1;
      if ( v16 != v12 )
        goto LABEL_17;
    }
    else
    {
      v11 = (unsigned __int64)(unsigned __int8)v15 >> 1;
      v12 = 22LL;
      if ( v11 != 22 )
      {
LABEL_17:
        if ( (v15 & 1) == 0 )
          goto LABEL_2;
        goto LABEL_21;
      }
    }
    std::string::__grow_by(&v15, v12, 1LL, v12, v12, 0LL, 0LL);
    if ( (v15 & 1) == 0 )
    {
LABEL_2:
      LOBYTE(v15) = 2 * v11 + 2;
      v3 = (char *)&v15 + 1;
      goto LABEL_3;
    }
LABEL_21:
    v3 = (char *)v17;
    v16 = v11 + 1;
LABEL_3:
    v3[v11] = v10;
    v3[v11 + 1] = 0;
  }
  if ( (v15 & 1) != 0 )
    v1 = (char *)v17;
  v13 = (*(__int64 (__fastcall **)(__int64, char *))(*(_QWORD *)a1 + 1336LL))(a1, v1);
  if ( (v15 & 1) == 0 )
  {
    if ( (v18 & 1) == 0 )
      goto LABEL_26;
LABEL_30:
    operator delete(v20);
    if ( (v21 & 1) == 0 )
      return v13;
LABEL_27:
    operator delete(ptr);
    return v13;
  }
  operator delete(v17);
  if ( (v18 & 1) != 0 )
    goto LABEL_30;
LABEL_26:
  if ( (v21 & 1) != 0 )
    goto LABEL_27;
  return v13;

我的评价是:真几把恶心,这么长的代码,最终化简了就这几句话😅

看完wp发现这是出题人故意加的混淆,然而萌新并不懂混淆,只能大眼瞪了呜呜呜

char a[] = "CSD!Os!yiyO#|iU`bu1";
char b[] = "Ikxc$dFdOCBq!Oh dtm";
char enf[50];
for (int i = 0; i < 19; ++i)
{
    enf[i * 2] = a[i];
    enf[i * 2 + 1] = b[i];
}

拼一下就能写出exp了

#include <bits/stdc++.h>
using namespace std;
char a[] = "CSD!Os!yiyO#|iU`bu1";
char b[] = "Ikxc$dFdOCBq!Oh dtm";
char enf[50];
int main()
{
	for (int i = 0; i < 19; ++i)
	{
	    enf[i * 2] = a[i];
	    enf[i * 2 + 1] = b[i];
	}
	for (int i = 0; i < 38; ++i) enf[i] ^= 16, putchar(enf[i]);
	return 0;
}

得到flag:

SYC{Th1s_4ct1Vity_iS_R3al1y_Exp0rted!}

posted @ 2022-02-15 13:22  iPlayForSG  阅读(225)  评论(0编辑  收藏  举报