测试题

拿到题目,要我们输入一个字符串

发现逻辑就是一个简单的异或

找到密文、

v="X<cP[?PHNB<P?aj"
a=[]
for i in range(len(v)):
c=ord(v[i])^15
a.append(c)
print(bytes(a))
#b'W3l_T0_GAM3_0ne'

GoodLuck

md5加密+混淆

调用oox00方法

之后观察发现就是一个手动实现md5加密,只不过加了很多混淆

偷天换日

调用本地check方法

这个base64是标准的,这个密文交叉引用可以发现是被初始化修改了

调用了java层的方法,what被变化的值可以得到,解密之后发现调用的方法只是getbytes

调用了大量java层的方法,应该还对传入的参数进行了变化,试过几个,感觉都是标准的API

#include <stdio.h>
int main()
{

char str[100];
int flag;
unsigned char what1[42] = {
0xF6, 0x92, 0xB4, 0xBF, 0xA8, 0xBF, 0xF1, 0xB2, 0xBF, 0xB0, 0xB9, 0xF1, 0x8D, 0xAA, 0xAC, 0xB7,
0xB0, 0xB9, 0xE5, 0xF7, 0x92, 0xB4, 0xBF, 0xA8, 0xBF, 0xF1, 0xB7, 0xB1, 0xF1, 0x97, 0xB0, 0xAE,
0xAB, 0xAA, 0x8D, 0xAA, 0xAC, 0xBB, 0xBF, 0xB3, 0xE5, 0xDE
};
unsigned char w20[20] = {
0x24, 0x2F, 0x38, 0x2F, 0x61, 0x20, 0x27, 0x21, 0x61, 0x0C, 0x37, 0x3A, 0x2B, 0x0C, 0x3B, 0x28,
0x28, 0x2B, 0x3C, 0x4E
};
for (int i = 0; i < 20; i++) {
w20[i] ^= 0x4E;
}
printf("%s\n", w20);
unsigned char w18[8] = {
0x57, 0x24, 0x3D, 0x36, 0x36, 0x56, 0x36, 0x7F
};
for (int i = 0; i < 8; i++) {
w18[i] ^= 0x7F;
}
printf("%s\n", w18);
unsigned char w16[5] = {
0xE3, 0xF4, 0xF0, 0xF5, 0x91
};
for (int i = 0; i < 5; i++) {
w16[i] ^= 0x91;
}
printf("%s\n", w16);
unsigned char w14[20] = {
0xD4, 0xDF, 0xC8, 0xDF, 0x91, 0xD7, 0xD1, 0x91, 0xF7, 0xD0, 0xCE, 0xCB, 0xCA, 0xED, 0xCA, 0xCC,
0xDB, 0xDF, 0xD3, 0xBE
};
for (int i = 0; i < 20; i++) {
w14[i] ^= 0xBE;
}
printf("%s\n", w14);
unsigned char w12[17] = {
0x0D, 0x06, 0x11, 0x06, 0x48, 0x0B, 0x06, 0x09, 0x00, 0x48, 0x34, 0x13, 0x15, 0x0E, 0x09, 0x00,
0x67
};
unsigned char w13[10] = {
0xA9, 0xAB, 0xBA, 0x82, 0xAB, 0xA0, 0xA9, 0xBA, 0xA6, 0xCE
};
for (int i = 0; i < 10; i++) {
w13[i] ^= 0xCE;
}
printf("%s\n", w13);
for (int i = 0; i < 16; i++) {
w12[i] ^= 0x67;
}
printf("%s\n", w12);
unsigned char w11[10] = {
0x98, 0x9A, 0x8B, 0xBE, 0x8C, 0x8C, 0x9A, 0x8B, 0x8C, 0xFF
};
for (int i = 0; i < 11; i++) {
w11[i] = ~w11[i];
}
printf("%s\n", w11);
unsigned char w8[33] = {
0x5C, 0x53, 0x59, 0x4F, 0x52, 0x54, 0x59, 0x12, 0x5E, 0x52, 0x53, 0x49, 0x58, 0x53, 0x49, 0x12,
0x4F, 0x58, 0x4E, 0x12, 0x7C, 0x4E, 0x4E, 0x58, 0x49, 0x70, 0x5C, 0x53, 0x5C, 0x5A, 0x58, 0x4F,
0x3D
};
unsigned char w10[38] = {
0x4E, 0x4F, 0x2A, 0x07, 0x08, 0x02, 0x14, 0x09, 0x0F, 0x02, 0x49, 0x05, 0x09, 0x08, 0x12, 0x03,
0x08, 0x12, 0x49, 0x14, 0x03, 0x15, 0x49, 0x27, 0x15, 0x15, 0x03, 0x12, 0x2B, 0x07, 0x08, 0x07,
0x01, 0x03, 0x14, 0x5D, 0x66, 0x00
};
for (int i = 0; i < 38; i++) {
w10[i] ^= 0x66;
}
printf("%s\n", w10);
for (int i = 0; i < 33; i++) {
w8[i] ^= 0x3D;
}
printf("%s\n", w8);
for (int i = 0; i < 42; i++) {
what1[i] ^= 0xDE;
}
unsigned char w7[7] = {
0x13, 0x0C, 0x19, 0x12, 0x3A, 0x18, 0x7C
};
for (int i = 0; i < 7; i++) {
w7[i] ^= 0x7C;
}
printf("%s\n", w7);
printf("%s\n", what1);
unsigned char what2[5] = {
0x8C, 0x93, 0x86, 0x8D, 0xE3
};
unsigned char what3[4] = {
0xD2, 0xD3, 0xB0, 0xFA
};
unsigned char w4[40] = {
0x63, 0x6C, 0x66, 0x70, 0x6D, 0x6B, 0x66, 0x2D, 0x61, 0x6D, 0x6C, 0x76, 0x67, 0x6C, 0x76, 0x2D,
0x70, 0x67, 0x71, 0x2D, 0x43, 0x71, 0x71, 0x67, 0x76, 0x44, 0x6B, 0x6E, 0x67, 0x46, 0x67, 0x71,
0x61, 0x70, 0x6B, 0x72, 0x76, 0x6D, 0x70, 0x02
};
unsigned char w5[7] = {
0x89, 0x89, 0xC4, 0x8E, 0x8B, 0x9E, 0xEA
};
for (int i = 0; i < 7; i++) {
w5[i] ^= 0xEA;
}
printf("%s\n", w5);
for (int i = 0; i < 40; i++) {
w4[i] ^= 2;
}

unsigned char w6[62] = {
0xD5, 0xB1, 0x97, 0x9C, 0x8B, 0x9C, 0xD2, 0x91, 0x9C, 0x93, 0x9A, 0xD2, 0xAE, 0x89, 0x8F, 0x94,
0x93, 0x9A, 0xC6, 0xD4, 0xB1, 0x9C, 0x93, 0x99, 0x8F, 0x92, 0x94, 0x99, 0xD2, 0x9E, 0x92, 0x93,
0x89, 0x98, 0x93, 0x89, 0xD2, 0x8F, 0x98, 0x8E, 0xD2, 0xBC, 0x8E, 0x8E, 0x98, 0x89, 0xBB, 0x94,
0x91, 0x98, 0xB9, 0x98, 0x8E, 0x9E, 0x8F, 0x94, 0x8D, 0x89, 0x92, 0x8F, 0xC6, 0xFD
};
for (int i = 0; i < 62; i++) {
w6[i] ^= 0xFD;
}
printf("%s\n", w6);
printf("%s\n", w4);
for (int i = 0; i < 4; i++) {
what3[i] ^= 0xFA;
}
printf("%s\n", what3);
for (int i = 0; i < 5; i++) {
what2[i] ^= 0xE3;
}
printf("%s\n", what2);
//printf("%s\n", cls);
//printf("%s", getgetr);
return 0;
}

我把这些字符串给dump下来,选择了几个比较长的进行自行解密,感觉是再调用asset目录

发现了一个字符串感觉可疑,跟踪一下

调用了rc4解密

发现是dex,dump下来

这里观察发现就是一个base58

这个木马在干啥

、SSL 连接向远程服务器发送请求,并接收返回的指令,调用了ooxx本地方法,是jni调用的

题目给了一个附件和一个好像是base64加密后的结果,这里跟那个字符串加密一样,对关键的交叉引用一下

上面的字符串都是我解密后的结果

#include <stdio.h>
#include <string.h>
int main() {
unsigned char a[68] = {
0x32, 0x3F, 0x3F, 0x3C, 0x30, 0x32, 0x27, 0x3C, 0x21, 0x6F, 0x07, 0x6D, 0x69, 0x69, 0x32, 0x3F,
0x3F, 0x3C, 0x30, 0x32, 0x27, 0x36, 0x7B, 0x20, 0x3A, 0x29, 0x36, 0x0C, 0x27, 0x73, 0x3D, 0x7A,
0x73, 0x74, 0x3D, 0x74, 0x73, 0x36, 0x2B, 0x30, 0x36, 0x36, 0x37, 0x20, 0x73, 0x3E, 0x32, 0x2B,
0x3A, 0x3E, 0x26, 0x3E, 0x73, 0x20, 0x26, 0x23, 0x23, 0x3C, 0x21, 0x27, 0x36, 0x37, 0x73, 0x20,
0x3A, 0x29, 0x36, 0x53
};
for (int i = 0; i < strlen(a); i++) {
a[i] ^= 0x53;
}
unsigned char b[17] = {
0x8A, 0xAD, 0xAE, 0xBB, 0x80, 0xAB, 0xA0, 0xAE, 0xA7, 0x8B, 0x8E, 0xAD, 0xB4, 0xA7, 0x97, 0xE3,
0xC2
};
for (int i = 0; i < strlen(b); i++) {
b[i] ^= 0xC2;
}
printf("%s", b);
//key= HolyBibleILoveU!

//allocator<T>::allocate(size_t n) 'n' exceeds maximum supported size
return 0;
}

用findcript可以搜到AES的痕迹,搜索这些字符串发现是AES,密钥得到了,密文是base64加密后的结果,

感觉没有魔改的样子

Harmony

这里对输入调用了一个md5加密的方法,这里看看比较的字符串

直接根据鸿蒙的编号机制,这里我们通过这个abcde工具打开,去找resouce.index找id(类似安卓的找id)

直接解密

ios逆向


不太会ios

其中这个后缀是APP的文件,我用010查看文件头的机器码数据后发现是

iOS Mach-O 文件 的一种变种,准确来说,它是 ARM64E 架构的 Mach-O 文件,也就是 Pointer Authentication (PAC) 启用版的 iOS App 二进制文件。

既然这样的话就拖进IDA了

思路正确

经过AI的帮助发现这个是Swift语言反编译后的伪c代码,这个1号是密文,2号是判断逻辑

