Skip to content

Instantly share code, notes, and snippets.

@captain-woof
Created July 13, 2021 19:43
Show Gist options
  • Select an option

  • Save captain-woof/6df47016494f49418a29e55d7568490d to your computer and use it in GitHub Desktop.

Select an option

Save captain-woof/6df47016494f49418a29e55d7568490d to your computer and use it in GitHub Desktop.
HackTheBox Flippin Bank Solution
from pwn.toplevel import remote, log
# Get ciphertext from encryption oracle for chosen username and password, and submit
# ciphertext as solution optionally
def get_username_password_ciphertext(username,password,ciphertext_to_submit = None):
r = remote(host,port)
r.sendafter("username: ",username)
r.sendafter("password: ",password)
r.recvuntil("Leaked ciphertext: ")
ciphertext = r.recvline().decode().rstrip()
if ciphertext_to_submit is None:
r.close()
return ciphertext
else:
r.sendafter("enter ciphertext: ",ciphertext_to_submit)
return r.recvall()
# Get n-th block from ciphertext hex string
def get_n_block(s,n):
return bytes.fromhex(s[(n-1)*32:(32*n)])
# MAIN
# Target host
# BLOCKS -> b"logged_username=",b"admin&password=g",b"0ld3n_b0y"+b"\x07"*7
host,port = "46.101.89.127",32216
real_username,incorrect_username,password = "admin","bdmin","g0ld3n_b0y" # Username starts where second block starts; Usernames differ only by first character
# Ciphertext for fake username
log.info("Getting ciphertext for {}:{}".format(incorrect_username,password))
incorrect_ciphertext = get_username_password_ciphertext(incorrect_username,password)
log.info("Fake ciphertext -> {}".format(incorrect_ciphertext))
# Flip 1st byte of block 2 by flipping 1st byte of b1 to get a correct ciphertext
b1 = get_n_block(incorrect_ciphertext,1)
b2 = get_n_block(incorrect_ciphertext,2)
b3 = get_n_block(incorrect_ciphertext,3)
b1_new = []
flipped_byte = (b1[0] ^ ord(real_username[0]) ^ ord(incorrect_username[0])).to_bytes(1,"big")
b1_new = flipped_byte + b1[1:]
correct_ciphertext = (bytes(b1_new) + b2 + b3).hex()
log.info("Correct ciphertext -> {}".format(correct_ciphertext))
# Make new connection
log.info("Submitting correct ciphertext and getting flag...")
log.info(get_username_password_ciphertext(incorrect_username,password,correct_ciphertext))
@captain-woof
Copy link
Author

I'm pretty sure that they must have changed Pwntools's implementation by the time I wrote this, because this worked for me perfectly.

Based on the error, try omitting .decode().rstrip() on line 10, see if the script runs without exception.

recvline() used to return a bytearray, it might now be returning a string.

@j0rg3k
Copy link

j0rg3k commented Dec 14, 2021

Hi, I did the change on line 10 as per suggestion, and I had to change line 20 to return bytearray(s[(n-1)32:(32n)]), however I am still getting error when running the code. I am new in Python language. any hint/help, much appreciated.
Cheers

Traceback (most recent call last):
File "/home/kaliuser/Documents/htb/ctf/htb-flippin-bank-solution.py", line 48, in
log.info(get_username_password_ciphertext(incorrect_username,password,correct_ciphertext))
File "/usr/local/lib/python3.9/dist-packages/pwnlib/log.py", line 395, in info
self._log(logging.INFO, message, args, kwargs, 'info')
File "/usr/local/lib/python3.9/dist-packages/pwnlib/log.py", line 292, in _log
msg = _need_text(msg)
File "/usr/local/lib/python3.9/dist-packages/pwnlib/util/packing.py", line 1051, in _need_text
return s.decode(encoding, errors)
AttributeError: 'str' object has no attribute 'decode'

@j0rg3k
Copy link

j0rg3k commented Dec 14, 2021

Solved in different way. I use original code, but I edited temporarily line 1051 of /usr/local/lib/python3.9/dist-packages/pwnlib/util/packing.py.
I commented and I insert return s. and after I got the flag, returned back the original line 1051. Thanks for sharing the code. I still have much to learn in python and cryptography. cheers

@lorschy
Copy link

lorschy commented Feb 12, 2022

Had the same issues, but you can simply use the still generated and displayed correct ciphertext to manually log in as this is only a problem in the part 2 of the script when i tries to send the values to the server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment