Flipping Bank
The Bank of the World is under attack. Hackers found a way in and locked the admins out. However, the netcat authentication by the intruders is not perfectly secure. Could you help the admins log in?
import socketserver
import socket, os
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
from Crypto.Random import get_random_bytes
from binascii import unhexlify
from secret import FLAG
wlcm_msg ='########################################################################\n'+\
'# Welcome to the Bank of the World #\n'+\
'# All connections are monitored and recorded #\n'+\
'# Disconnect IMMEDIATELY if you are not an authorized user! #\n'+\
'########################################################################\n'
key = get_random_bytes(16)
iv = get_random_bytes(16)
def encrypt_data(data):
padded = pad(data.encode(),16,style='pkcs7')
cipher = AES.new(key, AES.MODE_CBC,iv)
enc = cipher.encrypt(padded)
return enc.hex()
def decrypt_data(encryptedParams):
cipher = AES.new(key, AES.MODE_CBC,iv)
paddedParams = cipher.decrypt( unhexlify(encryptedParams))
print(paddedParams)
if b'admin&password=g0ld3n_b0y' in unpad(paddedParams,16,style='pkcs7'):
return 1
else:
return 0
def send_msg(s, msg):
enc = msg.encode()
s.send(enc)
def main(s):
send_msg(s, 'username: ')
user = s.recv(4096).decode().strip()
send_msg(s, user +"'s password: " )
passwd = s.recv(4096).decode().strip()
send_msg(s, wlcm_msg)
msg = 'logged_username=' + user +'&password=' + passwd
try:
assert('admin&password=g0ld3n_b0y' not in msg)
except AssertionError:
send_msg(s, 'You cannot login as an admin from an external IP.\nYour activity has been logged. Goodbye!\n')
raise
msg = 'logged_username=' + user +'&password=' + passwd
send_msg(s, "Leaked ciphertext: " + encrypt_data(msg)+'\n')
send_msg(s,"enter ciphertext: ")
enc_msg = s.recv(4096).decode().strip()
try:
check = decrypt_data(enc_msg)
except Exception as e:
send_msg(s, str(e) + '\n')
s.close()
if check:
send_msg(s, 'Logged in successfully!\nYour flag is: '+ FLAG)
s.close()
else:
send_msg(s, 'Please try again.')
s.close()
class TaskHandler(socketserver.BaseRequestHandler):
def handle(self):
main(self.request)
if __name__ == '__main__':
socketserver.ThreadingTCPServer.allow_reuse_address = True
server = socketserver.ThreadingTCPServer(('0.0.0.0', 1337), TaskHandler)
server.serve_forever()
Solution
In this challenge, we are asked username and password and then we are given a ciphertext.For login with admin username=admin and password=g0ld3n_b0y,But this is not accepted by server. So we have to find a way to login as admin.To do so we can use bit flipping attack..we can change start bit of ciphertext by the byte so that decrypted message becomes admin&password=g0ld3n_b0y
. So we can login as admin and get the flag.
pass username = "dmin",password = "g0ld3n_b0y" now get the ciphertext and xor first byte with ord('a')^ord('') and send it to server.
from pwn import *
r = remote('134.122.104.91', 30102)
r.recvuntil(b'username: ')
r.sendline(b'_dmin')
r.recvuntil(b'_dmin\'s password: ')
r.sendline(b'g0ld3n_b0y')
r.recvuntil(b'Leaked ciphertext: ')
ciphertext = r.recvline().strip()
r.recvuntil(b'enter ciphertext: ')
c0 = bytes.fromhex(ciphertext[:32].decode())
c1 = bytes.fromhex(ciphertext[32:].decode())
c0 = bytes([c0[0]^ord('a')^ord('_')]) + c0[1:]
cipher = c0.hex() + c1.hex()
r.sendline(cipher)
r.recvuntil(b': ')
print(r.recvall().decode())
After running code you will get flag HTB{b1t_fl1pp1ng_1s_c00l}