_QWORD *__usercall closure #1 in revealFlag(if:)@<X0>(__int64 *a1@<X0>, _QWORD *a2@<X8>)
{
__int64 v2; // x1
_QWORD *result; // x0
__int64 v4; // x1
int v5; // [xsp+3Ch] [xbp-74h]
char v6; // [xsp+44h] [xbp-6Ch]
__int64 v8; // [xsp+80h] [xbp-30h] BYREF
unsigned __int8 v9; // [xsp+8Ah] [xbp-26h] BYREF
char v10; // [xsp+8Bh] [xbp-25h] BYREF
__int16 v11; // [xsp+8Ch] [xbp-24h]
unsigned __int8 v12; // [xsp+8Fh] [xbp-21h] BYREF
__int64 v13; // [xsp+90h] [xbp-20h]
__int64 v14; // [xsp+98h] [xbp-18h]

v13 = 0LL;
v14 = 0LL;
v2 = a1[1];
v13 = *a1;
v14 = v2;
v11 = Character.asciiValue.getter();
if ( (v11 & 0x100) != 0 )
{
_assertionFailure(_:_:file:line:flags:)(
"Fatal error",
11LL,
2LL,
"Unexpectedly found nil while unwrapping an Optional value",
57LL,
2LL,
"DefinitelyNotAVulnerableApp/DefinitelyNotAVulnerableAppApp.swift",
64LL,
2,
17LL,
0);
__break(1u);
}
else
{
v6 = v11;
}
v10 = v6;
lazy protocol witness table accessor for type UInt8 and conformance UInt8();
lazy protocol witness table accessor for type UInt8 and conformance UInt8();
lazy protocol witness table accessor for type UInt8 and conformance UInt8();
UnsignedInteger<>.init<A>(_:)(
&v12,
(__int64)&type metadata for UInt8,
(__int64)&type metadata for UInt8,
(__int64)&v10);
v5 = v12;
v8 = 1LL;
lazy protocol witness table accessor for type Int and conformance Int();
result = UnsignedInteger<>.init<A>(_:)(
&v9,
(__int64)&type metadata for UInt8,
(__int64)&type metadata for Int,
(__int64)&v8);
if ( v5 - v9 == (unsigned __int8)(v5 - v9) )
{
Unicode.Scalar.init(_:)();
result = (_QWORD *)Character.init(_:)();
*a2 = result;
a2[1] = v4;
}
else
{
__break(1u);
}
return result;
}

经过查询发现就是一个减法

obfuscated = "gmbh|zpv`mppljoh`gps`nf~"

# 解密,每个字符减1
flag = ''.join([chr(ord(c) - 1) for c in obfuscated])
print(f"解密结果: {flag}")
#解密结果: flag{you_looking_for_me}

Baby apk

调用本地方法

一个异或key

旁边一个调用key的函数,进入看发现应该是提前就异或了,初始化的函数

#include <stdio.h>
int main() {
char key[] = { 0x56,0x57,0x58,0x59 };
key[0] ^= 0x47;
key[1] ^= 0x32;
key[2] ^= 0x11;
key[3] ^= 0x12;
char result[]={ 119, 9, 40, 44, 106, 84, 113, 124, 34, 93, 122, 121, 119, 4, 120, 124, 36, 7, 127, 42, 117, 6, 112, 41, 32, 4, 112, 47, 119, 81, 123, 47, 33, 81, 40, 120, 114, 24 };
for (int i = 0; i < 38; i++) {
result[i] ^= key[i % 4];
}
printf("%s", result);

return 0;
}
//flag{1873832fa175b6adc9b1a9df42d04a3c}

Magic

调用了本地的加密方法

这个base64加密的方法,注意看这个索引表被换了

是变表base64

import base64
import string

str1 = "l5FlaXCVBE2ALJgWLpekmm=="

string1 = "0123456789XYZabcdefghijklABCDEFGHIJKLMNOPQRSTUVWmnopqrstuvwxyz+/"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print (base64.b64decode(str1.translate(str.maketrans(string1,string2))).hex())

看看主逻辑

__int64 __fastcall encrypt(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v3; // x0
unsigned __int8 v5; // [xsp+34h] [xbp-65Ch]
FILE *stream; // [xsp+38h] [xbp-658h]
unsigned int fd_1; // [xsp+4Ch] [xbp-644h]
int fd; // [xsp+50h] [xbp-640h]
int i; // [xsp+54h] [xbp-63Ch]
unsigned __int8 *v10; // [xsp+58h] [xbp-638h]
unsigned __int8 *StringUTFChars; // [xsp+60h] [xbp-630h]
int v12; // [xsp+150h] [xbp-540h] BYREF
socklen_t addr_len; // [xsp+154h] [xbp-53Ch] BYREF
char s1[10]; // [xsp+158h] [xbp-538h] BYREF
char s[246]; // [xsp+162h] [xbp-52Eh] BYREF
char v16[1024]; // [xsp+258h] [xbp-438h] BYREF
struct sockaddr addr_; // [xsp+658h] [xbp-38h] BYREF
sockaddr addr; // [xsp+668h] [xbp-28h] BYREF
__int64 v19; // [xsp+678h] [xbp-18h]

v19 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
StringUTFChars = (unsigned __int8 *)_JNIEnv::GetStringUTFChars(a1, a3, 0LL);
v10 = (unsigned __int8 *)malloc(0x10uLL);
addr_len = 16;
fd = socket(2, 1, 0);
if ( fd < 0 )
__android_log_print(6, "NativeSocket", "TCP socket creation failed");
addr.sa_family = 2;
addr.sa_data[3] = 0;
*(_WORD *)&addr.sa_data[4] = 0;
strcpy(addr.sa_data, "09");
if ( bind(fd, &addr, 0x10u) )
{
__android_log_print(6, "NativeSocket", "TCP bind failed");
close(fd);
}
if ( listen(fd, 5) < 0 )
{
__android_log_print(6, "NativeSocket", "TCP listen failed");
close(fd);
}
__android_log_print(3, "NativeSocket", "TCP Server listening on port %d...", 12345);
fd_1 = accept(fd, &addr_, &addr_len);
if ( (fd_1 & 0x80000000) != 0 )
{
__android_log_print(6, "NativeSocket", "TCP accept failed");
close(fd);
}
v3 = __recvfrom_chk(fd_1, key, 16LL, 17LL, 0LL, 0LL, 0LL);
if ( v3 < 0 )
{
__android_log_print(6, "NativeSocket", "TCP recv failed");
}
else
{
v16[v3] = 0;
__android_log_print(3, "NativeSocket", "TCP Received: %s", v16);
}
close(fd_1);
close(fd);
stream = fopen("/proc/self/status", "r");
v12 = 0;
while ( __fgets_chk(s1, 256LL, stream, 256LL) )
{
if ( !strncmp(s1, "TracerPid:", 0xAuLL) )
{
sscanf(s, "%d", &v12);
break;
}
}
fclose(stream);
v5 = v12;
for ( i = 0; i <= 15; ++i )
{
v5 = sub_2954(v5);
key[i] ^= v5;
}
aesEncrypt(key, 0x10u, StringUTFChars, v10, 0x10u);
__memcpy_chk(&data, v10, 16LL, 25LL);
_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2));
return 0LL;
}

