Try   HackMD

KHÁI NIỆM

CÁC HỆ SỐ

Các khái niệm base16 (hex), base32, base64, và base85 là các thuật toán mã hóa dữ liệu. Các thuật toán này được định nghĩa trong RFC 4648

  1. Base16 (hex): Mã hóa dữ liệu thành các ký tự trong bảng chữ cái hexa (16 ký tự)
  2. Base32: Mã hóa dữ liệu thành các ký tự trong bảng chữ cái base32 (32 ký tự)
  3. Base64: Mã hóa dữ liệu thành các ký tự trong bảng chữ cái base64 (64 ký tự)
  4. Base85: Mã hóa dữ liệu thành các ký tự trong bảng chữ cái base85 (85 ký tự)

Mỗi thuật toán có cách mã hóa và giải mã dữ liệu khác nhau. Các thuật toán này thường được sử dụng để mã hóa các tệp tin nhị phân, email, hoặc các thông tin khác trước khi truyền đi qua mạng hoặc lưu trữ.

DES, AES

Data Encryption Algorithm (DES) là một thuật toán khóa đối xứng được sử dụng để mã hóa.
Thuật toán DES bao gồm 16 vòng xử lý dữ liệu với 16 khóa vòng trung gian 48 bit được tạo từ khóa mật mã 56 bit bởi Bộ tạo khóa vòng. Tương tự, mật mã đảo ngược DES tính toán dữ liệu ở định dạng văn bản rõ ràng từ văn bản mật mã bằng cách sử dụng cùng một khóa mật mã.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Advanced Encryption Standard (AES) là một thuật toán đối xứng khóa riêng nhưng mạnh hơn và nhanh hơn Triple-DES. Nó có thể mã hóa dữ liệu 128 bit với khóa 128/192/256 bit.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

PYCRYPTODOME

Thư viện PyCryptodome là 1 package python chứa các yếu tố mã hóa low-level.
Pycryptodome là một phiên bản của PyCrypto. Nó mang lại nhiều cải tiến so với phiên bản chính thức cuối cùng của PyCrypto, ví dụ như:

  1. Các chế độ mã hóa được xác thực (GCM, CCM, EAX, SIV, OCB)
  2. Hỗ trợ AES được tăng tốc trên các nền tảng Intel thông qua AES-NI
  3. Hỗ trợ đầu tiên cho PyPy
  4. Mã hóa đường cong Elliptic (NIST P-curve; Ed25519, Ed448)
  5. API tốt hơn và nhỏ gọn hơn

    PyCryptodome không phải là một bao bọc cho một thư viện C riêng biệt như OpenSSL. Đến mức tối đa có thể, các thuật toán được thực hiện bằng Python thuần. Chỉ những phần rất quan trọng đối với hiệu suất (vd như block cipher) được triển khai dưới dạng C extension.

OPENSSL, GPG

OpenSSL là một tiện ích nguồn mở được sử dụng để mã hóa dữ liệu. Nó cho phép tạo khóa RSA, DH, DSA,… và mã hóa dữ liệu với kết nối SSL/TLS. Đây là công cụ mã nguồn mở có sẵn trên Windows, Linux, Solaris, macOS, QNX và nhiều hệ điều hành khác
Bao gồm các phần mềm nguồn mở cho phép triển khai các giao thức mạng và mã hóa dữ liệu khác nhau như SSL và TLS. Thư viên gốc của phần mềm này được viết bằng ngôn ngữ lập trình C.Trong đó có sẵn những phần mềm cho phép người dùng sử dụng thư viện OpenSSL với nhiều nguôn ngữ khác nhau cùng với các chức năng mật mã tổng quát để có thể mã hóa và giải mã dữ liệu. OpenSSL cũng được sử dụng từ dòng lệnh để có thể yêu cầu, tạo và quản lý các chứng thực số.

