tea
1 IDA64
int __cdecl main(int argc, const char **argv, const char **envp)
{
boilWater();
if ( strlen(pwd) == 32 )
{
addSugar();
addTea();
addMilk();
strainAndServe();
}
else
{
puts("wrong length");
}
return 0;
}
unsigned __int64 addSugar()
{
int i; // [rsp+4h] [rbp-5Ch]
char v2[8]; // [rsp+10h] [rbp-50h] BYREF
__int64 v3; // [rsp+18h] [rbp-48h]
char v4; // [rsp+20h] [rbp-40h]
char dest[8]; // [rsp+30h] [rbp-30h] BYREF
__int64 v6; // [rsp+38h] [rbp-28h]
char v7; // [rsp+40h] [rbp-20h]
unsigned __int64 v8; // [rsp+48h] [rbp-18h]
v8 = __readfsqword(0x28u);
*(_QWORD *)v2 = 0LL;
v3 = 0LL;
v4 = 0;
*(_QWORD *)dest = 0LL;
v6 = 0LL;
v7 = 0;
for ( i = 0; i < strlen(pwd); ++i )
{
if ( (i & 1) != 0 )
strncat(v2, &pwd[i], 1uLL);
else
strncat(dest, &pwd[i], 1uLL);
}
strncat(v2, dest, 0x11uLL);
strcpy(pwd, v2);
return __readfsqword(0x28u) ^ v8;
}
unsigned __int64 addTea()
{
size_t v0; // rbx
size_t v1; // rbx
char src; // [rsp+7h] [rbp-49h] BYREF
int i; // [rsp+8h] [rbp-48h]
int j; // [rsp+Ch] [rbp-44h]
char dest[8]; // [rsp+10h] [rbp-40h] BYREF
__int64 v7; // [rsp+18h] [rbp-38h]
__int64 v8; // [rsp+20h] [rbp-30h]
__int64 v9; // [rsp+28h] [rbp-28h]
char v10; // [rsp+30h] [rbp-20h]
unsigned __int64 v11; // [rsp+38h] [rbp-18h]
v11 = __readfsqword(0x28u);
*(_QWORD *)dest = 0LL;
v7 = 0LL;
v8 = 0LL;
v9 = 0LL;
v10 = 0;
for ( i = 0; ; ++i )
{
v0 = i;
if ( v0 >= strlen(pwd) >> 1 )
break;
src = pwd[i] + 3 * (i / -2);
strncat(dest, &src, 1uLL);
}
for ( j = strlen(pwd) >> 1; ; ++j )
{
v1 = j;
if ( v1 >= strlen(pwd) )
break;
src = pwd[j] + j / 6;
strncat(dest, &src, 1uLL);
}
strcpy(pwd, dest);
return __readfsqword(0x28u) ^ v11;
}
unsigned __int64 addMilk()
{
size_t v0; // rax
size_t v1; // rax
int v3; // [rsp+4h] [rbp-ACh]
char dest[8]; // [rsp+10h] [rbp-A0h] BYREF
__int64 v5; // [rsp+18h] [rbp-98h]
__int64 v6; // [rsp+20h] [rbp-90h]
__int64 v7; // [rsp+28h] [rbp-88h]
char v8; // [rsp+30h] [rbp-80h]
char s[8]; // [rsp+40h] [rbp-70h] BYREF
__int64 v10; // [rsp+48h] [rbp-68h]
__int64 v11; // [rsp+50h] [rbp-60h]
__int64 v12; // [rsp+58h] [rbp-58h]
char v13; // [rsp+60h] [rbp-50h]
char v14[8]; // [rsp+70h] [rbp-40h] BYREF
__int64 v15; // [rsp+78h] [rbp-38h]
__int64 v16; // [rsp+80h] [rbp-30h]
__int64 v17; // [rsp+88h] [rbp-28h]
char v18; // [rsp+90h] [rbp-20h]
unsigned __int64 v19; // [rsp+98h] [rbp-18h]
v19 = __readfsqword(0x28u);
v3 = 0;
*(_QWORD *)dest = 0LL;
v5 = 0LL;
v6 = 0LL;
v7 = 0LL;
v8 = 0;
*(_QWORD *)s = 0LL;
v10 = 0LL;
v11 = 0LL;
v12 = 0LL;
v13 = 0;
*(_QWORD *)v14 = 0LL;
v15 = 0LL;
v16 = 0LL;
v17 = 0LL;
v18 = 0;
while ( pwd[v3] != '5' && v3 < strlen(pwd) )
strncat(dest, &pwd[v3++], 1uLL);
while ( pwd[v3] != 'R' && v3 < strlen(pwd) )
strncat(s, &pwd[v3++], 1uLL);
while ( v3 < strlen(pwd) )
strncat(v14, &pwd[v3++], 1uLL);
v0 = strlen(dest);
strncat(v14, dest, v0);
v1 = strlen(s);
strncat(v14, s, v1);
strcpy(pwd, v14);
return __readfsqword(0x28u) ^ v19;
}
int strainAndServe()
{
if ( !strcmp("R;crc75ihl`cNYe`]m%50gYhugow~34i", pwd) )
return puts("yep, that's right");
else
return puts("nope, that's not it");
}
2 gdb调试
gdb调试,输入32位单词abcdefghijklmnopqrstuvwxyz012345
,有如下输出:
# addSugar : $rdi : 0x0000555555558040 → "bdfhjlnprtvxz135acegikmoqsuwy024"
# addTea : 0x555555558040 <pwd>: "bdcedfegfhgih\037\036 cehjlnpruwy{}479"
# addMilk 0x555555558040 <pwd>: "bdcedfegfhgih\037\036 cehjlnpruwy{}479"
shellctf{abcdefghijklmnopqrstuv}
,有如下输出: # addSugar 0x555555558040 <pwd>: "hlcfacegikmoqsu}selt{bdfhjlnprtv"
# addTea : 0x555555558040 <pwd>: "hl`c[]\\^]_^`_a`hugow~egilnprtvy{"
# addMilk 0x555555558040 <pwd>: "hl`c[]\\^]_^`_a`hugow~egilnprtvy{"
r = b'abcdefghijklmnopqrstuvwxyz012345'
left=[]
right=[]
for i in range(len(r)):
if (i&1 != 0):
right.append(r[i])
else:
left.append(r[i])
cx = bytes(right) + bytes(left)
half = len(cx) // 2
r=[]
for i in range(0,half):
r.append(cx[i]-3*(i//2))
for i in range(half,len(cx)):
r.append(cx[i]+i//6)
bytes(r) # b'bacbdcedfegfh\x1c\x1e\x1dehjlnpruwy{}479'
3 逆向
cx = b'R;crc75ihl`cNYe`]m%50gYhugow~34i'
#cx = b'hl`c[]\\^]_^`_a`hugow~egilnprtvy{'
half = len(cx) // 2
r=[]
for i in range(0,half):
r.append(cx[i]+3*(i//2))
for i in range(half,len(cx)):
r.append(cx[i]-i//6)
left=r[:half]
right=r[half:len(cx)]
flag = []
for i in range(half):
flag.append(right[i])
flag.append(left[i])
print(bytes(flag))
4 addMilk
从逆向代码看:addMilk函数对pwd进行拼接: - 开始到字符5存入dest - 当前位置到字符R存入s - 其它字符存入v14 - v14拼接dest和s拷贝到pwd
gdb设置pwd包含5和R:
set {char [32]} 0x0000555555558040 = "012345ABCDERabcdefghjkloiuytrewq"
gef➤ ni
gef➤ x/s 0x0000555555558040
0x555555558040 <pwd>: "Rabcdefghjkloiuytrewq012345ABCDE"
set {char [32]} 0x0000555555558040 = "01234567ABCDEabcdeRfghjkloiuytrewq"
gef➤ ni
gef➤ x/s 0x0000555555558040
0x555555558040 <pwd>: "Rfghjkloiuytrewq01234567ABCDEabcde"
可以看到,addMilk对pwd在R处切断,调换前后顺序后拼接,所有有32种爆破可能:
逆向addMilk
5 exp:
ct = b'R;crc75ihl`cNYe`]m%50gYhugow~34i'
half = 16
for i in range(1,30):
cx = ct[i:32] + ct[0:i]
r=[]
for i in range(0,half):
r.append(cx[i]+3*(i//2))
for i in range(half,len(cx)):
r.append(cx[i]-i//6)
left=r[:half]
right=r[half:len(cx)]
flag = []
for i in range(half):
flag.append(right[i])
flag.append(left[i])
print(bytes(flag))
shellctf{T0_1nfiNi7y_4nD_B3y0nd}