注意这个key的获取是从服务端发到客户端的,题目的附件是包,所以我们用wireshark打开这个包,charles打不开,然后去找16字节的数据

密钥找到了,看看AES

可以看到这个S盒明显是被换了,对于AES的解密,有两个S盒,这是原本的S盒,还需要创建一个对应的逆S盒

S = [
0x31, 0x52, 0x5A, 0xC8, 0x0B, 0xAC, 0xF3, 0x3A, 0x8B, 0x54, 0x27, 0x9B, 0xAB, 0x95, 0xDE, 0x83,
0x60, 0xCB, 0x53, 0x7F, 0xC4, 0xE3, 0x0A, 0x97, 0xE0, 0x29, 0xD5, 0x68, 0xC5, 0xDF, 0xF4, 0x7B,
0xAA, 0xD6, 0x42, 0x78, 0x6C, 0xE9, 0x70, 0x17, 0xD7, 0x37, 0x24, 0x49, 0x75, 0xA9, 0x89, 0x67,
0x03, 0xFA, 0xD9, 0x91, 0xB4, 0x5B, 0xC2, 0x4E, 0x92, 0xFC, 0x46, 0xB1, 0x73, 0x08, 0xC7, 0x74,
0x09, 0xAF, 0xEC, 0xF5, 0x4D, 0x2D, 0xEA, 0xA5, 0xDA, 0xEF, 0xA6, 0x2B, 0x7E, 0x0C, 0x8F, 0xB0,
0x04, 0x06, 0x62, 0x84, 0x15, 0x8E, 0x12, 0x1D, 0x44, 0xC0, 0xE2, 0x38, 0xD4, 0x47, 0x28, 0x45,
0x6E, 0x9D, 0x63, 0xCF, 0xE6, 0x8C, 0x18, 0x82, 0x1B, 0x2C, 0xEE, 0x87, 0x94, 0x10, 0xC1, 0x20,
0x07, 0x4A, 0xA4, 0xEB, 0x77, 0xBC, 0xD3, 0xE1, 0x66, 0x2A, 0x6B, 0xE7, 0x79, 0xCC, 0x86, 0x16,
0xD0, 0xD1, 0x19, 0x55, 0x3C, 0x9F, 0xFB, 0x30, 0x98, 0xBD, 0xB8, 0xF1, 0x9E, 0x61, 0xCD, 0x90,
0xCE, 0x7C, 0x8D, 0x57, 0xAE, 0x6A, 0xB3, 0x3D, 0x76, 0xA7, 0x71, 0x88, 0xA2, 0xBA, 0x4F, 0x3E,
0x40, 0x64, 0x0F, 0x48, 0x21, 0x35, 0x36, 0x2F, 0xE8, 0x14, 0x5D, 0x51, 0xD8, 0xB5, 0xFE, 0xD2,
0x96, 0x93, 0xA1, 0xB6, 0x43, 0x0D, 0x4C, 0x80, 0xC9, 0xFF, 0xA3, 0xDD, 0x72, 0x05, 0x59, 0xBF,
0x0E, 0x26, 0x34, 0x1F, 0x13, 0xE5, 0xDC, 0xF2, 0xC6, 0x50, 0x1E, 0xE4, 0x85, 0xB7, 0x39, 0x8A,
0xCA, 0xED, 0x9C, 0xBB, 0x56, 0x23, 0x1A, 0xF0, 0x32, 0x58, 0xB2, 0x65, 0x33, 0x6F, 0x41, 0xBE,
0x3F, 0x6D, 0x11, 0x00, 0xAD, 0x5F, 0xC3, 0x81, 0x25, 0xA8, 0xA0, 0x9A, 0xF6, 0xF7, 0x5E, 0x99,
0x22, 0x2E, 0x4B, 0xF9, 0x3B, 0x02, 0x7A, 0xB9, 0x5C, 0x69, 0xF8, 0x1C, 0xDB, 0x01, 0x7D, 0xFD
]

# 计算逆 S 盒
InvS = [0] * 256
for i in range(256):
InvS[S[i]] = i

# 格式化输出
for i in range(16):
print(", ".join(f"0x{InvS[i*16 + j]:02X}" for j in range(16)) + ",")

之后去修改就行,脚本如下

// 验证网站: http://tool.chacuo.net/cryptaes/
//参考资料:https://blog.csdn.net/qq_35522513/article/details/83743538

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