GPG (hoặc GNU Privacy Guard), là một ứng dụng mã hóa khoá công khai, cho phép truyền tải thông tin giữa các bên an toàn và có thể được sử dụng để xác minh nguồn gốc của một thông điệp là chính chủ hay không
Cách thức làm việc của khóa công khai mã hóa (Public Key Encryption):

  • Đảm bảo rằng chỉ có người dùng được chỉ định mới ​​có thể đọc

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Hệ thống này cho phép tạo và mã hóa thông điệp một chiều bằng bất kỳ khóa nào, nhưng chỉ có thể được giải mã bởi người dùng được chỉ định thông qua khóa giải mã riêng. Nếu cả hai bên tạo cặp khóa (công khai và riêng), và chia sẻ khóa mã hóa công khai của họ cho nhau, họ có thể mã hóa và truyền thông điệp an toàn.

  • Xác nhận tính xác thực của người gửi
    Hệ thống cũng cho phép người gửi ký thông điệp bằng khóa cá nhân của mình. Người nhận có thể sử dụng khóa công khai để xác minh chữ ký và đảm bảo rằng thông điệp được gửi bởi người dùng đã chỉ định

CRYPTOHACK

Finding flags

Flag bài này là crypto{y0ur_f1rst_fl4g}, chủ yếu giới thiệu format của flag ra sao.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Great Snakes

Bài này chỉ cần mình run cái file py được cho sẵn thì tìm được flag là crypto{z3n_0f_pyth0n}

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

ASCII

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Mình dùng đoạn code dưới để chuyển từ ASCII -> Dec thì tìm được flag là crypto{ASCII_pr1nt4bl3}

A = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]
for a in A:
    x = chr(a)
    print(x,end ='')

Hex

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Mình cùng dùng đoạn code dưới để decode hex thì được flag là crypto{You_will_be_working_with_hex_strings_a_lot}

hex = "63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d"
x=bytes.fromhex(hex)
ascii=x.decode()
print(ascii)

Base64

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Dùng đoạn code dưới để decode base64 (đề gợi ý mình decode hex trước sau đó tới base64) và tìm được flag là crypto/Base+64+Encoding+is+Web+Safe/

import base64
h = "72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf"
x=bytes.fromhex(h)
flag = base64.b64encode(x).decode('utf-8')
print(flag)

Bytes and Big Integers

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Khóa RSA chỉ work với số. Bài này đề đã cung cấp cho mình messages sẵn dưới dạng số rồi nên chỉ cần apply vô.
Flag bài này là crypto{3nc0d1n6_4ll_7h3_w4y_d0wn}

from Crypto.Util.number import long_to_bytes
A = 11515195063862318899931685488813747395775516287289682636499965282714637259206269
flag = long_to_bytes(A).decode('utf-8')
print(flag)

XOR Starter

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Bài này là về XOR, với mỗi ký tự a trong chuỗi A, thực hiện phép XOR với số 13, sau đó chuyển kết quả thành ký tự tương ứng và thêm vào chuỗi flag.
Flag tìm được là crypto{aloha}

A = "label"
flag = ""
for a in A:
    flag += chr(ord(a) ^ 13)
print(f"crypto{{{flag}}}")

XOR Properties

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Cứ lấy mấy key xor với nhau theo thứ tự thì tìm được flag. Hàm unhexlify từ thư viện binascii là dùng để chuyển đổi một chuỗi hex thành dạng nhị phân.
Flag bài này là crypto{x0r_i5_ass0c1at1v3}

#!/usr/bin/env python3
from binascii import unhexlify

def xor_two_str(s1,s2):
    if len(s1) != len(s2):
        raise "XOR EXCEPTION: Strings are not of equal length!"

    return ''.join(format(int(a, 16) ^ int(b, 16), 'x') for a,b in zip(s1,s2))


KEY1 = "a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313"

KEY2 = xor_two_str("37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e", KEY1)
print("[-] KEY2: {}".format(KEY2))

KEY3 = xor_two_str("c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1", KEY2)
print("[-] KEY3: {}".format(KEY3))

