HGAME2021部分逆向WP

week1

apacha

名字提示的也很明确了,TEA算法,这里用的是xxtea算法
xxtea
脚本

#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))

void btea(uint32_t *v, int n, uint32_t const key[4])
{
	uint32_t y, z, sum;
	unsigned p, rounds, e;
	if (n > 1)            /* Coding Part */
	{
		rounds = 6 + 52 / n;
		sum = 0;
		z = v[n - 1];
		do
		{
			sum += DELTA;
			e = (sum >> 2) & 3;
			for (p = 0; p < n - 1; p++)
			{
				y = v[p + 1];
				z = v[p] += MX;
			}
			y = v[0];
			z = v[n - 1] += MX;
		} while (--rounds);
	}
	else if (n < -1)      /* Decoding Part */
	{
		n = -n;
		rounds = 6 + 52 / n;
		sum = rounds * DELTA;
		y = v[0];
		do
		{
			e = (sum >> 2) & 3;
			for (p = n - 1; p > 0; p--)
			{
				z = v[p - 1];
				y = v[p] -= MX;
			}
			z = v[n - 1];
			y = v[0] -= MX;
			sum -= DELTA;
		} while (--rounds);
	}
}


int main()
{
	uint32_t v[35] = {0xe74eb323,0xb7a72836,0x59ca6fe2,0x967cc5c1,0xe7802674,0x3d2d54e6,0x8a9d0356,0x99dcc39c,0x7026d8ed,0x6a33fdad,0xf496550a,0x5c9c6f9e,0x1be5d04c,0x6723ae17,0x5270a5c2,0xac42130a,0x84be67b2,0x705cc779,0x5c513d98,0xfb36da2d,0x22179645,0x5ce3529d,0xd189e1fb,0xe85bd489,0x73c8d11f,0x54b5c196,0xb67cb490,0x2117e4ca,0x9de3f994,0x2f5aa1aa,0xa7e801fd,0xc30d6eab,0x1baddc9c,0x3453b04a,0x92a406f9};
	uint32_t const k[4] = {1,2,3,4};
	int n = -35; //n的绝对值表示v的长度,取正表示加密,取负表示解密
	// v为要加密的数据是两个32位无符号整数
	// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位;
	btea(v, n, k);
	for (int i = 0; i < 35; i++)
	{
		printf("%c", (char)v[i]);

	}
	return 0;
}
//hgame{l00ks_1ike_y0u_f0Und_th3_t34}

helloRe

与0xff自减的异或在这里插入图片描述
脚本

tmp=[0x97,0x99,0x9c,0x91,0x9e,0x81,0x91,0x9d,0x9b,0x9a,0x9a,0xab,0x81,0x97,0xae,0x80,0x83,0x8f,0x94,0x89,0x99,0x97]
flag=[]
n=0xff
for i in range(22):
	flag.append(tmp[i]^n)
	n=n-1
print(''.join(map(chr,flag)))
#hgame{hello_re_player}

pypy

python字节码,每个块是代表一行,强行译一手

