crakme[Shangwendada ,wakappxc done]
法1
其实应该本来想考的是upx壳,但是似乎出题人没想到可以直接运行的问题….
法2
首先查壳
脱壳发现脱不了 放入010Editor查看并改特征码
载入ida里面
验证flag正确
mfx_re[Shangwendada done]
这玩意瞅着真熟悉
UPX老哥,改了特征码
修复文件
file_path = 'mfx_re' # 替换成你的二进制文件路径
with open(file_path, 'rb') as file:
content = file.read()
# 将所有的 "mfx" 替换为 "upx",不区分大小写
content = content.replace(b'upx', b'mfx')
content = content.replace(b'UPX', b'MFX')
# 将修改后的内容写回文件
with open(file_path, 'wb') as file:
file.write(content)
print("替换完成!")
再upx脱壳
int __cdecl main(int argc, const char **argv, const char **envp)
{
size_t v3; // rbx
int v5; // [rsp+0h] [rbp-A0h] BYREF
int i; // [rsp+4h] [rbp-9Ch]
int v7; // [rsp+8h] [rbp-98h]
int v8; // [rsp+Ch] [rbp-94h]
char s[8]; // [rsp+10h] [rbp-90h] BYREF
__int64 v10; // [rsp+18h] [rbp-88h]
__int64 v11; // [rsp+20h] [rbp-80h]
__int64 v12; // [rsp+28h] [rbp-78h]
__int64 v13; // [rsp+30h] [rbp-70h]
__int64 v14; // [rsp+38h] [rbp-68h]
__int16 v15; // [rsp+40h] [rbp-60h]
char s2[44]; // [rsp+50h] [rbp-50h] BYREF
int v17; // [rsp+7Ch] [rbp-24h]
__int16 v18; // [rsp+80h] [rbp-20h]
unsigned __int64 v19; // [rsp+88h] [rbp-18h]
v19 = __readfsqword(0x28u);
setbuf((FILE *)&dword_0, 0LL);
setbuf((FILE *)&dword_0, 0LL);
puts("Welcome To MFx_Reverse!");
puts("I have two questions. You need guess the flag from the first question.");
v7 = 1;
v8 = 2;
printf("a=%d, b=%d\n", 1LL, 2LL);
puts("The first question is a + b = ?");
printf("a + b = ");
v5 = 0;
scanf("%d", &v5);
if ( v5 == 3 )
puts("Good!");
else
puts("Wrong!");
puts("The second question is flag = ?");
printf("flag = ");
*(_QWORD *)s = 0LL;
v10 = 0LL;
v11 = 0LL;
v12 = 0LL;
v13 = 0LL;
v14 = 0LL;
v15 = 0;
scanf("%s", s);
strcpy(s2, "HRBSEz0627c4ee,`026,367a,`2b/,03/bcba5ea7/|");
v17 = 0;
v18 = 0;
for ( i = 0; ; ++i )
{
v3 = i;
if ( v3 >= strlen(s) )
break;
--s[i];
}
strcmp(s, s2);
puts("Now you know your flag!");
return 0;
}
密文每一位+1就有flag
WHRER[Shangwendada done]
AddVectoredExceptionHandler函数:
语法
C++复制
PVOID AddVectoredExceptionHandler(
ULONG First,
PVECTORED_EXCEPTION_HANDLER Handler
);
参数
First
处理程序的调用顺序。 如果参数为非零值,则处理程序是要调用的第一个处理程序。 如果 参数为零,则处理程序是最后一个要调用的处理程序。
Handler
指向要调用的处理程序的指针。 有关详细信息,请参阅 VectoredHandler。
解析
AddVectoredExceptionHandler函数加载了两个函数
分别是RC4,与TEA.都存在魔改。
程序执行流为->RC4->TEA->坐标系判断
那么解密部分首先为坐标系判断
在此处坐标系判断
保证坐标向下递增,同时放入byte_434d3c中,比较byte_41C0A0,那么byte_41C0A0保存的就是我们的坐标
使用idapython扫描一遍
addr = 0x41C0A0
for i in range(0,300):
for j in range(0,300):
if(get_wide_byte(addr+i*300+j)==1):
print(i,end=',')
print(j,end=',')
这就是我们的坐标了,然后将其异或回去
就能得到到tea加密里面的内容
TEA的加密流程为加密一号位和二号位时取三号位,最后两位取第一位作为key。
那么会发现当加密78位时,使用的key是加密后的1位,因此我们需要倒序解密。
void tea_decrypt(unsigned int *a1, unsigned char *v9, int index) {
unsigned int sum = 0;
for (int i = 0 ; i < 32 ; i ++ ) {
sum -= 559038737;
//printf("SUM:%X\n", sum);
}
printf("SUM:%X\n", sum);
//
// printf("%X\n", a1[0]);
// printf("%X\n", v9[0]);
unsigned int v5 = a1[0], v4 = a1[1];
for (int j = 0 ; j < 8 ; j ++ ) {
printf("%X,", a1[j - index]);
}
printf("\n%X,%X,%X,%X\n", v9[(4 * index + 8) % 32 + 0], v9[(4 * index + 8) % 32 + 1], v9[(4 * index + 8) % 32 + 2], v9[(4 * index + 8) % 32 + 3]);
for (int i = 0 ; i < 32 ; i ++ ) {
v4 -= (v9[(4 * index + 8) % 32 + 3] + (v5 >> 5)) ^ (sum + v5) ^ (v9[(4 * index + 8) % 32 + 2] + 16 * v5);
v5 -= (v9[(4 * index + 8) % 32 + 1] + (v4 >> 5)) ^ (sum + v4) ^ (v9[(4 * index + 8) % 32] + 16 * v4);
sum += 559038737;
}
a1[0] = v5;
a1[1] = v4;
}
for (int i = 6 ; i >= 0 ; i -= 2 ) {
tea_decrypt((unsigned int *)(flag + 4 * i), flag, i);
}
然后是RC4:
断点调出keystream,然后还原最后一个函数一把梭
unsigned char keystream[] = {
0xFB, 0x95, 0x14, 0x16, 0x23, 0xCA, 0x8E, 0x3F, 0xB3, 0xB2,
0x94, 0x54, 0x25, 0xA2, 0xF1, 0xDD, 0x4F, 0xF4, 0x5B, 0xC0,
0xF4, 0xDA, 0xD9, 0x20, 0x0F, 0x83, 0xAA, 0xCF, 0x99, 0xAB,
0x52, 0x10, 0x98, 0xF6, 0x7A, 0xDE, 0xD3, 0x81, 0x70, 0xE0,
0x59, 0x5A, 0x10, 0x62, 0x3D, 0xA0, 0x58, 0x91, 0xFA, 0x4D,
0x15, 0x69, 0xE3, 0x1F, 0xD7, 0x66, 0x99, 0x41, 0x29, 0x15,
0x62, 0x82, 0x93, 0xB1, 0xE1, 0x1D, 0x61, 0x6F, 0x8F, 0x49,
0x11, 0x71, 0xA1, 0x27, 0xE3, 0x55, 0xF2, 0x28, 0x49, 0x6D,
0x27, 0x9A, 0x7B, 0x5B, 0xA3, 0x27, 0x9A, 0x35, 0x9E, 0x72,
0xC8, 0x9E, 0x1A, 0x5C, 0xF1, 0x54, 0x73, 0xB4, 0xF6, 0xBF,
0x09, 0xE8, 0x75, 0xB9, 0x3B, 0x32, 0x80, 0xD1, 0xFB, 0x94,
0x57, 0x2E, 0xCE, 0xC2, 0x24, 0xCE, 0xDE, 0xED, 0x74, 0xB9,
0x4E, 0xFA, 0x5D, 0x65, 0xD8, 0x3D, 0xA0, 0x3B, 0x79, 0x40,
0x7D, 0xF7, 0x27, 0x98, 0x50, 0xFF, 0xBE, 0x0E, 0x8F, 0x44,
0x6B, 0x33, 0x2E, 0x8D, 0x8D, 0x2D, 0x4D, 0x10, 0xC6, 0x93,
0xCE, 0x2F, 0xA3, 0xE9, 0x04, 0x4D, 0xD5, 0xB5, 0xCF, 0x10,
0x33, 0xF7, 0xEB, 0x17, 0xEF, 0xD2, 0x34, 0x6E, 0xD9, 0x5A,
0x82, 0x0E, 0x22, 0x29, 0x31, 0x7D, 0x52, 0xAD, 0x47, 0x59,
0x08, 0xE3, 0xAA, 0x80, 0xE0, 0x80, 0xCE, 0x48, 0xDD, 0x44,
0xC4, 0xA4, 0xF4, 0xD1, 0xB9, 0x83, 0x63, 0xBC, 0x4E, 0xC2,
0x6A, 0x89, 0xCE, 0x8D, 0xF4, 0x0E, 0x43, 0x93, 0x87, 0x62,
0xAB, 0x62, 0x52, 0x01, 0xFE, 0x69, 0x5E, 0xBB, 0xE1, 0xF4,
0xBD, 0xD5, 0x1F, 0x0F, 0xFD, 0xD1, 0x18, 0xE0, 0xCC, 0x1F,
0x74, 0xE9, 0x60, 0x86, 0x75, 0x0E, 0xBD, 0x44, 0x7A, 0x29,
0xB1, 0x8B, 0xB9, 0xC6, 0x02, 0x0A, 0x18, 0x0B, 0xD5, 0x03,
0x3E, 0x34, 0x73, 0xC3, 0xC5, 0xA9
};
unsigned char ans[256] = {0};
for (int i = 0 ; i < 32 ; i ++ ) {
if (i == 0) {
ans[i] = flag[i] ^ keystream[i];
} else {
ans[i] = (flag[i] ^ flag[keystream[i]%i]^keystream[i]);
}
}
printf("\n%s", ans);
本题最开始还需要爆破一个输入,EXP的main函数的前几行就是在爆破
exp
#include <stdio.h>
#include <bits/stdc++.h>
#include <Windows.h>
using namespace std;
int v3; // eax
int v4; // eax
int v5; // [esp-Ch] [ebp-FCh]
int v7; // [esp-8h] [ebp-F8h]
int v8; // [esp-4h] [ebp-F4h]
char v13; // [esp+CFh] [ebp-21h]
int v14; // [esp+D0h] [ebp-20h]
int v15; // [esp+D4h] [ebp-1Ch]
int v16; // [esp+D8h] [ebp-18h]
int v17; // [esp+DCh] [ebp-14h] BYREF
int v18; // [esp+E0h] [ebp-10h]
size_t v19; // [esp+E4h] [ebp-Ch]
char *v20; // [esp+E8h] [ebp-8h]
int v21; // [esp+ECh] [ebp-4h]
unsigned char Destination[256]; // [esp+158h] [ebp-400h] BYREF
//char key[256]; // [esp+258h] [ebp-300h] BYREF
unsigned char box1[256]; // [esp+358h] [ebp-200h] BYREF
unsigned char box2[256]; // [esp+458h] [ebp-100h] BYREF
int __cdecl sub_401390(int a1, int a2) {
return ~(a2 + ~a1);
}
void tea_decrypt(unsigned int *a1, unsigned char *v9, int index) {
unsigned int sum = 0;
for (int i = 0 ; i < 32 ; i ++ ) {
sum -= 559038737;
//printf("SUM:%X\n", sum);
}
printf("SUM:%X\n", sum);
//
// printf("%X\n", a1[0]);
// printf("%X\n", v9[0]);
unsigned int v5 = a1[0], v4 = a1[1];
for (int j = 0 ; j < 8 ; j ++ ) {
printf("%X,", a1[j - index]);
}
printf("\n%X,%X,%X,%X\n", v9[(4 * index + 8) % 32 + 0], v9[(4 * index + 8) % 32 + 1], v9[(4 * index + 8) % 32 + 2], v9[(4 * index + 8) % 32 + 3]);
for (int i = 0 ; i < 32 ; i ++ ) {
v4 -= (v9[(4 * index + 8) % 32 + 3] + (v5 >> 5)) ^ (sum + v5) ^ (v9[(4 * index + 8) % 32 + 2] + 16 * v5);
v5 -= (v9[(4 * index + 8) % 32 + 1] + (v4 >> 5)) ^ (sum + v4) ^ (v9[(4 * index + 8) % 32] + 16 * v4);
sum += 559038737;
}
a1[0] = v5;
a1[1] = v4;
}
unsigned char xorr[] = {
0xCA, 0x6D, 0xED, 0x4F, 0x59, 0x11, 0xE0, 0xCD, 0xC5, 0x4E,
0x60, 0xAB, 0x7B, 0x76, 0x8B, 0x40, 0x38, 0x2C, 0x0F, 0x1C,
0x9C, 0x2D, 0xF6, 0x5A, 0x7A, 0x55, 0x16, 0xF8, 0xD6, 0x8C,
0x95, 0x1A
};
unsigned char xorrr[] = {
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x31,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x31,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x31,
0x31, 0x32
};
int main() {
for (int i = 0 ; i < 0xFFFFFFFF ; i++ ) {
v17 = i;
v16 = v17 / 10000;
v15 = v17 % 10000 / 100;
v14 = v17 % 10000 % 100;
v5 = v15;
v3 = sub_401390(7 * v15, 1);
v4 = sub_401390(11 * (13 * v3 + v14 + 3), v5);
v18 = ((v4 - v14) / 10 + 11) ^ 0x104B4;
if ( (v17 & 1) != 0 || v17 < 233 || v16 > 9999 || v15 > 12 || v14 > 32 || v18 * (v15 + v14 + v16) != 0x821472C ) {
continue;
} else {
printf("%d\n", i);
break;
}
}
unsigned char ida_chars[] = {
0xF1, 0xEF, 0x61, 0xBB, 0xC9, 0x45, 0x57, 0x43, 0x36, 0xEB,
0xC3, 0xF5, 0x61, 0x1F, 0xE0, 0xED, 0x5F, 0x19, 0xC3, 0x83,
0x0B, 0x67, 0x5B, 0x44, 0x7A, 0x9D, 0xB2, 0x7E, 0xF5, 0xB5,
0x22, 0x65
};
unsigned char flag[] = { 30, 15, 43, 28, 86, 5, 97, 100, 120, 21, 135, 89, 138, 28, 154, 250, 180, 99, 189, 100, 200, 1, 220, 213, 225, 54, 235, 235, 246, 66, 255, 255};
for (int i = 0 ; i < 32 ; i ++ ) {
flag[i] ^= ida_chars[i];
printf("0x%X,", flag[i]);
}
puts("");
for (int i = 6 ; i >= 0 ; i -= 2 ) {
tea_decrypt((unsigned int *)(flag + 4 * i), flag, i);
}
for (int i = 0 ; i < 8 ; i ++) {
unsigned int *p = (unsigned int *)(flag + 4 * i);
printf("0x%X,", *p);
}
puts("");
unsigned char keystream[] = {
0xFB, 0x95, 0x14, 0x16, 0x23, 0xCA, 0x8E, 0x3F, 0xB3, 0xB2,
0x94, 0x54, 0x25, 0xA2, 0xF1, 0xDD, 0x4F, 0xF4, 0x5B, 0xC0,
0xF4, 0xDA, 0xD9, 0x20, 0x0F, 0x83, 0xAA, 0xCF, 0x99, 0xAB,
0x52, 0x10, 0x98, 0xF6, 0x7A, 0xDE, 0xD3, 0x81, 0x70, 0xE0,
0x59, 0x5A, 0x10, 0x62, 0x3D, 0xA0, 0x58, 0x91, 0xFA, 0x4D,
0x15, 0x69, 0xE3, 0x1F, 0xD7, 0x66, 0x99, 0x41, 0x29, 0x15,
0x62, 0x82, 0x93, 0xB1, 0xE1, 0x1D, 0x61, 0x6F, 0x8F, 0x49,
0x11, 0x71, 0xA1, 0x27, 0xE3, 0x55, 0xF2, 0x28, 0x49, 0x6D,
0x27, 0x9A, 0x7B, 0x5B, 0xA3, 0x27, 0x9A, 0x35, 0x9E, 0x72,
0xC8, 0x9E, 0x1A, 0x5C, 0xF1, 0x54, 0x73, 0xB4, 0xF6, 0xBF,
0x09, 0xE8, 0x75, 0xB9, 0x3B, 0x32, 0x80, 0xD1, 0xFB, 0x94,
0x57, 0x2E, 0xCE, 0xC2, 0x24, 0xCE, 0xDE, 0xED, 0x74, 0xB9,
0x4E, 0xFA, 0x5D, 0x65, 0xD8, 0x3D, 0xA0, 0x3B, 0x79, 0x40,
0x7D, 0xF7, 0x27, 0x98, 0x50, 0xFF, 0xBE, 0x0E, 0x8F, 0x44,
0x6B, 0x33, 0x2E, 0x8D, 0x8D, 0x2D, 0x4D, 0x10, 0xC6, 0x93,
0xCE, 0x2F, 0xA3, 0xE9, 0x04, 0x4D, 0xD5, 0xB5, 0xCF, 0x10,
0x33, 0xF7, 0xEB, 0x17, 0xEF, 0xD2, 0x34, 0x6E, 0xD9, 0x5A,
0x82, 0x0E, 0x22, 0x29, 0x31, 0x7D, 0x52, 0xAD, 0x47, 0x59,
0x08, 0xE3, 0xAA, 0x80, 0xE0, 0x80, 0xCE, 0x48, 0xDD, 0x44,
0xC4, 0xA4, 0xF4, 0xD1, 0xB9, 0x83, 0x63, 0xBC, 0x4E, 0xC2,
0x6A, 0x89, 0xCE, 0x8D, 0xF4, 0x0E, 0x43, 0x93, 0x87, 0x62,
0xAB, 0x62, 0x52, 0x01, 0xFE, 0x69, 0x5E, 0xBB, 0xE1, 0xF4,
0xBD, 0xD5, 0x1F, 0x0F, 0xFD, 0xD1, 0x18, 0xE0, 0xCC, 0x1F,
0x74, 0xE9, 0x60, 0x86, 0x75, 0x0E, 0xBD, 0x44, 0x7A, 0x29,
0xB1, 0x8B, 0xB9, 0xC6, 0x02, 0x0A, 0x18, 0x0B, 0xD5, 0x03,
0x3E, 0x34, 0x73, 0xC3, 0xC5, 0xA9
};
unsigned char ans[256] = {0};
for (int i = 0 ; i < 32 ; i ++ ) {
if (i == 0) {
ans[i] = flag[i] ^ keystream[i];
} else {
ans[i] = (flag[i] ^ flag[keystream[i]%i]^keystream[i]);
}
}
printf("\n%s", ans);
}
/*
30,15
43,28
86,5
97,100
120,21
135,89
138,28
154,250
180,99
189,100
200,1
220,213
225,54
235,235
246,66
255,255
*/
babyre[Shangwendada done]
由Pyinstaller打包的py程序直接使用
pyinstxtractor解包
unconpyle6反编译
# uncompyle6 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)]
# Embedded file name: babyRe.py
import libnum
from crypto.Util.number import *
flag = 'ISCTF{******************}'
flags = flag.encode()
e = 65537
p = libnum.generate_prime(1024)
q = libnum.generate_prime(1024)
n = p * q
m = bytes_to_long(flags)
c = pow(m, e, n)
output = open('output.txt', 'w')
output.write('p+q =' + str(p + q) + '\n')
output.write('(p+1)*(q+1)=' + str((p + 1) * (q + 1)) + '\n')
output.write('c=' + str(c) + '\n')
output.close()
# okay decompiling .\babyRe.pyc
一道RSA我们已知p+q与(p+1)*(q+1) 使用求根公式解二次方程然后解RSA
from sympy import Symbol, Eq, solve
import libnum
from Crypto.Util.number import *
import gmpy2
# 已知的值
p_plus_q = 292884018782106151080211087047278002613718113661882871562870811030932129300110050822187903340426820507419488984883216665816506575312384940488196435920320779296487709207011656728480651848786849994095965852212548311864730225380390740637527033103610408592664948012814290769567441038868614508362013860087396409860
p_q_plus_1 = 21292789073160227295768319780997976991300923684414991432030077313041762314144710093780468352616448047534339208324518089727210764843655182515955359309813600286949887218916518346391288151954579692912105787780604137276300957046899460796651855983154616583709095921532639371311099659697834887064510351319531902433355833604752638757132129136704458119767279776712516825379722837005380965686817229771252693736534397063201880826010273930761767650438638395019411119979149337260776965247144705915951674697425506236801595477159432369862377378306461809669885764689526096087635635247658396780671976617716801660025870405374520076160
# 计算二次方程的系数
a = 1
b = -p_plus_q
c = p_q_plus_1 - (p_plus_q + 1)
# 计算二次方程的根
delta = gmpy2.isqrt(b * b - 4 * a * c)
p = (-b + delta) // (2 * a)
q = (-b - delta) // (2 * a)
print("p =", p)
print("q =", q)
# 已知的值
e = 65537
c = 5203005542361323780340103662023144468501161788183930759975924790394097999367062944602228590598053194005601497154183700604614648980958953643596732510635460233363517206803267054976506058495592964781868943617992245808463957957161100800155936109928340808755112091651619258385206684038063600864669934451439637410568700470057362554045334836098013308228518175901113235436257998397401389511926288739759268080251377782356779624616546966237213737535252748926042086203600860251557074440685879354169866206490962331203234019516485700964227924668452181975961352914304357731769081382406940750260817547299552705287482926593175925396
n = p * q
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
print("Decrypted message:", long_to_bytes(m))
Easyre[余,Shangwendada done]
异或后如果等于’B’或者’X’,或者直接满足等于v4,但是出题人未考虑都满足情况
0 : 73
0 : 82
1 : 72
1 : 83
2 : 67
3 : 84
4 : 70
5 : 72
5 : 83
6 : 78
7 : 88
8 : 74
9 : 72
9 : 83
10 : 73
10 : 82
11 : 65
12 : 79
13 : 87
14 : 67
15 : 66
16 : 88
17 : 78
18 : 65
19 : 76
发现有5个地方出现重复值,hint给出了正确答案的md5,那么我们排列组合产生32组数据判断哈希
import hashlib
from itertools import product
s = "]P_ISRF^PCY[I_YWERYC"
new_s = [ord(s[i]) for i in range(len(s)-1, -1, -1)]
data = {}
for i in range(len(new_s)):
values = []
for j in range(32, 128):
a = j ^ 0x11
if a == ord('B') or a == ord('X'):
b = 0x9b - a
if b == new_s[i]:
values.append(j)
else:
b = a
if b == new_s[i]:
values.append(j)
data[i] = values
result = []
for values in product(*(data[i] for i in sorted(data.keys()))):
combination_str = ''.join(chr(value) for value in values)
md5_hash = hashlib.md5(combination_str.encode()).hexdigest()
if md5_hash == "d26628cceedb1f8bdb3535913c82d959":
result.append(combination_str)
# 输出MD5值等于给定字符串的组合
for combination in result:
print(combination)
easy_flower_tea[Shangwendada done]
#include <stdio.h>
#include <stdint.h> // 使用uint32_t数据类型需要包含此头文件
#include <string.h>
// 定义加密函数
void tea_encrypt(uint32_t *v, uint32_t *k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
uint32_t delta = 0x9e3779b9;
for (i = 0; i < 32; i++) {
sum += delta;
v0 += ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
v1 += ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
}
v[0] = v0;
v[1] = v1;
}
// 定义解密函数
void tea_decrypt(uint32_t *v, uint32_t *k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i; // 根据TEA算法,解密轮次的计算需要初始化sum
uint32_t delta = 0x9e3779b9;
for (i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
int main() {
unsigned int key[] = {12,34,56,78};
unsigned int flag[] = {0x42777AFA,0x781A30CA};
tea_decrypt(flag,key);
for(int i = 0 ; i < 2 ; i ++ ){
printf("%d ",flag[i]);
}
//cout<<endl;
}
easy_z3[Shangwendada done]
# print("Please input flag:")
# flag = input()
# if len(flag)!=42:
# print("Check your length!")
# exit()
#
# l=[]
# for i in range(6):
# s=""
# for j in flag[i*7:i*7+7]:
# s+=hex(ord(j))[2:]
# l.append(int(s,16))
# if (
# (593*l[5] + 997*l[0] + 811*l[1] + 258*l[2] + 829*l[3] + 532*l[4])== 0x54eb02012bed42c08 and \
# (605*l[4] + 686*l[5] + 328*l[0] + 602*l[1] + 695*l[2] + 576*l[3])== 0x4f039a9f601affc3a and \
# (373*l[3] + 512*l[4] + 449*l[5] + 756*l[0] + 448*l[1] + 580*l[2])== 0x442b62c4ad653e7d9 and \
# (560*l[2] + 635*l[3] + 422*l[4] + 971*l[5] + 855*l[0] + 597*l[1])== 0x588aabb6a4cb26838 and \
# (717*l[1] + 507*l[2] + 388*l[3] + 925*l[4] + 324*l[5] + 524*l[0])== 0x48f8e42ac70c9af91 and \
# (312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5])== 0x4656c19578a6b1170):
# print("Good job!")
# else:
# print("Wrong\nTry again!!!")
# exit()
from z3 import *
# 创建6个未知数
l = [Int('l{}'.format(i)) for i in range(6)]
# 创建6个方程
s = Solver()
s.add(
(593 * l[5] + 997 * l[0] + 811 * l[1] + 258 * l[2] + 829 * l[3] + 532 * l[4]) == 0x54eb02012bed42c08,
(605 * l[4] + 686 * l[5] + 328 * l[0] + 602 * l[1] + 695 * l[2] + 576 * l[3]) == 0x4f039a9f601affc3a,
(373 * l[3] + 512 * l[4] + 449 * l[5] + 756 * l[0] + 448 * l[1] + 580 * l[2]) == 0x442b62c4ad653e7d9,
(560 * l[2] + 635 * l[3] + 422 * l[4] + 971 * l[5] + 855 * l[0] + 597 * l[1]) == 0x588aabb6a4cb26838,
(717 * l[1] + 507 * l[2] + 388 * l[3] + 925 * l[4] + 324 * l[5] + 524 * l[0]) == 0x48f8e42ac70c9af91,
(312 * l[0] + 368 * l[1] + 884 * l[2] + 518 * l[3] + 495 * l[4] + 414 * l[5]) == 0x4656c19578a6b1170
)
import struct
# 检查是否有解并输出
if s.check() == sat:
m = s.model()
solution = [m.evaluate(l[i]).as_long() for i in range(6)] # 将解转换为整数
# 将整数转换为字节表示
byte_solution = bytearray()
for val in solution:
byte_solution.extend(val.to_bytes((val.bit_length() + 7) // 8, 'big'))
# 解码字节表示为 ASCII 字符串
ascii_solution = byte_solution.decode('ascii', 'ignore')
print("Solution as integers:", solution)
print("Solution as ASCII string:", ascii_solution)
else:
print("No solution found.")
z3_revenge[Shangwendada done]
一眼约束条件,更改寄存器 int改为char
这是更改之后的图片!
拿到正常的数组,梭了
from z3 import *
v4 = [Int(f"v4_{i}") for i in range(44)]
s = Solver()
s.add(
v4[43] == 0,
v4[0] - 683 - (v4[1] + 765) == -1458,
v4[1] + 993 - (v4[2] + 801) == 208,
v4[2] - 395 - 834 * v4[3] == -70384,
v4[3] + 854 + 950 * v4[4] == 67438,
222 * v4[4] - (177 - v4[5]) == 15486,
v4[6] + 226 + 301 * v4[5] == 37304,
v4[6] - 373 - (889 - v4[7]) == -1108,
896 * v4[7] - (v4[8] + 148) == 88455,
v4[8] - 458 - (881 - v4[9]) == -1140,
v4[9] + 551 + 110 * v4[10] == 6369,
v4[10] - 245 + v4[11] + 773 == 636,
466 * v4[11] + 972 - v4[12] == 27015,
721 * v4[12] - (v4[13] + 848) == 37317,
552 * v4[13] - (381 - v4[14]) == 26160,
v4[14] - 698 - 494 * v4[15] == -49559,
v4[15] + 940 + v4[16] + 150 == 1239,
v4[16] + 972 + 362 * v4[17] == 19484,
v4[17] - 966 + 225 * v4[18] == 11910,
v4[18] - 549 - (v4[19] + 526) == -1063,
v4[20] + 706 + 260 * v4[19] == 12458,
v4[20] + 390 + 801 - v4[21] == 1142,
v4[21] - 271 - (653 - v4[22]) == -770,
v4[22] + 416 - (v4[23] + 912) == -493,
566 * v4[23] - (518 - v4[24]) == 27827,
v4[24] + 589 + v4[25] + 254 == 985,
v4[25] - 268 - (720 - v4[26]) == -839,
883 * v4[26] - (344 - v4[27]) == 45629,
v4[27] - 245 + v4[28] + 996 == 905,
129 * v4[28] + v4[29] + 907 == 13465,
v4[29] - 492 + v4[30] + 765 == 368,
725 * v4[30] - (v4[31] + 194) == 35957,
v4[31] - 553 - 469 * v4[32] == -26718,
v4[32] + 694 + 649 - v4[33] == 1347,
v4[33] + 135 - (449 - v4[34]) == -212,
v4[34] + 651 - (v4[35] + 620) == -17,
v4[35] + 716 + 813 * v4[36] == 46342,
273 * v4[36] - (v4[37] + 556) == 14679,
558 * v4[37] - (v4[38] + 538) == 28939,
v4[38] - 776 - (914 - v4[39]) == -1494,
v4[39] + 605 + 809 * v4[40] == 46008,
v4[40] - 816 - 789 * v4[41] == -43366,
v4[42] + 391 + 616 * v4[41] == 33780,
v4[42] - 200 - 758 * v4[0] == -55409
)
if s.check() == sat:
m = s.model()
result = ''.join([chr(m[v4[i]].as_long()) for i in range(43)])
print("Solution found:")
print(result)
else:
print("No solution found.")
FlowerRSA[Shangwendada done]
去掉花之后长这样
知道了e和n
e = 465 n = 3162244531
分解n得到pq
http://factordb.com/index.php?showid=1100000004799187287
然后就是喜闻乐见的解RSA了
import gmpy2
from sympy import Symbol, Eq, solve
import libnum
from Crypto.Util.number import *
import gmpy2
p = 56099
q = 56369
e = 465
ciphertexts = [
1966878405,
2375075638,
2166893744,
2129446000,
2488145363,
746243878,
1904115824,
818668601,
2983811740,
1840670651,
306202172,
2009857636,
299417177
]
n = p * q
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
for ciphertext in ciphertexts:
plaintext = pow(ciphertext, d, n)
print(long_to_bytes(plaintext).decode(),end='')
Ezrust[Shangwendada done]
先调试
看到单字节判断点,下断
cmp下断打条件断点
from idaapi import get_reg_val
print(chr(get_reg_val('al')),':',chr(get_reg_val('cl')),end='\n')
反调也要nop掉
发现我们输入中所有的字符都被-1了
int main () {
char flag[] = "HRBSEzQt4s^3mc^0msdfdq^/u2qeknv|";
for(int i = 0 ; i < 32 ; i ++ ){
printf("%c",flag[i]+1);
}
}
shangwendada!!!!!!!!!!ヾ(≧∇≦*)ゝ
请问我的条件断点为什么只输出一次 0 : H 就没了