Vishwactf 2024

VISHWACTF 2024

CRYPTOGRAPHY WRITEUP

Author:

  • Pham Quoc Trung

Used Language:

  • Python3

Problem Solving:

Happy Valentine's Day

Description:

My girlfriend and I captured our best moments of Valentine's Day in a portable graphics network. But unfortunately I am not able to open it as I accidentally ended up encrypting it. Can you help me get my memories back?

Author : Pushkar Deore

Attachments:

source.txt

from PIL import Image
from itertools import cycle

def xor(a, b):
    return [i^j for i, j in zip(a, cycle(b))]

f = open("original.png", "rb").read()
key = [f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]]

enc = bytearray(xor(f,key))

open('enc.txt', 'wb').write(enc)

enc.txt

Solution:

Ở bài này, chương trình thực hiện XOR một bức ảnh png với key là 8 bytes đầu của nó. Vì là file png nên mình có thể dễ dàng biết được 8 bytes này thông qua File SIgnature trên Google. Tiến hành xor lại với key đó mình sẽ ra được ảnh gốc

Code để recover bức ảnh:

from PIL import Image
from itertools import cycle

def xor(a, b):
    return [i^j for i, j in zip(a, cycle(b))]

f = open("enc.txt", "rb").read()
key = [137, 80, 78, 71, 13, 10, 26, 10]

flag = bytearray(xor(f,key))

open('flag.png', 'wb').write(flag)

Ảnh thu được:

Flag: VishwaCTF{h3ad3r5_f0r_w1nn3r5}

Teyvat Tales

Description:

All tavern owners in Mondstadt are really worried because of the frequent thefts in the Dawn Winery cellars. The Adventurers’ Guild has decided to secure the cellar door passwords using a special cipher device. But the cipher device itself requires various specifications….which the guild decided to find out by touring the entire Teyvat.

PS: The Guild started from the sands of Deshret then travelled through the forests of Sumeru and finally to the cherry blossoms of Inazuma

Author: Amruta Patil

Solution:

Đây là giao diện của trang web challenge:

Đến tận bây giờ thì mình cũng chưa biết đống này là cái của khỉ gì. Cách mình giải được bài này là bằng cách nhìn vào code front-end

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Teyvat Tales</title>
    <link rel="icon" type="image/x-icon" href="./favicon.ico">
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <main>
        <section class="fours first-four centered-align">
            <div class="img-div">
                <img src="img/1.jpg" alt="">
            </div>
            <div class="form-div">
                <input type="text" name="input1" id="input1" placeholder="Enter decoded text">
                <button id="submit-btn-1">Submit</button>
            </div>
        </section>


        <section class="fours sec-four centered-align">
            <div class="img-div">
                <img src="img/2.jpg" alt="">
            </div>
            <div class="form-div">
                <input type="text" name="input2" id="input2" placeholder="Enter decoded text">
                <button id="submit-btn-2">Submit</button>
            </div>
        </section>


        <section class="fours third-four centered-align">
            <div class="img-div">
                <img src="img/3a.jpg" alt="">
                <img src="img/3b.jpg" alt="">
                <img src="img/3c.jpg" alt="">
            </div>
            <div class="form-div">
                <input type="text" name="input3" id="input3" placeholder="Enter decoded text">
                <button id="submit-btn-3">Submit</button>
            </div>
        </section>


        <section class="fours fourth-four centered-align">
            <div class="img-div">
                <img src="img/4.jpg" alt="">
            </div>
            <div class="form-div">
                <input type="text" name="input4" id="input4" placeholder="Enter decoded text">
                <button id="submit-btn-4">Submit</button>
            </div>
        </section>
    </main>

    <script src="script.js"></script>
</body>
</html>

Ở đây mình thấy một file script.js ở cuối. Đây là đoạn code của nó

const submitBtn1 = document.getElementById("submit-btn-1");
const firstFour = document.querySelector(".first-four");

const submitBtn2 = document.getElementById("submit-btn-2");
const secFour = document.querySelector(".sec-four");

const submitBtn3 = document.getElementById("submit-btn-3");
const thirdFour = document.querySelector(".third-four");

const submitBtn4 = document.getElementById("submit-btn-4");
const fourthFour = document.querySelector(".fourth-four");


submitBtn1.addEventListener("click", ()=> {
    const inputText1 = document.getElementById("input1").value.trim();

    if (inputText1.toLowerCase() === "enigma m3") {
        firstFour.classList.remove("centered-align");
        firstFour.classList.add("hidden");
    }
    else{
        alert("Incorrect deciphering! Try again!")
    }
});

submitBtn2.addEventListener("click", ()=> {
    const inputText2 = document.getElementById("input2").value.trim();

    if (inputText2.toLowerCase() === "ukw c") {
        secFour.classList.remove("centered-align");
        secFour.classList.add("hidden");
    }
    else{
        alert("Incorrect deciphering! Try again!")
    }
});

submitBtn3.addEventListener("click", ()=> {
    const inputText3 = document.getElementById("input3").value.trim();

    if (inputText3.toLowerCase() === "rotor1 i p m rotor2 iv a o rotor3 vi i n") {
        thirdFour.classList.remove("centered-align");
        thirdFour.classList.add("hidden");
    }
    else{
        alert("Incorrect deciphering! Try again!")
    }
});

