一
easyre
input = argv[1];
j = 1i64;
for ( i = 0i64; i != 43; ++i )
{
input->m128i_i8[i] ^= input->m128i_u8[i + 1 + -42 * (j / 42)];
++j;
}
for(int i = 0; i < 43; ++i)
{
input[i] ^= input[i + 1 - 42 * (i + 1 / 42)]
}
if (_mm_movemask_epi8(_mm_and_si128(_mm_cmpeq_epi8(_mm_loadu_si128(input), data1),
_mm_cmpeq_epi8(_mm_loadu_si128(input + 1), data2))) == 0xFFFF)data1 = [0x0A, 0x0D, 0x06, 0x1C, 0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03,
0x04, 0x0A, 0x14, 0x49, 0x05, 0x57, 0x0A, 0x0D, 0x06, 0x1C,
0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03, 0x04, 0x0A, 0x14, 0x49,
0x05, 0x57, 0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C,
0x56, 0x00, 0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54, 0x55, 0x03,
0x53, 0x57, 0x01, 0x03, 0x07, 0x04, 0x4A, 0x77, 0x0D]data2 = [0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C, 0x56, 0x00,
0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54]
input
地址处加载一个 128 位(16 字节)的未对齐数据到一个 SSE 寄存器中。_mm_loadu_si128(input)
中的每个字节和data1
中的每个字节;结果是每个字节比较的结果:如果某个字节相等,则对应的结果字节为 0xFF(即全1),否则为 0x00(全0)。==0xFFFF
,相当于全为1。cipher = [
0x0A, 0x0D, 0x06, 0x1C, 0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03, 0x04, 0x0A,
0x14, 0x49, 0x05, 0x57, 0x00, 0x1B, 0x19, 0x02, 0x01, 0x54, 0x4E, 0x4C,
0x56, 0x00, 0x51, 0x4B, 0x4F, 0x57, 0x05, 0x54, 0x55, 0x03, 0x53, 0x57,
0x01, 0x03, 0x07, 0x04, 0x4A, 0x77, 0x0D
]x = ord('f')
input = []for i in range(len(cipher)):
for num in range(32, 128):
if x ^ num == cipher[i]:
input.append(num)
x = num
breakflag = ''
for j in range(len(input)):
flag += chr(input[j])print('f' + flag)
# flag{fcf94739-da66-467c-a77f-b50d12a67437}
二
tmaze
if(v5 == 43)
处下断点,调试可以发现终端并未让输入。xyz。
path。
i = 0;
do
j = i++;
while ( path[j] );
if ( i == 43 )
v7 = sub_7FF7D50A1230(&unk_7FF7D50D7000, dword_7FF7D50D7FA0, envp);
unk_7FF7D50D7000
中是若干1和0组成的数组,猜测是构成迷宫的参数,dword_7FF7D50D7FA0
是固定参数10。sub_7FF7D50A1230
里是复杂的迷宫生成函数,对我来说难以分析我就先没管。if ( argc != 1 )
{
m = *path == 0;
if ( *path )
{
v14 = 1;
v15 = data1;
k = 0i64;
do
{
chose = path[k];
switch ( chose )
{
case 'z':
v19 = *(v15 + 16);
if ( !v19 || *(v15 + 26) )
goto LABEL_12;
break;
case 'y':
v19 = *(v15 + 8);
if ( !v19 || *(v15 + 25) )
goto LABEL_12;
break;
case 'x':
v19 = *v15;
if ( !*v15 || *(v15 + 24) )
goto LABEL_12;
break;
default:
goto LABEL_12;
}
data1 = v19;
*(v19 + 27) = 1;
k = v14;
len = strlen(path);
++v14;
v15 = v19;
m = len <= k;
}
while ( !m );
}
LABEL_12:
if ( m && data1 == v7 )
{
v13 = sub_7FF7D50A1770(&qword_7FF7D50D92C0, "yes flag is flag{UUID(md5(your input))}");
sub_7FF7D50A1B70(v13);
}
data1
其实就是当前操作对应地址,最开始的的data1就是start_loc
,data2
就是最后的地址end_loc。
case 'z':
v19 = *(v15 + 16);
if ( !v19 || *(v15 + 26) )
goto LABEL_12;
break;
now_loc
,v19存储的是*(now_loc + 16)这个地址的值,而这个值恰好又是一个地址,可以说v19 是next。
1.3
分析的内容全部理解为:获得start_loc
和end_loc。
idapython
,把start_loc
到end_loc
的内容当作迷宫,根据switch-case的限制逻辑,利用深度搜索算法来输出符合条件的xyz
,即path。all_visited_loc
,来实现减少搜索量。import idc start_loc = 0x1DDFFDAEA60
end_loc = 0x1DDFFDAEE20def dfs(path, all_visited_loc, now_loc):
if now_loc == end_loc:
if len(path) == 42:
print("Yes! Found the path")
for i in range(len(path)):
print(path[i], end='')
else:
print("Not Found the path")
returnif now_loc in all_visited_loc:
returnall_visited_loc.append(now_loc)
x_location = idc.get_qword(now_loc)
y_location = idc.get_qword(now_loc + 8)
z_location = idc.get_qword(now_loc + 16)x_judge = idc.get_wide_byte(now_loc + 24)
y_judge = idc.get_wide_byte(now_loc + 25)
z_judge = idc.get_wide_byte(now_loc + 26)if x_location > 0 and x_judge == 0:
path.append("x")
dfs(path, all_visited_loc, x_location)
path.pop()if y_location > 0 and y_judge == 0:
path.append("y")
dfs(path, all_visited_loc, y_location)
path.pop()if z_location > 0 and z_judge == 0:
path.append("z")
dfs(path, all_visited_loc, z_location)
path.pop()all_visited_loc.pop()
returnpath = []
all_visited_loc = []
dfs(path, all_visited_loc, start_loc)
三
xiran_encrypto
Tips:
xiran_encrypto是恶意样本分析,本质是从cha文件里解出一个数据流,clickme文件是chacha20对flag.png文件进行加密。对本人来说太难了,分析不出来QAQ,后续若能理解再来分享。看雪ID:Sh4d0w
https://bbs.kanxue.com/user-home-1002267.htm
# 往期推荐
2、恶意木马历险记
球分享
球点赞
球在看
点击阅读原文查看更多