static unsigned char AesSbox[16 * 16] =
{
0x31, 0x52, 0x5A, 0xC8, 0x0B, 0xAC, 0xF3, 0x3A, 0x8B, 0x54, 0x27, 0x9B, 0xAB, 0x95, 0xDE, 0x83,
0x60, 0xCB, 0x53, 0x7F, 0xC4, 0xE3, 0x0A, 0x97, 0xE0, 0x29, 0xD5, 0x68, 0xC5, 0xDF, 0xF4, 0x7B,
0xAA, 0xD6, 0x42, 0x78, 0x6C, 0xE9, 0x70, 0x17, 0xD7, 0x37, 0x24, 0x49, 0x75, 0xA9, 0x89, 0x67,
0x03, 0xFA, 0xD9, 0x91, 0xB4, 0x5B, 0xC2, 0x4E, 0x92, 0xFC, 0x46, 0xB1, 0x73, 0x08, 0xC7, 0x74,
0x09, 0xAF, 0xEC, 0xF5, 0x4D, 0x2D, 0xEA, 0xA5, 0xDA, 0xEF, 0xA6, 0x2B, 0x7E, 0x0C, 0x8F, 0xB0,
0x04, 0x06, 0x62, 0x84, 0x15, 0x8E, 0x12, 0x1D, 0x44, 0xC0, 0xE2, 0x38, 0xD4, 0x47, 0x28, 0x45,
0x6E, 0x9D, 0x63, 0xCF, 0xE6, 0x8C, 0x18, 0x82, 0x1B, 0x2C, 0xEE, 0x87, 0x94, 0x10, 0xC1, 0x20,
0x07, 0x4A, 0xA4, 0xEB, 0x77, 0xBC, 0xD3, 0xE1, 0x66, 0x2A, 0x6B, 0xE7, 0x79, 0xCC, 0x86, 0x16,
0xD0, 0xD1, 0x19, 0x55, 0x3C, 0x9F, 0xFB, 0x30, 0x98, 0xBD, 0xB8, 0xF1, 0x9E, 0x61, 0xCD, 0x90,
0xCE, 0x7C, 0x8D, 0x57, 0xAE, 0x6A, 0xB3, 0x3D, 0x76, 0xA7, 0x71, 0x88, 0xA2, 0xBA, 0x4F, 0x3E,
0x40, 0x64, 0x0F, 0x48, 0x21, 0x35, 0x36, 0x2F, 0xE8, 0x14, 0x5D, 0x51, 0xD8, 0xB5, 0xFE, 0xD2,
0x96, 0x93, 0xA1, 0xB6, 0x43, 0x0D, 0x4C, 0x80, 0xC9, 0xFF, 0xA3, 0xDD, 0x72, 0x05, 0x59, 0xBF,
0x0E, 0x26, 0x34, 0x1F, 0x13, 0xE5, 0xDC, 0xF2, 0xC6, 0x50, 0x1E, 0xE4, 0x85, 0xB7, 0x39, 0x8A,
0xCA, 0xED, 0x9C, 0xBB, 0x56, 0x23, 0x1A, 0xF0, 0x32, 0x58, 0xB2, 0x65, 0x33, 0x6F, 0x41, 0xBE,
0x3F, 0x6D, 0x11, 0x00, 0xAD, 0x5F, 0xC3, 0x81, 0x25, 0xA8, 0xA0, 0x9A, 0xF6, 0xF7, 0x5E, 0x99,
0x22, 0x2E, 0x4B, 0xF9, 0x3B, 0x02, 0x7A, 0xB9, 0x5C, 0x69, 0xF8, 0x1C, 0xDB, 0x01, 0x7D, 0xFD
};

static unsigned char AesiSbox[16 * 16] =
{
0xE3, 0xFD, 0xF5, 0x30, 0x50, 0xBD, 0x51, 0x70, 0x3D, 0x40, 0x16, 0x04, 0x4D, 0xB5, 0xC0, 0xA2,
0x6D, 0xE2, 0x56, 0xC4, 0xA9, 0x54, 0x7F, 0x27, 0x66, 0x82, 0xD6, 0x68, 0xFB, 0x57, 0xCA, 0xC3,
0x6F, 0xA4, 0xF0, 0xD5, 0x2A, 0xE8, 0xC1, 0x0A, 0x5E, 0x19, 0x79, 0x4B, 0x69, 0x45, 0xF1, 0xA7,
0x87, 0x00, 0xD8, 0xDC, 0xC2, 0xA5, 0xA6, 0x29, 0x5B, 0xCE, 0x07, 0xF4, 0x84, 0x97, 0x9F, 0xE0,
0xA0, 0xDE, 0x22, 0xB4, 0x58, 0x5F, 0x3A, 0x5D, 0xA3, 0x2B, 0x71, 0xF2, 0xB6, 0x44, 0x37, 0x9E,
0xC9, 0xAB, 0x01, 0x12, 0x09, 0x83, 0xD4, 0x93, 0xD9, 0xBE, 0x02, 0x35, 0xF8, 0xAA, 0xEE, 0xE5,
0x10, 0x8D, 0x52, 0x62, 0xA1, 0xDB, 0x78, 0x2F, 0x1B, 0xF9, 0x95, 0x7A, 0x24, 0xE1, 0x60, 0xDD,
0x26, 0x9A, 0xBC, 0x3C, 0x3F, 0x2C, 0x98, 0x74, 0x23, 0x7C, 0xF6, 0x1F, 0x91, 0xFE, 0x4C, 0x13,
0xB7, 0xE7, 0x67, 0x0F, 0x53, 0xCC, 0x7E, 0x6B, 0x9B, 0x2E, 0xCF, 0x08, 0x65, 0x92, 0x55, 0x4E,
0x8F, 0x33, 0x38, 0xB1, 0x6C, 0x0D, 0xB0, 0x17, 0x88, 0xEF, 0xEB, 0x0B, 0xD2, 0x61, 0x8C, 0x85,
0xEA, 0xB2, 0x9C, 0xBA, 0x72, 0x47, 0x4A, 0x99, 0xE9, 0x2D, 0x20, 0x0C, 0x05, 0xE4, 0x94, 0x41,
0x4F, 0x3B, 0xDA, 0x96, 0x34, 0xAD, 0xB3, 0xCD, 0x8A, 0xF7, 0x9D, 0xD3, 0x75, 0x89, 0xDF, 0xBF,
0x59, 0x6E, 0x36, 0xE6, 0x14, 0x1C, 0xC8, 0x3E, 0x03, 0xB8, 0xD0, 0x11, 0x7D, 0x8E, 0x90, 0x63,
0x80, 0x81, 0xAF, 0x76, 0x5C, 0x1A, 0x21, 0x28, 0xAC, 0x32, 0x48, 0xFC, 0xC6, 0xBB, 0x0E, 0x1D,
0x18, 0x77, 0x5A, 0x15, 0xCB, 0xC5, 0x64, 0x7B, 0xA8, 0x25, 0x46, 0x73, 0x42, 0xD1, 0x6A, 0x49,
0xD7, 0x8B, 0xC7, 0x06, 0x1E, 0x43, 0xEC, 0xED, 0xFA, 0xF3, 0x31, 0x86, 0x39, 0xFF, 0xAE, 0xB9,
};
static unsigned char AesRcon[11 * 4] =
{
0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00,
0x36, 0x00, 0x00, 0x00
};


