waRSAw - InCTFi 2019

Intended solution of waRSAw challenge from InCTF Internationals 2019 tl;dr variant of LSB Oracle Attack on unpadded RSA ...

September 29, 2019

Blind - Volga CTF Quals

Challenge Points: 200 Challenge Description: Pull the flag…if you can. tl;dr solving RSA Digital Signature using it’s homomorphic property: Calculate the signature of factors of message M to be signed, separately Combine them by multiplication over modulus to get the signature of M Based on Unpadded RSA Digital Signature about which you can read here- https://github.com/ashutosh1206/Crypton/tree/master/Digital-Signatures/Unpadded-RSA-Digital-Signatures There are various bash commands the program allows us to execute on the server: ls – list all files in a directory dir – list all files in a directory cd – change directory cat – print contents of a file exit – exit the program Notice in the given source code that the server allows execution of ls and dir commands without a signature, while it requires signature of the whole command when we want to execute cd, cat, exit commands. ...

March 31, 2019 · Ashutosh Ahelleya

RSA - Teaser CONFidence CTF

tl;dr Coppersmith’s Attack to recover RSA primes Challenge Points: 99 Challenge Description: You can’t break my public key if you don’t know it, amirite? The challenge is based on RSA and we are given the following script: def bytes_to_long(data): return int(data.encode("hex"),16) def rsa(msg,e,n): return pow(bytes_to_long(msg),e,n) flag = open('flag.txt','r').read() tmp = randint(2**1023, 2**1024) e = 65537 p = next_prime(0xDEAD*tmp+randint(2, 2**500)) q = next_prime(0xBEEF*tmp+randint(2, 2**500)) N = p*q print('msg1 = '+str(rsa("You can't factor the modulus",e,N))) print('msg2 = '+str(rsa("If you don't know the modulus!",e,N))) print('flag = '+str(rsa(flag,e,N))) We are given ciphertext of two plaintext messages \(m_1\) “You can’t factor the modulus” and \(m_2\) “If you don’t know the modulus!”, and encrypted text of the flag in output.txt: ...

March 18, 2019 · Ashutosh Ahelleya

Daring - Hxp CTF

Challenge Points: Challenge Description: We encrypted our flag, but we lost the keys. Can you help? This was a simple yet a very tricky challenge aimed at testing Number Theory basics. In this challenge we are given a small script: #!/usr/bin/env python3 import os from Crypto.Cipher import AES from Crypto.Hash import SHA256 from Crypto.Util import Counter from Crypto.PublicKey import RSA flag = open('flag.txt', 'rb').read().strip() key = RSA.generate(1024, e=3) open('pubkey.txt', 'w').write(key.publickey().exportKey('PEM').decode() + '\n') open('rsa.enc', 'wb').write(pow(int.from_bytes(flag.ljust(128, b'\0'), 'big'), key.e, key.n).to_bytes(128, 'big')) key = SHA256.new(key.exportKey('DER')).digest() open('aes.enc', 'wb').write(AES.new(key, AES.MODE_CTR, counter=Counter.new(128)).encrypt(flag)) If we analyse the script carefully, we would notice that the same flag is encrypted in two different, independent ways: ...

December 9, 2018 · Ashutosh Ahelleya

Crypto writeups [Part-2] - InCTFi 2018

This blog post covers intended solutions of two crypto challenges from InCTF-2018: Request-Auth and EC-Auth. Request-Auth Challenge Description This was a medium level crypto challenge that I created for InCTF International-2018. In the challenge you are given multiple files: iv.txt, key.enc, publickey.pem, ServerSide.py, session.enc and also have a service running these files. Contents of ServerSide.py: #!/usr/bin/env python2.7 from Crypto.Cipher import AES from Crypto.PublicKey import RSA from Crypto.Util.number import * from os import urandom import sys BLOCKSIZE = 16 class Unbuffered(object): def __init__(self, stream): self.stream = stream def write(self, data): self.stream.write(data) self.stream.flush() def writelines(self, datas): self.stream.writelines(datas) self.stream.flush() def __getattr__(self, attr): return getattr(self.stream, attr) sys.stdout = Unbuffered(sys.stdout) class colors: reset='\033[0m' red='\033[31m' green='\033[32m' orange='\033[33m' blue='\033[34m' def unpad(s): s = s[:-ord(s[len(s) - 1])] return s def check_valid_request(s): try: s = s.split(":") except: return False if len(s) != 3: return False if s[0] != "bi0s": return False if s[1][:7] != "userid=": return False if s[2][:5] != "user=": return False return True class ServerSide: def __init__(self, key, iv): self.key = key[-16:] self.iv = iv[-16:] def process_request(self, req_enc): try: obj2 = AES.new(self.key, AES.MODE_CBC, self.iv) request = obj2.decrypt(req_enc) return check_valid_request(request) except: return False def get_AES_key(): try: key_enc = raw_input("Enter encrypted key value in hex: ") key_enc = int(key_enc, 16) except: print colors.red + "Enter valid input!" + colors.reset sys.exit() priv_key = RSA.importKey(open("privatekey.pem").read()) n, d = priv_key.n, priv_key.d key_AES = pow(key_enc, d, n) key_AES = long_to_bytes(key_AES) return key_AES string1 = colors.blue + """ $$\ $$\ $$$$$$\\ $$ | \__|$$$ __$$\\ $$$$$$$\ $$\ $$$$\ $$ | $$$$$$$\\ $$ __$$\ $$ |$$\$$\$$ |$$ _____| $$ | $$ |$$ |$$ \$$$$ |\$$$$$$\\ $$ | $$ |$$ |$$ |\$$$ | \____$$\\ $$$$$$$ |$$ |\$$$$$$ /$$$$$$$ | \_______/ \__| \______/ \_______/ """ + colors.reset if __name__ == '__main__': print colors.orange + "Welcome to bi0s Request Validation Service" + colors.reset print string1 key = get_AES_key() iv = open("iv.txt").read() obj1 = ServerSide(key, iv) try: ct = raw_input("\nEnter value of encrypted session request in hex: ") ct = ct.decode("hex") except TypeError: print colors.red + "Enter a valid hex string!" + colors.reset sys.exit() if obj1.process_request(ct) == True: print colors.green + "\nValid request!" + colors.reset else: print colors.red + "\nInvalid request!" + colors.reset Okay, so the service is basically implementing a hybrid cipher- a combination of RSA and AES to authenticate session requests coming from a user and is internally using a public and a private key in this process. ...

October 14, 2018 · Ashutosh Ahelleya