1.[V&N2020 公开赛]CSRe

CSRe,打开报错,DIE查了一下,啥也没有,只知道.net程序,.net程序有de4dot(脱壳)和dnSpy(反编译),exeinfope查壳,由此可见.net程序在exeinfope查壳,发现Eazfuscator.NET的混淆,去混淆后在dnSpy里打开,在每个类里搜索main,终于在class3里找到main函数,

unity2d地图迷雾_unity2d地图迷雾


smethod_0加密两段字符串,最终得到了加密后的结果,第二段异或为0,表示字符串相等,smethod_0函数SHA1,找个解密网站即可得到原文。

2.[ACTF新生赛2020]usualCrypt

主函数打开,sub401080加密函数,下面是一个比较。

unity2d地图迷雾_反调试_02


sub_401080仔细看分为三层:

sub_401000对base64变表处理

中间base64加密

sub_401030大小写互换

逻辑清晰,逆向写出脚本。

import base64

Str = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
model = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
for i in range(6,15):
    Str[i],Str[i+10] = Str[i+10],Str[i]
Str = ''.join(Str)
enc = "zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9".swapcase()
dec = ""
for i in range(len(enc)):
    dec += model[Str.find(enc[i])]
print (dec)
print (Str)
print (base64.b64decode(dec))![在这里插入图片描述](https://img-blog.csdnimg.cn/202010011712288.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTA1NTI2OQ==,size_16,color_FFFFFF,t_30#pic_center)

函数一大串极有可能是某种常见算法。
识别出是一种算法,看其中还包含那些其他函数。
base64的换表操作,在表中的位置不变。

base64换表操作的进一步说明:
dec += model[Str.find(enc[i])]

3.[GWCTF 2019]xxor

unity2d地图迷雾_数组_03


主函数一个加密函数。一个比较函数。

比较函数,Z3脚本爆破。

from z3 import *
s=Solver()
a1=[0 for i in range(6)]
for i in range(6):
	a1[i]=Int('a1['+str(i)+']')
s.add(a1[2]-a1[3]==0x84A236FF)
s.add(a1[3]+a1[4]==0xFA6CB703)
s.add(a1[2]-a1[4]==0x42D731A8)
s.add(a1[0]==0xDF48EF7E)
s.add(a1[5]==0x84F30420)
s.add(a1[1]==0x20CAACF4)
print(s.check())
answer=s.model()
print(answer)
#a1[0] = 3746099070
#a1[1] = 550153460
#a1[2] = 3774025685
#a1[3] = 1548802262
#a1[4] = 2652626477
#a1[5] = 2230518816

加密函数,异或部分看成整体。IDA脚本向C脚本转变。

#include<iostream>
using namespace std;
int main()
{
	__int64 result; // rax
	unsigned int v3; // [rsp+1Ch] [rbp-24h]
	unsigned int v4; // [rsp+20h] [rbp-20h]
	int v5; // [rsp+24h] [rbp-1Ch]
	unsigned int i; // [rsp+28h] [rbp-18h]

	__int64 a1[6] = { 3746099070 ,550153460 ,3774025685 ,1548802262 ,2652626477,2230518816 };
	char a2[4] = { 2,2,3,4 };
	for (char j = 0; j <= 4; j += 2)
	{
		v3 = a1[j];
		v4 = a1[j+1];
		v5 = 0x458BCD42 * 64;
		for (i = 0; i <= 63; ++i)
		{
			v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
			v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + a2[0]) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
			v5 -= 0x458BCD42;
		}
	
	a1[j] = v3;
	a1[j+1] = v4;
	}
	
	for (int i = 0; i <= 5; i++)
	{
		cout << hex << a1[i];
	}
		
}
//666c61677b72655f69735f6772656174217d

unity2d地图迷雾_unity2d地图迷雾_04


C 16进制输出 cout << hex << a1[i];

4.[MRCTF2020]Transform

IDA虽然爆红,但整体逻辑还是清楚的,核心操作数组赋值加异或,和已知字符串比较。

unity2d地图迷雾_unity2d地图迷雾_05


逆向写出脚本。

r=[0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53, 0x79, 0x57, 0x5E, 0x5D, 0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E,0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E, 0x65, 0x3C, 0x5C, 0x45, 0x6F, 0x62, 0x4D]
tmp1=[0x09, 0x0A, 0x0F, 0x17, 0x07, 0x18, 0x0C, 0x06, 0x01, 0x10, 0x03, 0x11, 0x20, 0x1D, 0x0B, 0x1E, 0x1B, 0x16, 0x04, 0x0D,0x13, 0x14, 0x15, 0x02, 0x19, 0x05, 0x1F, 0x08, 0x12, 0x1A, 0x1C, 0x0E,0x0]
tmp2=[0 for i in range(33)]
flag=[0 for i in range(33)]
for i in range(33):
	tmp2[i]=tmp1[i]^r[i]
for i in range(33):
	flag[tmp1[i]]=tmp2[i]
print(''.join(map(chr,flag)))
#MRCTF{Tr4nsp0sltiON_Clph3r_1s_3z}
5.crackMe

输入要求输入姓名和密码,姓名已知是welcomebeijing。

