工具
IDA动态调试+环境变量设置
思路展开
0x01.xz压缩,windows两次后缀改为.zip,解压得elf文件
xz压缩第一次见,两次解压得到最终文件
尝试运行,没有参数输入,直接出flag(假的),推测要动态调试解决。
0x02.IDA启动
果真没有输入,使用动调调试解决
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
int v3; // ebx
__int64 v4; // rax
__m128i v5; // xmm0
__m128i v6; // xmm1
__m128i v7; // xmm0
__m128i v8; // xmm0
__m128i v9; // xmm1
__m128i v10; // xmm3
__m128i v11; // xmm1
__m128i v12; // xmm3
__m128i v13; // xmm0
__m128i v14; // xmm0
v3 = sub_400820(dword_6012B4);
byte_6012A8[0] = HIBYTE(v3);
byte_6012A9 = BYTE2(v3) & 0xFD;
byte_6012AA = BYTE1(v3) & 0xDF;
byte_6012AB = v3 & 0xBF;
if ( getenv("ASIS") && (*(_DWORD *)getenv("CTF") ^ v3) == 0xFEEBFEEB )
dword_6012AC = *(_DWORD *)getenv("ASIS");
v4 = 0LL;
do
{
haystack[v4] ^= byte_6012A8[v4 & 7];
++v4;
}
while ( v4 != 33 );
v5 = _mm_load_si128((const __m128i *)haystack);
v6 = _mm_unpacklo_epi8(v5, (__m128i)0LL);
v7 = _mm_unpackhi_epi8(v5, (__m128i)0LL);
v8 = _mm_add_epi32(
_mm_unpackhi_epi16(v7, (__m128i)0LL),
_mm_add_epi32(
_mm_add_epi32(_mm_unpackhi_epi16(v6, (__m128i)0LL), _mm_unpacklo_epi16(v6, (__m128i)0LL)),
_mm_unpacklo_epi16(v7, (__m128i)0LL)));
v9 = _mm_load_si128((const __m128i *)&xmmword_601290);
v10 = v9;
v11 = _mm_unpackhi_epi8(v9, (__m128i)0LL);
v12 = _mm_unpacklo_epi8(v10, (__m128i)0LL);
v13 = _mm_add_epi32(
_mm_add_epi32(
_mm_add_epi32(
_mm_add_epi32(v8, _mm_unpacklo_epi16(v12, (__m128i)0LL)),
_mm_unpackhi_epi16(v12, (__m128i)0LL)),
_mm_unpacklo_epi16(v11, (__m128i)0LL)),
_mm_unpackhi_epi16(v11, (__m128i)0LL));
v14 = _mm_add_epi32(v13, _mm_srli_si128(v13, 8));
if ( _mm_cvtsi128_si32(_mm_add_epi32(v14, _mm_srli_si128(v14, 4))) != 2388 )
{
*(_DWORD *)haystack = 1600414050;
*(_DWORD *)&haystack[4] = 1600414050;
*(_DWORD *)&haystack[8] = 1600414050;
*(_DWORD *)&haystack[12] = 1600414050;
*(_QWORD *)&xmmword_601290 = 6873726006409322850LL;
BYTE7(xmmword_601290) = 0;
}
printf("Flag: ASIS{%s}\n", haystack);
if ( strstr(haystack, "bad_") )
puts("this flag is absolutely fake ");
return 0LL;
}
整体逻辑明朗,haystack是flag,向上找,haystack是和byte_6012A8异或得出,byte_6012A8由v3得出,v3经过sub_400820函数得出。
纵览代码最奇怪的一句话
if ( getenv("ASIS") && (*(_DWORD *)getenv("CTF") ^ v3) == 0xFEEBFEEB ) dword_6012AC = *(_DWORD *)getenv("ASIS");
getenv C 库函数 char *getenv(const char *name) 搜索 name 所指向的环境字符串,并返回相关的值给字符串。
dword_6012AC与byte_6012A8之间差4,而在下面关键函数(下面的代码)
do
{
haystack[v4] ^= byte_6012A8[v4 & 7];
++v4;
}
while ( v4 != 33 );
v4&7是0到7的循环,这样看来与haystack异或的一定有dword_6012AC。所以就让if ( getenv("ASIS") && (*(_DWORD *)getenv("CTF") ^ v3) == 0xFEEBFEEB )
满足,v3动调可出0xB11924E1,0xB11924E1 ^ 0xFEEBFEEB = 0x4ff2da0a
linux里面用export对环境变量进行设置,创建这两个变量。然后设置环境变量,运行,flag就出来了。参数小端存储
export ASIS="$(printf "\x0a\xda\xf2\x4f")"
export CTF="$(printf "\x0a\xda\xf2\x4f")"
ASIS{600d_j0b_y0u_4r3_63771n6_574r73d}