2021 津门杯&红帽杯re部分复现
在军训,比赛快结束时看了看题,做不来,完全做不来,复现学习,复现了简单的3道题,其他题确实能力还不行,下载做题工具时,还中毒了。。。。
GoodRE
这个题的难点就在于函数名不知道,一个tea加密,有点不一样的是,里面的一些加,除,位移都用了一些大数函数,导致看起来不像tea加密,而且把dealt给分为了两个数的xor,特征也没有了。
ida分析
接下来看8个字符转16进制的函数
然后就是tea内部
脚本
#include<stdio.h>
void decrypt(unsigned int *code , unsigned int *key)
{
unsigned int delta=0x9e3779b9;
unsigned int v0,v1,sum=0xC6EF3720,i;// sum=0xC6EF3720
v0=code[0];
v1=code[1];
for(i=0;i<32;i++)
{
v1-=( (v0<<4)+key[2] ) ^ (v0+sum) ^ ( (v0>>5)+key[3] );
v0-=( (v1<<4)+key[0] ) ^ (v1+sum) ^ ( (v1>>5)+key[1] );
sum-=delta;
}
code[0]=v0;
code[1]=v1;
printf("%X%X",code[0],code[1]);
}
int main()
{
unsigned int key[4]={17,17,17,17};
unsigned int code[8]={0x79AE1A3B,0x596080D3,0x80E03E80, 0x846C8D73, 0x21A01CF7, 0xC7CACA32, 0x45F9AC14, 0xC5F5F22F};
int i;
printf("flag{");
for(i=0;i<4;i++)
{
decrypt(&code[i*2],key);
}
printf("}");
}
//flag{7DEA3F6D3B3D6C0C620864ADD2FA2AE1A61F2736F0060DA0B97E8356D017CE59}
easyRe
这道题的考点是,爆破,z3,和c语言调用lua文件中的函数。题目给了3个文件,output.txt不知道什么用。
ida流程
看看处理函数
所以先解密my.lua文件
#include<stdio.h>
int main()
{
FILE *p;
char v[0x170]={0};
char m[8]="cgfffce";
int v4[3]={2,3,5};
int i;
p=fopen("my.lua","rb");
fread(&v, 1, 0x16f, p);
for(i=0;i<0x16f;i++)
{
v[i]=v[i]^v4[i%3];
}
FILE *p1 = fopen("my.txt", "wb");
fwrite(&v, 1, 0x16f, p1);
for(i=0;i<7;i++)
{
m[i]=m[i]^v4[i%3];
printf("%c",m[i]);
}
}
//adcdefg
得到的my.txt,就是一个异或。
function BitXOR(a,b)
local p,c=1,0
while a>0 and b>0 do
local ra,rb=a%2,b%2
if ra~=rb then c=c+p end
a,b,p=(a-ra)/2,(b-rb)/2,p*2
end
if a<b then a=b end
while a>0 do
local ra=a%2
if ra>0 then c=c+p end
a,p=(a-ra)/2,p*2
end
return c
end
function adcdefg(j)
return BitXOR(5977654,j)
end
用z3写的python脚本如下
from z3 import *
code=[5977672,338,5978023,3630,5977188,524,5977313,4067,5977511,207,5973801,3662,5977375,42,5974494,8361,5978164,988,5976337,12273,5976967,6871,5979438,5916,5976793,1485,5978936,8243,5974126,3027,5969737,9510,684,5973999,3840,5978418,13036,5975191,11850,5979906,7247,5978814,12173,5976318,1252,5974940,5736,5969435,757,5973565,4036,5979036,7999,5973024,859,5973093,3278,5973550,3179,5976631,3699,5977985,373,5977828]
def decode(table):
s = Solver()
flag = [BitVec(('x%d' % i), 8) for i in range(32)]
mid=[0]*64
for j in range(32):
for k in range(33):
mid[j+k]+=(flag[j]^table[k])
mid[j+k]=mid[j+k]^5977654
for i in range(64):
s.add(mid[i]==code[i])
if s.check() == sat:
model = s.model()
str = [chr(model[flag[i]].as_long().real) for i in range(32)]
print("".join(str))
exit()
else:
print("no_sat")
def creat_seedtable(seed):
s=[0]*33
for i in range(33):
s[i]=(32310901 * seed + 1729) % 254
seed=s[i]
return s
for i in range(0xff):
table=creat_seedtable(i)
print(i)
print(table)
decode(table)
//45c48cce2e2d7fbdea1afc51c7c6ad26
红帽杯-ezRev
一个变换key的xtea加密,中间有许多错误的比较和判断,需要自己patch这些点,然后动调出key,并且里面很多函数的名称也不知道,增加了难度。
ida看流程
第一个patch,if判断
第二个patch,根据动调来看,两个随机数,前一个数要大于后一个数,并且都小于10。最终来看是需要两个rand随机数必须是4,2,才能通过后面的判断。
经过不断的试rand的值,终于发现了判断的要求
假设rand1=a,rand2=b,a**b转化为2进制的长度为len1,b**a转换为2进制的长度为len2,需要满足len1>>2==len2>>2。
例子1:
a=8
b=4
len1=20
len2=16
不行,会exit
例子2:
a=4
b=2
len1=8
len2=8
ok
所以当a ** b == b ** a时,是一定会满足的,但是由于有>>2的缘故,也不知道会不会有其他值来满足这个条件,但是4,2一定是满足的。
获得key
tea加密
解密
#include<stdio.h>
void decrypt(unsigned int r ,unsigned int *code ,unsigned int *key)
{
unsigned int v0,v1,i,delta=0x9e3779b9;
unsigned int sum=delta*r;
v0=code[0];
v1=code[1];
for(i=0;i<r;i++)
{
v1-=( ((v0<<4) ^(v0>>5)) +v0 ) ^ ( sum + key[ (sum>>11)&3 ]);
sum-=delta;
v0-=( ((v1<<4) ^ (v1>>5)) +v1 ) ^ ( sum + key[sum&3] );
}
code[0]=v0;
code[1]=v1;
key[0]+=789;
key[3]+=135;
printf("%c%c",code[0],code[1]);
}
int main()
{
unsigned int key[4]={0x00067932, 0x0004F765, 0x0007FAFF, 0x00067932};
unsigned int r=32;
unsigned int code[16]={0xd118c7b2,0x7fc3f3a8,0x4a19f2da,0x472469e1,0x7c682864,0x50c0e3d1,0xc595670b,0x2ee07578,0xd040a3f0,0xc5590286,0xd82b07a8,0xd5978c2c,0x4e2bc556,0x079e2e90,0xc7a353b5,0x493995B};
int i;
for(i=0;i<8;i++)
{
decrypt(r,&code[i*2],key);
}
}
动调getflag