sub_401090函数生成byte_416050数组。

main函数想要跳出死循环,sub_401830和sub_4011A0(loc_4011A0全部选中,按p,创造函数)返回值大于0。

sub_4011A0函数反编译可知只生成成功字符串和失败字符串,返回值必为1,所以重点来到sub_401830。

点击进入sub_401830,从后往前看 return v14 == 43924,找最近的v14调用,上面的函数sub_401470就必需成立,进入之后v17=dbappsec满足条件。其中掺着类似Ntglobalflag的反调试,通过分析反调试代码可知a[5]=s而不是f。

接着向上找v17的调用。

unity2d地图迷雾_字符串_06


sub_401710调用v17,但此函数a3<=v6一直成立,导致下面的if条件根本不会进入,对v17的没有改变。

上面的异或才是真正改变v17的值。找关键函数后,从前往后看。

字符转整型

unity2d地图迷雾_字符串_07


复杂数组变化,动调解决

unity2d地图迷雾_unity2d地图迷雾_08


动调可得byte_416050每次异或的值是0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd。

import hashlib

box = [0x2a, 0xd7, 0x92, 0xe9, 0x53, 0xe2, 0xc4, 0xcd]
s = "dbappsec"

secret = []

for i in range(len(s)):
    secret.append(hex(ord(s[i])^box[i]).replace("0x",''))
flag = ''.join(secret)
print(flag)
md = hashlib.md5()
md.update(flag.encode('utf-8'))
print ("flag{"+md.hexdigest()+"}")

这里存在的问题,字符转整型,这个过程是不可逆的,所以真正的password是得不到了,还有偶数位和奇数位高低位互换,最后的flag要互换回来吗?。出题没想这么多,只是将异或出来的v15的值作为了flag。

反调试的绕过是本题的重点:两种思路一种是利用插件使程序检测不到异常,不触发反调试,另一种思路是触发反调试改调试的跳转,这个需要精确的找到在哪里跳转。

本题采用第二种反调试方法将关键异或的上下两句反调的jz跳转改为jnz(字节74->75),因为只有上下两个反调影响v12,也就是影响的异或的取值。

unity2d地图迷雾_字符串_09

本题中还穿插着Ntglobalflag的反调试技巧。

6.[BJDCTF2020]BJD hamburger competition

小汉堡,233。unity游戏,找Assembly-CSharp.dll,再通过搜索flag或dasctf等关键字符串,找到核心函数。

在ButtonSpawnFruit里找到Spawn函数,SHA1加密的字符串,SHA1爆破后,再md5加密即可。

unity2d地图迷雾_unity2d地图迷雾_10


进入md5加密。

unity2d地图迷雾_unity2d地图迷雾_11


自己定义的md5取前20位大写的md5加密

7.[HDCTF2019]Maze

UPX的壳,脱壳后,拖到IDA里。主函数反编译不了,考虑去除花指令。

unity2d地图迷雾_字符串_12


jnz short near ptr loc_40102E+1跳转到下一行指令,花指令去除,nop掉,剩下的字符按C转汇编。红色代码部分按P创建函数。F5得到观察逻辑得到上下左右-wsad,和赛车游戏的上下左右同。

搜字符找到地图,猜测7*10地图。原本是空格我这里用0填充了一下。

unity2d地图迷雾_字符串_13


IDA指令:按D转数据,按C转代码。

8.[FlareOn4]IgniteMe

unity2d地图迷雾_数组_14


unity2d地图迷雾_unity2d地图迷雾_15


函数少的一批,输入字符串反向的异或操作

tmp=[0xd,0x26,0x49,0x45,0x2a,0x17,0x78,0x44,0x2b,0x6c,
0x5d,0x5e,0x45,0x12,0x2f,0x17,0x2b,0x44,0x6f,0x6e,![在这里插入图片描述](https://img-blog.csdnimg.cn/20201003174551425.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTA1NTI2OQ==,size_16,color_FFFFFF,t_70#pic_center)

0x56,0x9,0x5f,0x45,0x47,0x73,0x26,0xa,0xd,0x13,
0x17,0x48,0x42,0x1,0x40,0x4d,0xc,0x2,0x69]
v4=4
flag=[0 for i in range(39)]
for i in range(38,-1,-1):
	flag[i]=tmp[i]^v4
	v4=flag[i]
print(''.join(map(chr,flag)))
#R_y0u_H0t_3n0ugH_t0_1gn1t3@flare-on.com
9.[WUSTCTF2020]level1

奇偶数的分开操作,数组下标的关系是本题考点

unity2d地图迷雾_反调试_16

tmp=[198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782,65536000]
flag=[0 for i in range(19)]
for i in range(1,20):
	if(i&1):
		flag[i-1]=tmp[i-1]>>i
	else:
		flag[i-1]=tmp[i-1]//i
print(''.join(map(chr,flag)))
#ctf2020{d9-dE6-20c}
10.[WUSTCTF2020]level2

linux下UPX脱壳,IDA打开,flag映入眼帘。

unity2d地图迷雾_字符串_17

11.firmware

固件安全,完整版binwalk+firmware-mod-kit,步骤操作得flag。