0. はじめに
h4ckc0n CTFにソロでゆるっと参加して70/286位でした
1. thepassw902jtxjuo90tj(26 solved)
from Crypto.Util.number import getPrime, bytes_to_long
from Crypto.Util.Padding import pad, unpad
# how about 2 part flags
flag1 = b"FLAG PART 1 HEHEHE"
flag2 = b"FLAG PART 2 not hehe :("
flagnum = bytes_to_long(flag1)
flagnum2 = bytes_to_long(pad(flag2, 256))
assert len(bin(flagnum)[2:]) == 303
p = getPrime(2048)
q = getPrime(2048)
N = p * q
e = 65537
# p isn't needed anymore; must be corrupted
p = p^flagnum
print("masked_p={}".format(hex(p)))
print("N={}\ne={}".format(hex(N), hex(e)))
ct = pow(flagnum2, e, N)
print("ct={}".format(hex(ct)))
pの下位303bitがマスクされている。pは2048bitなのでcoppersmith attackが適応できる
from sage.all import *
N = Integer(0x8c69cb58bd9b5f6cfbe5973aadad07e20f117333cde4650bafaa76fdb888436d60c61bc883e9bead6edee6d8323fa344a0dec482100c826ada5e3c970e6f017faa25e06680d36ceb2fc53b0d4065a5ef411d595a8ae749e01dc9eea1a79a6da2ec4c9428d3ef1577cc2c8ab48fe2d2a19313dc92c6ff2aaa36f0122f047c8fd2793fa10f09955a8473b397983774acc1f64b105adc5adad6a1edfba78fd80d0b04476ab24b60710c3c20e9c3914456d1425b34449cd81bf01d43bb3d9bf3a100dd599443eb94aa5f7d884889585d7f0008c1bbe1403fd9f17a3c5901327fb5c66c04af09d134327dfc3222359e3249bb8309c93f74dc93d981f72e99bde0124800807878f04c5aaebff4a3236d29abbc98b16b0c0657d1e905888cbccc8c0306d7c576f5386068eedcb51753ae20cd314199ab144bcf994d3f015a05e4735dd2d2301ed904a13ce763413b3f007ff3c25ba30e6e809522574c8c37d3c8b1fe7c5de75c8162f42051a062384f237cea5cab45f40fc38e28ebd949de6352f6e289ed855c0aec761a886cb0a6916067d77947d42e4bb6d0b399ca0502776ba0c847831fd07e721a2a01466f4b42bd2ed82bdc3e39637862902b8c3d8cc302d20180bb503a01eac75f433d3d601792c1f4a6e1c62e6d83b3d37cb0d200ee3e6b9463b90b43064d902d93f8578e3aaaa76a356d08d25965ada3f2af3c0a55e20580af )
masked_p =Integer(0x9ac12962669f9be2f8e6edbca1e6c307b0d0cf2432c4afdeefaa0fd7d106964056a326f8af960ad4e5aa392625f67d46d05c3dbf82b8d508cf4c9369faf7c6a36ffd4028de967424f75c880042bfcf8e731f67629f600f1b4bf27476599aaaed866f7c2e2d2a52fe6b4444b1d2ae67af561829db0229883f23b880dd326df8d38eeeb3f8f7f0d3c4b357175f219f3dad751855e011b9dd088bb046ca1a3943808c19daedf014245a8e165854931eff3a56b57c0adf9546550ac473e29e10b077ce8f6ac2e044d853ab9662ba8bba387afd29355c8d1a0ce96ea5cad161b25ddc34dd43724ce6977916379ef35038a82a1c5c8cbf8ee333ba76ed3150e1b626c0 )
# Parameters
beta = 0.4
epsilon = beta^2/7
# The number of bits we are trying to recover
kbits = 303
# p's actual number of bits
pbits = masked_p.nbits() + kbits
# Polynomial
PR.<x> = PolynomialRing(Zmod(N))
f = x + masked_p
# Use Coppersmith to find the roots
x0 = f.small_roots(X=2^kbits, beta=beta)[0]
# Recover the actual p
recovered_p = x0 + masked_p
print(f"Recovered p: {recovered_p}")
from Crypto.Util.number import long_to_bytes
p = 19535950528273173801307205065648197564656577746427362111408212925358866027088703661563448359317128204554242408864028829931524358913776666778058594300674954640063834193692016163823175265801478791076451827175050543373784406340739445539664909757065622955558914381802289641859082341256264724387476231698822681833805942025080196305529640258512998138907995265169057305182676545564777870850023901248774372842539748299080308873891914029166222403511434627002311407340107241222099255577238133982069869299282687923205427201146620320451449522010581068888174444898490022087276552987982107899113990810595965291458473027587217509119
masked_p = 0x9AC12962669F9BE2F8E6EDBCA1E6C307B0D0CF2432C4AFDEEFAA0FD7D106964056A326F8AF960AD4E5AA392625F67D46D05C3DBF82B8D508CF4C9369FAF7C6A36FFD4028DE967424F75C880042BFCF8E731F67629F600F1B4BF27476599AAAED866F7C2E2D2A52FE6B4444B1D2AE67AF561829DB0229883F23B880DD326DF8D38EEEB3F8F7F0D3C4B357175F219F3DAD751855E011B9DD088BB046CA1A3943808C19DAEDF014245A8E165854931EFF3A56B57C0ADF9546550AC473E29E10B077CE8F6AC2E044D853AB9662BA8BBA387AFD29355C8D1A0CE96EA5CAD161B25DDC34DD43724CE6977916379EF35038A82A1C5C8CBF8EE333BA76ED3150E1B626C0
N = 0x8C69CB58BD9B5F6CFBE5973AADAD07E20F117333CDE4650BAFAA76FDB888436D60C61BC883E9BEAD6EDEE6D8323FA344A0DEC482100C826ADA5E3C970E6F017FAA25E06680D36CEB2FC53B0D4065A5EF411D595A8AE749E01DC9EEA1A79A6DA2EC4C9428D3EF1577CC2C8AB48FE2D2A19313DC92C6FF2AAA36F0122F047C8FD2793FA10F09955A8473B397983774ACC1F64B105ADC5ADAD6A1EDFBA78FD80D0B04476AB24B60710C3C20E9C3914456D1425B34449CD81BF01D43BB3D9BF3A100DD599443EB94AA5F7D884889585D7F0008C1BBE1403FD9F17A3C5901327FB5C66C04AF09D134327DFC3222359E3249BB8309C93F74DC93D981F72E99BDE0124800807878F04C5AAEBFF4A3236D29ABBC98B16B0C0657D1E905888CBCCC8C0306D7C576F5386068EEDCB51753AE20CD314199AB144BCF994D3F015A05E4735DD2D2301ED904A13CE763413B3F007FF3C25BA30E6E809522574C8C37D3C8B1FE7C5DE75C8162F42051A062384F237CEA5CAB45F40FC38E28EBD949DE6352F6E289ED855C0AEC761A886CB0A6916067D77947D42E4BB6D0B399CA0502776BA0C847831FD07E721A2A01466F4B42BD2ED82BDC3E39637862902B8C3D8CC302D20180BB503A01EAC75F433D3D601792C1F4A6E1C62E6D83B3D37CB0D200EE3E6B9463B90B43064D902D93F8578E3AAAA76A356D08D25965ADA3F2AF3C0A55E20580AF
e = 0x10001
ct = 0x79481001FE7AA55C996E3CF84F9E675842B515EAB2C30B43C210206235116C9525FF78C6FDC26699D7F680B4B779D792CAC8CDBBF54E39CBF95260BB669D6CD1591CD131A7AD4D36183C7970BD491851943366EF960989541912CC317AEDF576BC0F10ED3B0D3FD3B6A2E2B706A7C927C04C8282ADA3F1C762DD01BDD87CA3E58E38365982E96AC8D7A9365BD9AF556F6F1B45CCFC3840E95445247FAE08F427763E0CE16788539F84822E25070414BD559B195E6F63A66D7289140BD40F0D7017EF93A29D42957DE441D5868B13678D3670C2E33BF16BCB5D0C1F8F2C17C6C2DEFD3820CB89D13AF09ADBA0130C3485F14FC6F5C3CA40554D322A6B222CCC95FACF77510245431479DDDC98C5F7624539A1850AAA9D3447576A7C8EA51E2B573FD8C5358315CAF6B83265631897ABBB9F0794174B64731C3E6E652453C0FA837B78D8D57E064E27C745272AD7D255FF5123DD0F8466A4A5F9587508BAA47F1CBE2CF19C65C345CDC91488FB6849FBD7029D6AEF964D407E810AC23225555D55CE539C3BB0CA09897DDBBF647FD39E1521DD7D0A3B70F22D3A1D4A4261422397A553DCE42E821D140AE48E3BB1A758054CED96DC729BB02E027A043464ED71717441417F4CA2A050B83F4911FD429CB69C00AD043303B9F9966D26AD9DCA3788D5870C78ABAFDDBEA8BD1BEEC7E60B86DAF5F2B2CBA49B34430664BA893AC0E0
print(N % p)
q = N // p
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
print(long_to_bytes(p ^ masked_p))
print(long_to_bytes(pow(ct, d, N)))
b'd4rkc0de{uhh_1s_thi5_inn0vative_et_al?'
b'ig_n0t_hehe}
参考
2. Faster FastAPI(110 solved)
こんな感じのサイト。お金をためてAdmin Lounge Couponを買ってあげたい
試行錯誤の末、Admin Lounge Couponの購入の際Burp suiteでquantityの数を0にしてやった
You bought a lounge coupon! Code: d4rk{cyth0n_1s_f4st_but_r1sky}c0d3
3. always painted, never gifted
$ apngdis lessgo.apng
変な写真が見えたのでまずはapngをpngに変換
co48r455qh4dkz3zqjhun5tsmh5uyz5pgtiugz3wm7tsopdcptxzkpjtpa5f6pdopa5f6cdqpthi6auig7xsopdrmh5uyz5pgtiugz3tg7xun5tzgbxsec5dgb1dg3u1mhaghc57ccage3e
ここでも無理だ。うーーんcyberchefも色々試したんだけどなぁ
z-base-32らしい
知るかボケ
d4rk{w45_7ry1n6_70_m4k3_4_ch4ll_u51n6_4pn6_0nly_bu7_h4d_70_m4k3_17_1n70_d3c0d3fr_0n3}c0de
どっかの外人さんにこれ使うといいよって言われた。ほんとだ、、天才、、