unsigned char FA(unsigned char b) { if (b < 0x80) return (b << 1); else return ((b << 1) ^ (0x1b)); }
unsigned char FB(unsigned char b) { return FA(b) ^ b; }
unsigned char FC(unsigned char b) { return FA(FA(FA(b))) ^ b; }
unsigned char FD(unsigned char b) { return FA(FA(FA(b))) ^ FA(b) ^ b; }
unsigned char FE(unsigned char b) { return FA(FA(FA(b))) ^ FA(FA(b)) ^ b; }
unsigned char Ff(unsigned char b) { return FA(FA(FA(b))) ^ FA(FA(b)) ^ FA(b); }

void Cipher(unsigned char* input, unsigned char* output, unsigned char* exp_key)
{
int i, j;
int round;
unsigned char ttt[4 * 4];
unsigned char State[4][4];
for (i = 0; i < 16; i++) State[i % 4][i / 4] = input[i];
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = State[i][j] ^ exp_key[4 * j + i];
for (round = 1; round <= 9; round++)
{
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = AesSbox[State[i][j]];
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)ttt[4 * i + j] = State[i][j];
for (i = 1; i < 4; i++)for (j = 0; j < 4; j++)
{
if (i == 1)State[i][j] = ttt[4 * i + (j + 1) % 4]; else if (i == 2)State[i][j] = ttt[4 * i + (j + 2) % 4]; else if (i == 3)State[i][j] = ttt[4 * i + (j + 3) % 4];
}
for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) ttt[4 * i + j] = State[i][j];
for (j = 0; j < 4; j++)
{
State[0][j] = FA(ttt[0 + j]) ^ FB(ttt[4 * 1 + j]) ^ ttt[4 * 2 + j] ^ ttt[4 * 3 + j];
State[1][j] = ttt[0 + j] ^ FA(ttt[4 * 1 + j]) ^ FB(ttt[4 * 2 + j]) ^ ttt[4 * 3 + j];
State[2][j] = ttt[0 + j] ^ ttt[4 * 1 + j] ^ FA(ttt[4 * 2 + j]) ^ FB(ttt[4 * 3 + j]);
State[3][j] = FB(ttt[0 + j]) ^ ttt[4 * 1 + j] ^ ttt[4 * 2 + j] ^ FA(ttt[4 * 3 + j]);
}
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = State[i][j] ^ exp_key[4 * ((round * 4) + j) + i];
}
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = AesSbox[State[i][j]];
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)ttt[4 * i + j] = State[i][j];
for (i = 1; i < 4; i++)for (j = 0; j < 4; j++)
{
if (i == 1)State[i][j] = ttt[4 * i + (j + 1) % 4]; else if (i == 2)State[i][j] = ttt[4 * i + (j + 2) % 4]; else if (i == 3)State[i][j] = ttt[4 * i + (j + 3) % 4];
}
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = State[i][j] ^ exp_key[4 * (40 + j) + i];
for (i = 0; i < 16; i++)output[i] = State[i % 4][i / 4];
}

//Aes解密函数
void InvCipher(unsigned char* input, unsigned char* output, unsigned char* exp_key)
{
int round;
int i, j;
unsigned char ttt[4 * 4];
unsigned char State[4][4];
for (i = 0; i < 16; i++)State[i % 4][i / 4] = input[i];
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = State[i][j] ^ exp_key[4 * (40 + j) + i];
for (round = 9; round >= 1; round--)
{
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)ttt[4 * i + j] = State[i][j];
for (i = 1; i < 4; i++)for (j = 0; j < 4; j++)
{
if (i == 1)State[i][j] = ttt[4 * i + (j + 3) % 4]; else if (i == 2)State[i][j] = ttt[4 * i + (j + 2) % 4]; else if (i == 3)State[i][j] = ttt[4 * i + (j + 1) % 4];
}
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = AesiSbox[State[i][j]];
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = State[i][j] ^ exp_key[4 * ((round * 4) + j) + i];
for (i = 0; i < 4; i++)for (j = 0; j < 4; j++) ttt[4 * i + j] = State[i][j];
for (j = 0; j < 4; j++)
{
State[0][j] = Ff(ttt[j]) ^ FD(ttt[4 + j]) ^ FE(ttt[4 * 2 + j]) ^ FC(ttt[4 * 3 + j]);
State[1][j] = FC(ttt[j]) ^ Ff(ttt[4 + j]) ^ FD(ttt[4 * 2 + j]) ^ FE(ttt[4 * 3 + j]);
State[2][j] = FE(ttt[j]) ^ FC(ttt[4 + j]) ^ Ff(ttt[4 * 2 + j]) ^ FD(ttt[4 * 3 + j]);
State[3][j] = FD(ttt[j]) ^ FE(ttt[4 + j]) ^ FC(ttt[4 * 2 + j]) ^ Ff(ttt[4 * 3 + j]);
}
}
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)ttt[4 * i + j] = State[i][j];
for (i = 1; i < 4; i++)for (j = 0; j < 4; j++)
{
if (i == 1)State[i][j] = ttt[4 * i + (j + 3) % 4]; else if (i == 2)State[i][j] = ttt[4 * i + (j + 2) % 4]; else if (i == 3)State[i][j] = ttt[4 * i + (j + 1) % 4];
}
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = AesiSbox[State[i][j]];
for (j = 0; j < 4; j++)for (i = 0; i < 4; i++)State[i][j] = State[i][j] ^ exp_key[4 * j + i];
for (i = 0; i < 16; i++)output[i] = State[i % 4][i / 4];
}