raw_flag=input('give me your flag:\n')
cipher=list(raw_flag[6:-1])
length=len(cipher)
for i in range(length//2):
	cipher[2*i+1],cipher[2*i]=cipher[2*i],cipher[2*i+1]
res=[]
for i in range(length):
	res.append(ord(cipher[i])^i)
res=bytes(res).hex()
print('your flag: '+res)

逆向写出脚本即可

flag0='30466633346f59213b4139794520572b45514d61583151576638643a'
tmp=bytearray.fromhex(flag0)
length=len(tmp)
flag=[]
for i in range(length):
	flag.append(tmp[i]^i)
for i in range(length//2):
	flag[2*i+1],flag[2*i]=flag[2*i],flag[2*i+1]
print('hgame{'+''.join(map(chr,flag))+'}')
#hgame{G00dj0&_H3r3-I$Y@Ur_$L@G!~!~}

week2

helloRe2

输入两部分password
password1:
password
xmm,所以逆序字符串

2b0c5e6a3a20b189

password2:
静态看基本可以确定,AES CBC模式,所以找Key和iv,iv可以找到memcpy(v14, &unk_40312C, *(size_t *)v46);。Key的原理是
开启了一个新线程,共享内存,将输入的password1与0-f异或,得到Key。不过直接动调也可,CNG的加密方式BCryptGenerateSymmetricKey产生密钥,倒数第三个参数就是密钥
在这里插入图片描述
如何动调?此程序存在一个IsDebuggerPresent()反调,X32dbg有反调插件,直接过反调,但在实操过程中发现无法停到password2,也就是输入后下断停不下来,这点小疑惑。所以换IDA,先输入password1,然后IDA attach上去。
动调可得Key,逆序
key

2c2`1`0f;h8;n<66

在这里插入图片描述
flag就是两个password的合体

week3

FAKE

常规思路找字符串,进而找到算法,这个分析一波发现是z3,z3脚本写了写,一直跑不出来,开始苦恼。后来init()中发现反调试,sub_406A11()中,取/proc/self/status中的值, TracerPid的值非0判断为调试,进而SMC异或解密数据。写个idc脚本,模拟执行一下

#include <idc.idc>
static main()
{
	auto addr=0x00401216; //函数地址
	auto addr2=0x00409080; //byte数组地址
	auto i = 0;
	for(i=0;i<=0x43E;i++)
	{
		PatchByte(addr+i,Byte(addr+i)^Byte(addr2+i));
	}
}

ait+f7加载脚本,选中函数区域按C转代码,
测试
z3脚本跑一下

from z3 import *
s=Solver()
a1=[0 for i in range(36)]
for i in range(36):
	a1[i]=Int('a1['+str(i)+']')
v2=[0 for i in range(36)]
v1=[0 for i in range(36)]
v3=[0 for i in range(36)]
v2[0] = 55030
v2[1] = 61095
v2[2] = 60151
v2[3] = 57247
v2[4] = 56780
v2[5] = 55726
v2[6] = 46642
v2[7] = 52931
v2[8] = 53580
v2[9] = 50437
v2[10] = 50062
v2[11] = 44186
v2[12] = 44909
v2[13] = 46490
v2[14] = 46024
v2[15] = 44347
v2[16] = 43850
v2[17] = 44368
v2[18] = 54990
v2[19] = 61884
v2[20] = 61202
v2[21] = 58139
v2[22] = 57730
v2[23] = 54964
v2[24] = 48849
v2[25] = 51026
v2[26] = 49629
v2[27] = 48219
v2[28] = 47904
v2[29] = 50823
v2[30] = 46596
v2[31] = 50517
v2[32] = 48421
v2[33] = 46143
v2[34] = 46102
v2[35] = 46744
v1[0] = 104
v1[1] = 103
v1[2] = 97
v1[3] = 109
v1[4] = 101
v1[5] = 123
v1[6] = 64
v1[7] = 95
v1[8] = 70
v1[9] = 65
v1[10] = 75
v1[11] = 69
v1[12] = 95
v1[13] = 102
v1[14] = 108
v1[15] = 97
v1[16] = 103
v1[17] = 33
v1[18] = 45
v1[19] = 100
v1[20] = 111
v1[21] = 95
v1[22] = 89
v1[23] = 48
v1[24] = 117
v1[25] = 95
v1[26] = 107
v1[27] = 111
v1[28] = 110
v1[29] = 119
v1[30] = 95
v1[31] = 83
v1[32] = 77
v1[33] = 67
v1[34] = 63
v1[35] = 125
for i in range(6):
	for j in range(6):
		for k in range(6):
			v3[6 * i + j] += v1[6 * k + j] * a1[6*i+k]
for x in range(6):
	for y in range(6):
		s.add(v3[6 * x + y] == v2[6 * x + y])
print(s.check())
print(s.model())
answer=s.model()
for i in range(36):
	print(answer[a1[i]],end=' ')

跑出转字符串即可
hgame{E@sy_Se1f-Modifying_C0oodee33}

helloRe3

我运行不了,新本子计划启动中
这里记一下思路,通过调试信息搜字符串,找到关键变量,找引用发现是call+pop结构,病毒常用结构,nop掉,F5找到算法,取反+RC4

week4

vm
在学了在学了

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值