Describe: We were pretty sure the service at tonnerre.pwning.xxx:8561 source was totally secure. But then we came across this website and now we’re having second thoughts… We think they store the service users in the same database?
给了一个服务,和代码,然后一个使用了相同数据库的网站.
网站有SQLi, 很简单,直接用sqlmap跑就行了得到:
1 2 3
salt,user,verifier D14058efb3f49bd1f1c68de447393855e004103d432fa61849f0e5262d0d9e8663c0dfcb877d40ea6de6b78efd064bdd02f6555a90d92a8a5c76b28b9a785fd861348af8a7014f4497a5de5d0d703a24ff9ec9b5c1ff8051e3825a0fc8a433296d31cf0bd5d21b09c8cd7e658f2272744b4d2fb63d4bccff8f921932a2e81813,get_flag,ebedd14b5bf7d5fd88eebb057af43803b6f88e42f7ce2a4445fdbbe69a9ad7e7a76b7df4a4e79cefd61ea0c4f426c0261acf5becb5f79cdf916d684667b6b0940b4ac2f885590648fbf2d107707acb38382a95bea9a89fb943a5c1ef6e6d064084f8225eb323f668e2c3174ab7b1dbfce831507b33e413b56a41528b1c850e59 # salt 并没发现有啥用
然后这段代码拿去sage跑出x
1 2 3 4 5 6
N = 168875487862812718103814022843977235420637243601057780595044400667893046269140421123766817420546087076238158376401194506102667350322281734359552897112157094231977097740554793824701009850244904160300597684567190792283984299743604213533036681794114720417437224509607536413793425411636411563321303444740798477587 g = 9797766621314684873895700802803279209044463565243731922466831101232640732633100491228823617617764419367505179450247842283955649007454149170085442756585554871624752266571753841250508572690789992495054848 v = 165674960298677315369642561867883496091624769292792204074150337092614964752287803122621876963359715780971900093578962850132496591192295131510624917204670192364009271723089444839548606533268832368676268405764377988005323809734321470184299186127132537376393324213965008025487569799622831466701444653263068925529 A = g ** 2 % N (aa, bb, cc) = xgcd(v/A, N) x = (bb * A) mod N
python版:
1 2 3 4 5 6 7
from gmpy2 import invert N = 168875487862812718103814022843977235420637243601057780595044400667893046269140421123766817420546087076238158376401194506102667350322281734359552897112157094231977097740554793824701009850244904160300597684567190792283984299743604213533036681794114720417437224509607536413793425411636411563321303444740798477587 g = 9797766621314684873895700802803279209044463565243731922466831101232640732633100491228823617617764419367505179450247842283955649007454149170085442756585554871624752266571753841250508572690789992495054848 v = 165674960298677315369642561867883496091624769292792204074150337092614964752287803122621876963359715780971900093578962850132496591192295131510624917204670192364009271723089444839548606533268832368676268405764377988005323809734321470184299186127132537376393324213965008025487569799622831466701444653263068925529 A = g ** 2 % N k = invert(A, N) x = invert(k*v, N)
x = "e2a218006a120b096d7836bf397e7dbb1a8f8f6cedb87c20fe3d4a2b99fc9f6661777bbe804b82e9c17a0ad2d508b97031d146934479076a4c11c199322e0dc9724d2cdac24480c6decae4e547f020273f3a2849f9d068cb8c774e029a747fc7c726a1bad2b9f9a7c091096002c364f018f2f1157ad492d42c00305d84f37db7" v = 165674960298677315369642561867883496091624769292792204074150337092614964752287803122621876963359715780971900093578962850132496591192295131510624917204670192364009271723089444839548606533268832368676268405764377988005323809734321470184299186127132537376393324213965008025487569799622831466701444653263068925529 N = 168875487862812718103814022843977235420637243601057780595044400667893046269140421123766817420546087076238158376401194506102667350322281734359552897112157094231977097740554793824701009850244904160300597684567190792283984299743604213533036681794114720417437224509607536413793425411636411563321303444740798477587L
if c in [N-g, N-1, 0, 1, g]: req.sendall('Sorry, not permitted.\n') req.close() return
不过并没啥影响,我们仍然能继续构造一个x使得 $$(x * v)\ mod\ N = c = g^2$$ 接着就可以推出 $$session\_secret = g^{2*r}\ mod\ N = (g^r\ mod\ N)^2\ mod\ N$$
然后现在的问题是怎么算x,就用上面构造的等式 $$(x * v)\ mod\ N = g^2$$ 可以得出 $$(x * v * g^{-2})\ mod\ N = 1$$
这个就用扩展欧几里德算呗,不过这里有一个知识点
假设$A = g^2$,那么$A^{-1}$值为啥?A明显是大整数,数论是研究整数性质的学科,所以不可能有分数参与计算,所以就有了这个推论 $$(x * v * A^{-1})\ mod\ N = ((x * v)\ mod\ N) * (A^{-1}\ mod\ N)\ mod\ N$$ 假设$A^{-1}\ mod\ N \equiv k$ 这不就模逆元么,可得$A * k \equiv 1\ (mod\ N)$ 这不就可以用扩展欧几里德算出k么,所以最后是 $$x * (v * k) \equiv 1\ (mod\ N)$$ 又是通过扩展欧几里德算出x
rabit
Describe: Just give me a bit, the least significant’s enough. Just a second we’re not broken, just very, very insecure. Running at rabit.pwning.xxx:7763
已知$N = p * q$, N的值可以得到,p和q却是未知
我们还知道c的值,$c = flag^2\ mod\ N$
我们可控设为x, 当 $$x^{\frac{\phi(q)}{2}}\ mod\ q = 1$$ $$x^{\frac{\phi(p)}{2}}\ mod\ p = 1$$ 同时成立时, $$x^{\frac{\phi(N)+4}{8}}\ mod\ N = m$$ 我们可得知m的奇偶性
from Crypto.Util.number import GCD, bytes_to_long, long_to_bytes import math
FLAG = "testtesttesttesttesttest" p = 9106955210961894382213398084695411548991508552135116475739483485343599066229167723931080143408618040894126850992819734177810259561241614741757319165906087L q = 10285773789873373607105204107746706058912747747297377854417892145690734334799058020026041693440549801695363225930871791013981165203481480366182233263169487L N = p * q
msg = """Welcome to the LSB oracle! N = {}\n""".format(N) print msg padded = pad(FLAG) print padded enc_flag = encrypt(padded, N) assert long_to_bytes(padded)[:len(FLAG)] == FLAG assert decrypt(enc_flag, p, q) == padded assert decrypt(2, p, q) != None
print "Encrypted Flag: {}\n".format(enc_flag)
m = decrypt(enc_flag, p, q)
# while True: # x = raw_input("Give a ciphertext: ") # x = long(x) # m = decrypt(x, p, q) # # print m # if m is None: # m = 0 # print "lsb is {}\n".format(m % 2)
flag_lower_bound = 0 flag_upper_bound = N mult = 0 c = enc_flag iter_count = math.log(N, 2) for i in xrange(0, long(math.ceil(long(iter_count)))): c = ((encrypt(2, N) * c) % N) mult += 1 print("upper = %d" % flag_upper_bound) print("upper flag = %s" % long_to_bytes(flag_upper_bound)) print("lower = %d" % flag_lower_bound) print("lower flag = %s" % long_to_bytes(flag_lower_bound)) print("multiplier = %d" % mult) mm = decrypt(c, p, q) if mm is None: mm = 0 if mm % 2 == 0: flag_upper_bound = (flag_upper_bound + flag_lower_bound) / 2 else: flag_lower_bound = (flag_upper_bound + flag_lower_bound) / 2
本题就是利用这样的方法来确定出flag的范围,然后逐渐缩小范围,到最后确定值,我再多推一步,这一步理解了就可以全部理解了 下一步用$m^e\ mod\ N = c$ 乘以 $4^e\ mod\ N = c_2$ 得到 $$(4*m)^e\ mod\ N = c * c_2\ mod\ N = CC_2$$
然后把$CC_2$拿去解密 $$CC_{2}^{d}\ mod\ N = (4 * m)^{e*d}\ mod\ N = 4*m\ mod\ N = MM_2$$
1 2 3 4 5 6 7 8 9 10
if MM is odd: if $MM_2$ is odd: 3N < 4 * m < 4N else: 2N < 4 * m < 3N else: if $MM_2$ is odd: N < 4 * m < 2N else: 0 < 4 * m < N