submitBtn4.addEventListener("click", ()=> {
    const inputText4 = document.getElementById("input4").value.trim();

    if (inputText4.toLowerCase() === "vi sh wa ct fx") {
        fourthFour.classList.remove("centered-align");
        fourthFour.classList.add("hidden");        
    }
    else{
        alert("Incorrect deciphering! Try again!")
    }
});

Từ đây thì mình có được luôn 4 đáp án cho 4 ảnh lần lượt là:

enigma m3
ukw c
rotor1 i p m rotor2 iv a o rotor3 vi i n
vi sh wa ct fx

Sau khi điền từng kết quả vào thì mình ra được ảnh sau (thứ mà mình cũng đã thấy trước ở trong style.css với url(img/GenshinNoticeBoard.png);)

Mình thu được đoạn flag bị mã hóa là CYNIPJ_RE_LSKR-YAZN_MBSJ. Ban đầu, mình không tìm ra được nó là thể loại mã hóa gì. Tuy nhiên, sau khi nhìn vào đống đáp án mà mình phải điền trước đó, mình thử search enigma m3 và mình tìm thấy một loại mã hóa có các tham số như trong đáp án.

Sau khi chỉnh các tham số đó cho y hệt như các đáp án trước đó, mình đã ra được flag.

Flag: Vishwactf{beware_of_tone-deaf_bard}

Poly Fun

Description:

Its a simple symmetric key encryption, I am sure you will be able to solve it (what do you mean the key looks weird)

Author : Revak Pandkar

Attachments:

challenge.py

import numpy as np
import random

polyc = [4,3,7]
poly = np.poly1d(polyc)


def generate_random_number():
    while True:
        num = random.randint(100, 999)
        first_digit = num // 100
        last_digit = num % 10
        if abs(first_digit - last_digit) > 1:
            return num


def generate_random_number_again():
    while True:
        num = random.randint(1000, 9999)
        if num % 1111 != 0:
            return num


def transform(num):
    number = random.randint(1, 100000)
    org = number
    number *= 2
    number += 15
    number *= 3
    number += 33
    number /= 6
    number -= org
    if number == 13:
        num1 = random.randint(1, 6)
        num2 = random.randint(1, 6)
        number = num1 * 2
        number += 5
        number *= 5
        number += num2
        number -= 25
        if int(number / 10) == num1 and number % 10 == num2:
            number = generate_random_number()
            num1 = int(''.join(sorted(str(number), reverse=True)))
            num2 = int(''.join(sorted(str(number))))
            diff = abs(num1 - num2)
            rev_diff = int(str(diff)[::-1])
            number = diff + rev_diff
            if number == 1088:
                org = num
                num *= 2
                num /= 3
                num += 5
                num *= 4
                num -= 9
                num -= org
                return num
            else:
                number = generate_random_number_again()
                i = 0
                while number != 6174:
                    digits = [int(d) for d in str(number)]
                    digits.sort()
                    smallest = int(''.join(map(str, digits)))
                    digits.reverse()
                    largest = int(''.join(map(str, digits)))
                    number = largest - smallest
                    i += 1

                if i <= 7:
                    org = num
                    num *= 2
                    num += 7
                    num += 5
                    num -= 12
                    num -= org
                    num += 4
                    num *= 2
                    num -= 8
                    num -= org
                    return num
                else:
                    org = num
                    num **= 4
                    num /= 9
                    num += 55
                    num *= 6
                    num += 5
                    num -= 23
                    num -= org
                    return num
        else:
            org = num
            num *= 10
            num += 12
            num **= 3
            num -= 6
            num += 5
            num -= org
            return num
    else:
        org = num
        num += 5
        num -= 10
        num *= 2
        num += 12
        num -= 20
        num -= org
        return num


def encrypt(p,key):
    return ''.join(chr(p(transform(i))) for i in key)


key = open('key.txt', 'rb').read()
enc = encrypt(poly,key)
print(enc)

encoded_flag.txt

u5FUKxDUxH9y8yxvfaaU+GSXDwvJS6QxlN/3udOEzpU6fIVUExjDLsB3LKqUTz/x

encoded_key.txt

Solution:

<Updating>

Lets smother the King!

Description:

In my friend circle, Mr. Olmstead and Mr. Ben always communicate with each other through a secret code language that they created, which we never understand. Here is one of the messages Mr. Ben sent to Mr. Olmstead, which I somehow managed to hack and extract it from Ben's PC. However, it's encrypted, and I don't comprehend their programming language. Besides being proficient programmers, they are also professional chess players. It appears that this is a forced mate in a 4-move chess puzzle, but the information needs to be decrypted to solve it. Help me out here to solve the chess puzzle and get the flag.

Flag format: VishwaCTF{move1ofWhite_move1ofBlack_move2ofWhite_move2ofBlack_move3ofWhite_move3ofBlack_move4ofWhite}.

Note: Please use proper chess notations while writing any move.

# Author : Naman Chordia

Attachment:

code.txt