KEY4 = xor_two_str(xor_two_str(KEY1, KEY2), KEY3)
print("[-] KEY4: {}\n".format(KEY4))

FLAG = xor_two_str("04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf", KEY4)
print("[*] FLAG: {}".format(unhexlify(FLAG)))

Favourite byte

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Bài này là single byte - xor, vậy nên mình phải xor từng byte với nhau, lặp đi lặp lại cho tới hết thì mới tìm được flag.
Flag bài này làcrypto{0x10_15_my_f4v0ur173_by7e}

from binascii import unhexlify
import string

def single_byte_xor(input, key):
    if len(chr(key)) != 1:
      raise "KEY LENGTH EXCEPTION: In single_byte_xor key must be 1 byte long!"

    output = b''
    for b in input:
        output += bytes([b ^ key])

    try:
        return output.decode("utf-8")
    except:
        return "Cannot Decode some bytes"

data = "73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d"
decoded = unhexlify(data)

print("[-] HEX_DECODE: {}\n".format(decoded))

result = {}
for i in range(256):
    result[i] = (single_byte_xor(decoded, i))
    

print("[*] FLAG: {}".format([s for s in result.values() if "crypto" in s]))

You either know, XOR you don't

image

Bài này đề gợi ý mình nhớ lại format flag là crypto{ (7 char). Vậy thì lấy nó đi xor với 7 char đầu trong cipher (data sau khi chuyển về nhị phân). Thì tìm được 1 cái key mới là myXORke, nhưng mà cái key này còn thiếu chữ y nên mình phải tự add vào. Sau đó mình lặp đi lặp cái key myXORkey sao cho nó dài bằng cái cipher, rồi đem đi xor với nhau thì tìm được flag.
Flag bài này là crypto{1f_y0u_Kn0w_En0uGH_y0u_Kn0w_1t_4ll}

from binascii import unhexlify
def brute(input, key):
    if len(input) != len(key):
        return "Failed!"

    output = b''
    for b1, b2 in zip(input, key):
        output += bytes([b1 ^ b2])
    try:
        return output.decode("utf-8")
    except:
        return "Cannot Decode some bytes"

data = "0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104"
cipher = unhexlify(data)
print("[-] CIPHER: {}".format(cipher))

# Buoc1
key_part = brute(cipher[:7], "crypto{".encode())
print("[-] PARTIAL KEY FOUND: {}".format(key_part))

# Buoc2
key = (key_part + "y").encode()
key += key * int((len(cipher) - len(key))/len(key))
key += key[:((len(cipher) - len(key))%len(key))]
print("[-] Decoding using KEY: {}".format(key))

plain = brute(cipher, key)
print("\n[*] FLAG: {}".format(plain))

Challenges

Challenge 1:

Giải mã đoạn ciphertext mã hoá bằng AES-128 mode CBC sau sử dụng CyberChef + Code (viết cả 2 cách giải):

cipher text: hf5lMhAM4ZGmYN44XXRElo0OMm+XGEsLAiCNwy3Twqg=
key: longphuckhanhquy
iv: trongquocduykhoa

Flag bài này là KCSC{ma_hoa_hay_ko_e}

CyberChef:

Ảnh chụp màn hình 2023-11-14 200755
Code
Đầu tiên mình import thư viện Pycryptodome. Sau đó đổi chuỗi base64 kia thành bytes.
Tạo đối tượng AES.new với key và iv.
Sử dụng cipher.decrypt để giải mã và unpad để loại bỏ các bytes được thêm vào để đảm bảo kích thước block đúng. Cuối cùng nhập các info đã cho key,iv,ciphertext để decode.

from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from Crypto.Util.strxor import strxor_c
import base64

def aes_128_cbc_decrypt(ciphertext_base64, key, iv):
    ciphertext = base64.b64decode(ciphertext_base64)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    flag = unpad(cipher.decrypt(ciphertext), AES.block_size)
    return flag

ciphertext_base64 = "hf5lMhAM4ZGmYN44XXRElo0OMm+XGEsLAiCNwy3Twqg="
key = b'longphuckhanhquy'
iv = b'trongquocduykhoa'
flag = aes_128_cbc_decrypt(ciphertext_base64, key, iv)
print("Flag:", flag.decode('utf-8'))

image

Challenge 2:

Trong tập tin "bai2.zip", đọc bash và kết hợp với những gì đã tìm hiểu về openssl, hãy giải mã flag.enc và phục hồi file gốc.
Đây là bash đã cho

image

Mình dùng openssl để decrypt
openssl enc -aes-256-cbc -d -in flag.enc -out flag.xlsx -K $key2 -iv d14cc2932227ad3eb8354fc18057b292

Thu được flag.xlsx, file này có PK nên đổi thành .zip. Sau đó unzip, vào sharedStrings.xml thì tìm được 1 chuỗi ngăn cách bằng tên Long, Quoc,Kiet,Phuc,Loi, ghép lại ta được S0NTQ3tzYXVfbmF5X2Nob2lfZm9yX3NlX2dhcF9yYXRfbmhpZXVfbWFfaG9hX25odV90aGVfbmF5fQ== và đem đi decode base64 thì được flag

Flag bài này là
KCSC{sau_nay_choi_for_se_gap_rat_nhieu_ma_hoa_nhu_the_nay}

Challenge 3:

Trong tập tin "bai3.zip". Làm bằng CyberChef và sửa đổi source được cho để giải mã (hoặc tự code mới nếu thích hehe).
Mình thêm đoạn code decrypt vào source có sẵn

def decrypt(key, iv, ciphertext):
    key = bytes.fromhex(key)
    iv = ciphertext[:16]
    ciphertext = ciphertext[16:]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    pt = unpad(cipher.decrypt(ciphertext), 16)
    return pt

Sau đó decrypt 2 file là docvippro.docx.kcschinhvippro.jpg.kcsc lần lượt thành 2 file output.txtoutput1.txt

with open("docvippro.docx.kcsc","rb") as file:
    bytes_from_file = file.read()

bytes_from_file = bytes_from_file[16:]
key = bytes.fromhex("b78b4f82c24917cf740250da0f3c1bb7748c6c6c8f0df1f74948af97bebea675")
iv = bytes.fromhex("11b2e8dc1947c39260873cae34850eda")

cipher = AES.new(key,AES.MODE_CBC,iv)

with open("output.txt","wb") as file_out:
    file_out.write(cipher.decrypt(bytes_from_file))

key = "b78b4f82c24917cf740250da0f3c1bb7748c6c6c8f0df1f74948af97bebea675"
iv = "11b2e8dc1947c39260873cae34850eda"

with open("hinhvippro.jpg.kcsc","rb") as file:
    bytes_from_file = file.read()

bytes_from_file = bytes_from_file[16:]
key = bytes.fromhex("b78b4f82c24917cf740250da0f3c1bb7748c6c6c8f0df1f74948af97bebea675")
iv = bytes.fromhex("11b2e8dc1947c39260873cae34850eda")

cipher = AES.new(key,AES.MODE_CBC,iv)

with open("output1.txt","wb") as file_out:
    file_out.write(cipher.decrypt(bytes_from_file))

File mở file output.txtPK thì mình đổi đuôi thành zip, output1.txtjfif thì đổi đuôi thành png, mình được tấm hình

output1

Unzip file output, sau đó vào file document.xml cũng thấy chuỗi kí tự base85 91)WFH['IHB4#ahF),-#@<l4%BPCgqBk;6jFD,6(?ZTdcCgg[m@<63kFDl&0?YF@s?Z'Og?Y+(]BOtjg/73:.DdRF#?XdGXI/ decode xong thì tìm được flag.

Flag bài này là

KCSC{xong_task_nay_thi_tiep_theo_se_la_task_tong_hop_nhe_em_hehe,_nho_on_bai}