/*****************************************************
*函数功能: AES加密, 模式CBC,数据块128位,填充方式:pkcs5padding
* 参数:
* input_buff:需要加密的数组指针
* InputLen:加密数据的字节长度
* p_key: 指向密钥数据的指针, 1~16字节长度
* output_buff:加密结果输出指针
*
* 返回值: OutLength 加密后的输出长度
*********************************************************/
unsigned long AES128_CBC_Encrypt(unsigned char* input_buff, unsigned long InputLen, unsigned char* p_key, unsigned char* output_buff, unsigned char* iv)
{
unsigned long OutLength = 0;
long i, j;
unsigned char* lpCurInBuff = input_buff;
unsigned char* lpCurOutBuff = output_buff;
long blocknum = InputLen / 16;
long leftnum = InputLen % 16;

int row;
unsigned char temp[4];
unsigned char ex_key[16 * 15];
for (row = 0; row < 4; row++) //拷贝seed 密钥
{
ex_key[4 * row + 0] = *(p_key + 4 * row);
ex_key[4 * row + 1] = *(p_key + 4 * row + 1);
ex_key[4 * row + 2] = *(p_key + 4 * row + 2);
ex_key[4 * row + 3] = *(p_key + 4 * row + 3);
}
for (row = 4; row < 44; row++)
{
temp[0] = ex_key[4 * row - 4]; //当前列的前一列
temp[1] = ex_key[4 * row - 3];
temp[2] = ex_key[4 * row - 2];
temp[3] = ex_key[4 * row - 1];
if (row % 4 == 0)
{
unsigned char exchange_buff = 0;
exchange_buff = temp[0];
temp[0] = AesSbox[16 * (temp[1] >> 4) + (temp[1] & 0x0f)];
temp[1] = AesSbox[16 * (temp[2] >> 4) + (temp[2] & 0x0f)];
temp[2] = AesSbox[16 * (temp[3] >> 4) + (temp[3] & 0x0f)];
temp[3] = AesSbox[16 * (exchange_buff >> 4) + (exchange_buff & 0x0f)];

temp[0] = temp[0] ^ AesRcon[4 * (row / 4) + 0];
temp[1] = temp[1] ^ AesRcon[4 * (row / 4) + 1];
temp[2] = temp[2] ^ AesRcon[4 * (row / 4) + 2];
temp[3] = temp[3] ^ AesRcon[4 * (row / 4) + 3];
}
ex_key[4 * row + 0] = ex_key[4 * (row - 4) + 0] ^ temp[0];
ex_key[4 * row + 1] = ex_key[4 * (row - 4) + 1] ^ temp[1];
ex_key[4 * row + 2] = ex_key[4 * (row - 4) + 2] ^ temp[2];
ex_key[4 * row + 3] = ex_key[4 * (row - 4) + 3] ^ temp[3];
}
for (i = 0; i < blocknum; i++)
{
for (j = 0; j < 16; j++)lpCurOutBuff[j] = lpCurInBuff[j] ^ iv[j];
Cipher(lpCurOutBuff, lpCurOutBuff, ex_key);
memcpy(iv, lpCurOutBuff, 16);
lpCurInBuff += 16;
lpCurOutBuff += 16;
OutLength += 16;
}
if (leftnum)
{
unsigned char inbuff[16];
memset(inbuff, 16 - leftnum, 16);
memcpy(inbuff, lpCurInBuff, leftnum);
for (j = 0; j < 16; j++)lpCurOutBuff[j] = inbuff[j] ^ iv[j];
Cipher(lpCurOutBuff, lpCurOutBuff, ex_key);
memcpy(iv, lpCurOutBuff, 16);
lpCurOutBuff += 16;
OutLength += 16;
}
else
{
unsigned char extrabuff[16];
memset(extrabuff, 16, 16);
for (j = 0; j < 16; j++)lpCurOutBuff[j] = extrabuff[j] ^ iv[j];
Cipher(lpCurOutBuff, lpCurOutBuff, ex_key);
memcpy(iv, lpCurOutBuff, 16);
OutLength += 16;
}
return OutLength;
}