D'`A_9!7};|jE7TBRdQbqM(n&JlGGE3feB@!x=v<)\r8YXtsl2Sonmf,jLKa'edFEa`_X|?UTx;WPUTMqKPONGFjJ,HG@d'=BA@?>7[;4z21U54ts10/.'K+$j(!Efe#z@a}vut:[Zvutsrqj0ngOe+Lbg`edc\"CBXW{[TSRvP8TMq4JONGFj-IBGF?c=a$@9]=6|:3W10543,P*/.'&%$Hi'&%${z@a}vut:xqp6nVrqpoh.fedcb(IHdcba`_X|V[ZYXWPOsMLKJINGkKJI+G@dDCBA#"8=6Z4z21U5ut,P0)(-&J*)"!E}e#"!x>|uzs9qvo5srkpingf,Mchg`_%cbaZBXW{>=YXWPOs65KPImMLEDIBf)(D=a$:?>7<54X210/43,Pqp(',+*#G'gf|B"y?}v^tsr8vuWsrqpi/POkdibgf_%]b[Z_X|?>TYRQu8TMqQPIHGkEJIBA@dD&B;@?8\<5{3W70/.-Q10/on,%Ij('~}|B"!~}_u;y[Zponm3qpoQg-kjihgfeG]#aCBXW{[ZYX:Pt7SRQJONMLEiIHA@?cCB$@9]~<;:921U543,10/.-&J*j('~}${A!~}vuzs9Zponm3qpihmf,jihgfeG]#n

Solution:

Đây là ngôn ngữ lập trình Malbolge. Mình sẽ sử dụng tool để compile nó xem ra được gì

Ở đây mình dùng trang: https://www.tutorialspoint.com/execute_malbolge_online.php

Mình ra được một chuỗi như sau:

White- Ke1,Qe5,Rc1,Rh1,Ne6,a2,b3,d2,f2,h2 Black- Ka8,Qh3,Rg8,Rh8,Bg7,a7,b7,e4,g2,g6,h7

Đó chính là vị trí để ta dựng lại một tình huống trong bộ môn cờ vua. Mình sử dụng trang sau để dựng lại bàn cờ: https://nextchessmove.com/

FEN: k5rr/pp4bp/4N1p1/4Q3/4p3/1P5q/P2P1PpP/2R1K2R w - - 0 1

Các bạn có thể tự giải sao cho trắng thắng trong 4 bước, hoặc có thể dùng chức năng Calculate Next Move của trang web trên để tính được 4 bước đó. Kết quả mình ra được chính là flag

Flag: VishwaCTF{Nc7+_Kb8_Na6+_Ka8_Qb8+_Rxb8_Nc7#}

CODEON

Description:

My biochemist friend has doubt that his phone is used by others for calling without knowing him. So, he wants me to find some information related to it, that’s why he sent me some information related to it, also he uses one word short-forms mostly. But I am unable to understand sent data, can you help me?

Author : Sankalp Chakre

Attachment:

CODEON.txt

DATA:
RSC BGT FFH HFT TPD WMA OCZ CCD DCZ ZVA

He gave me some instructions related to it:

1)He told me he saw some names in call logs those are:
	Felix Delastelle, Dmitri Mendeleev

2)He also gave me 2 matrices A and B and told to perform same operation on matrix A and B as of performed on matrix P and Q. Find something related to biochemistry to crack my phone password.
  Matrix A =    45 35 93 95 24 65
		25 15 55 64 36 45
		15 65 62 16 65 38
		19 64 35 69 65 63
		47 67 48 60 39 27
		66 48 77 22 10 69
 
Matrix B =	33 25 30 11 68 65
		83 36 19 33 55 51
		20 16 48 63 41 71
		30 42 12 25 31 37
		51 03 44 23 43 85
		20 39 28 41 01 70


Matrix P= 	13 81 60
		40 99 88
		39 87 92

Matrix Q=	50 52 36 
		90 75 28
		80 9  18

Result Matrix of P and Q =		60   82   36 
			   		60   109  104 
					52   75   4

Solution:

Ở đây với hint đầu tiên, mình có 2 cái tên là Felix DelastelleDmitri Mendeleev.

Với Felix, mình tìm thấy được ông là một nhà mật mã học, nổi tiếng nhất với Bifid cipher. Nó cũng có vẻ giống với data mình nhận được luôn. Tuy nhiên, để giải được mình phải tìm được ra key nữa.

Với Dmitri, đây là người tìm ra bảng tuần hoàn hóa học, có thể sẽ liên quan tới Periodic table cipher.

Đến với hint thứ 2, mình có 2 ma trận A, B. Mình được yêu cầu phải thực hiện một phép toán nào đó giữa chúng giống với phép toán của 2 ma trận P, Q. Tuy nhiên, mình chưa biết phép toán đó là gì mà chỉ biết output của chúng.

Ta có:

<latex>

Sau một hồi guessing thì mình nhận ra các số này đều có thể chuyển về dạng các nguyên tố trong bảng tuần hoàn hóa học. Hiện tại bảng tuần hoàn có 118 nguyên tố, nên mình đã thử lấy ma trận (P*Q)% 119 nhưng không ra. Thử với (P*Q)%118 và mình đã ra được ma trận kết quả

import numpy as np

P = np.array([
    [13, 81, 60],
    [40, 99, 88],
    [39, 87, 92]
])

Q = np.array([
    [50, 52, 36],
    [90, 75, 28],
    [80, 9, 18]
])

Result= np.array([
    [60, 82, 36],
    [60, 109, 104],
    [52, 75, 4]
])

test = np.multiply(P, Q) % 118

print(test == Result)

Thực hiện với ma trận A, B, mình ra được ma trận sau:

import numpy as np

A = np.array([
    [45, 35, 93, 95, 24, 65],
    [25, 15, 55, 64, 36, 45],
    [15, 65, 62, 16, 65, 38],
    [19, 64, 35, 69, 65, 63],
    [47, 67, 48, 60, 39, 27],
    [66, 48, 77, 22, 10, 69]
])

B = np.array([
    [33, 25, 30, 11, 68, 65],
    [83, 36, 19, 33, 55, 51],
    [20, 16, 48, 63, 41, 71],
    [30, 42, 12, 25, 31, 37],
    [51, 3, 44, 23, 43, 85],
    [20, 39, 28, 41, 1, 70]
])

res = np.multiply(A, B) % 118

print(res)

Chuyển các số trong ma trận về dạng các nguyên tố trong bảng tuần hoàn, mình thu được ma trận sau:

grid = np.array([
    ["TM", "IN", "OS", "MD", "CF", "AM"],
    ["TM", "ER", "MD", "SG", "U", "I"],
    ["GD", "CM", "FE", "GD", "TM", "NO"],
    ["CF", "U", "DY", "TA", "F", "AC"],
    ["RB", "BI", "SG", "PB", "MN", "I"],
    ["TI", "NO", "GE", "OS", "NE", "DS"]
])

print(grid)

Mình để ý ở cột cuối cùng, ta thu được từ "AMINOACIDS", có vẻ đây chính là key. Mình thử dùng một số tool để giải mã Bifid cipher tuy nhiên không hiểu sao mình dùng mãi không ra. Thế là mình đã giải tay qua video này: https://www.youtube.com/watch?v=zE34jDx2gWE (Sau thì mình có tìm ra web này giải được: https://calcoolator.eu/bifid-cipher-encoder-decoder-)

43 23 21 24 32 44 31 31 33 33 31 44 44 41 22 52 12 11 15 21 55 21 21 22 22 21 55 55 51 11 

43 23 21 24 32 44 31 31 33 33 31 44 44 41 22 
52 12 11 15 21 55 21 21 22 22 21 55 55 51 11 

4 3 2 3 2 1 2 4 3 2 4 4 3 1 3 1 3 3 3 3 3 1 4 4 4 4 4 1 2 2 
5 2 1 2 1 1 1 5 2 1 5 5 2 1 2 1 2 2 2 2 2 1 5 5 5 5 5 1 1 1 

U G C G C A C U G C U U G A G A G G G G G A U U U U U A C C

Đoạn mã mình thu được là UGCGCACUGCUUGAGAGGGGGAUUUUUACC, chỉ chứa 4 kí tự U, A, G, C, giống các bazơ nitơ của gen trong bộ môn Sinh Học. Mình tìm thì có một cipher liên quan tới nó là Codon cipher (Giờ thì mình đã hiểu tên challenge :v)

Và sau khi decode, mình đã ra được flag.

Flag: Vishwactf{CALLERGIFT}

Intellectual Heir

Description:

You received a package, and you got to know that you are the descendant of RIADSH. There are four files and a safe in the package.

You should analyze the files, unlock the safe, and prove your worth. The safe has alphanumeric and character combinations.

PS: The safe has no lowercase buttons.

Author : Abhishek Mallav

Attachments:

file.txt

4400037514278889258479265625258024039636437755883377709505596356049534358755375772484057042989024750972247184288820831886430459963472328358741858934783775986591400972020736548834642094922678189447202173710409868474198821576627330424767999152339702779346380

file1.txt

5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
1.000000000000000000e+00
5.403023058681397650e-01
5.403023058681397650e-01
5.403023058681397650e-01

file2.txt

8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01
0.000000000000000000e+00
8.414709848078965049e-01

Intellectual Heir.py

# my secret to hide the combination of my safe in fornt of all without anyone getting a clue what it is ;)

#some boring python function for conversion nothing new
def str_to_ass(input_string):
    ass_values = []
    for char in input_string:
        ass_values.append(str(ord(char)))
    ass_str = ''.join(ass_values)
    return ass_str

input_string = input("Enter the Combination: ")
result = str_to_ass(input_string)
msg = int(result)

#not that easy, you figure out yourself what the freck is a & z
a = 
z = 

f = (? * ?) #cant remember what goes in the question mark
e = #what is usually used

#ohh yaa!! now you cant figure out $h!t
encrypted = pow(msg, e, f)
print(str(encrypted))

#bamm!! protection for primes
number = 
bin = bin(number)[2:]

#bamm!! bamm!! double protection for primes
bin_arr = np.array(list(bin), dtype=int)
result = np.sin(bin_arr)
result = np.cos(bin_arr)
np.savetxt("file1", result)
np.savetxt("file2", result)

Solution:

Bài này thì không khó, chủ yếu mình phải guessing. Đầu tiên mình phân tích hàm str_to_ass.

def str_to_ass(input_string):
    ass_values = []
    for char in input_string:
        ass_values.append(str(ord(char)))
    ass_str = ''.join(ass_values)
    return ass_str

Hàm này sẽ lấy từng kí tự trong input_string , biến chúng về dạng ascii decimal sau đó join với nhau để tạo thành một chuỗi số.

Để dịch ngược hàm này thì ĐÁNG LẼ chúng ta phải handle trường hợp mã ascii là 2 hay 3 chữ số (cũng không khó). Tuy nhiên, do đề bài nói rằng cái két này không có kí tự lowercase (ascii sẽ có phần 3 chữ số), nên ta có thể bỏ trường hợp 3 chữ số đi và viết được một hàm kiểu như sau:

def ass_to_str(ass_str):
    output_string = ""
    i = 0
    while i < len(ass_str):
        if i + 2 <= len(ass_str):
            part = ass_str[i:i+2]
            output_string += chr(int(part))
            i += 2
    return output_string

Tiếp theo là đoạn này:

input_string = input("Enter the Combination: ")
result = str_to_ass(input_string)
msg = int(result)

#not that easy, you figure out yourself what the freck is a & z
a = 
z = 

f = (? * ?) #cant remember what goes in the question mark
e = #what is usually used

#ohh yaa!! now you cant figure out $h!t
encrypted = pow(msg, e, f)
print(str(encrypted))

Nếu các bạn đã chơi Crypto nhiều thì có thể dễ dàng nhận ra đây là mã hóa RSA với a, z là p, q; f là n. Tham số e được comment là #what is usually used, có thể đoán là 65537. Kết quả được in ra có vẻ chính là số trong file.txt

Tiếp đến là đoạn này:

#bamm!! protection for primes
number = 
bin = bin(number)[2:]

#bamm!! bamm!! double protection for primes
bin_arr = np.array(list(bin), dtype=int)
result = np.sin(bin_arr)
result = np.cos(bin_arr)
np.savetxt("file1", result)
np.savetxt("file2", result)

Đoạn này sẽ thực hiện chuyển một số đầu vào thành dạng nhị phân, sau đó với mỗi bit nhị phân, ta lấy sin và cos của nó? Tuy nhiên khi mình nhìn vào 2 file file1.txtfile2.txt thì có vẻ một file là lấy sin một file là lấy cos. Hàm sin, cos chưa chắc có thể reverse, tuy nhiên do nhị phân chỉ có 2 bit 0 và 1, mình hoàn toàn có thể khôi phục lại 2 số này. Và vì là 2 số, mình đoán đây chính là p,q bị mã hóa.

with open('file1.txt', 'r') as file:
    data1 = file.readlines()

data1 = [float(line.strip()) for line in data1]

bits1 = ['0' if value == 1.0 else '1' for value in data1]

bit_string1 = ''.join(bits1)

prime1 = int(bit_string1,2)
assert isPrime(prime1) == True

with open('file2.txt', 'r') as file:
    data2 = file.readlines()

data2 = [float(line.strip()) for line in data2]

bits2 = ['0' if value == 0.0 else '1' for value in data2]

bit_string2 = ''.join(bits2)

prime2 = int(bit_string2,2)
assert isPrime(prime2) == True

Hai assert của mình đều không trả về lỗi, có nghĩa là ta đã có được 2 số nguyên tố p, q

Giờ chỉ cần tiến hành giải mã RSA, mình sẽ ra được flag

Code final:

from Crypto.Util.number import *

def ass_to_str(ass_str):
    output_string = ""
    i = 0
    while i < len(ass_str):
        if i + 2 <= len(ass_str):
            part = ass_str[i:i+2]
            output_string += chr(int(part))
            i += 2
    return output_string


with open('file1.txt', 'r') as file:
    data1 = file.readlines()

data1 = [float(line.strip()) for line in data1]

bits1 = ['0' if value == 1.0 else '1' for value in data1]

bit_string1 = ''.join(bits1)

prime1 = int(bit_string1,2)
assert isPrime(prime1) == True

with open('file2.txt', 'r') as file:
    data2 = file.readlines()

data2 = [float(line.strip()) for line in data2]

bits2 = ['0' if value == 0.0 else '1' for value in data2]

bit_string2 = ''.join(bits2)

prime2 = int(bit_string2,2)
assert isPrime(prime2) == True

p = prime1
q = prime2

n = p*q
e = 65537

d = inverse(e, (p-1)*(q-1))
c = 4400037514278889258479265625258024039636437755883377709505596356049534358755375772484057042989024750972247184288820831886430459963472328358741858934783775986591400972020736548834642094922678189447202173710409868474198821576627330424767999152339702779346380

m = pow(c, d, n)

print("VishwaCTF{" + ass_to_str(str(m)) + "}")

Flag: VishwaCTF{Y0U_@R3_T#3_W0RT#Y_OF_3}

BitBane - Cryptic Chaos

Description:

Once again, Mr. David made a blunder by encrypting some confidential data and deleting the original file. Can you help him retrieve the data from the encrypted file?

Author : Saksham Saipatwar

Attachments:

Encrypt.cpp

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

int createTopping(int curr, int idx, int &not_remainder)
{
    int temp = 0;
    int num = 1;
    num = num << 1;
    while (curr)
    {
        int remainder = curr % idx;
        if (remainder)
        {
            temp = temp * 10 + remainder;
            curr = curr - remainder;
        }
        else
        {
            num = num | 1;
            curr = curr / idx;
        }
        num = num << 1;
    }
    temp = temp << 1;
    temp = temp | 1;
    not_remainder = temp;
    return num | 1;
}

int createBase(int not_remainder)
{
    int num = 0;
    for (int i = 0; i < 30; ++i)
    {
        if (not_remainder)
        {
            num = num | (not_remainder & 1);
            not_remainder = not_remainder >> 1;
        }
        num = num << 1;
    }
    return num;
}

int create(int curr, int idx)
{
    int not_remainder = 0;
    int topping = createTopping(curr, idx, not_remainder);
    int base = createBase(not_remainder);
    int num = base | topping;
    return num;
}

bool checkValidity(int num)
{
    for (int i = 2; i * i < num; ++i)
    {
        if (num % i == 0)
            return false;
    }
    return true;
}

void extraSecurity(vector<int> &encryption)
{
    int n = encryption.size();
    for (int i = 0; i < n; ++i)
    {
        int idx = i + 2;
        if (checkValidity(idx))
        {
            encryption[i] = ~encryption[i];
        }
    }
}

void encode(vector<int> &encryption, const string &data, string &key)
{
    int len = data.length();
    for (int i = 0; i < len; ++i)
    {
        int curr = data[i];
        int idx = (i % 8) + 2;
        int num = create(curr, idx);
        encryption.push_back(num);
    }
}

void applyKey(vector<int> &encryption, string &key)
{
    int n = key.size();
    for (int i = 0; i < n; ++i)
    {
        int curr = key[i];
        int cnt = 0;
        int cpy = curr;
        while (cpy)
        {
            if (cpy & 1)
                ++cnt;
            cpy = cpy >> 1;
        }
        curr = curr << (i + 10);
        while (cnt--)
        {
            curr = curr << 1;
            curr = curr ^ 1;
        }
        int k = encryption.size();
        for (int j = 0; j < k; ++j)
        {
            encryption[j] = encryption[j] ^ curr;
        }
    }
}

void writeToFile(const vector<int> &encryption)
{
    ofstream outfile("Encrypted.txt");
    string data;
    for (auto ele : encryption)
    {
        data += to_string(ele);
        data += " ";
    }
    outfile << data;
    outfile.close();
}

int main()
{
    fstream file;
    file.open("Flag.txt");
    string data;
    file >> data;
    file.close();
    vector<int> encryption;
    string key = "VishwaCTF";
    encode(encryption, data, key);
    applyKey(encryption, key);
    extraSecurity(encryption);
    writeToFile(encryption);
    return 0;
}

Encrypt.txt

2055736685 1183318357 2065694901 1811939381 1547698261 1352663125 1704984661 1182793749 2014538421 1925185973 1883242709 1342177309 1778384949 1946157101 1224736789

Solution:

Ở bài này, flag được mã hóa qua 3 bước là encode, applyKeyextraSecurity. Mình sẽ giải mã ngược lại từng bước để ra được flag

Với bước extraSecurity:

bool checkValidity(int num)
{
    for (int i = 2; i * i < num; ++i)
    {
        if (num % i == 0)
            return false;
    }
    return true;
}

void extraSecurity(vector<int> &encryption)
{
    int n = encryption.size();
    for (int i = 0; i < n; ++i)
    {
        int idx = i + 2;
        if (checkValidity(idx))
        {
            encryption[i] = ~encryption[i];
        }
    }
}

Trông có vẻ dài dòng, nhưng code này chỉ check một số các phần tử sao cho nếu nó không phải số nguyên tố thì thực hiện phép NOT (đảo bit). Hàm này có thể được reverse bằng cách chạy chính nó lần nữa

Với bước applyKey:

void applyKey(vector<int> &encryption, string &key)
{
    int n = key.size();
    for (int i = 0; i < n; ++i)
    {
        int curr = key[i];
        int cnt = 0;
        int cpy = curr;
        while (cpy)
        {
            if (cpy & 1)
                ++cnt;
            cpy = cpy >> 1;
        }
        curr = curr << (i + 10);
        while (cnt--)
        {
            curr = curr << 1;
            curr = curr ^ 1;
        }
        int k = encryption.size();
        for (int j = 0; j < k; ++j)
        {
            encryption[j] = encryption[j] ^ curr;
        }
    }
}

Hàm này sẽ làm một loạt các thao tác với key, sau đó lấy key đã biến đổi để XOR với input. Do ta đã biết key, hàm này cũng có thể dễ dàng được reverse chỉ bằng cách chạy lại lần nữa.

Cuối cùng là hàm encode:

int createTopping(int curr, int idx, int &not_remainder)
{
    int temp = 0;
    int num = 1;
    num = num << 1;
    while (curr)
    {
        int remainder = curr % idx;
        if (remainder)
        {
            temp = temp * 10 + remainder;
            curr = curr - remainder;
        }
        else
        {
            num = num | 1;
            curr = curr / idx;
        }
        num = num << 1;
    }
    temp = temp << 1;
    temp = temp | 1;
    not_remainder = temp;
    return num | 1;
}

int createBase(int not_remainder)
{
    int num = 0;
    for (int i = 0; i < 30; ++i)
    {
        if (not_remainder)
        {
            num = num | (not_remainder & 1);
            not_remainder = not_remainder >> 1;
        }
        num = num << 1;
    }
    return num;
}

int create(int curr, int idx)
{
    int not_remainder = 0;
    int topping = createTopping(curr, idx, not_remainder);
    int base = createBase(not_remainder);
    int num = base | topping;
    return num;
}

void encode(vector<int> &encryption, const string &data, string &key)
{
    int len = data.length();
    for (int i = 0; i < len; ++i)
    {
        int curr = data[i];
        int idx = (i % 8) + 2;
        int num = create(curr, idx);
        encryption.push_back(num);
    }
}

Hàm này sẽ truyền 2 giá trị curidx vào hàm create. Hàm create cũng sẽ lại gọi tới 2 hàm createToppingcreateBase để thực hiện một loại các thao tác với 2 tham số này. Nhìn qua một hồi thì có thể thấy các thao tác này khá là khó để reverse, vì các phép như OR không có trường hợp cố định.

Tuy nhiên, để ý thì idx được tính bằng (i%8) + 2 , là thứ mà ta hoàn toàn có thể tính được hết. cur chính là từng kí tự của flag. Do đã reverse hết 2 hàm trước đó nên mình có kết quả của hàm encode này. Từ đây, mình nghĩ có thể bruteforce giá trị cur, sao cho nếu output của hàm encode ra đúng thì đấy sẽ chính là kí tự của flag. Kể cả khi bạn bruteforce cả 256 kí tự ascii cho mỗi kí tự, việc này cũng sẽ diễn ra rất rất nhanh

Dưới đây là code final:

from Crypto.Util.number import *
import random

enc = [-1934298443, -1728250251, -2103640211, -1153630219, 1775435890, -1670578291, 2009268234, -2009268235, 1950549658, -1992754035, 1673724026, -1398997107, 1405288466, 1824718858, 2131951730, -1765998643, 1934298490, -1330315635, 2063794322, 1889730674, 1124270194, -2059599891, 1086521394, -1858273331, 1909484170, 1229390194, 1757609994, -1275265139, 1201864818, -1892876403, 1673723922, 2009268234, 1950549402, 1229390194, 1947140466, -1942159371, 1849884786, 1703084146, 1824718858, -1665335347, 1909484170, -1229390195, 1757609994, 1170407434, 1124270194, -1918042227, 2038628466, -1982005363, 1950549834, 1124270322, 1782775922, -1738735731, 1768095858, 1842544754, 2127757426]

key = "VishwaCTF"

def check_validity(num):
    for i in range(2, int(num**0.5) + 1):
        if num % i == 0:
            return False
    return True

def extra_security(encryption):
    n = len(encryption)
    for i in range(n):
        idx = i + 2
        if check_validity(idx):
            encryption[i] = ~encryption[i]
    
extra_security(enc)
print(enc)

def apply_key(encryption, key):
    n = len(key)
    for i in range(n):
        curr = ord(key[i])
        cnt = 0
        cpy = curr
        while cpy:
            if cpy & 1:
                cnt += 1
            cpy = cpy >> 1
        curr = curr << (i + 10)
        while cnt:
            curr = curr << 1
            curr = curr ^ 1
            cnt -= 1
        k = len(encryption)
        for j in range(k):
            encryption[j] = encryption[j] ^ curr

apply_key(enc, key)
print(enc)

def create_topping(curr, idx):
    temp = 0
    num = 1
    num = num << 1
    not_remainder = 0
    while curr:
        remainder = curr % idx
        if remainder:
            temp = temp * 10 + remainder
            curr = curr - remainder
        else:
            num = num | 1
            curr = curr // idx
        num = num << 1 
    temp = temp << 1 
    temp = temp | 1 
    not_remainder = temp
    return num | 1, not_remainder

def create_base(not_remainder):
    num = 0
    for i in range(30):
        if not_remainder:
            num = num | (not_remainder & 1)
            not_remainder = not_remainder >> 1
        num = num << 1
    return num

def create(curr, idx):
    topping, not_remainder = create_topping(curr, idx)
    base = create_base(not_remainder)
    num = base | topping
    return num

flag = []
for i in range(len(enc)):
    for curr in range(48, 126):
        idx = (i % 8) + 2
        num = create(curr, idx)
        if(num == enc[i]):
            flag.append(chr(curr))

print(''.join(flag))

# VihwaCF{BIT5_3NCRYPT3_D3CRYPTED_M1ND5_D33PLYTE5T3D}

Mặc dù mình vẫn đoán được ra flag tuy nhiên nhìn hơi ngứa mắt, có vẻ do mình implement từ C++ sang python bị sai ở đâu đó. Dưới đây là code final sử dụng C++:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>

bool checkValidity(int num)
{
    for (int i = 2; i * i < num; ++i)
    {
        if (num % i == 0)
            return false;
    }
    return true;
}

void extraSecurity(std::vector<int>& encryption)
{
    int n = encryption.size();
    for (int i = 0; i < n; ++i)
    {
        int idx = i + 2;
        if (checkValidity(idx))
        {
            encryption[i] = ~encryption[i];
        }
    }
}

void applyKey(std::vector<int>& nums, std::string& key)
{
    int n = key.size();
    for (int i = 0; i < n; ++i)
    {
        int curr = key[i];
        int cnt = 0;
        int cpy = curr;
        while (cpy)
        {
            if (cpy & 1)
                ++cnt;
            cpy = cpy >> 1;
        }
        curr = curr << (i + 10);
        while (cnt--)
        {
            curr = curr << 1;
            curr = curr ^ 1;
        }
        int k = nums.size();
        for (int j = 0; j < k; ++j)
        {
            nums[j] = nums[j] ^ curr;
        }
    }
}

int createTopping(int curr, int idx, int &not_remainder)
{
    int temp = 0;
    int num = 1;
    num = num << 1;
    while (curr)
    {
        int remainder = curr % idx;
        if (remainder)
        {
            temp = temp * 10 + remainder;
            curr = curr - remainder;
        }
        else
        {
            num = num | 1;
            curr = curr / idx;
        }
        num = num << 1;
    }
    temp = temp << 1;
    temp = temp | 1;
    not_remainder = temp;
    return num | 1;
}

int createBase(int not_remainder)
{
    int num = 0;
    for (int i = 0; i < 30; ++i)
    {
        if (not_remainder)
        {
            num = num | (not_remainder & 1);
            not_remainder = not_remainder >> 1;
        }
        num = num << 1;
    }
    return num;
}

int create(int curr, int idx)
{
    int not_remainder = 0;
    int topping = createTopping(curr, idx, not_remainder);
    int base = createBase(not_remainder);
    int num = base | topping;
    return num;
}

std::string decode(std::vector<int>& nums)
{
    std::string message;

    for (int i = 0; i < nums.size(); i++) {
        int idx = (i % 8) + 2;

        // Brute force character
        int c = 0;
        for (c = 0; c < 128; c++) {
            int num = create(c, idx);
            if (num == nums[i])
                break;
        }
        message += c;
    }

    return message;
}

void print_nums(std::vector<int>& nums)
{
    for (int i = 0; i < nums.size() - 1; i++)
        std::cout << nums[i] << ' ';
    std::cout << nums[nums.size() - 1] << std::endl;
}

int main()
{
    std::string key = "VishwaCTF";

    // Read encrypted nums
    std::fstream file("Encrypted.txt");
    std::vector<int> nums;
    while (true) {
        int num;
        file >> num;
        if (file.fail())
            break;
        nums.push_back(num);
    }
    file.close();

    // Undo extraSecurity
    extraSecurity(nums);

    // Undo applyKey
    applyKey(nums, key);

    // Undo encode
    std::string message = decode(nums);
    std::cout << message << std::endl;

    return 0;
}

Flag: VishwaCTF{BIT5_3NCRYPT3D_D3CRYPTED_M1ND5_D33PLY_TE5T3D}

The Naughty Friend

Description:

One of my friends Dhruv is a cryptography genius, but he likes to annoy me by playing pranks with my passwords. He recently changed my accounts password and has given the following files as hints, he also gave this buggy code which had some import statements removed, help me retrieve my lost password!!!

Author : Kanishk Kumar

Attachments:

Code.txt

There are some things missing here but I can assure you there are no changes in the encryption
Code:

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

import java.util.Scanner;

public class BuggedBlowfish {
    public static void main(String[] args) throws Exception {
        Scanner myObj = new Scanner(System.in);
        System.out.println("Enter the text to be encrypted: ");
        String plaintext = myObj.nextLine();
        System.out.println("Enter the key: ")
        String keyString = myObj.nextLine();
        byte[] keyData = keyString.getBytes();
        SecretKey secretKey = new SecretKeySpec(keyData, "Blowfish");
        String encryptedText = encrypt(plaintext, secretKey);
        System.out.println("Encrypted Text: " + encryptedText)
    }
    
    private static String encrypt(String plaintext, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
        byte[] ivBytes = new byte[cipher.getBlockSize()];
        SecureRandom random = new SecureRandom();
        random.nextBytes(ivBytes);
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        encryptedBytes = cipher.doFinal(encryptedBytes);

        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    
}

Encryption&Key.txt

Encryption:
mF1b8dUwdPVhc/0Hfu1ONep6V6oTHnRqhEMEgtCsge+GncFq9YbX1eCkYwmrHTvajsiyj/vd4IV0BbZI1Obq3/uD7nDyAJ/FxZJNAFRAUuGm3LLXf4vn3zKWsZATypBkkgEQLWfIpg0tP13wJRhk6JUVPi17AaKHrodTtWOq54FqKIaT1DoifMjtJ4TCG3IXmjEo+6ZsBokIjxeCjamGBwNAqFaqIikkHJo7L1PiCFds/lAaB38KqHGL/E2pfw0CK3XYzKV8gBdwhnrUq1UN1Q==

Key:
*tz tw% u~ $%#p! QE?2EC@A>x ED@| 69E 6C2 5?t 5?2 8?:??:86q 69%Q

Solution:

<Updating>

© 2024,Pham Quoc Trung. All rights reserved.

Last updated