INS'hAck CTF Write-up
- はじめに
- Telegram [Misc]
- gflag [Misc]
- Dashlame - Part 1 [Rev]
- intergover [Pwn]
- signed or not signed [Pwn]
- Yet Another RSA Challenge - Part 1 [Crypto]
- まとめ
はじめに
2019/05/03 ~ 2019/05/06に開催されたINS'hAck CTFに参加しました.
初日しか参加してないので最終的な順位は分かりません.
Telegram [Misc]
Join our Telegram channel !
アプローチ:リンク先にとぶ
INSA{is_e2e_8annEd_1n_Russi4_too}
gflag [Misc]
My brother likes esoteric programming. He sent me this file but I don't see what it is for. Could you help me ?
> file gflag gflag: ASCII text
アプローチ:gcode
> wc -l gflag 1754 gflag
> head gflag M73 P0 R2 M201 X9000 Y9000 Z500 E10000 M203 X500 Y500 Z12 E120 M204 P2000 R1500 T2000 M205 X10.00 Y10.00 Z0.20 E2.50 M205 S0 T0 M107 M115 U3.1.0 M83 M204 S2000 T1500
既視感があるなと思ったらNCプログラムでした(5,6年前にCNC旋盤使ったことがある)
(gcode
だから gflag
ってことか〜)
適当なNCViewerに流すとflagが表示されます.
INSA{3d_pr1nt3d_fl49}
Dashlame - Part 1 [Rev]
Can you try our new password manager ? There's a free flag in every password archive created !
This challenge contains a second part in the Crypto category.
> file dashlame.pyc dashlame.pyc: python 2.7 byte-compiled
アプローチ:uncompyle
バイトコンパイルされたPythonファイルが渡されるのでとりあえずuncompyle
します.
> uncompyle6 dashlame.pyc # uncompyle6 version 3.2.6 # Python bytecode 2.7 (62211) # Decompiled from: Python 2.7.15 |Anaconda, Inc.| (default, May 1 2018, 18:37:05) # [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] # Embedded file name: dashlame.py # Compiled at: 2019-04-17 06:56:53
from Crypto.Cipher import AES import os, random, sys, sqlite3, time, zlib HEADER = " /.m.\\\n /.mnnm.\\ ___\n |.mmnvvnm.\\. .,,,/`mmm.\\\n |.mmnnvvnm.\\:;,. ..,,;;;/.mmnnnmm.\\\n \\ mmnnnvvnm.\\::;;, .,;;;;;;;;/.mmmnnvvnnm.|\n \\`mmnnnvvnm.\\::;::.sSSs sSSs ,;;;;;;;;;;/.mmmnnvvvnnmm'/\n \\`mmnnnvnm.\\:::::SSSS,,,,,,SSSS:::::::;;;/.mmmnnvvvnnmmm'/\n \\`mnvvnm.\\::%%%;;;;;;;;;;;%%%%:::::;/.mnnvvvvnnmmmmm'/\n \\`mmmm.%%;;;;;%%%%%%%%%%%%%%%::/.mnnvvvnnmmmmm'/ '\n \\`%%;;;;%%%%s&&&&&&&&&s%%%%mmmnnnmmmmmm'/ '\n | `%;;;%%%%s&&.%%%%%%.%&&%mmmmmmmmmm'/ '\n\\ | / %;;%%%%&&.%;` '%.&&%%%////// '\n \\ | / %%%%%%s&.%% x %.&&%%%%%//%\n \\ .:::::. ,;%%%%s&&&&.%; ;.&&%%%%%%%%/,\n-!!!- ::#:::::%%%%%%s&&&&&&&&&&&&&&&&&%%%%%%%%%%%\n / :##:::::&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%,\n / | `:#:::&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%\n | `&&&&&&&&&,&&&&&&&&&&&&SS%%%%%%%%%%%%%\n `~~~~~'~~ SSSSSSS%%%%%%%%%%%%%\n SSSSSSSS%%%%%%%%%%%%%%\n SSSSSSSSSS%%%%%%%%%%%%%.\n SSSSSSSSSSSS%%%%%%%%%%%%%%\n SSSSSSSSSSSSS%%%%%%%%%%%%%%%.\n SSSSSSSSSSSSSSS%%%%%%%%%%%%%%%%\n SSSSSSSSSSSSSSSS%%%%%%%%%%%%%%%%%.\n SSSSSSSSSSSSSSSSS%%%%%%%%%%%%%%%%%%%\n SSSSSSSSSSSSSSSSSS%%%%%%%%%%%%%%%%%%%%.\n\n WELCOME TO DASHLAME\n" PEARSON_TABLE = [ 199, 229, 151, 178, 53, 6, 131, 42, 248, 110, 39, 28, 51, 216, 32, 14, 77, 34, 166, 213, 157, 150, 115, 197, 228, 221, 254, 172, 84, 27, 36, 156, 69, 96, 12, 220, 225, 137, 246, 141, 44, 208, 191, 109, 163, 21, 173, 250, 98, 227, 203, 162, 188, 3, 105, 171, 215, 15, 207, 218, 234, 56, 136, 235, 97, 79, 189, 102, 134, 11, 224, 117, 177, 222, 100, 129, 78, 18, 130, 187, 9, 184, 99, 108, 202, 13, 238, 17, 94, 70, 180, 144, 185, 168, 123, 71, 176, 91, 4, 153, 103, 242, 80, 127, 198, 82, 169, 148, 48, 120, 59, 55, 230, 209, 50, 73, 31, 49, 142, 149, 167, 249, 116, 1, 7, 86, 143, 101, 29, 52, 114, 154, 160, 128, 19, 170, 46, 214, 38, 67, 186, 252, 181, 145, 212, 183, 22, 231, 107, 43, 47, 122, 251, 217, 5, 62, 88, 244, 200, 93, 240, 219, 124, 58, 161, 89, 211, 158, 247, 60, 236, 65, 106, 113, 66, 81, 165, 194, 223, 40, 233, 126, 139, 72, 132, 61, 135, 57, 87, 182, 164, 35, 159, 118, 8, 83, 210, 243, 104, 76, 75, 119, 90, 138, 20, 206, 95, 16, 74, 33, 245, 237, 111, 64, 253, 125, 23, 232, 193, 37, 175, 92, 30, 241, 255, 133, 0, 140, 2, 155, 85, 10, 146, 179, 25, 26, 226, 201, 195, 121, 190, 63, 68, 152, 45, 147, 41, 204, 192, 205, 196, 54, 174, 239, 112, 24] def pad(s): mark = chr(16 - len(s) % 16) while len(s) % 16 != 15: s += chr(random.randint(0, 255)) return s + mark def unpad(s): return s[:-ord(s[-1])] def get_random_passphrase(): sys.stdout.write('Getting random data from atmospheric noise and mouse movements') sys.stdout.flush() for i in range(10): sys.stdout.write('.') sys.stdout.flush() time.sleep(random.randint(1, 20) / 10.0) print '' with open('wordlist.txt', 'rb') as (fi): passwords = fi.read().strip().split('\n') return (random.choice(passwords), random.choice(passwords)) def get_pearson_hash(passphrase): key, iv = ('', '') for i in range(32): h = (i + ord(passphrase[0])) % 256 for c in passphrase[1:]: h = PEARSON_TABLE[h ^ ord(c)] if i < 16: key += chr(h) else: iv += chr(h) return ( key, iv) def encrypt_stream(data, passphrase): key, iv = get_pearson_hash(passphrase) aes = AES.new(key, AES.MODE_CBC, iv) data = pad(data) return aes.encrypt(data) def decrypt_stream(data, passphrase): key, iv = get_pearson_hash(passphrase) aes = AES.new(key, AES.MODE_CBC, iv) data = unpad(aes.decrypt(data)) return data def encrypt_archive(archive_filename, passphraseA, passphraseB): with open(archive_filename, 'rb') as (db_fd): with open(archive_filename.replace('.db', '.dla'), 'wb') as (dla_fd): enc1 = encrypt_stream(db_fd.read(), passphraseA) enc2 = encrypt_stream(enc1, passphraseB) dla_fd.write(enc2) os.unlink(archive_filename) def decrypt_archive(archive_filename, passphraseA, passphraseB): with open(archive_filename, 'rb') as (dla_fd): with open(archive_filename.replace('.dla', '.db'), 'wb') as (db_fd): dec1 = decrypt_stream(dla_fd.read(), passphraseB) dec2 = decrypt_stream(dec1, passphraseA) db_fd.write(dec2) os.unlink(archive_filename) def createArchive(): archive_name = raw_input('Please enter your archive name: ') passphraseA, passphraseB = get_random_passphrase() print 'This is your passphrase :', passphraseA, passphraseB print 'Please remember it or you will lose all your passwords.' archive_filename = archive_name + '.db' with open(archive_filename, 'wb') as (db_fd): db_fd.write(zlib.decompress('x\x9c\x0b\x0e\xf4\xc9,IUH\xcb/\xcaM,Q0f`a`ddpPP````\x82b\x18`\x04b\x164>!\xc0\xc4\xa0\xfb\x8c\x9b\x17\xa4\x98y.\x03\x10\x8d\x82Q0\n\x88\x05\x89\x8c\xec\xe2\xf2\xf2\x8c\x8d\x82%\x89I9\xa9\x01\x89\xc5\xc5\xe5\xf9E)\xc5p\x06\x93s\x90\xabc\x88\xabB\x88\xa3\x93\x8f\xab\x02\\X\xa3<5\xa9\x18\x94\xabC\\#Bt\x14J\x8bS\x8b\xf2\x12sa\xdc\x02\xa820W\x13\x927\xcf0\x00\xd1(\x18\x05\xa3`\x08\x03#F\x16mYkh\xe6\x8fO\xadH\xcc-\xc8I\x85\xe5~O\xbf`\xc7\xea\x90\xcc\xe2\xf8\xa4\xd0\x92\xf8\xc4\xf8`\xe7"\x93\x92\xe4\x8cZ\x00\xa8&=\x8f')) encrypt_archive(archive_filename, passphraseA, passphraseB) print 'Archive created successfully.' def updateArchive(): archive_name = raw_input('Please enter your archive name: ') passphrase = raw_input('Please enter your passphrase: ') passphraseA, passphraseB = passphrase.split() website = raw_input('Website: ') username = raw_input('Username: ') password = raw_input('Password: ') dla_filename = archive_name + '.dla' db_filename = archive_name + '.db' decrypt_archive(dla_filename, passphraseA, passphraseB) conn = sqlite3.connect(db_filename) cur = conn.cursor() cur.execute('INSERT INTO Passwords VALUES(?,?,?)', (website, username, password)) conn.commit() conn.close() encrypt_archive(db_filename, passphraseA, passphraseB) print 'Update done.' def accessArchive(): archive_name = raw_input('Please enter your archive name: ') passphrase = raw_input('Please enter your passphrase: ') passphraseA, passphraseB = passphrase.split() website = raw_input('Website: ') dla_filename = archive_name + '.dla' db_filename = archive_name + '.db' decrypt_archive(dla_filename, passphraseA, passphraseB) conn = sqlite3.connect(db_filename) cur = conn.cursor() cur.execute('SELECT Username, Password FROM Passwords WHERE Website=?', (website,)) results = cur.fetchall() conn.close() encrypt_archive(db_filename, passphraseA, passphraseB) if len(results) == 0: print 'No results.' else: for result in results: print result[0], ':', result[1] if __name__ == '__main__': print HEADER print '1. Create a new password archive' print '2. Add a password to an archive' print '3. Access a password from an existing archive' try: res = raw_input() if res == '1': createArchive() else: if res == '2': updateArchive() else: if res == '3': accessArchive() else: print 'Wrong choice' except: print 'Error.'
ぱっと見dbファイル作成してあれこれしてっるぽいですね.
パスワードアーカイブ作成
> python dashlame.py /.m.\ /.mnnm.\ ___ |.mmnvvnm.\. .,,,/`mmm.\ |.mmnnvvnm.\:;,. ..,,;;;/.mmnnnmm.\ \ mmnnnvvnm.\::;;, .,;;;;;;;;/.mmmnnvvnnm.| \`mmnnnvvnm.\::;::.sSSs sSSs ,;;;;;;;;;;/.mmmnnvvvnnmm'/ \`mmnnnvnm.\:::::SSSS,,,,,,SSSS:::::::;;;/.mmmnnvvvnnmmm'/ \`mnvvnm.\::%%%;;;;;;;;;;;%%%%:::::;/.mnnvvvvnnmmmmm'/ \`mmmm.%%;;;;;%%%%%%%%%%%%%%%::/.mnnvvvnnmmmmm'/ ' \`%%;;;;%%%%s&&&&&&&&&s%%%%mmmnnnmmmmmm'/ ' | `%;;;%%%%s&&.%%%%%%.%&&%mmmmmmmmmm'/ ' \ | / %;;%%%%&&.%;` '%.&&%%%////// ' \ | / %%%%%%s&.%% x %.&&%%%%%//% \ .:::::. ,;%%%%s&&&&.%; ;.&&%%%%%%%%/, -!!!- ::#:::::%%%%%%s&&&&&&&&&&&&&&&&&%%%%%%%%%%% / :##:::::&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%, / | `:#:::&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%% | `&&&&&&&&&,&&&&&&&&&&&&SS%%%%%%%%%%%%% `~~~~~'~~ SSSSSSS%%%%%%%%%%%%% SSSSSSSS%%%%%%%%%%%%%% SSSSSSSSSS%%%%%%%%%%%%%. SSSSSSSSSSSS%%%%%%%%%%%%%% SSSSSSSSSSSSS%%%%%%%%%%%%%%%. SSSSSSSSSSSSSSS%%%%%%%%%%%%%%%% SSSSSSSSSSSSSSSS%%%%%%%%%%%%%%%%%. SSSSSSSSSSSSSSSSS%%%%%%%%%%%%%%%%%%% SSSSSSSSSSSSSSSSSS%%%%%%%%%%%%%%%%%%%%. WELCOME TO DASHLAME 1. Create a new password archive 2. Add a password to an archive 3. Access a password from an existing archive 1 Please enter your archive name: cawayui Getting random data from atmospheric noise and mouse movements.......... This is your passphrase : sabally discombobulation Please remember it or you will lose all your passwords. Archive created successfully.
パスワード追加
[snip] 1. Create a new password archive 2. Add a password to an archive 3. Access a password from an existing archive 2 Please enter your archive name: cawayui Please enter your passphrase: sabally discombobulation Website: satto.hatenadiary.com Username: satto1237 Password: pass Update done.
パスワード確認
[snip] 1. Create a new password archive 2. Add a password to an archive 3. Access a password from an existing archive 3 Please enter your archive name: cawayui Please enter your passphrase: sabally discombobulation Website: satto.hatenadiary.com satto1237 : pass
生成ファイル確認
> file cawayui.dla cawayui.dla: data
> head cawayui.dla IZ���]6���)��9-ei�l�00���ײZ��A\�L� eKFp�1�G&z]�S�0��9�� >D�����OFK��` ��O��0{�� �{��̵�_FZ �ןy�|g�� {>�z�A������}yX����>�%oH�"�f7�y�i�^�0"M��AF�=�ʋT�dA�&W|?�w�������R��:{Y,�H� �xM�j� ����S\�0����/(�D��'���� 9��?]#���Ṳ���1 Q��OI��ퟳ �e���8R�A���y�*��q�-A������i�#zѕp!e��/]gv��U�t�5��7�#�RXD ���B�#�J�m�&�߯��30M�x���o�B+��(�"S�Ow�K�� Q"~� �^1��%"1N�[�MR�+q̏Fm"��.�GbY�� NN}S������b��$|����)`�R�B��<��#���{��j�d���?>�H��)q-�x���Eԩ !��i��s�A>i������n�l?�U�#�0�g Tէ�v{O��y�|χ+�ƒ&[�_�;�.!җ��o'��[�%���:$ 2UfjW�j�4{�qjƥB���.�{aj���]?.���;g$W�d���ūm���;wM�BY����]C��ޖ Ns�)[�I�y-r(��f�U�o I4ٱ*ݢ(&à-N�E�^0���,���|ť������~Ae8X�:y���"沬��B{�k�Ka%�I��� �����^ٱux� ��?���[�љ���[�]�� ^(���UÒ�,:�����o��⪻�B�R�7�õXM]r5�P��O�Q����]��z���L2��O�����-B��� �N��W;a� �P���f��L��FkYU�Xt�T���,������j��ς8G!�?�mvW��Ȩ�w���.���|����`y5�&� S�{�1o����+ũ]/nڎ� �
ソースコードを読む限り新しいアーカイブを作成するときに謎データを書き込んでいるのでAdd
したユーザとパスワード以外にもユーザデータが存在すると考えられます.
また,accessArchive
内でデータを読み出した後(decrypt_archive
した後)にencrypt_archive
しているためこの処理をコメントアウトすることでdecryptされたdbファイルにアクセスできるようになることが分かります.
> sqlite3 sqlite> .open cawayui.db sqlite> .tables Passwords sqlite> .schema CREATE TABLE Passwords(website TEXT, username TEXT, password TEXT); sqlite> SELECT * FROM Passwords; website_example|username|INSA{Tis_bUt_a_SCr4tch} satto.hatenadiary.com|satto1237|pass
INSA{Tis_bUt_a_SCr4tch}
intergover [Pwn]
I hope you know how integers are stored.
ssh -i <your_keyfile> -p 2223 user@intergover.ctf.insecurity-insa.fr To find your keyfile, look into your profile on this website.
> ssh -i ~/.ssh/id_inshack -p 2223 user@intergover.ctf.insecurity-insa.fr ___ _ _ _ ____ ___ _ ___ |_ _|_ __ ___| | | | __ _ ___| | __ |___ \ / _ \/ |/ _ \ | || '_ \/ __| |_| |/ _` |/ __| |/ / __) | | | | | (_) | | || | | \__ \ _ | (_| | (__| < / __/| |_| | |\__, | |___|_| |_|___/_| |_|\__,_|\___|_|\_\ |_____|\___/|_| /_/ =========================================================== You are accessing a sandbox challenge over SSH This sandbox will be killed soon enough. Please wait while we launch your sandbox... =========================================================== Give me one param: 1127 No, I can't give you the flag: 1127
アプローチ:読む
与えられたバイナリファイルをida
で開くと242をパラメータとして与えればいいことが分かります.
[snip] Give me one param: 242 INSA{B3_v3rY_c4r3fUL_w1tH_uR_1nt3g3r_bR0}
INSA{B3_v3rY_c4r3fUL_w1tH_uR_1nt3g3r_bR0}
signed or not signed [Pwn]
Signed or not signed, this is the question :) ssh -i <your_keyfile> -p 2228 user@signed-or-not-signed.ctf.insecurity-insa.fr To find your keyfile, look into your profile on this website.
アプローチ:unsigned
> ssh -i ~/.ssh/id_inshack -p 2228 user@signed-or-not-signed.ctf.insecurity-insa.fr - ___ _ _ _ ____ ___ _ ___ |_ _|_ __ ___| | | | __ _ ___| | __ |___ \ / _ \/ |/ _ \ | || '_ \/ __| |_| |/ _` |/ __| |/ / __) | | | | | (_) | | || | | \__ \ _ | (_| | (__| < / __/| |_| | |\__, | |___|_| |_|___/_| |_|\__,_|\___|_|\_\ |_____|\___/|_| /_/ =========================================================== You are accessing a sandbox challenge over SSH This sandbox will be killed soon enough. Please wait while we launch your sandbox... =========================================================== Please give me a number: 1127 Bro, it's really too big.
とりあえず与えられたバイナリファイルをida
で開きます.
10以下かつ64870である数値を入力しなければいけませんがunsigned
であることを利用すればいけます.
[snip] Please give me a number:-666 INSA{Th3_qU3sTi0n_1s_S1gN3d_0r_x90} Connection to signed-or-not-signed.ctf.insecurity-insa.fr closed.
INSA{Th3_qU3sTi0n_1s_S1gN3d_0r_x90}
Yet Another RSA Challenge - Part 1 [Crypto]
Buy an encrypted flag, get a (almost intact) prime factor for free !
You can find a harder version of this challenge in the Programming category.
import subprocess p = subprocess.check_output('openssl prime -generate -bits 2048 -hex') q = subprocess.check_output('openssl prime -generate -bits 2048 -hex') flag = int('INSA{REDACTED}'.encode('hex'), 16) N = int(p,16) * int(q,16) print N print '0x'+p.replace('9F','FC') print pow(flag,65537,N)
719579745653303119025873098043848913976880838286635817351790189702008424828505522253331968992725441130409959387942238566082746772468987336980704680915524591881919460709921709513741059003955050088052599067720107149755856317364317707629467090624585752920523062378696431510814381603360130752588995217840721808871896469275562085215852034302374902524921137398710508865248881286824902780186249148613287250056380811479959269915786545911048030947364841177976623684660771594747297272818410589981294227084173316280447729440036251406684111603371364957690353449585185893322538541593242187738587675489180722498945337715511212885934126635221601469699184812336984707723198731876940991485904637481371763302337637617744175461566445514603405016576604569057507997291470369704260553992902776099599438704680775883984720946337235834374667842758010444010254965664863296455406931885650448386682827401907759661117637294838753325610213809162253020362015045242003388829769019579522792182295457962911430276020610658073659629786668639126004851910536565721128484604554703970965744790413684836096724064390486888113608024265771815004188203124405817878645103282802994701531113849607969243815078720289912255827700390198089699808626116357304202660642601149742427766381 0xDCC5A0BD3A1FC0BEB0DA1C2E8CF6B474481B7C12849B76E03C4C946724DB577D2825D6AA193DB559BC9DBABE1DDE8B5E7805E48749EF002F622F7CDBD7853B200E2A027E87E331AFCFD066ED9900F1E5F5E5196A451A6F9E329EB889D773F08E5FBF45AACB818FD186DD74626180294DCC31805A88D1B71DE5BFEF3ED01F12678D906A833A78EDCE9BDAF22BBE45C0BFB7A82AFE42C1C3B8581C83BF43DFE31BFD81527E507686956458905CC9A660604552A060109DC81D01F229A264AB67C6D7168721AB36DE769CEAFB97F238050193EC942078DDF5329A387F46253A4411A9C8BB71F9AEB11AC9623E41C14FCD2739D76E69283E57DDB11FC531B4611EE3 596380963583874022971492302071822444225514552231574984926542429117396590795270181084030717066220888052607057994262255729890598322976783889090993129161030148064314476199052180347747135088933481343974996843632511300255010825580875930722684714290535684951679115573751200980708359500292172387447570080875531002842462002727646367063816531958020271149645805755077133231395881833164790825731218786554806777097126212126561056170733032553159740167058242065879953688453169613384659653035659118823444582576657499974059388261153064772228570460351169216103620379299362366574826080703907036316546232196313193923841110510170689800892941998845140534954264505413254429240789223724066502818922164419890197058252325607667959185100118251170368909192832882776642565026481260424714348087206462283972676596101498123547647078981435969530082351104111747783346230914935599764345176602456069568419879060577771404946743580809330315332836749661503035076868102720709045692483171306425207758972682717326821412843569770615848397477633761506670219845039890098105484693890695897858251238713238301401843678654564558196040100908796513657968507381392735855990706254646471937809011610992016368630851454275478216664521360246605400986428230407975530880206404171034278692756
アプローチ:全探索
配布されたプログラムを確認すると素数p
の9F
をFC
に置換していることが分かります.
置換後のp
のFC
の出現数は4なので元々FC
だった場合も考慮し計算すると置換前のパターン数は16になることが分かります.
あとは全探索して正規のp
を見つければ終わりです.
以下が頭ガバガバソルバです.
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from Crypto.Util.number import * str_p = 'DCC5A0BD3A1FC0BEB0DA1C2E8CF6B474481B7C12849B76E03C4C946724DB577D2825D6AA193DB559BC9DBABE1DDE8B5E7805E48749EF002F622F7CDBD7853B200E2A027E87E331AFCFD066ED9900F1E5F5E5196A451A6F9E329EB889D773F08E5FBF45AACB818FD186DD74626180294DCC31805A88D1B71DE5BFEF3ED01F12678D906A833A78EDCE9BDAF22BBE45C0BFB7A82AFE42C1C3B8581C83BF43DFE31BFD81527E507686956458905CC9A660604552A060109DC81D01F229A264AB67C6D7168721AB36DE769CEAFB97F238050193EC942078DDF5329A387F46253A4411A9C8BB71F9AEB11AC9623E41C14FCD2739D76E69283E57DDB11FC531B4611EE3' n = 719579745653303119025873098043848913976880838286635817351790189702008424828505522253331968992725441130409959387942238566082746772468987336980704680915524591881919460709921709513741059003955050088052599067720107149755856317364317707629467090624585752920523062378696431510814381603360130752588995217840721808871896469275562085215852034302374902524921137398710508865248881286824902780186249148613287250056380811479959269915786545911048030947364841177976623684660771594747297272818410589981294227084173316280447729440036251406684111603371364957690353449585185893322538541593242187738587675489180722498945337715511212885934126635221601469699184812336984707723198731876940991485904637481371763302337637617744175461566445514603405016576604569057507997291470369704260553992902776099599438704680775883984720946337235834374667842758010444010254965664863296455406931885650448386682827401907759661117637294838753325610213809162253020362015045242003388829769019579522792182295457962911430276020610658073659629786668639126004851910536565721128484604554703970965744790413684836096724064390486888113608024265771815004188203124405817878645103282802994701531113849607969243815078720289912255827700390198089699808626116357304202660642601149742427766381 e = 65537 c = 596380963583874022971492302071822444225514552231574984926542429117396590795270181084030717066220888052607057994262255729890598322976783889090993129161030148064314476199052180347747135088933481343974996843632511300255010825580875930722684714290535684951679115573751200980708359500292172387447570080875531002842462002727646367063816531958020271149645805755077133231395881833164790825731218786554806777097126212126561056170733032553159740167058242065879953688453169613384659653035659118823444582576657499974059388261153064772228570460351169216103620379299362366574826080703907036316546232196313193923841110510170689800892941998845140534954264505413254429240789223724066502818922164419890197058252325607667959185100118251170368909192832882776642565026481260424714348087206462283972676596101498123547647078981435969530082351104111747783346230914935599764345176602456069568419879060577771404946743580809330315332836749661503035076868102720709045692483171306425207758972682717326821412843569770615848397477633761506670219845039890098105484693890695897858251238713238301401843678654564558196040100908796513657968507381392735855990706254646471937809011610992016368630851454275478216664521360246605400986428230407975530880206404171034278692756 index = [11, 143, 475, 499] def searchP(s, d): if d == 4: p = int(s,16) if n % p == 0: print(p) else: searchP(s[:index[d]] + 'FC' + s[index[d]+2:], d + 1) searchP(s[:index[d]] + '9F' + s[index[d]+2:], d + 1) def solve(): p = 27869881035956015184979178092922248885674897320108269064145135676677416930908750101386898785101159450077433625380803555071301130739332256486285289470097290409044426739584302074834857801721989648648799253740641480496433764509396039330395579654527851232078667173592401475356727873045602595552393666889257027478385213547302885118341490346766830846876201911076530008127691612594913799272782226366932754058372641521481522494577124999360890113778202218378165756595787931498460866236502220175258385407478826827807650036729385244897815805427164434537088709092238894902485613707990645011133078730017425033369999448757627854563 q = n // p phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) print(long_to_bytes(m)) if __name__ == '__main__': searchP(str_p, 0) solve()
27869881035956015184979178092922248885674897320108269064145135676677416930908750101386898785101159450077433625380803555071301130739332256486285289470097290409044426739584302074834857801721989648648799253740641480496433764509396039330395579654527851232078667173592401475356727873045602595552393666889257027478385213547302885118341490346766830846876201911076530008127691612594913799272782226366932754058372641521481522494577124999360890113778202218378165756595787931498460866236502220175258385407478826827807650036729385244897815805427164434537088709092238894902485613707990645011133078730017425033369999448757627854563 b'INSA{I_w1ll_us3_OTp_n3xT_T1M3}'
INSA{I_w1ll_us3_OTp_n3xT_T1M3}
まとめ
- また簡単な問題しかとけなかった
- べんきょうする