admin管理员组文章数量:1624790
REVERSE-COMPETITION-HWS-5TH-2022
- re1
- re2
- re3
re1
64位exe,ida打开,来到main函数
输入的长度应为32,输入经过TEA加密,密文与已知的cipher进行比较
进入TEA函数,发现是魔改TEA,需一次性传入8个unsigned int,delta已知,key已知
用C还原出程序的魔改TEA加密过程,对解密过程进行相应的修正,解密得到flag
#include <stdio.h>
#include <stdint.h>
//加密函数
void encrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3],v4 = v[4], v5 = v[5],v6 = v[6], v7 = v[7],sum = 0;
int v15,v17=12;
do{
sum -= 0x61C88647;
v0 += ((sum ^ v1) + (k[(sum >> 2) & 3] ^ v7)) ^ (((16 * v7) ^ (v1 >> 3)) + ((v7 >> 5) ^ (4 * v1)));
v[0] = v0;
v1 += ((k[(sum >> 2) & 3 ^ 1] ^ v0) + (sum ^ v2)) ^ (((16 * v0) ^ (v2 >> 3)) + ((v0 >> 5) ^ (4 * v2)));
v[1] = v1;
v2 += ((sum ^ v3) + (k[(sum >> 2) & 3 ^ 2] ^ v1)) ^ (((16 * v1) ^ (v3 >> 3)) + ((v1 >> 5) ^ (4 * v3)));
v[2] = v2;
v3 += ((sum ^ v4) + (k[(sum >> 2) & 3 ^ 3] ^ v2)) ^ (((16 * v2) ^ (v4 >> 3)) + ((v2 >> 5) ^ (4 * v4)));
v[3] = v3;
v4 += ((sum ^ v5) + (k[(sum >> 2) & 3] ^ v3)) ^ (((16 * v3) ^ (v5 >> 3)) + ((v3 >> 5) ^ (4 * v5)));
v[4] = v4;
v5 += ((k[(sum >> 2) & 3 ^ 1] ^ v4) + (sum ^ v6)) ^ (((16 * v4) ^ (v6 >> 3)) + ((v4 >> 5) ^ (4 * v6)));
v[5] = v5;
v6 += (((sum ^ v7) + (k[(sum >> 2) & 3 ^ 2] ^ v5)) ^ (((16 * v5) ^ (v7 >> 3)) + ((v5 >> 5) ^ (4 * v7))));
v[6] = v6;
v7 += (((sum ^ v0) + (k[(sum >> 2) & 3 ^ 3] ^ v6))) ^ (((16 * v6) ^ (v0 >> 3))+ ((v6 >> 5) ^ (4 * v0)));
v[7] = v7;
v15 = v17-- == 1;
}while(!v15);
printf("sum==0x%x\n",sum);
}
//解密函数
void decrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3],v4 = v[4], v5 = v[5],v6 = v[6], v7 = v[7],sum = 0x6a99b4ac;
int v15,v17=12;
do{
v7 -= (((sum ^ v0) + (k[(sum >> 2) & 3 ^ 3] ^ v6))) ^ (((16 * v6) ^ (v0 >> 3))+ ((v6 >> 5) ^ (4 * v0)));
v[7] = v7;
v6 -= (((sum ^ v7) + (k[(sum >> 2) & 3 ^ 2] ^ v5)) ^ (((16 * v5) ^ (v7 >> 3)) + ((v5 >> 5) ^ (4 * v7))));
v[6] = v6;
v5 -= ((k[(sum >> 2) & 3 ^ 1] ^ v4) + (sum ^ v6)) ^ (((16 * v4) ^ (v6 >> 3)) + ((v4 >> 5) ^ (4 * v6)));
v[5] = v5;
v4 -= ((sum ^ v5) + (k[(sum >> 2) & 3] ^ v3)) ^ (((16 * v3) ^ (v5 >> 3)) + ((v3 >> 5) ^ (4 * v5)));
v[4] = v4;
v3 -= ((sum ^ v4) + (k[(sum >> 2) & 3 ^ 3] ^ v2)) ^ (((16 * v2) ^ (v4 >> 3)) + ((v2 >> 5) ^ (4 * v4)));
v[3] = v3;
v2 -= ((sum ^ v3) + (k[(sum >> 2) & 3 ^ 2] ^ v1)) ^ (((16 * v1) ^ (v3 >> 3)) + ((v1 >> 5) ^ (4 * v3)));
v[2] = v2;
v1 -= ((k[(sum >> 2) & 3 ^ 1] ^ v0) + (sum ^ v2)) ^ (((16 * v0) ^ (v2 >> 3)) + ((v0 >> 5) ^ (4 * v2)));
v[1] = v1;
v0 -= ((sum ^ v1) + (k[(sum >> 2) & 3] ^ v7)) ^ (((16 * v7) ^ (v1 >> 3)) + ((v7 >> 5) ^ (4 * v1)));
v[0] = v0;
sum += 0x61C88647;
v15 = v17-- == 1;
}while(!v15);
printf("sum==0x%x\n",sum);
}
//打印数据 hex_or_chr: 1-hex 0-chr
void dump_data(uint32_t * v,int n,bool hex_or_chr)
{
if(hex_or_chr)
{
for(int i=0;i<n;i++)
{
printf("0x%x,",v[i]);
}
}
else
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < sizeof(uint32_t)/sizeof(uint8_t); j++)
{
printf("%c", (v[i] >> (j * 8)) & 0xFF);
}
}
}
printf("\n");
return;
}
int main()
{
// v为要加解密的数据
uint32_t v[] = { 0x10bd3b47,0x6155e0f9,0x6af7ebc5,0x8d23435f,0x1a091605,0xd43d40ef,0xb4b16a67,0x6b3578a9 };
// k为加解密密钥
uint32_t k[6] = { 0x1234, 0x2345, 0x4567, 0x6789, 0, 0 };
// num_rounds,建议取值为32
unsigned int r = 32;
int n = sizeof(v) / sizeof(uint32_t);
/*
printf("加密前明文数据:");
dump_data(v,n,1);
for(int i=0;i<n/2;i++)
{
encrypt(r,&v[i*2], k);
}
*/
printf("加密后密文数据:");
dump_data(v,n,1);
/*
for(int i=0;i<n/2;i++)
{
decrypt(r,&v[i*2], k);
}
*/
decrypt(0,v,k);
printf("解密后明文数据:");
dump_data(v,n,1);
printf("解密后明文字符:");
dump_data(v,n,0);
return 0;
}
// 7f943921724d63dc0ac9c6febf99fa88
re2
32位exe,ida打开,来到main函数
main函数读取输入,没有对输入的其他处理
对输入查找交叉引用,来到sub_4013D0函数,输入和下标异或,结果与已知的res比较
解异或得知是假flag,左边函数窗口看到tls,有一段SMC
解SMC,在StartAddress处创建函数,反编译,输入和byte_41B30A异或,调试得到byte_41B30A==0x48
然后对输入进行RC4加密,密钥为"Qfrost",密文为0x401307地址处开始的28个字节
解密RC4,再异或0x48即可得到flag
#include<stdio.h>
/*
RC4初始化函数
*/
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k)
{
unsigned 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;
}
}
/*
RC4加解密函数
unsigned char* Data 加解密的数据
unsigned long Len_D 加解密数据的长度
unsigned char* key 密钥
unsigned long Len_k 密钥长度
*/
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] ^ 0x48;
}
}
int main()
{
//字符串密钥
unsigned char key[] = "Qfrost";
unsigned long key_len = sizeof(key) - 1;
/*
//数组密钥
unsigned char key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
unsigned long key_len = sizeof(key);
*/
//加解密数据
unsigned char data[] = {0x7F, 0xB6, 0x88, 0x12, 0xDC, 0xC3, 0xDE, 0xDB, 0x30, 0x24,
0xE3, 0xC1, 0x0F, 0xC9, 0x7F, 0xC2, 0x4D, 0x9C, 0x6B, 0x02,
0x26, 0x20, 0xF1, 0x25, 0xA0, 0xE3, 0xC6, 0xDE };
//加解密
rc4_crypt(data, sizeof(data), key, key_len);
for (int i = 0; i < sizeof(data); i++)
{
printf("%c", data[i]);
}
printf("\n");
return 0;
}
// QDbg-Is_an_1ntereSting-Game!
re3
安卓逆向,jadx-gui打开
输入的长度应小于420,trans是将输入的字符,三个一组,转成36进制,每组存储为两个字节
ida打开so文件,Java_com_example_ctf_MainActivity_check没什么用
对输入的校验在JNI_OnLoad的sub_D060方法
通过调试知道,for循环将传入的36进制转为16进制,这里会被char类型截断
然后是RSA加密,n和e已知,密文和sure_flag的20个字节比较
解RSA,将明文用16进制表示,每两个16进制转成三个10进制,不足三位的补0即可
import gmpy2
n=0x7019325b70f4a2f26e921102a0206de415caeb535cd4ec9d23d6608630dd00a9db5db8faef4621ccb2e775844c7447a1a843ebac03eca6f329feabcd6560b80aacf7a54a298548827c9d75e1450fcf7e53dac37c0f7fd25d509c342c23bda0619504b28ec903c56c87
p=1475203612633975218848450285487339190962027688336790188873776418606441616307026173067
q=1475203612633975218848450285487339190962027688336790188873776418606441616307046219549
r=1475203612633975218848450285487339190962027688336790188873776418606441616307129708089
e=0x10001
phin=(p-1)*(q-1)*(r-1)
d=gmpy2.invert(e,phin)
c=0x4920616D207375726520697420697320666C3467
m=gmpy2.powmod(c,d,n)
s=hex(m)[2:]
flag=""
for i in range(0,len(s),2):
tmp=int(s[i:i+2],16)
if tmp<100:
flag+="0"
flag+=str(tmp)
print(flag)
# 037087131219012107229231067248093076089082070175138132195124126254031088197066063081248248223201185154047168242228140155089071245228045160218140167117182217137118206104215018068031237111113041220252131252040018130017184197145113066057103096226240251147039224115177108218078236161028053035089246229073211242029209057
输入验证成功,但是貌似多解,不太理解怎么回事
本文标签: competitionREVERSEHWS
版权声明:本文标题:REVERSE-COMPETITION-HWS-5TH-2022 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1726693388a1080925.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论