原来一直没弄过TLS的流,今天看到一个WP,按这个一步步重来一遍。
Square的题目会一直开放下载 原题点这里
下来后的数据包包含一个go的原码程序和一个流量包
流量是经过加密的,所以看不到内容。
第一步就是取得RSA的公钥。先在包里找到 Server Hello Certificate, 的包,这里包含公钥。在下边的Certificate: xxxx 这点右键导出分组字节流。在另处会导出多余的东西,这里只要一个证书。
这个证书是der格式的。用openssl 转成pem 证书
openssl x509 -inform der -in cer.der -out cer.pem
证书是这样的
┌──(kali㉿kali)-[~/ctf/jule]
└─$ openssl x509 -inform der -in cer.der -publickey
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIQU/j4K9G616sT/G9f82Yu/jANBgkqhkiG9w0BAQsFADAa
MRgwFgYDVQQKEw9NeSBDb29sIFByaW50ZXIwHhcNMjIxMTE2MTkxMTM3WhcNMjMw
MjE0MTkxMTM3WjAaMRgwFgYDVQQKEw9NeSBDb29sIFByaW50ZXIwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7HxjWHSOjL4bb4yJb16VsplrBaZJ1C9Dy
i7r5d/dO6coH5T3BnaCRl+2uQ4MSaGGnWnF7hBKvT12BPcGNI+qDjv37JRq+HpUV
iCcm0sGMy2i5gQUdk2DT21Z5pgimCHoZx2fmZQRlBvh4xARDGDD+m0ksREP1izXC
Z4gI0twh+75pNtv1D9xLUAZrMYVXNOkIKxYrkVsTHn6nEGEB43euOy3XbkgdS0DQ
xhWKx8/nM2LWyHpI83tXeBzXHhnetgeNtC0rWaz+x5x/sw2mcDnysumN0R7k7LVY
EFDx+YpRlm9C6xygFTJzhpjTSS3Ub6hR6c/tM0OiMsRWUqpwY7E7AgMBAAGjSzBJ
MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8E
AjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAnadS
aRPhPIqkZUMOBW3YsHCXc9wrxriwNPnO7BDpeczaezoEazYFcK4noFIR24aTZUyY
OyFZO2MTH5EQ+778D58qleO2IxX7Ui7c0gJuaFfsX0zEvTr5rvSpTdEuQQHHc5Bb
VyTqk4jvh0uNOahKDzKy/eMHEVXOY+b9UKEpZPoXQ5mVZ+yYgJBvuHYdjysPo0k2
i6RfIN/ZtdUfHgMQBpazD32cqDmDtPjvB/TP1+DUNvYrjYOZsjVIuzbTfZdffScY
wZ1uLk+PUfsPQMwCmEib4W7Qf+ApctWGPZ1v+2frSwPhZY3cftAojTp21pC9d13f
zOid8AIxlw6Gj6PYZA==
-----END CERTIFICATE-----
对这个证书到在线网站ssleye.com上转出n 和 e 当然也可以用程序
from Crypto.PublicKey import RSA
f = open('cer.pem','rb').read()
pub = RSA.importKey(f)
n, e = pub.n,pub.e
print(f"{n = }\n{e = }")
第二步根据printer.go里对p,q的描述
p是一个1024位的素数,q是p^(1<<1021)位+2*i,爆破一般素数的间隔是1000多,所以直接爆破2000范围内即可。
from z3 import *
n = 23621897539318735382781746886812894513691748769885872561608018745569703193093855463437952944858188722853908795670837963164709616242593638401041032595833264922632543233131776723436806335966522962980332524550454606209746603582382656306848557857064499642423449000991045716976106596626510521840476248557767311518172872788877427817242273511650663556017746625391305473837996013171596099512668142370526423632408066956471075397237532978090078953286385148467587638857728496028131872602103616105358742971697903227400622583960651099656237391304458477107349123418958226433986832338800716565565348303844157431915191481285604520251
e = 65537
#q = p + 2*i + (1<<(2048//2-3))
'''
r = 1<<1021
for i in range(1000):
s = Solver()
p,q = Ints('p q')
s.add(p>0)
s.add(q>0)
s.add(p*q == n)
s.add(q == p + r + 2*i)
if s.check() == sat:
print(i)
d = s.model()
p = d[p].as_long()
q = d[q].as_long()
print(f"{p = }\n{q = }")
break
#579
p = 142868719742863293783230979998595876793415956014235960922151036241155398557013175374929194646682931157376392447724131367775640007550829960268051112176549732008858300548786079341071746721635835744957674944791270662022918676753662719533721899116906331154776508780823125564615147531881573980598054432598254739019
q = 165339883928642242629847294883458685963640668251014793081329796385871983032700795766517754311983873160016406682708055537482988728652632038079657041006483997556079287226894265000609524171791597509889310313801896383127687512046470579717961037934509735800195322616396412844608553274191538518702473973801282757329
然后根据分解得到的p,q生成pem私钥证书
phi = (p-1)*(q-1)
from gmpy2 import invert
d = invert(e, phi)
print(f"{d = }")
#d = 9400532671971129858222542083936815872127111397643978855902753206634472572425970739306426152476409052607729912871982619242546828527748976656507792104184313936359298717721437794283463479383293183964631468831353381823342557151412515970198776835529536218838915015866570995688753469744053296918099104912265273840691949686655715992589014464656027757651892151294209883699345261818253760961724945295415136166834702090266574962457088834177900317557100854147681109386784781178976305637394835754893756950628990148376816379799340092246538098974858552629104624969892840096009738614177925561065451704981409324313334874286334651425
from Crypto.PublicKey import RSA
priv_key = RSA.construct((n, e, d, p, q))
open('priv_key.pem', 'wb').write(priv_key.exportKey())
然后将这个证书导入到wireshark: 编辑-首选项-RSA密钥-Add New keyfile...
重新打开wireshark,那些原来加密的流就可以看到了。
看流量这是个打印服务,找到 IPP Requst (Print-Job)将这个包里的数据导出
保存为pdf 文件,打开就有flag了。