RVCExIITB CTF Writeup
This is my writeup for the all the challenges i completed in ctf conducted by RVCExIITB
Reverse Engineering
Unscramble
I first started to decode the hint given and I found nothing :(
Then Started to analyse the Java program
This is the python code used to solve this challenge
import base64
def xor_with_key(hex_input, key):
xored = ""
for i in range(0, len(hex_input), 2):
hex_char = int(hex_input[i:i+2], 16)
hex_char ^= key
xored += chr(hex_char)
return xored
def hex_to_ascii(hex_input):
ascii_str = ""
for i in range(0, len(hex_input), 2):
ascii_str += chr(int(hex_input[i:i+2], 16))
return ascii_str
def caesar_shift(input_str, amount):
shifted = ""
for c in input_str:
if c.isalpha():
base = 'A' if c.isupper() else 'a'
shifted += chr((ord(c) - ord(base) - amount) % 26 + ord(base))
else:
shifted += c
return shifted
def main():
encrypted_flag = "465a38585060405f685f4465734d6a636d4f45705f4e67384565403d5d5c6e506d5d3c4d513a513c5862663c58636a736a5c404d504e6639453866676d4f3873"
# Step 1: XOR with key 9
step1 = xor_with_key(encrypted_flag, 9)
print(f"After XOR: {step1}")
# Step 2: Convert from hexadecimal to ASCII
step2 = hex_to_ascii(step1.encode('utf-8').hex())
print(f"After hex to ASCII: {step2}")
# Step 3: Reverse the Caesar shift by 25
step3 = caesar_shift(step2, 25)
print(f"After Caesar shift: {step3}")
# Step 4: Base64 decode
step4 = base64.b64decode(step3).decode()
print(f"After Base64 decode 1: {step4}")
# Step 5: Reverse the string
step5 = step4[::-1]
print(f"After reversing: {step5}")
# Step 6: Base64 decode
flag = base64.b64decode(step5).decode()
print("The flag is:", flag)
if __name__ == "__main__":
main()
1.Reverse XOR Operation:
XOR each pair of hexadecimal digits in the encrypted flag with the key 9.
2.Convert Hexadecimal to ASCII:
Convert each pair of hexadecimal digits from the result of the XOR operation to their corresponding ASCII characters.
3.Reverse Caesar Shift:
Reverse the Caesar shift by shifting each letter in the result back by 25 positions in the alphabet.
4.Base64 Decode:
Base64 decode the string obtained after reversing the Caesar shift.
5.Reverse the String:
Reverse the string obtained from the Base64 decode.
6.Base64 Decode Again:
Base64 decode the final reversed string to obtain the original flag.
Nebula
Python code
encrypted_string = "_UX^BK\nOfA\tKf\\WzK@iVwD"
decrypted_messages = []
# Brute-force XOR key
for key in range(256):
decrypted_message = "".join([chr(ord(char) ^ key) for char in encrypted_string])
if decrypted_message.startswith("flag{"):
print(f"Key: {key}, Decrypted Message: {decrypted_message}")
break
Cryptography
Secrets From The Past
XOR Enigma
Challenge.txt
X1: b3c8d73e3a9b23df7cc1253277a4878ef65bcfe9735f29d84424
X2^X1: fb3514ac2e94885e9d5ec915821650572d5e0b842e9630f32b1b
X2^X3: d2656867798e8584ec34ab2d4562b1a9c82b8fcf1feeeddf70e2
FLAG^X1^X3^X2: 07c1de3e3867c32fe29cbd6957a2695f0e021f4b58c2b03446bb
To solve this XOR Enigma challenge, we need to use the given XORed values to retrieve the flag. FLAG=(FLAG⊕X1⊕X3⊕X2)⊕X1⊕X3⊕X2
Python code to solve the challenge
from binascii import unhexlify
# Given hexadecimal strings
X1_hex = "b3c8d73e3a9b23df7cc1253277a4878ef65bcfe9735f29d84424"
X2_X1_hex = "fb3514ac2e94885e9d5ec915821650572d5e0b842e9630f32b1b"
X2_X3_hex = "d2656867798e8584ec34ab2d4562b1a9c82b8fcf1feeeddf70e2"
FLAG_X1_X3_X2_hex = "07c1de3e3867c32fe29cbd6957a2695f0e021f4b58c2b03446bb"
# Convert hex to bytes
X1 = unhexlify(X1_hex)
X2_X1 = unhexlify(X2_X1_hex)
X2_X3 = unhexlify(X2_X3_hex)
FLAG_X1_X3_X2 = unhexlify(FLAG_X1_X3_X2_hex)
# XOR function
def xor_bytes(a, b):
return bytes(x ^ y for x, y in zip(a, b))
# Find X2
X2 = xor_bytes(X2_X1, X1)
# Find X3
X3 = xor_bytes(X2_X3, X2)
# Find FLAG
FLAG = xor_bytes(FLAG_X1_X3_X2, xor_bytes(X1, xor_bytes(X3, X2)))
# Print the FLAG as text
print("FLAG:", FLAG.decode())
Builder Bob and Alice
Modulus N1: 429121770631378567901343966601594638005200015410084049877005074706242144998835920068635924092327155154777724260920698564074246047428058702591438336354875385912113367812170140583119952718402254809563407665546757040976089024031265008069827573661895233187750822966323913745243562262084682435720233192587715830559
Public exponent 1 : 386032633976106490452762780248103046765080671002988892055330641519564235852922762822642402279578918838636246752652910094048142722891896247145254930177193887644017516737007121616205743252470102524562046452022844285592502850136557110998891279346966111674327705149116034487327385428052869529026582167188809884767
Ciphertext1: 87502995845613296640748517793461033238581559539831264070261405010457509045073974678421603483424284030953936003665163387882484477968792761078988595610302455403388677294958433069302896533782914177156060718958383452389999702278314396059598387560745347823772156262268912853464875822933280715397288456397500467082
Modulus N2: 429121770631378567901343966601594638005200015410084049877005074706242144998835920068635924092327155154777724260920698564074246047428058702591438336354875385912113367812170140583119952718402254809563407665546757040976089024031265008069827573661895233187750822966323913745243562262084682435720233192587715830559
Ciphertext2: 136066714893268542026804519389494696977338362492232911025630528665249367078493449633065764703691698428341934584595699819793588312946103371760765032815931350400960037961574476205220355485393336049341594068050222109820636564284034763886026894874140832144968716951111868453836181469982554783322713071884032213425
Public exponent 2 : 163750396495935852923904966204815324377529736034694345075646930507887571607611362069683718460469444053908143551023118580605176614326477189584938691146244409712347416452049032774643069943984015216081063830861336324570672997063592368707183334828352359237101478758418750499394554746092209859925767816955766723283
To decrypt the message sent to Alice and Charlotte, we need to use the Chinese Remainder Theorem (CRT) attack. This attack is applicable because the same modulus N is used with different exponents e1 and e2.
This is my Python code to solve.
from sympy import mod_inverse
# Given values
N = 429121770631378567901343966601594638005200015410084049877005074706242144998835920068635924092327155154777724260920698564074246047428058702591438336354875385912113367812170140583119952718402254809563407665546757040976089024031265008069827573661895233187750822966323913745243562262084682435720233192587715830559
e1 = 386032633976106490452762780248103046765080671002988892055330641519564235852922762822642402279578918838636246752652910094048142722891896247145254930177193887644017516737007121616205743252470102524562046452022844285592502850136557110998891279346966111674327705149116034487327385428052869529026582167188809884767
e2 = 163750396495935852923904966204815324377529736034694345075646930507887571607611362069683718460469444053908143551023118580605176614326477189584938691146244409712347416452049032774643069943984015216081063830861336324570672997063592368707183334828352359237101478758418750499394554746092209859925767816955766723283
C1 = 87502995845613296640748517793461033238581559539831264070261405010457509045073974678421603483424284030953936003665163387882484477968792761078988595610302455403388677294958433069302896533782914177156060718958383452389999702278314396059598387560745347823772156262268912853464875822933280715397288456397500467082
C2 = 136066714893268542026804519389494696977338362492232911025630528665249367078493449633065764703691698428341934584595699819793588312946103371760765032815931350400960037961574476205220355485393336049341594068050222109820636564284034763886026894874140832144968716951111868453836181469982554783322713071884032213425
# Step 1: Verify that gcd(e1, e2) = 1
def extended_gcd(a, b):
if a == 0:
return b, 0, 1
gcd, x1, y1 = extended_gcd(b % a, a)
x = y1 - (b // a) * x1
y = x1
return gcd, x, y
gcd, a, b = extended_gcd(e1, e2)
assert gcd == 1, "gcd(e1, e2) is not 1"
# Step 2: Compute the combined ciphertext C using the formula C = (C1^a * C2^b) % N
def mod_exp(base, exp, mod):
if exp < 0:
base = mod_inverse(base, mod)
exp = -exp
return pow(base, exp, mod)
M = (mod_exp(C1, a, N) * mod_exp(C2, b, N)) % N
# Step 3: Print the decrypted message M
print(M)
# Convert the decrypted message to a readable string if it's in byte format
print(bytes.fromhex(hex(M)[2:]).decode('utf-8'))
OSINT
— — Almost got not solved— — — — — -
Steganography
Law liet’s Successor Beyond
jsteg
is a package for hiding data inside jpeg files, a technique known as steganography. This is accomplished by copying each bit of the data into the least-significant bits of the image. The amount of data that can be hidden depends on the filesize of the jpeg; it takes about 10-14 bytes of jpeg to store each byte of the hidden data.
Web
Robot Uprising
Confidential leak
/scripts
var express = require('express');
var app = express();
var port = process.env.PORT || 9898;
var crypto = require('crypto');
var bodyParser = require('body-parser')
var salt = 'somestring';
var iteration = /// some number here;
var keylength = // some number here;
app.post('/login', function (req, res) {
var username = req.body.username;
var password = req.body.password;
if (username !== 'joemama') {
res.send('Username is wrong');
return;
}
if (crypto.pbkdf2Sync(password, salt, iteration, keylength).toString() === hashOfPassword) {
if (password === 'plnlrtfpijpuhqylxbgqiiyipieyxvfsavzgxbbcfusqkozwpngsyejqlmjsytrmd') {
// some logic here and return something
} else {
// return flag here
}
} else {
res.send('Password is wrong');
}
});
From this got username as joemama
https://mathiasbynens.be/notes/pbkdf2-hmac
From this password eBkXQTfuBqp'cTcar&g*
Forensics
Labyrinth
After Opening dirr3
Ao(mgHXnjO1LkM\EbT*+?["5HBPD?kA8-'q@oRAEBgm)MF>RcEFD*CMAo(mgFDk`3@ps=f<+oiZ@:FM&Bl8$+I/
After decoding the encrypted text from Base85 we got flag.
TheChinesePhilosopher
After extracting all frames in the gif in one of the frames we got some part of the flag :)
We need remaining part of the flag after doing exif in the given gif we got an link to the website where chinese text is present after decoding we got remaining part of the flag
After Combining Flag i got flag{m4yb3_Th3_un1v3r53_w4s_ju5t_a_5imul4t10n}
Miscellaneous
PWN
The Baker 1
The Baker 2
Finally, the CTF has ended, and I secured 39th place! :)
Thanks For Reading :)
Don’t miss out on my upcoming articles! Follow me on Medium for more insightful content. Clap and share this article to spread the knowledge among fellow bug bounty hunters and cybersecurity enthusiasts.
If you have any further questions or would like to connect, feel free to reach out to me
My LinkedIn handle: https://www.linkedin.com/in/kishoreram-k/