whileTrue: pts = [xor(key, c) for c in ct] for i, pt inenumerate(pts): print(i, pt) idx = int(input("Enter index: ")) if idx == -1: break c = input("Enter next char: ")[0] key += bytes([ord(c) ^ ct[idx][len(key)]]) print("Current key:", key.hex()) print([xor(key, c) for c in ct]) # SECFEST{be_cautious_with_xor!}
from random import randrange from gmpy2 import next_prime, is_prime bits = 128 bound = randrange(2**(bits-1), 2**bits) print("b =", bound) #299089579545315329927831077361748367952 B = int(next_prime(bound**2)) print("B =", B) #89454576592593506198091003676782760426164579104178557226654770323935580674319 d = 8
defgen_prime(): whileTrue: ps = [randrange(bound) for _ inrange(d)] p = 0 for i inrange(d): p += ps[i]*B**i if is_prime(p): break print(ps) return p
p = gen_prime() q = gen_prime() n = p*q print(f"{n = }") #34636826522268200537774154204941407529988822872148894567372441583415254552447302749228340228906546920018188955427366065775864988572478602396106371080685655564033817360335889100181326997156956367867826271804748628399970980872535732627789819667138755054766468613617857322669943746935541793686046017146304058463046888768033823974071280198556883407966869840605294817458160107581025567028344865676401747062383757953634109234225473151412286700057343914024601771084294978143682676406989676297209210216751760067457688993962995389392757065579902776423369572207772618783218733875876004666171649676348837063312375577831738151728184702454332533310164381393954188000484797023852778358325185035355456975120195736428957973841058260571165844580731851332614644310138023335666774129908073810240673290494869672972129721881195738377137440359704474859842375310892200036137555884160008753002740372280734559191112796694291489720084349580961011222521816640149582773655766774142060407687849118888102012006683658983742498222152936133450205031770557715936326829853770866589383519670805541691607883632863177387841208657406032490492781368768715851417369111054048036698365329818004529
e = 65537 m = b"[REDACTED]" m = int.from_bytes(m, "big") c = pow(m, e, n) print(f"{c = }") #20028745085195583678378916660396397538994010666442432435713640627343638544983255393172148533881365971854283869014758186049316988000737550769605639679479180589253955045598774721246899297252406061180515011481963360240256930643234163280545121729316133742144823763601498670419742214338058035882729739026231634052850909950379775962557912899396425158183194713786156167265753101307366270122197291552260459611820717997757267712339753750891161458350673859656475246424157412488302546155825912483333623112241511338503582503574264361642880778925970123483773426929656284901291439896260232211956880277503017106751458194801408711006508735697948503777541874602351630564440747713117941961365774432080957568074493024639496001096643016830901025267139229529531498995611208677992804905291286283800620644472474016518205177496080326978650925595478508487654201440611536444236269249350798132974110183405726386731371083064781799161730272554725154294836754680153505618540394615227117220937285324830238267813179531144987439258005506277060338763635818845237827323991005526601556189238304698762279589753458427889093496877392067155432030319457380945056863466258912867795091887061462273
from Crypto.Util.number import * from itertools import product
B = 89454576592593506198091003676782760426164579104178557226654770323935580674319 n = 34636826522268200537774154204941407529988822872148894567372441583415254552447302749228340228906546920018188955427366065775864988572478602396106371080685655564033817360335889100181326997156956367867826271804748628399970980872535732627789819667138755054766468613617857322669943746935541793686046017146304058463046888768033823974071280198556883407966869840605294817458160107581025567028344865676401747062383757953634109234225473151412286700057343914024601771084294978143682676406989676297209210216751760067457688993962995389392757065579902776423369572207772618783218733875876004666171649676348837063312375577831738151728184702454332533310164381393954188000484797023852778358325185035355456975120195736428957973841058260571165844580731851332614644310138023335666774129908073810240673290494869672972129721881195738377137440359704474859842375310892200036137555884160008753002740372280734559191112796694291489720084349580961011222521816640149582773655766774142060407687849118888102012006683658983742498222152936133450205031770557715936326829853770866589383519670805541691607883632863177387841208657406032490492781368768715851417369111054048036698365329818004529 c = 20028745085195583678378916660396397538994010666442432435713640627343638544983255393172148533881365971854283869014758186049316988000737550769605639679479180589253955045598774721246899297252406061180515011481963360240256930643234163280545121729316133742144823763601498670419742214338058035882729739026231634052850909950379775962557912899396425158183194713786156167265753101307366270122197291552260459611820717997757267712339753750891161458350673859656475246424157412488302546155825912483333623112241511338503582503574264361642880778925970123483773426929656284901291439896260232211956880277503017106751458194801408711006508735697948503777541874602351630564440747713117941961365774432080957568074493024639496001096643016830901025267139229529531498995611208677992804905291286283800620644472474016518205177496080326978650925595478508487654201440611536444236269249350798132974110183405726386731371083064781799161730272554725154294836754680153505618540394615227117220937285324830238267813179531144987439258005506277060338763635818845237827323991005526601556189238304698762279589753458427889093496877392067155432030319457380945056863466258912867795091887061462273
from random import sample, randint p = random_prime(2^1024) R = Zmod(p) groups = list(randint(2, 6) for i inrange(40)) thresh = list(randint(i//2, i//2 + 1) for i in groups) G = list( list(R.random_element() for i inrange(c)) for c in groups ) message = list( sorted(sample(range(g), i))[::-1] for g, i inzip(groups, thresh) ) P = sum( sum(g[i] for i in m) for m, g inzip(message, G) ) print(f"p = {p}") print(f"groups = {groups}") print(f"thresh = {thresh}") print(f"G = {G}") print(f"P = {P}") deflexorder(x, m): iflen(x) == 0: return1 return binomial(x[0], len(x)) + lexorder(x[1:], x[0]) flag, b = 0, 1 for m, g inzip(message, groups): flag += lexorder(m, g) * b b *= binomial(g, len(m)) print(f"flag = {flag}")
直接看 source code 可以知道
的某個 subset 加總起來會是 ,因為
density 不高 (~0.15) 所以直接 LLL,然後回推 message 拿 flag
即可。
backend webserver http-response set-header Server webserver server s1 loadbalancer:80 resolvers dns check
Caddyfile:
1 2 3 4 5 6 7 8 9 10 11
:80 {
@blacklist { not { path /admin* } }
reverse_proxy @blacklist backend:80
}
總之它就只是擋 /admin 之類的 path 而已。
官方解 (by @avlidienbrunn):
1 2
1. bypass HAP using keep-alive + CONNECT verb + 2xx status (will put HAP in "tunnel mode", it thinks it is supposed to be a proxy, and not apply any rules) 2. bypass caddy blacklist with either invalid pct encoding or GET /admin/../blablabla. caddy uses matching on normalized path, but doesnt actually send normalized path over the wire
它能讓你直接把 DNS 的 packet 用 base64 encode 放在 url
上傳送,然後回傳值是直接 binary DNS
response。所以可以看看有沒有什麼方法能讓 DNS response 變成 js 來繞
CSP。
所以我去查了一查 DNS protocol 的細節,找到了這個讓我簡單的了解了
DNS packet 的格式。而關鍵在於 DNS header 最開頭有個 16 bits 的
ID,response 也會是以相同 ID
回傳的。所以只要讓 ID 變成是 0x2F2A 就能讓
response 以 /* 開頭。