/*******************************************************
*函数功能: AES解密, 模式CBC,数据块128位,填充方式:pkcs5padding
* 参数:
* input_buff:需要解密的数组指针
* InputLen:需要解密数据的字节长度
* p_key: 指向密钥数据的指针, 1~16字节长度
* output_buff:加密结果输出指针
*
* 返回值: OutLength 加密后的输出长度

********************************************************/
void fuck(unsigned char* a1) {
unsigned int i; // [esp+0h] [ebp-Ch]
unsigned int v2; // [esp+4h] [ebp-8h]
char v3; // [esp+Bh] [ebp-1h]

v2 = 0;
for (i = 15; v2 < i; --i)
{
v3 = a1[v2] ^ 0xF;
a1[v2] = a1[i] ^ 0xF;
a1[i] = v3;
++v2;
}
}
unsigned long AES128_CBC_Decrypt(unsigned char* input_buff, unsigned long InputLen, unsigned char* p_key, unsigned char* output_buff, char* iv)
{
unsigned long OutLength = 0;
long blocknum = InputLen / 16;
long leftnum = InputLen % 16;
long i, j;
unsigned char temp[16];

unsigned char* pCurInBuf = input_buff;
unsigned char* pCurOutBuf = output_buff;
int row;
unsigned char ex_key[16 * 15];
for (row = 0; row < 4; row++)
{
ex_key[4 * row + 0] = *(p_key + 4 * row);
ex_key[4 * row + 1] = *(p_key + 4 * row + 1);
ex_key[4 * row + 2] = *(p_key + 4 * row + 2);
ex_key[4 * row + 3] = *(p_key + 4 * row + 3);
}
for (row = 4; row < 44; row++)
{
temp[0] = ex_key[4 * row - 4]; //当前列的前一列
temp[1] = ex_key[4 * row - 3];
temp[2] = ex_key[4 * row - 2];
temp[3] = ex_key[4 * row - 1];
if (row % 4 == 0)
{
unsigned char exchange_buff = 0;
exchange_buff = temp[0];
temp[0] = AesSbox[16 * (temp[1] >> 4) + (temp[1] & 0x0f)];
temp[1] = AesSbox[16 * (temp[2] >> 4) + (temp[2] & 0x0f)];
temp[2] = AesSbox[16 * (temp[3] >> 4) + (temp[3] & 0x0f)];
temp[3] = AesSbox[16 * (exchange_buff >> 4) + (exchange_buff & 0x0f)];
temp[0] = temp[0] ^ AesRcon[4 * (row / 4) + 0];
temp[1] = temp[1] ^ AesRcon[4 * (row / 4) + 1];
temp[2] = temp[2] ^ AesRcon[4 * (row / 4) + 2];
temp[3] = temp[3] ^ AesRcon[4 * (row / 4) + 3];
}
ex_key[4 * row + 0] = ex_key[4 * (row - 4) + 0] ^ temp[0];
ex_key[4 * row + 1] = ex_key[4 * (row - 4) + 1] ^ temp[1];
ex_key[4 * row + 2] = ex_key[4 * (row - 4) + 2] ^ temp[2];
ex_key[4 * row + 3] = ex_key[4 * (row - 4) + 3] ^ temp[3];
}
for (i = 0; i < blocknum; i++)
{
InvCipher(pCurInBuf, pCurOutBuf, ex_key);
/*for (j = 0; j < 16; j++)
{
pCurOutBuf[j] = pCurOutBuf[j] ^ iv[j];
}*/
memcpy(iv, pCurInBuf, 16);
if (i == (blocknum - 1))
{
memset(temp, 0, 16);
if (pCurOutBuf[15] != 0x10)
{
if (pCurOutBuf[15] < 0x10)
{
OutLength = InputLen - pCurOutBuf[15];
memcpy(temp, pCurOutBuf, 16 - pCurOutBuf[15]);
memcpy(pCurOutBuf, temp, 16);
}
else
break;
}
else
{
OutLength = InputLen - 16;
memcpy(pCurOutBuf, temp, 16);
}
}
pCurInBuf += 16;
pCurOutBuf += 16;
}
return OutLength;
}
int main(int argc, char* argv[])
{
int i = 0;
unsigned long outlen;
unsigned char flag[] = { 0xcd, 0x16, 0xdb, 0xb5, 0xd1, 0x2, 0xa4, 0x82, 0x8e, 0x59, 0x73, 0x9e, 0x96, 0x26, 0x56, 0xf2, 0x16, 0x8e, 0x46, 0xf2, 0x55, 0x7b, 0x92, 0x31, 0x30, 0xdc, 0xaa, 0x8a, 0xf3, 0x1c, 0xa0, 0xaa };
//unsigned char key[16] = { 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70, };
char iv[16] = { 0 };
unsigned char okflag[96] = { 0 };
int len_flag = 16;
char v2; // [esp+7h] [ebp-1h]
/*for (i = 0; i < 32; ++i)
flag[i] ^= 0x11u;*/
//数据
unsigned char buf[] = { 0x60,0x57,0x98,0x34,0xa6,0xee,0x69,0xd0,0x99,0x92,0x24,0xef,0x93,0x34,0x57,0xc3 };
//密钥
unsigned char key[] = { 0x12,0x34 ,0x55,0x66,0x77,0x88,0x43,0x21,0x70,0x34,0x73,0x73,0x57,0x72,0x30,0x64 };
unsigned char x = 0;
for (int i = 0; i < 16; i++) {
x = (0x99 * x - 1);
key[i] ^= x;
}

unsigned char digest[16];
int j;

outlen = AES128_CBC_Decrypt(buf, len_flag, key, okflag, iv);


for (j = 0; j < 32; j++)
{
printf("%c", okflag[j]);

}
printf("\n");
return 0;
}



MedSecureAdmin| lOSE

用户名的加密是在java层,一个魔改rc4

用户名@dm1n234

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char byte;
void swap(byte* a, byte* b) {
byte temp = *a;
*a = *b;
*b = temp;
}
void KSA(byte* S, byte* key, int key_length) {
int i, j = 0;
for (i = 0; i < 256; i++)
S[i] = i;
for (i = 0; i < 256; i++) {
j = (j + S[i] + key[i % key_length]) % 256;
swap(&S[i], &S[j]);
}
}
void generate_username() {
byte lII[] = { 0x8D, 0xF4, 0x91, 0x6A, 0x75, 0x19, 0x11, 0xA3,
0x68, 0xB6, 0x68, 0xE4, 0x16, 0x93, 0x11, 0x49 };
byte ll_xor[] = { 43, 235, 184, 60, 130, 73, 116, 215 };
byte S[256];
KSA(S, lII, 16);
byte current_S[256], username[8];
memcpy(current_S, S, 256);
int lIll = 0;
for (int i = 0; i < 8; i++) {
int i2 = 0, i3 = lIll;
byte b = current_S[i2];
int i4 = (i3 + b + 1) % 256;
swap(&current_S[i2], &current_S[i4]);
byte s_i2 = current_S[i2];
byte s_i4_prev = b;
int pos = (s_i2 + b + current_S[(i2 + i4) % 256]) % 256;
byte keyStream = current_S[pos];
username[i] = (ll_xor[i] ^ keyStream) ^ 0x77;
lIll = i4;
}
printf("Username: ");
for (int i = 0; i < 8; i++)
printf("%c", username[i]);
printf("\n");
}
int main() {
generate_username();
return 0;
}
密码的验证是在so层
密文
6E5203FC428CA98EB21860C47E0842C237140100675D487900F45AE1C9FA7205

DES??