Pragyan CTF 2017 Writeup

この大会は2017/3/2 16:30(JST)~2017/3/5 16:30(JST)に開催されました。
今回もチームで参戦。結果は910点で525チーム中61位でした。
自分で解けた問題をWriteupとして書いておきます。

Game starts here (Miscellaneous 10)

フラグの書き方のサンプルがそのまま答え。

pragyanctf{HelloWorld}

Look Harder (Forensics 50)

うっすらQRコードが見える。QRコードリーダで読み取ると、以下の文字列だった。

stay_pragyaned
pragyanctf{stay_pragyaned}

Interstellar (Forensics 150)

StegSolveで開き、XORにすると、フラグが見えた。
f:id:satou-y:20170309222613p:plain

pragyanctf{Cooper_Brand}

Star Wars (Steganography 100)

JPEGファイルの末尾「FF D9」の後ろに以下の文字列がある。
100110101010101010111010100110101010101110101010011110

点字と考えて縦に3行×2列で区切り文字に置き換えていくとdoordonotになるが、pragyanctf{doordonot}はフラグではなかった。

steghideを使い、パスフレーズとして、doordonotを指定する。

$ steghide extract -sf star-wars.jpg 
Enter passphrase: 
wrote extracted data to "flag.txt".

すると、flag.txtを取り出せた。

$ cat flag.txt
YmVjb21lYWplZGltYXN0ZXJ5b3V3aWxs
$ cat flag.txt | base64 -d
becomeajedimasteryouwill
pragyanctf{becomeajedimasteryouwill}

Xiomara CTF 2017 Writeup

この大会は2017/2/25 23:30(JST)~2017/2/27 23:30(JST)に開催されました。
今回もチームで参戦。結果は401点で334チーム中71位でした。
自分で解けた問題をWriteupとして書いておきます。

Xiomara (Joy 1)

問題はxiomara{md5sum_of_xiomara}。

$ echo -n xiomara | md5sum
ca0d5a691beb274bb736f14cb4a8eaac  -
xiomara{ca0d5a691beb274bb736f14cb4a8eaac}

Easy Login (Web Exploitation 50)

main.jsに条件が書いてある。

function Login(){
	
	var username=document.login.username.value;
	var password=document.login.password.value;
         
       
    
	
	if (password == "53cure" && username=="@nokh@") {
	    alert("Awesome!");
             window.open("secureflag.html");
	} else { 
	    alert("Oh swap!You are close. Why cant you try again?");
              
	}
}

ログインしたページのhiddenflag.jpegの末尾にフラグが入っている。

xiomara{50_y0u_ar3_@_h@ck3r}

No Flags? (Web Exploitation 50)

http://139.59.61.220:23467/robots.txt にアクセスすると、以下のように表示される。

User-agent:*
Disallow: /flags/
Disallow: /more_flags/
Disallow: /more_and_more_flags/
Disallow: /no_flag/

http://139.59.61.220:23467/no_flag/ のソースを見る。

<script>
function encode(str) {
str = str.replace(/http:/g, "^^^");
str = str.replace(/bin/g, "*^$#!")
str= str.replace(/com/g, "*%=_()");
str= str.replace(/paste/g, "~~@;;");
}
</script>
<iframe src="flag.txt" width="2500" height="2255">
</iframe>

文字列置換が行われているようなので、flag.txtを落としてきて、文字列を戻してやる。すると、以下のURLが埋め込まれていた。

http://pastebin.com/SwzEKazp

アクセスしても、削除済みのようなメッセージがあり、他に何もない。
https://archive.org/で、2/25時点の上記のURLのページを見てみると、以下のBase64文字列が書かれていた。

eGlvbWFyYXsxXzRtX21yX3IwYjA3fQ==
$ echo eGlvbWFyYXsxXzRtX21yX3IwYjA3fQ== | base64 -d
xiomara{1_4m_mr_r0b07}
xiomara{1_4m_mr_r0b07}

(not) Guilty Boyfriend (Forensics/Network 100)

FTK Imagerで開くと、[root]-lulz_secにflag.pngがある。この画像ファイルをStegosolveで開き、Green plane 0にすると、フラグが見える。
f:id:satou-y:20170306232221p:plain

xiomara{i_am_a_lord_of_hacker}

Boston Key Party CTF 2017 Writeup

この大会は2017/2/25 10:00(JST)~2017/2/27 10:00(JST)に開催されました。
今回もチームで参戦。結果は401点で948チーム中120位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity Check (cloud 1)

問題はrubyのコード。

ruby -e 'puts ("bkp{flaglol}").gsub("flaglol", "welcome_to_2017")'

実行した結果がフラグ。

bkp{welcome_to_2017}

RSA Buffet (crypto 150)

平文の生成と、暗号化のスクリプト、10個の公開鍵と5個の暗号文が添付されている。まず10個全部の公開鍵を見てみる。

$ openssl rsa -pubin -in key-0.pem -text -noout
Public-Key: (4096 bit)
Modulus:
    00:d7:af:32:b0:93:d6:e2:24:bb:96:3a:9a:7b:c8:
    73:b2:e7:7c:6a:ce:76:3e:7d:6c:6d:d7:d1:d1:11:
    82:85:2f:68:4b:50:3d:d7:2e:76:94:fd:ec:46:68:
    af:bf:6f:90:c4:af:46:62:ab:ee:1c:3a:33:c5:0e:
    c5:c5:2a:8c:0a:9a:af:4d:0f:31:61:eb:b4:ee:76:
    22:a2:2f:f1:fb:67:b9:30:23:d4:94:31:30:6f:fc:
    01:40:19:1b:10:77:b1:14:cc:a8:84:db:4c:cd:d8:
    d1:f7:bb:13:1e:f3:21:b4:90:70:03:54:81:61:92:
    1d:29:3a:42:63:18:97:08:ba:07:55:45:2a:66:a6:
    dc:91:61:88:b2:63:01:05:36:fd:23:9e:be:da:8d:
    87:7a:66:dd:84:cb:43:1f:5a:62:ab:90:8b:66:b4:
    e6:4d:3e:57:bf:ba:33:8e:13:b0:37:7c:03:03:d6:
    38:60:75:58:64:78:5a:1c:8f:4b:5f:b4:7c:6f:c4:
    f2:a9:fd:85:30:73:23:07:33:c6:8b:75:4b:2b:48:
    01:07:02:73:33:03:9b:b1:d8:49:13:13:7e:6d:fa:
    47:3e:92:d4:b2:4a:f5:7e:73:0a:4a:34:f6:e0:1a:
    41:6f:94:a8:35:5c:cf:46:95:4c:d2:6d:25:03:bc:
    ea:20:90:3e:cd:77:a0:1f:26:84:cf:1d:7c:71:24:
    b4:5d:ef:ab:d6:c2:b4:7f:26:dc:14:28:12:c8:35:
    73:c4:12:81:3f:01:68:04:e2:c1:2f:31:ca:43:3d:
    ed:d4:76:34:bb:e3:e4:93:5d:76:2a:b6:e5:9e:72:
    ea:09:32:ff:75:f1:88:07:a8:b1:7a:2f:68:81:76:
    3c:f3:02:8b:9e:15:a5:11:4c:06:81:7f:b0:76:e0:
    5f:4d:41:fa:52:b9:db:79:59:9f:f4:07:a1:85:6b:
    4e:b4:73:8f:1c:ed:34:0a:44:07:07:29:c2:a5:6a:
    d7:3b:61:24:3b:6c:a9:96:a2:0d:50:54:8d:fc:b1:
    1d:75:06:89:ae:93:47:13:31:fe:68:c2:29:22:68:
    7f:16:c4:83:08:d3:ad:74:e8:c9:bf:f8:c1:74:4c:
    06:74:d2:03:a5:6c:09:9d:7b:ee:8e:f9:4d:92:d9:
    b4:ec:3d:1e:91:97:a0:ac:49:25:75:45:fc:09:e1:
    ed:73:9d:6a:10:ad:da:08:2e:5b:18:f7:ea:a8:3e:
    78:6e:e9:ad:85:86:07:0e:a6:5d:b4:f9:b5:ab:b9:
    39:4d:a3:2f:b7:4d:68:c8:d4:a6:4e:f5:c4:a1:2c:
    c2:9d:61:22:64:e7:3d:25:9a:3f:d6:88:c5:56:75:
    58:be:a9
Exponent: 65537 (0x10001)

key-1.pem ~ key-9.pemも同様に見てみると、n0~n9、e3の値は以下の通り。他のeは65537。

n0 = 0x00d7af32b093d6e224bb963a9a7bc873b2e77c6ace763e7d6c6dd7d1d11182852f684b503dd72e7694fdec4668afbf6f90c4af4662abee1c3a33c50ec5c52a8c0a9aaf4d0f3161ebb4ee7622a22ff1fb67b93023d49431306ffc0140191b1077b114cca884db4ccdd8d1f7bb131ef321b4907003548161921d293a4263189708ba0755452a66a6dc916188b263010536fd239ebeda8d877a66dd84cb431f5a62ab908b66b4e64d3e57bfba338e13b0377c0303d63860755864785a1c8f4b5fb47c6fc4f2a9fd853073230733c68b754b2b480107027333039bb1d84913137e6dfa473e92d4b24af57e730a4a34f6e01a416f94a8355ccf46954cd26d2503bcea20903ecd77a01f2684cf1d7c7124b45defabd6c2b47f26dc142812c83573c412813f016804e2c12f31ca433dedd47634bbe3e4935d762ab6e59e72ea0932ff75f18807a8b17a2f6881763cf3028b9e15a5114c06817fb076e05f4d41fa52b9db79599ff407a1856b4eb4738f1ced340a44070729c2a56ad73b61243b6ca996a20d50548dfcb11d750689ae93471331fe68c22922687f16c48308d3ad74e8c9bff8c1744c0674d203a56c099d7bee8ef94d92d9b4ec3d1e9197a0ac49257545fc09e1ed739d6a10adda082e5b18f7eaa83e786ee9ad8586070ea65db4f9b5abb9394da32fb74d68c8d4a64ef5c4a12cc29d612264e73d259a3fd688c5567558bea9

n1 = 0x00c4ff486b14cd9c37b956f08ff19ca2f83dba86509cb840cd6a5a95f1352009b18d1d56b4a0fec0e95a29ca96caefaa5deff71d6aeb0ad89eeaad908cee93582bd71b2cd7daf709a54b98d163b508d3fd1f0a9709fb69e499d1b8abc50af3a4cbae77c070444933613a452954f91acdaf461d6a364035920561f7885d30ebdc82be3560e6428864b9715e1734d013e23dfb8c1da662f5ce6da3712402f8da445d0ca49b9bb1e47abeeef58a6385ca3f9eb9d24008b6e68e1de7c2f12fea14f7729c248d8db7d9b85e6279ab68b0517f739d9745ba02f8aabc33819c326116c327396b5716c6895495ae8d3cf60a3b6a11557329383f6d5f414d9e05e87e13d5d7cbf87994c86f1419a8fc969500e36d8570fbe1bc13df8bfe3888209b0bd684b9265bf7f4e05cf670d8f288e1d82740e9812f9aa68a99b5e569420b38cc1538787ead253df53341e3c2697ce76152b02ed437cce19386e2a13608bfb7b23336356f032c550f1fbc4f8ee00294cbecb03ece45dfc5f5c115d73adc988ba297104c81351bb73c2ac01d3acfc5a814c4947b5758b0193222102c1541f398d2d7b1c2cfdd53a172aa899880f53a8b5c7e6a39e6e408141df99ae2f6befc00b02e2ac4c3af122be5097f3231c5b4e607bca2a78c1f1040aa3c4351de4b3172e3882c116e5f586de33cee9c911875ac196efb8355d4cddfe5479b19fa426a25e0ea1891

n2 = 0x0086986548c02b2d6b0461a74a09a5ee4efa07882d5c610bdb14d1ba3044effd5570e4c509d116aca992a342cf52ed0463db6d4648a3013ba8219c3a72b1998796253dd11ecc536087e6e5bd207c1387af9df6bf875ab319556dcc0bad6a90f017459760ee7d274fe6046e7599385f7607d29ed235477695e3365fc6b9f5270183e9c4c2c118aa676c1d9cbe06864507e4310d85b8cacff9f5a3eed487b71d2d75b00943d7eda9aaf5b2bb69271625de2469d6a7c4f50c4eeac54b1605793cc0f7fe9167452ff5fef3647c9eec8866730732c05dca4c56f393ca2e61e7d76442822b9da56d96f67bba9f6095f761d0f2a3de62ea8c6fc7ac2fa7b727684947f7640711b700f40a1799d0265eefe94952b50e5e10b15bec14cc1664714c6c1ff1c16454f4a912ec19760d80c4759ff3130da43b13e7967d5cea526402cf2b566653c0cd5d7d0995357661c0308cbd11aaeb832ca9093dc3981d1fb6b62fd98a883e8d4c1548521c3e2f0bef76c7220d8093c2bdb1ae017f2e48d0defe42ce5713955ae294bec2b5da9b81cf9bb1d8ca5e5dcc9bf930edb7a3f6d2d350d2aa478e01070dbc151d6f9f6dba473ec001432de4e2ced4611955f294b3d48631dd51eb7c50a97f5165731d597129d3335f4c994234d89095335c705f075a1ba08a0f5cf383d65cd424524a48a415ce2ca5a34b4287e4efacb243e68b9c90a3679bef2757

n3 = 0x00994a5e2c2303b40943d9b744b5709ee601fb5c4ac300cfa44a7608107a74d06ac04963a3f8201fa7801335edd3f323090425924b74f6ac39eeaff7b4a6bcaa241533fd5f57505b388668f24d8d65330745cc515ee1b3c96016b399c35eefef0612baff82761088117b07e25f9263f914981023319165d209c4784bc37a92ed7fecb470317b3fde5343cdd9aa13794b74831892cf6ea1002d7a3f760f1bb3edfbf6273b15361127424f1712892e0c6cc759b3c690da8c6184a90be6486b8f25c745554c0aaa445764589a5177038a67cd73e66fe1b0d559e0bbbe3e5b8d4aeef72ffa874cc16110bbc135c3e9928c5fcae737815f49fb023c64eda62ad2ed7d0d32249617dc512dc540006c0f059b2fdaeb3b0ae1c2b9615db7c83b909e222719451736e1f07c3919c3965fd9d003bd8813ec1e9cd540faf7f70f72fe8f0f544b2cab51a8a062865ae4f46a0530b7e11a264d717f3cf13b6018d09de1a0c28ea20cee2a6711da5d115fd71c096d115c13f0b5e40d94696c67105c2f709ae5d2fe0ac85847b3c9017ace7db2eb00d410d9d2da7685776a8099472d01791c57810d160abd6c9e420276320eb11b80a0b2f5722e20e9d8822a1d143c97a63ef81733e52f263e3a7f77b6900bf95da215544df51e61ecc468f037a2b39ccf153d984b32a9a4ce757bbb38798ce0b080f503ce1a396d47e14cc41bf18e34edbd9137eb

n4 = 0x00a9dffbcdf808e4a5120b876d4be077cef21b6ef3bbccdae77b6afc988ea068cad52c6e7d1797049394caaee701e916b3d192c6fc8f8ab2c8a0bcdc75cfb1c436a914c128046b889aeb5f1c89852856cad179a0958a4aeb87ba778ea62187ad1931d5bdcf85d57361fd2941a076ea9b3652110287755e663e679892b4ff0519042b0b3a85aa99f623a1037d503b245cf3205c3c5b24139b3abf0881fbc1b0f7e03444149f69427fd78cdbc75b634a5160e9b2aadbfd9cfd6150ab0ace72dd1d95e1d884153cbe9dd62458745a0fe95014e89f263a9730ff2205b108e3985bb9da9a1b68b4ae1d52cec2b3a5320e02392e9e8b802d190de6e4f75388c3fafdb2ba58904eceaa613c3d67d81ede381a0f15a2822bd1a5a1854df38aea7d32e6cf8c38d8d6a8daf384befc5ee06c9be1a4b2216b690b28dfaaebd9d47b3d96fddd96114dc6df9b1eb21343098ef9e6540fbac0c19a63cdaf6e4528ae41d212e50dab72ff4529b042ec22dd8d61166d29548559ed7de469391781444baee28f3ecbed79169a7134da785d476533ace2ffe3aee5b9501549a8061ad50b352d01735dfb4ca7d4d0bf759c9dbcbb1ba4793a30238f959ad033b5691920b3e2fc793fe154ee9f6ebc5d64744b518a41e26803d11f1fda6d223904c26054b4c685e3640da0e1f4da6445b55757ac7e4e18c938168c1d8c64f31eb11e4aaa09d0c94fca9973

n5 = 0x0088ef837570c4161f5ef7d6e65deafb9840cffae5f3377d7b2c4fa8ee99286fda86d1dd77aec9a7d9751328c0d0db4481f8a108b4d844262ea1fb8bf02aa44dba0f9c02baf186bac37e02314c48277803b088c2921076b155c4882cf4c2397796959edf22af6a2ff769ca4668f370eea104ac006df3fead69e1b7c00b8d4ea0b8e99f904c7b66fad4cea031091b66a21373c0cc64d2151d8274f128d183a7f3d697965f1590f3f2656259fda9be417510949dab2163c5f450d662a899fcaa31344ad0decd558fa3e9f9247a23fe451c8f846acad19360e66720909f405064f576b6c925a081d4865f7bc861d51101c33d695656b33d164e38948234db1cdc0fbf8608aff64f67ddbaf3e3ead882d8ab69916dd6b922cec62f3d53567b0e644f990add24b22d3021178da47355bdf1714ce142f98d03daf7b525d0c6aebf42f2f5e9352584ba503f1771bf5b2ed7f77023c3c82e8aefc79d3c22d177b3f6e3d5e399f586b4041cba5e4cd66e30fe9666df9fc6216f2ba1d0ff002fa1d6f1ca787a3130a6a5ca929fa737c8fcd86c753709bc23f54eddd6c1fc6d121932e900f4be24200329432bacf3aa8e6fc9e87a226457dfe24745fc7c969390f992f999ea4920cfccc4c47c06b9aebabab4c91f14d8ff85e27576f0a027ca70093c185c008b27e8243121551e4705fd46c3561485abf2fbaa0fc28a87871fe2e3f5afa30527

n6 = 0x00bc0d4dd9ed44c44c2173abd3b025401b366816d913f7b4271b71abcded21ab0d04c2fc577a313b794275845dbb89e8151cf4bd3825e9240c88eb93a824caa8b0b563960ffcb12fbcafcd9d38fbdf87b134395d0ea316186beaf2470a535a1da3529c005cb9062f0d43eb8e7bf4cd79425a6cab65a15c905713abcedbf4a715c46465becbba9ed60fd77bf82f035d8a394c56f13898834b277c6749261a9c95b22574c1f7781550345588cf2ff1d22eaeb1137aee4d41f6e288759844a4eb8e8cbdfaea1776d3c45e7551c9924317d0efe36a686afb3ac8a12ab809a3deee27d7f69f26b70b97cd1ed51426e489e804881dcae802fba751c3f83b6983cfcb4c30c966ca92e7bf08874b2848e098f021f183ae839be30191e3bcd2ce38325e3991c6e733bf00cf3f60aaef2b7ebd0554fb0c980a6f62db59974e7f3ce46afb24e43e107ec8d1cc0e772f997ff0c5a602fa8bcd0cbbf78cc2d1a84903a3cc00b397858c02c28f7c0707e66d6dc0de2ce747d99dc4038bdd924cf3c534bcec6dcf3d4f0247e30875f39af7ab0fda69fca12d7104c51bf6d66aff2d12338ffbf51e243ade078de6cc1930f872c3ad91d8f822668e56d352c0156e513033ea20c0f163d558b69119734684f98cf789df72f8c534d008a535c9dafebe8774140adc0c53eeb021852ec282b7bddce58c9ffb87a7b4f20b91bfd04ed84ea6566bc397f1d9

n7 = 0x00b7d5a8ccd362a3f4691641ee9176e4d025159ad60a427a7e21343acea9ef3f96fa1d70460a504a9c78acf899dc5f42ec55d00078343b40f9eeeaf5740bd8be047f66cc01ad7df6d66a8dd42265a6ff87e8ce168c9a18465002a8e6ba5bc4f108d6e70bb1ff2646492f9c154adec571153178606c07299664d3ec7eb1f1301f01d13b3865db6fa6d27d61667c42c16e764e03f312017109b19a7f9eedd00a6b082f35bc4399f76d646416a9a40e7c5a2774cf84e9c0d978f316fc95bf391c1b1a4e6753dc4c2ba31af2de8a485e65408f63d34b17318c1b83d437964ae047842bc73c4a020888b7988755c7e64f35e8fe7f812217fdfb87f815995815343409b5b6bed6869181f72e0737f4f98456f0c6a084cae14960e44a091714c4941ab4a37a657b241795b7315a6ed24c038e7ecce82586810d0fb33b503c2a0f72377db68a02f0fd1e20287155df960d3d0dd33675f5a4788bcea886bd64aaa984db29045ae886c38c61671b629de16a743f6fbabb5e6e7fb7a577cd6628757c71469555b9b0517fb4ed115269ed7367b30bd0b1782d19879d7bfcbe33336d070a4bd75e86c90e171409e69b867bfe1be1537966be6ac20702457fc04e150ac2f3bf33f4181128690899c976acf7b6141e9f59176bb0b6f9a52066c79bf669c539714a389136274785593f5ae3bb3af2effcb47f4a45ba72a5117fa89c4173c79d663e99

n8 = 0x00ccd36579389be5198dde695c2d97b7efcc04e332161ac60f82dac6ae33bb96dd885713915af2e997b1fdc307673560a3f9fe1935ad3b2a08dffa55c8d743cdcc9e6528e43fc0bd030cb1b49e12e42888c71801e072b8ddd345a0a28a76cac3af17574768e4a66a8e07d9658fff1ad9dbba618588c6c4cbc342a786de733a7d0bdb1f08e48cbad45865abcc4ac68db2a1e3a14f159add984eb83cb9241bab797f477931869bd36f42324e88541a7096ecb5895644b411e199e21cce30b835256d555b613185583eefdc27ba3883518c843f4044c309e39c7661cf149c3c0e0f65659544681803fafbd372955a878dcbb344f38d4cb39da21a46fc8c79fb39b619a8c4baac769106addb00742171c44509329fa7673a8178574e5f5d6a1c6b9db39e25f80ae7937a63e4609ac4f9a3e82c6a3b8fb12927ffc5ba87b256a3f3916ad8b2dda4b837bf6fa9f905d2d62c669f9b407bc4c67c4582544ebb61e1b077f0446895f58891e6a90460f7f09981bf3bb57d24ced44bb6cb31859d159f100cc35a1e123417dae4823b374a25dcce3f176af21125cf94898576741155086782915ee6b7be7c3a415fb7c3dcf83c6ad4b93e5846ed3955b6d8f2dd5145c15ff9195255db8279cdc6d935fe727fe39df02fba31b6aac52fb605f1ceec30faffa7324d1fb2a1ad5b325c48b35cd962130ed6da64a1c172e7863d505411592b8665d7

n9 = 0x00b17acf77309dccdcf05a4259212ee3b148b24e52fd39aad9cb558caa4c49a35bed6904037a065f92f3affe60dc0123f7c79f1fd52cf8fcb03095e33ccee9be8d55796b610077fd06de336cd2553f0695d809bf0eeeabcea5085387fa2670dc81b40f4334a2093446c5e53635a7b7fb3d1561a62d91b9669361294b4e68cb1548d9c48df3ef4da9a9b3c8eedd4f9901c3b29f5593db28023aa7c39400d21a53d7cd014f37d1687c7a7c7f3598ffd7d024941bf62806a92368d73418c05aaa67145d17306dec22be5e35473b83d9a6b71ade5abc3440d6e9da0d5a122ad11deacc45c5d2124755f1a60c919ef7ef4220a1ed253eb1ada0de0308681c3d0f558dea7de1e396430782a1dda11b44e1d6a11922e66d77285301e212c2cda17709008cbe138aa6c9ee152001700d3f2bf72dd8b168f9b6764f5bf9e7e736d4fb9b4053bf5e205d7f85404fae20aa9ab5131e8edc17dd1e134b8343f080ae05328925947612eeaf4fb4438c0cf82b6c938fefebf8583eda54494858d033f6af03fb52f8c02ec40c6f1041f9195499ce3bca7bf6924631ed3691e976707ed3e701b7637ae3c8b84df5b2864a7283c6b7bbcade2c0e29815f930506e472dcf3e4c97890f91bf9fe224e4c2e75325907228dcda9d7cce17872540c4e2e99fce1f91a755f2372cfc71808e779f4090671b00e88b7b7a45dd304a81cb04b7a18f4567ed77305

e3 = 0x380d01edb6ecc75e51056ef60dec807a8c17356ea6644ecf62c2b85763f79fa65f1b54d4ff283fbb0b0b3e6fa57186c52bea20e096368c194141cded75978bbe14d2709d20145601d0dd6b7e2df0dded42a514d298c68182289b8241aa09afebe7f3d0a187a6545b89a06cee5287e8257264e04bd09683d9b4b3b04f2ea86782d3e379e5014ff616202c78ad9b0801b67eeeeaaf3b43055a6f096c9bfb119f1b57c78c6e4050acf3c9677f93257a2baab9ffbc0f562fc64d468d639db090cdb626101268fbc286c5c9845abafb6c06fc0625904ccf32837fb2fd5d160df8360b33fe2fa55fb43fd4ba0ba69dde44f72f9e06509a636ec8456857597b9a5530b43b6c2f11038c9fce71d5debd7b63c7fb1daf7c84379093b1f9d8f5e1d4ab5e96e487c4ac4cd1629767a559e0fe95699975d3b2969fbc48e6c0529b42e45051ac5ce998b8a7772512dc32c48902a996c3fbd315967be6a4035563088f3bbee79dc324fd083b2e529f2d114bae5e6dea53dde3e518081a4a13e696b50ed8a51bac565353a98a6b841fad798e970150629956a4816b1d7968f65cefe71b192073412cdd69c0c22219a49c5891e636662ae3429ca9c2a3a29a89251674b37c076f66244b41fb228c82568967c0940e454f4974f68d1863f7398ddd6231fae8c7ff6f83faf31b472e75ae26ced598191b0f627dc2759e2a9a860a3e3b03caf68aacbf

n3, e3の値からWienere's Attackで素因数分解する。

from fractions import Fraction

def continued_fractions(n,e):
    cf = [0]
    while e != 0:
        cf.append(int(n/e))
        N = n
        n = e
        e = N%e
    return cf

def calcKD(cf):
    kd = list()
    for i in range(1,len(cf)+1):
        tmp = Fraction(0)
        for j in cf[1:i][::-1]:
            tmp = 1/(tmp+j)
        kd.append((tmp.numerator,tmp.denominator))
    return kd

def int_sqrt(n):
    def f(prev):
        while True:
            m = (prev + n/prev)/2
            if m >= prev:
                return prev
            prev = m
    return f(n)

def calcPQ(a,b):
    if a*a < 4*b or a < 0:
        return None
    c = int_sqrt(a*a-4*b)
    p = (a + c) /2
    q = (a - c) /2
    if p + q == a and p * q == b:
        return (p,q)
    else:
        return None

def wiener(n,e):
    kd = calcKD(continued_fractions(n,e))
    for (k,d) in kd:
        if k == 0:
            continue
        if (e*d-1) % k != 0:
            continue
        phin = (e*d-1) / k
        if phin >= n:
            continue
        ans = calcPQ(n-phin+1,n)
        if ans is None:
            continue
        return (ans[0],ans[1])

n = 0x00994a5e2c2303b40943d9b744b5709ee601fb5c4ac300cfa44a7608107a74d06ac04963a3f8201fa7801335edd3f323090425924b74f6ac39eeaff7b4a6bcaa241533fd5f57505b388668f24d8d65330745cc515ee1b3c96016b399c35eefef0612baff82761088117b07e25f9263f914981023319165d209c4784bc37a92ed7fecb470317b3fde5343cdd9aa13794b74831892cf6ea1002d7a3f760f1bb3edfbf6273b15361127424f1712892e0c6cc759b3c690da8c6184a90be6486b8f25c745554c0aaa445764589a5177038a67cd73e66fe1b0d559e0bbbe3e5b8d4aeef72ffa874cc16110bbc135c3e9928c5fcae737815f49fb023c64eda62ad2ed7d0d32249617dc512dc540006c0f059b2fdaeb3b0ae1c2b9615db7c83b909e222719451736e1f07c3919c3965fd9d003bd8813ec1e9cd540faf7f70f72fe8f0f544b2cab51a8a062865ae4f46a0530b7e11a264d717f3cf13b6018d09de1a0c28ea20cee2a6711da5d115fd71c096d115c13f0b5e40d94696c67105c2f709ae5d2fe0ac85847b3c9017ace7db2eb00d410d9d2da7685776a8099472d01791c57810d160abd6c9e420276320eb11b80a0b2f5722e20e9d8822a1d143c97a63ef81733e52f263e3a7f77b6900bf95da215544df51e61ecc468f037a2b39ccf153d984b32a9a4ce757bbb38798ce0b080f503ce1a396d47e14cc41bf18e34edbd9137eb
e = 0x380d01edb6ecc75e51056ef60dec807a8c17356ea6644ecf62c2b85763f79fa65f1b54d4ff283fbb0b0b3e6fa57186c52bea20e096368c194141cded75978bbe14d2709d20145601d0dd6b7e2df0dded42a514d298c68182289b8241aa09afebe7f3d0a187a6545b89a06cee5287e8257264e04bd09683d9b4b3b04f2ea86782d3e379e5014ff616202c78ad9b0801b67eeeeaaf3b43055a6f096c9bfb119f1b57c78c6e4050acf3c9677f93257a2baab9ffbc0f562fc64d468d639db090cdb626101268fbc286c5c9845abafb6c06fc0625904ccf32837fb2fd5d160df8360b33fe2fa55fb43fd4ba0ba69dde44f72f9e06509a636ec8456857597b9a5530b43b6c2f11038c9fce71d5debd7b63c7fb1daf7c84379093b1f9d8f5e1d4ab5e96e487c4ac4cd1629767a559e0fe95699975d3b2969fbc48e6c0529b42e45051ac5ce998b8a7772512dc32c48902a996c3fbd315967be6a4035563088f3bbee79dc324fd083b2e529f2d114bae5e6dea53dde3e518081a4a13e696b50ed8a51bac565353a98a6b841fad798e970150629956a4816b1d7968f65cefe71b192073412cdd69c0c22219a49c5891e636662ae3429ca9c2a3a29a89251674b37c076f66244b41fb228c82568967c0940e454f4974f68d1863f7398ddd6231fae8c7ff6f83faf31b472e75ae26ced598191b0f627dc2759e2a9a860a3e3b03caf68aacbf

(p,q) = wiener(n,e)

print 'p = ', str(p)
print 'q = ', str(q)

これでp, qの値がわかる。これからkey-3.pemに対応する秘密鍵を作成する。

p =  25699922293123622238012005113928758274338093880738911843144609876290300384447243164527369410936522534026502861166228851341858617366580840945546916656960397913459416157594030359887797479829819533476376181670391998963549074371737295746623468123112547424135047636878302121269250886314724602949616886176008642837449632045010113812032294774060357611189602487961064611234002464905006798590256478016955856378120527444702590839053848988168714049387256070864726124290373739801554166928887083826045058481026363141572007235867367607974662051368481037707609970666363610931674810380477197023311110704572295255843715262143691203301
q =  24333562944687516822197571192658754203291290861678417217447438854540594847087766562404339574537862439116548079253289466115128767870577648533973566286797593441730003379848043825634065823911136780045362090360846493427099473619203426216220826743478974241107765471416754913629766068614128278553165309459614540881272639715963742807416312087758332567870818068056326342400589601117982695439948496482753836668023789721452705706258642830333890588979897355741176673670662543132574318628603066958811749579934075668455748590286427527491514861437629540690813171672435522560204943058263324060332232490301430308879676240097644556943
$ rsatool.py -f PEM -o secret3.pem -p 25699922293123622238012005113928758274338093880738911843144609876290300384447243164527369410936522534026502861166228851341858617366580840945546916656960397913459416157594030359887797479829819533476376181670391998963549074371737295746623468123112547424135047636878302121269250886314724602949616886176008642837449632045010113812032294774060357611189602487961064611234002464905006798590256478016955856378120527444702590839053848988168714049387256070864726124290373739801554166928887083826045058481026363141572007235867367607974662051368481037707609970666363610931674810380477197023311110704572295255843715262143691203301 -q 24333562944687516822197571192658754203291290861678417217447438854540594847087766562404339574537862439116548079253289466115128767870577648533973566286797593441730003379848043825634065823911136780045362090360846493427099473619203426216220826743478974241107765471416754913629766068614128278553165309459614540881272639715963742807416312087758332567870818068056326342400589601117982695439948496482753836668023789721452705706258642830333890588979897355741176673670662543132574318628603066958811749579934075668455748590286427527491514861437629540690813171672435522560204943058263324060332232490301430308879676240097644556943 -e 228667357288918039245378693853585657521675864952652022596906774862933762099300789254749604425410946822615083373857144528433260602296227303503891476899519658402024054958055003935382417495158976039669297102085384069060239103495133686397751308534862740272246002793830176686556622100583797028989159199545629609021240950860918369384255679720982737996963877876422696229673990362117541638946439467137750365479594663480748942805548680674029992842755607231111749435902398183446860414264511210472086370327093252168733191324465379223167108867795127182838092986436559312004954839317032041477453391803727162991479936070518984824373880381139279500094875244634092093215146125326800209962084766610206048422344237134106891516381979347888453395909395872511361844386280383251556028219600028715738105327585286564058975370316649206938752448895524147428799966328319661372247669163998623995646371176483786757036960204837994662752770358964913870689131473714797550537422931003343433377469029232185552979648755665051117443571002017829146470221483652014417043043920340602378994630507647460734411326405049128160906832664174206633659153486878241903912874200129515570971220983561054906106575556061388168231915057339795246395626504771079756241685975773086049021119
           :
Saving PEM as secret3.pem

秘密鍵を作成できたので、5つの暗号ファイルに対して、復号を試す。

from Crypto.Cipher import AES,PKCS1_OAEP
from Crypto.PublicKey import RSA

def decrypt(private_key, ciphertext):
    if len(ciphertext) < 512 + 16:
        return None
    msg_header = ciphertext[:512]
    msg_iv = ciphertext[512:512+16]
    msg_body = ciphertext[512+16:]
    try:
        symmetric_key = PKCS1_OAEP.new(private_key).decrypt(msg_header)
    except ValueError:
        return None
    if len(symmetric_key) != 32:
        return None
    return AES.new(symmetric_key,
        mode=AES.MODE_CFB,
        IV=msg_iv).decrypt(msg_body)

with open('secret3.pem', 'r') as f:
    pri1 = RSA.importKey(f.read())

for i in range(5):
    file = 'ciphertext-%d.bin' % (i+1)
    with open(file, 'rb') as f:
        ciphertext = f.read()
    d = decrypt(pri1, ciphertext)
    if d is not None:
        print i
        print d

この結果、以下のように復号された。

3 ←これは暗号ファイルの番号
Congratulations, you decrypted a ciphertext!  One down, two to go :)
4-4a87367d053c533fd995032ed1e651487cb5dc1e0b1cb70a7662b152c73650f039a60f391a52f2413f43bd54eb7b12c41b42f31ac557edd4bfe46a396a8cdbe19dc9d8121924f43be51c976d
4-abbbcee71f140198ff8c50f51069465075979c31d32b052e7ae82ec7f6783aef7b41a597f9504d3340967b8d70cbe5a3
4-35fbbe40058e20463547b363d1f164c0bbbb97cfd9ffe7619bce31a59392f0e9625a2cd035276e09c4df3c0932f22bd322f16e375c7c7fd88da0f972832707eb549ff1e776db37649019ebce
4-12b466934911986bda845d8d26710a12250d210546f46716c78d7a17b1f2c893b95b934c8c7beafcf81a3123eb2ea05ca89101b23349e455794a8d56608c8ee49dd

他のnについても素因数分解できるものを探し同じような手順をとる。
今度はFermat法で素因数分解できるものを探す。

def isqrt(n):
    x = n
    y = (x + n // x) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x

def fermat(n):
    x = isqrt(n) + 1
    y = isqrt(x * x - n)

    while True:
        w = x * x - n - y * y
        if w == 0:
            break
        elif w > 0:
            y += 1
        else:
            x += 1
    return x - y, x + y

n = 0x00c4ff486b14cd9c37b956f08ff19ca2f83dba86509cb840cd6a5a95f1352009b18d1d56b4a0fec0e95a29ca96caefaa5deff71d6aeb0ad89eeaad908cee93582bd71b2cd7daf709a54b98d163b508d3fd1f0a9709fb69e499d1b8abc50af3a4cbae77c070444933613a452954f91acdaf461d6a364035920561f7885d30ebdc82be3560e6428864b9715e1734d013e23dfb8c1da662f5ce6da3712402f8da445d0ca49b9bb1e47abeeef58a6385ca3f9eb9d24008b6e68e1de7c2f12fea14f7729c248d8db7d9b85e6279ab68b0517f739d9745ba02f8aabc33819c326116c327396b5716c6895495ae8d3cf60a3b6a11557329383f6d5f414d9e05e87e13d5d7cbf87994c86f1419a8fc969500e36d8570fbe1bc13df8bfe3888209b0bd684b9265bf7f4e05cf670d8f288e1d82740e9812f9aa68a99b5e569420b38cc1538787ead253df53341e3c2697ce76152b02ed437cce19386e2a13608bfb7b23336356f032c550f1fbc4f8ee00294cbecb03ece45dfc5f5c115d73adc988ba297104c81351bb73c2ac01d3acfc5a814c4947b5758b0193222102c1541f398d2d7b1c2cfdd53a172aa899880f53a8b5c7e6a39e6e408141df99ae2f6befc00b02e2ac4c3af122be5097f3231c5b4e607bca2a78c1f1040aa3c4351de4b3172e3882c116e5f586de33cee9c911875ac196efb8355d4cddfe5479b19fa426a25e0ea1891
p, q = fermat(n)
print 'p =', p
print 'q =', q

この結果、n1を素因数分解できた。

p = 28349223152666012309896421767725787316124897111416473420803849019741154117582482568645254183215552986563114855665416593397403745371086355268654763921803558654340155902194948080056226592560917521612824589013349044205989541259468856602228462903448721105774109966325479530181197156476502473067978072053273437369680433495259118953717909524799086692640103084287064091489681162498101607280822202773532998098050880803631144514377948079277690787622279940743498439084904702494445241729763146426258407468147831250550239995285695193105630324823153678214290802694619958991541957383815098042054239547145549933872335482492225099839
q = 28349223152666012309896421767725787316124897111416473420803849019741154117582482568645254183215552986563114855665416593397403745371086355268654763921803558654340155902194948080056226592560917521612824589013349044205989541259468856602228462903448721105774109966325479530181197156476502473067978072053273437369680433495259118953717909524799086692640103084287064091489681162498108275295255082627807077949841602061428289272700263987438087045434043977981316071156426134695316796020506076336851840708593720052204359360366058549157961154869248835793804817253083037277453771408544063058190126149127240681909811943783388977967
$ rsatool.py -f PEM -o secret1.pem -p 28349223152666012309896421767725787316124897111416473420803849019741154117582482568645254183215552986563114855665416593397403745371086355268654763921803558654340155902194948080056226592560917521612824589013349044205989541259468856602228462903448721105774109966325479530181197156476502473067978072053273437369680433495259118953717909524799086692640103084287064091489681162498101607280822202773532998098050880803631144514377948079277690787622279940743498439084904702494445241729763146426258407468147831250550239995285695193105630324823153678214290802694619958991541957383815098042054239547145549933872335482492225099839 -q 28349223152666012309896421767725787316124897111416473420803849019741154117582482568645254183215552986563114855665416593397403745371086355268654763921803558654340155902194948080056226592560917521612824589013349044205989541259468856602228462903448721105774109966325479530181197156476502473067978072053273437369680433495259118953717909524799086692640103084287064091489681162498108275295255082627807077949841602061428289272700263987438087045434043977981316071156426134695316796020506076336851840708593720052204359360366058549157961154869248835793804817253083037277453771408544063058190126149127240681909811943783388977967
           :
Saving PEM as secret1.pem

key-1.pemに対応する秘密鍵を作成できたので、また暗号ファイル5つに対して、復号を試す。
この結果、以下のように復号された。

4
Congratulations, you decrypted a ciphertext!  One down, two to go :)
5-7d29041c468b680fcff93c16011a2869f17de75b929b787503b412becde0321ec72fe1e499f2150a1dacb9a5f701c0b37470049dd560cef5163543469817971f50782f763f0b05ab7088f7ae
5-a7a1e271cf263279cece532b540545fa539b0f3650e2929163b02ee5459debdc53c1e07149eb2153015bb5c88e6270e8
5-149480c5c75cbe320564adfa432ac8ea241e048ed39c8bc6be14ca80c392487f43a7882075d785d62cb314ea6c89a6b5f28adfa56ec481e124567b88241de2a6cabcc7ec9de3acac8be5375b
5-7285289084282d559573f68eef10191091d76d6670014202670651f867cd2bc8640a86eef1c1e482affc7ae801fa446956c2186972fb6b7bac88c91d050c9d3cca

今度はfactordbでの素因数分解を試す。この結果、n2を素因数分解することができた。

p = 2758599203
q = 199050626189790903113151725251371951406311367304411013359159100762029303668345459282823483508119186508070350039475140948570888009866572148405365532164833126992414461936781273087675274788769905198546175946505790118332257676994622928414648644875376193656132263418075334807302665038501361680530751104620475935886499714767992159620130246904875540624651891646715835632182355428589610236128648209568297096024509697960196858754170641081387466229916585122877955908862176165344465889280850859817985096316883025515924332365977538735425288433292357532172467247159245727072344354499113900733623716569924461327947462469348798798400461045817375922057805611166274339541877392159201774893120311667898551312256530117094221191204981071357303328506659872809131929265966688409379037586014938643190675726674943253875287765020503118408406103824607730713529079962656130622218633922911733000466212212532871890933508287965723844399784165195088175666883742686183165151553009638524764735387233844317375317153437534933611361683136151569588355535831475925641431859231311079029505004457816932257031352498323214304125608733640306746900473758755832661915903475867854937735150255829715879232213599597863424779218670961633567259935246911742292942052832671549
$ rsatool.py -f PEM -o secret2.pem -p 2758599203 -q 199050626189790903113151725251371951406311367304411013359159100762029303668345459282823483508119186508070350039475140948570888009866572148405365532164833126992414461936781273087675274788769905198546175946505790118332257676994622928414648644875376193656132263418075334807302665038501361680530751104620475935886499714767992159620130246904875540624651891646715835632182355428589610236128648209568297096024509697960196858754170641081387466229916585122877955908862176165344465889280850859817985096316883025515924332365977538735425288433292357532172467247159245727072344354499113900733623716569924461327947462469348798798400461045817375922057805611166274339541877392159201774893120311667898551312256530117094221191204981071357303328506659872809131929265966688409379037586014938643190675726674943253875287765020503118408406103824607730713529079962656130622218633922911733000466212212532871890933508287965723844399784165195088175666883742686183165151553009638524764735387233844317375317153437534933611361683136151569588355535831475925641431859231311079029505004457816932257031352498323214304125608733640306746900473758755832661915903475867854937735150255829715879232213599597863424779218670961633567259935246911742292942052832671549
           :
Saving PEM as secret2.pem

key-2.pemに対応する秘密鍵を作成できたので、また暗号ファイル5つに対して、復号を試す。
この結果、以下のように復号された。

0
Congratulations, you decrypted a ciphertext!  One down, two to go :)
1-32a1cd9f414f14cff6685879444acbe41e5dba6574a072cace6e8d0eb338ad64910897369b7589e6a408c861c8e708f60fbbbe91953d4a73bcf1df11e1ecaa2885bed1e5a772bfed42d776a9
1-e0c113fa1ebea9318dd413bf28308707fd660a5d1417fbc7da72416c8baaa5bf628f11c660dcee518134353e6ff8d37c
1-1b8b6c4e3145a96b1b0031f63521c8df58713c4d6d737039b0f1c0750e16e1579340cfc5dadef4e96d6b95ecf89f52b8136ae657c9c32e96bf4384e18bd8190546ff5102cd006be5e1580053
1-c332b8b93a914532a2dab045ea52b86d4d3950a990b5fc5e041dce9be1fd3912f9978cad009320e18f4383ca71d9d79114c9816b5f950305a6dd19c9f458695d52

今度は2個のnで共通の素数を持っていないかを探す。

import itertools

def egcd(a, b):
    x,y, u,v = 0,1, 1,0
    while a != 0:
        q, r = b//a, b%a
        m, n = x-u*q, y-v*q
        b,a, x,y, u,v = a,r, u,v, m,n
    gcd = b
    return gcd, x, y

n0 = 0x00d7af32b093d6e224bb963a9a7bc873b2e77c6ace763e7d6c6dd7d1d11182852f684b503dd72e7694fdec4668afbf6f90c4af4662abee1c3a33c50ec5c52a8c0a9aaf4d0f3161ebb4ee7622a22ff1fb67b93023d49431306ffc0140191b1077b114cca884db4ccdd8d1f7bb131ef321b4907003548161921d293a4263189708ba0755452a66a6dc916188b263010536fd239ebeda8d877a66dd84cb431f5a62ab908b66b4e64d3e57bfba338e13b0377c0303d63860755864785a1c8f4b5fb47c6fc4f2a9fd853073230733c68b754b2b480107027333039bb1d84913137e6dfa473e92d4b24af57e730a4a34f6e01a416f94a8355ccf46954cd26d2503bcea20903ecd77a01f2684cf1d7c7124b45defabd6c2b47f26dc142812c83573c412813f016804e2c12f31ca433dedd47634bbe3e4935d762ab6e59e72ea0932ff75f18807a8b17a2f6881763cf3028b9e15a5114c06817fb076e05f4d41fa52b9db79599ff407a1856b4eb4738f1ced340a44070729c2a56ad73b61243b6ca996a20d50548dfcb11d750689ae93471331fe68c22922687f16c48308d3ad74e8c9bff8c1744c0674d203a56c099d7bee8ef94d92d9b4ec3d1e9197a0ac49257545fc09e1ed739d6a10adda082e5b18f7eaa83e786ee9ad8586070ea65db4f9b5abb9394da32fb74d68c8d4a64ef5c4a12cc29d612264e73d259a3fd688c5567558bea9
n1 = 0x00c4ff486b14cd9c37b956f08ff19ca2f83dba86509cb840cd6a5a95f1352009b18d1d56b4a0fec0e95a29ca96caefaa5deff71d6aeb0ad89eeaad908cee93582bd71b2cd7daf709a54b98d163b508d3fd1f0a9709fb69e499d1b8abc50af3a4cbae77c070444933613a452954f91acdaf461d6a364035920561f7885d30ebdc82be3560e6428864b9715e1734d013e23dfb8c1da662f5ce6da3712402f8da445d0ca49b9bb1e47abeeef58a6385ca3f9eb9d24008b6e68e1de7c2f12fea14f7729c248d8db7d9b85e6279ab68b0517f739d9745ba02f8aabc33819c326116c327396b5716c6895495ae8d3cf60a3b6a11557329383f6d5f414d9e05e87e13d5d7cbf87994c86f1419a8fc969500e36d8570fbe1bc13df8bfe3888209b0bd684b9265bf7f4e05cf670d8f288e1d82740e9812f9aa68a99b5e569420b38cc1538787ead253df53341e3c2697ce76152b02ed437cce19386e2a13608bfb7b23336356f032c550f1fbc4f8ee00294cbecb03ece45dfc5f5c115d73adc988ba297104c81351bb73c2ac01d3acfc5a814c4947b5758b0193222102c1541f398d2d7b1c2cfdd53a172aa899880f53a8b5c7e6a39e6e408141df99ae2f6befc00b02e2ac4c3af122be5097f3231c5b4e607bca2a78c1f1040aa3c4351de4b3172e3882c116e5f586de33cee9c911875ac196efb8355d4cddfe5479b19fa426a25e0ea1891
n2 = 0x0086986548c02b2d6b0461a74a09a5ee4efa07882d5c610bdb14d1ba3044effd5570e4c509d116aca992a342cf52ed0463db6d4648a3013ba8219c3a72b1998796253dd11ecc536087e6e5bd207c1387af9df6bf875ab319556dcc0bad6a90f017459760ee7d274fe6046e7599385f7607d29ed235477695e3365fc6b9f5270183e9c4c2c118aa676c1d9cbe06864507e4310d85b8cacff9f5a3eed487b71d2d75b00943d7eda9aaf5b2bb69271625de2469d6a7c4f50c4eeac54b1605793cc0f7fe9167452ff5fef3647c9eec8866730732c05dca4c56f393ca2e61e7d76442822b9da56d96f67bba9f6095f761d0f2a3de62ea8c6fc7ac2fa7b727684947f7640711b700f40a1799d0265eefe94952b50e5e10b15bec14cc1664714c6c1ff1c16454f4a912ec19760d80c4759ff3130da43b13e7967d5cea526402cf2b566653c0cd5d7d0995357661c0308cbd11aaeb832ca9093dc3981d1fb6b62fd98a883e8d4c1548521c3e2f0bef76c7220d8093c2bdb1ae017f2e48d0defe42ce5713955ae294bec2b5da9b81cf9bb1d8ca5e5dcc9bf930edb7a3f6d2d350d2aa478e01070dbc151d6f9f6dba473ec001432de4e2ced4611955f294b3d48631dd51eb7c50a97f5165731d597129d3335f4c994234d89095335c705f075a1ba08a0f5cf383d65cd424524a48a415ce2ca5a34b4287e4efacb243e68b9c90a3679bef2757
n3 = 0x00994a5e2c2303b40943d9b744b5709ee601fb5c4ac300cfa44a7608107a74d06ac04963a3f8201fa7801335edd3f323090425924b74f6ac39eeaff7b4a6bcaa241533fd5f57505b388668f24d8d65330745cc515ee1b3c96016b399c35eefef0612baff82761088117b07e25f9263f914981023319165d209c4784bc37a92ed7fecb470317b3fde5343cdd9aa13794b74831892cf6ea1002d7a3f760f1bb3edfbf6273b15361127424f1712892e0c6cc759b3c690da8c6184a90be6486b8f25c745554c0aaa445764589a5177038a67cd73e66fe1b0d559e0bbbe3e5b8d4aeef72ffa874cc16110bbc135c3e9928c5fcae737815f49fb023c64eda62ad2ed7d0d32249617dc512dc540006c0f059b2fdaeb3b0ae1c2b9615db7c83b909e222719451736e1f07c3919c3965fd9d003bd8813ec1e9cd540faf7f70f72fe8f0f544b2cab51a8a062865ae4f46a0530b7e11a264d717f3cf13b6018d09de1a0c28ea20cee2a6711da5d115fd71c096d115c13f0b5e40d94696c67105c2f709ae5d2fe0ac85847b3c9017ace7db2eb00d410d9d2da7685776a8099472d01791c57810d160abd6c9e420276320eb11b80a0b2f5722e20e9d8822a1d143c97a63ef81733e52f263e3a7f77b6900bf95da215544df51e61ecc468f037a2b39ccf153d984b32a9a4ce757bbb38798ce0b080f503ce1a396d47e14cc41bf18e34edbd9137eb
n4 = 0x00a9dffbcdf808e4a5120b876d4be077cef21b6ef3bbccdae77b6afc988ea068cad52c6e7d1797049394caaee701e916b3d192c6fc8f8ab2c8a0bcdc75cfb1c436a914c128046b889aeb5f1c89852856cad179a0958a4aeb87ba778ea62187ad1931d5bdcf85d57361fd2941a076ea9b3652110287755e663e679892b4ff0519042b0b3a85aa99f623a1037d503b245cf3205c3c5b24139b3abf0881fbc1b0f7e03444149f69427fd78cdbc75b634a5160e9b2aadbfd9cfd6150ab0ace72dd1d95e1d884153cbe9dd62458745a0fe95014e89f263a9730ff2205b108e3985bb9da9a1b68b4ae1d52cec2b3a5320e02392e9e8b802d190de6e4f75388c3fafdb2ba58904eceaa613c3d67d81ede381a0f15a2822bd1a5a1854df38aea7d32e6cf8c38d8d6a8daf384befc5ee06c9be1a4b2216b690b28dfaaebd9d47b3d96fddd96114dc6df9b1eb21343098ef9e6540fbac0c19a63cdaf6e4528ae41d212e50dab72ff4529b042ec22dd8d61166d29548559ed7de469391781444baee28f3ecbed79169a7134da785d476533ace2ffe3aee5b9501549a8061ad50b352d01735dfb4ca7d4d0bf759c9dbcbb1ba4793a30238f959ad033b5691920b3e2fc793fe154ee9f6ebc5d64744b518a41e26803d11f1fda6d223904c26054b4c685e3640da0e1f4da6445b55757ac7e4e18c938168c1d8c64f31eb11e4aaa09d0c94fca9973
n5 = 0x0088ef837570c4161f5ef7d6e65deafb9840cffae5f3377d7b2c4fa8ee99286fda86d1dd77aec9a7d9751328c0d0db4481f8a108b4d844262ea1fb8bf02aa44dba0f9c02baf186bac37e02314c48277803b088c2921076b155c4882cf4c2397796959edf22af6a2ff769ca4668f370eea104ac006df3fead69e1b7c00b8d4ea0b8e99f904c7b66fad4cea031091b66a21373c0cc64d2151d8274f128d183a7f3d697965f1590f3f2656259fda9be417510949dab2163c5f450d662a899fcaa31344ad0decd558fa3e9f9247a23fe451c8f846acad19360e66720909f405064f576b6c925a081d4865f7bc861d51101c33d695656b33d164e38948234db1cdc0fbf8608aff64f67ddbaf3e3ead882d8ab69916dd6b922cec62f3d53567b0e644f990add24b22d3021178da47355bdf1714ce142f98d03daf7b525d0c6aebf42f2f5e9352584ba503f1771bf5b2ed7f77023c3c82e8aefc79d3c22d177b3f6e3d5e399f586b4041cba5e4cd66e30fe9666df9fc6216f2ba1d0ff002fa1d6f1ca787a3130a6a5ca929fa737c8fcd86c753709bc23f54eddd6c1fc6d121932e900f4be24200329432bacf3aa8e6fc9e87a226457dfe24745fc7c969390f992f999ea4920cfccc4c47c06b9aebabab4c91f14d8ff85e27576f0a027ca70093c185c008b27e8243121551e4705fd46c3561485abf2fbaa0fc28a87871fe2e3f5afa30527
n6 = 0x00bc0d4dd9ed44c44c2173abd3b025401b366816d913f7b4271b71abcded21ab0d04c2fc577a313b794275845dbb89e8151cf4bd3825e9240c88eb93a824caa8b0b563960ffcb12fbcafcd9d38fbdf87b134395d0ea316186beaf2470a535a1da3529c005cb9062f0d43eb8e7bf4cd79425a6cab65a15c905713abcedbf4a715c46465becbba9ed60fd77bf82f035d8a394c56f13898834b277c6749261a9c95b22574c1f7781550345588cf2ff1d22eaeb1137aee4d41f6e288759844a4eb8e8cbdfaea1776d3c45e7551c9924317d0efe36a686afb3ac8a12ab809a3deee27d7f69f26b70b97cd1ed51426e489e804881dcae802fba751c3f83b6983cfcb4c30c966ca92e7bf08874b2848e098f021f183ae839be30191e3bcd2ce38325e3991c6e733bf00cf3f60aaef2b7ebd0554fb0c980a6f62db59974e7f3ce46afb24e43e107ec8d1cc0e772f997ff0c5a602fa8bcd0cbbf78cc2d1a84903a3cc00b397858c02c28f7c0707e66d6dc0de2ce747d99dc4038bdd924cf3c534bcec6dcf3d4f0247e30875f39af7ab0fda69fca12d7104c51bf6d66aff2d12338ffbf51e243ade078de6cc1930f872c3ad91d8f822668e56d352c0156e513033ea20c0f163d558b69119734684f98cf789df72f8c534d008a535c9dafebe8774140adc0c53eeb021852ec282b7bddce58c9ffb87a7b4f20b91bfd04ed84ea6566bc397f1d9
n7 = 0x00b7d5a8ccd362a3f4691641ee9176e4d025159ad60a427a7e21343acea9ef3f96fa1d70460a504a9c78acf899dc5f42ec55d00078343b40f9eeeaf5740bd8be047f66cc01ad7df6d66a8dd42265a6ff87e8ce168c9a18465002a8e6ba5bc4f108d6e70bb1ff2646492f9c154adec571153178606c07299664d3ec7eb1f1301f01d13b3865db6fa6d27d61667c42c16e764e03f312017109b19a7f9eedd00a6b082f35bc4399f76d646416a9a40e7c5a2774cf84e9c0d978f316fc95bf391c1b1a4e6753dc4c2ba31af2de8a485e65408f63d34b17318c1b83d437964ae047842bc73c4a020888b7988755c7e64f35e8fe7f812217fdfb87f815995815343409b5b6bed6869181f72e0737f4f98456f0c6a084cae14960e44a091714c4941ab4a37a657b241795b7315a6ed24c038e7ecce82586810d0fb33b503c2a0f72377db68a02f0fd1e20287155df960d3d0dd33675f5a4788bcea886bd64aaa984db29045ae886c38c61671b629de16a743f6fbabb5e6e7fb7a577cd6628757c71469555b9b0517fb4ed115269ed7367b30bd0b1782d19879d7bfcbe33336d070a4bd75e86c90e171409e69b867bfe1be1537966be6ac20702457fc04e150ac2f3bf33f4181128690899c976acf7b6141e9f59176bb0b6f9a52066c79bf669c539714a389136274785593f5ae3bb3af2effcb47f4a45ba72a5117fa89c4173c79d663e99
n8 = 0x00ccd36579389be5198dde695c2d97b7efcc04e332161ac60f82dac6ae33bb96dd885713915af2e997b1fdc307673560a3f9fe1935ad3b2a08dffa55c8d743cdcc9e6528e43fc0bd030cb1b49e12e42888c71801e072b8ddd345a0a28a76cac3af17574768e4a66a8e07d9658fff1ad9dbba618588c6c4cbc342a786de733a7d0bdb1f08e48cbad45865abcc4ac68db2a1e3a14f159add984eb83cb9241bab797f477931869bd36f42324e88541a7096ecb5895644b411e199e21cce30b835256d555b613185583eefdc27ba3883518c843f4044c309e39c7661cf149c3c0e0f65659544681803fafbd372955a878dcbb344f38d4cb39da21a46fc8c79fb39b619a8c4baac769106addb00742171c44509329fa7673a8178574e5f5d6a1c6b9db39e25f80ae7937a63e4609ac4f9a3e82c6a3b8fb12927ffc5ba87b256a3f3916ad8b2dda4b837bf6fa9f905d2d62c669f9b407bc4c67c4582544ebb61e1b077f0446895f58891e6a90460f7f09981bf3bb57d24ced44bb6cb31859d159f100cc35a1e123417dae4823b374a25dcce3f176af21125cf94898576741155086782915ee6b7be7c3a415fb7c3dcf83c6ad4b93e5846ed3955b6d8f2dd5145c15ff9195255db8279cdc6d935fe727fe39df02fba31b6aac52fb605f1ceec30faffa7324d1fb2a1ad5b325c48b35cd962130ed6da64a1c172e7863d505411592b8665d7
n9 = 0x00b17acf77309dccdcf05a4259212ee3b148b24e52fd39aad9cb558caa4c49a35bed6904037a065f92f3affe60dc0123f7c79f1fd52cf8fcb03095e33ccee9be8d55796b610077fd06de336cd2553f0695d809bf0eeeabcea5085387fa2670dc81b40f4334a2093446c5e53635a7b7fb3d1561a62d91b9669361294b4e68cb1548d9c48df3ef4da9a9b3c8eedd4f9901c3b29f5593db28023aa7c39400d21a53d7cd014f37d1687c7a7c7f3598ffd7d024941bf62806a92368d73418c05aaa67145d17306dec22be5e35473b83d9a6b71ade5abc3440d6e9da0d5a122ad11deacc45c5d2124755f1a60c919ef7ef4220a1ed253eb1ada0de0308681c3d0f558dea7de1e396430782a1dda11b44e1d6a11922e66d77285301e212c2cda17709008cbe138aa6c9ee152001700d3f2bf72dd8b168f9b6764f5bf9e7e736d4fb9b4053bf5e205d7f85404fae20aa9ab5131e8edc17dd1e134b8343f080ae05328925947612eeaf4fb4438c0cf82b6c938fefebf8583eda54494858d033f6af03fb52f8c02ec40c6f1041f9195499ce3bca7bf6924631ed3691e976707ed3e701b7637ae3c8b84df5b2864a7283c6b7bbcade2c0e29815f930506e472dcf3e4c97890f91bf9fe224e4c2e75325907228dcda9d7cce17872540c4e2e99fce1f91a755f2372cfc71808e779f4090671b00e88b7b7a45dd304a81cb04b7a18f4567ed77305

n = [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9]

for c in list(itertools.combinations(n, 2)):
    p = egcd(c[0], c[1])
    if p[0] > 1:
        print 'p =', str(p[0])
        print 'q1 =', str(c[0]/p[0])
        print 'q2 =', str(c[1]/p[0])
        print 'c[0] =', str(c[0])
        print 'c[1] =', str(c[1])

この結果、n0とn6を素因数分解することができた。

p = 28796899277235049975421947378568428888005019408631005870725337759187744546493409470582705210790627097597656481534493716225301660663533212040068163723937803169735485217437722947354732420098585958967033073629288721874028940705969141716032409906092583043329293532612601200186754187377338924379443611709918885185638934712580040042904995838353611699081350712817357237035507539201368300463060034856220488010509411264244138417348439340955309300128758040513940379009974696105387107481999359705587790254117489020540714253505694682552102843028243384677060490696214834957049391213864664165843655260698241682369402177091178720927
q1 = 30555909537318327326226067108345484260972616392831008890345613182167918843881096961410781393695029449357707848545288220880122374798556583885387343041975279297622137379354808942799947266338126600859247945486391385249259848502175234010967289831554894776077704571261457595823825245669052206379832284446373088109050246642453540203667448240894956074979263603360448779126929364191229791046048600648158120404404766763070327940029813826415327745664993191485439444296109763969948631755535163926384703087422857642736153852582820056661551903549876616627900530084158172809851351898663554970528201875223815554349604138636668040631
q2 = 26641239846781539174997613915486416003684568556746576609279663468469031683562139918289710191916575980269872103186803161203776420494840845869372424906386190919487401478921545410628828040240934885968480468559124463233908052442280478139872489261920279274813374296134128578293855845928227225795788061940296913771355415137193729864318300987109915105382195425114525826138321815629366884757211418011082865207792823895128910178064295532964692290697547400111032047363746813247658976480566291220338236760240639947583180060309174234225896967104503916386813098322083010876516252218060276731781117933746509243898480864478441202823
c[0] = 879915449270461710485190695384984333346108808238163100635589622985858681174840077891791908299778396399761712011997011746463613908680308851346753645211864161697422478686970556327768137361234129772891278276357122727947947950244829806055158881016642817199313982712486191412897962236823871269648420736534924423486406548812730734126326674748473583138652251560681262492811924913496720278164857004639526764284643238839653952620488132689109774675909664582253141977855536278849104478716737830183823218243357824262208874640011261393661502090701835779701622110255634550577381315794398401099288190684976087038357375439896657810260507762688383926068495576680257990550715767191269347630617636238617346854357508261801349618172932911727280032490944086446846201447378546844207137105811675361827084844211756092591937052615042095862729647068769829375686485423039379493711843213227723084973490186764653471416174456924874481547963600275748770741484515078249187279735372230164334982815930799440541523328018129242237204214842553638367339912643041927393196022387262262204652591800895390943699817163674861716528082374689844511331037929096168076500795597504227135991135809164087623928304090411617142569812170269488375850421090620593124327092827212833845984937
c[1] = 767185100488428919016632170568302864430595686111633853865853178271740753807631107438469636874149151975213091797469800231881024440218931836348027417405438325824297104749723127225412009768596670293358224481910117990221965588027812122211776093837448747674231104831266261442032627678816332117512253254417902273087090526668802909231100189062059172214484966826827211424626065276059613985574544412609131190663177251147222337439529271810128210037468960468152611646862922563271251560265472129891502660301505695797093180509246596535280995459316546041298821485677298673720375230145667734470085748234479066650224747956677855856599512299156493819425327975989659334858931601551091941865956355246897792662048547218085830897307455941801348993015738325478197038027303177775403199123814405059965177746759645789493365730861927684438829511689481413687211445070334362680691231035336073760204340782163790243228692508230246815979346673469404207207020959641247494823624451087045877926954318590208564006401609051341418752333546705485665209085221084705978680432756976392471120062576376133959869719109290112050140002435438961179172972247159977728102448723565655241549851208603332382646287005177858241486292754465516995791462277418258182436844243511176521576921
$ rsatool.py -f PEM -o secret0.pem -p 28796899277235049975421947378568428888005019408631005870725337759187744546493409470582705210790627097597656481534493716225301660663533212040068163723937803169735485217437722947354732420098585958967033073629288721874028940705969141716032409906092583043329293532612601200186754187377338924379443611709918885185638934712580040042904995838353611699081350712817357237035507539201368300463060034856220488010509411264244138417348439340955309300128758040513940379009974696105387107481999359705587790254117489020540714253505694682552102843028243384677060490696214834957049391213864664165843655260698241682369402177091178720927 -q 30555909537318327326226067108345484260972616392831008890345613182167918843881096961410781393695029449357707848545288220880122374798556583885387343041975279297622137379354808942799947266338126600859247945486391385249259848502175234010967289831554894776077704571261457595823825245669052206379832284446373088109050246642453540203667448240894956074979263603360448779126929364191229791046048600648158120404404766763070327940029813826415327745664993191485439444296109763969948631755535163926384703087422857642736153852582820056661551903549876616627900530084158172809851351898663554970528201875223815554349604138636668040631
           :
Saving PEM as secret0.pem

key-0.pemに対応する秘密鍵を作成できたので、また暗号ファイル5つに対して、復号を試す。
この結果、以下のように復号された。

2
Congratulations, you decrypted a ciphertext!  One down, two to go :)
3-17e568ddc3ed3e6fe330ca47a2b27a2707edd0e0839df59fe9114fe6c08c6fc1ac1c3c8d9ab3cf7860dac103dff464d4c215e197b54f0cb46993912c3d0220a3eb1b80adf33ee2cc59b0372c
3-b69efb4f9c5205175a4c9afb9d3c7bef728d9fb6c9cc1241411b31d4bd18744660391a330cefa8a86af8d2b80c881cfa
3-572e70c5acfbe8b4c2cbd47217477d217da88c256ff2586af6a18391972c258bbea6143e7cd2ff6d39393efeb64d51d9318a2c337e50e2d764a42173bc3a1d5c7c8f24b64043daf5d2a8e9f4
3-e9e6850880eb0a44d36fe9f2e5a458c6da3977b7fcd285afa27e9bfc116b1408570991504116b81864b03a7060bfd5d3fb6e007bb346f276d749befd545d1489c4

もう一つのkey-6.pemに対応する秘密鍵を作成して、また暗号ファイル5つに対して、復号を試したがどれも復号できなかった。
あと一つ暗号ファイルが残っているが、とりあえずsecretsharingのライブラリで元の平文に戻してみる。

from secretsharing import PlaintextToHexSecretSharer

shares1 = 'Congratulations, you decrypted a ciphertext!  One down, two to go :)'
print shares1

shares2 = ['1-32a1cd9f414f14cff6685879444acbe41e5dba6574a072cace6e8d0eb338ad64910897369b7589e6a408c861c8e708f60fbbbe91953d4a73bcf1df11e1ecaa2885bed1e5a772bfed42d776a9', '3-17e568ddc3ed3e6fe330ca47a2b27a2707edd0e0839df59fe9114fe6c08c6fc1ac1c3c8d9ab3cf7860dac103dff464d4c215e197b54f0cb46993912c3d0220a3eb1b80adf33ee2cc59b0372c', '4-4a87367d053c533fd995032ed1e651487cb5dc1e0b1cb70a7662b152c73650f039a60f391a52f2413f43bd54eb7b12c41b42f31ac557edd4bfe46a396a8cdbe19dc9d8121924f43be51c976d', '5-7d29041c468b680fcff93c16011a2869f17de75b929b787503b412becde0321ec72fe1e499f2150a1dacb9a5f701c0b37470049dd560cef5163543469817971f50782f763f0b05ab7088f7ae']
print PlaintextToHexSecretSharer.recover_secret(shares2[0:3])

shares3 = ['1-e0c113fa1ebea9318dd413bf28308707fd660a5d1417fbc7da72416c8baaa5bf628f11c660dcee518134353e6ff8d37c', '3-b69efb4f9c5205175a4c9afb9d3c7bef728d9fb6c9cc1241411b31d4bd18744660391a330cefa8a86af8d2b80c881cfa', '4-abbbcee71f140198ff8c50f51069465075979c31d32b052e7ae82ec7f6783aef7b41a597f9504d3340967b8d70cbe5a3', '5-a7a1e271cf263279cece532b540545fa539b0f3650e2929163b02ee5459debdc53c1e07149eb2153015bb5c88e6270e8']
print PlaintextToHexSecretSharer.recover_secret(shares3[0:3])

shares4 = ['1-1b8b6c4e3145a96b1b0031f63521c8df58713c4d6d737039b0f1c0750e16e1579340cfc5dadef4e96d6b95ecf89f52b8136ae657c9c32e96bf4384e18bd8190546ff5102cd006be5e1580053', '3-572e70c5acfbe8b4c2cbd47217477d217da88c256ff2586af6a18391972c258bbea6143e7cd2ff6d39393efeb64d51d9318a2c337e50e2d764a42173bc3a1d5c7c8f24b64043daf5d2a8e9f4', '4-35fbbe40058e20463547b363d1f164c0bbbb97cfd9ffe7619bce31a59392f0e9625a2cd035276e09c4df3c0932f22bd322f16e375c7c7fd88da0f972832707eb549ff1e776db37649019ebce', '5-149480c5c75cbe320564adfa432ac8ea241e048ed39c8bc6be14ca80c392487f43a7882075d785d62cb314ea6c89a6b5f28adfa56ec481e124567b88241de2a6cabcc7ec9de3acac8be5375b']
print PlaintextToHexSecretSharer.recover_secret(shares4[0:3])

shares5 = ['1-c332b8b93a914532a2dab045ea52b86d4d3950a990b5fc5e041dce9be1fd3912f9978cad009320e18f4383ca71d9d79114c9816b5f950305a6dd19c9f458695d52', '3-e9e6850880eb0a44d36fe9f2e5a458c6da3977b7fcd285afa27e9bfc116b1408570991504116b81864b03a7060bfd5d3fb6e007bb346f276d749befd545d1489c4', '4-12b466934911986bda845d8d26710a12250d210546f46716c78d7a17b1f2c893b95b934c8c7beafcf81a3123eb2ea05ca89101b23349e455794a8d56608c8ee49dd', '5-7285289084282d559573f68eef10191091d76d6670014202670651f867cd2bc8640a86eef1c1e482affc7ae801fa446956c2186972fb6b7bac88c91d050c9d3cca']
print PlaintextToHexSecretSharer.recover_secret(shares5[0:3])

実行結果は、以下の通りで、一応フラグが得られた。

Congratulations, you decrypted a ciphertext!  One down, two to go :)
And another one's down, and another one's down, and another one bites the dust!

Three's the magic number!  FLAG{ndQzjRpnSP60NgWET6jX}

D#lliJ3]vHmXdi?m+8*OEb2(^|horg+pP;zP]HT
L       unx]{:u&uG28j=)``$gI;}F/$J#P8:j*k-=NU2e%Oo/OGGG_v    [(};
KY$$skn?d78mwh_ t

続きはボーナスラウンドに持ち込みということらしい。

FLAG{ndQzjRpnSP60NgWET6jX}

VolgaCTF 2017 Teaser Writeup

この大会は2017/2/25 18:00(JST)~2017/2/26 0:00(JST)に開催されました。
今回もチームで参戦。結果は335点で292チーム中6位でした。
自分で解けた問題をWriteupとして書いておきます。

Now you see me (Crypto 150)

スクリプトと暗号化されたPNGファイルが添付されている。
スクリプトを読むと、IDATのデータ部が4バイトごとに暗号化されていることがわかる。CRC部に鍵を暗号化しているので、まず鍵を復号して、その鍵を使って復号するコードを書く。

def bytes2reg(m):
    L = 8
    pol = []
    dic = {'1' : 1, '0' : 0}
    for i in m:
        b = bin(ord(i)).split('b')
        b = b[1]
        b = '0'*(L - len(b)) + b
        for c in b:
            pol.append(dic[c])
    return pol

def reg2bytes(pol):
    res = ""
    if len(pol) % 8 != 0:
        pol.extend([0 for _ in range(8 - (len(pol) % 8))])
    b = [int(i) for i in pol]
    for i in range(4):
        ch = 0
        pw = 7
        for _ in range(8):
            ch += b.pop(0) * (2**pw)
            pw -= 1
        res += chr(ch)
    return res

def decrypt(c, k):
    dec = [0] * 32 + [i for i in c]
    for i in range(31, -1, -1):
        dec[i] = dec[32+i] ^ dec[31+i] ^ dec[16+i] ^ dec[1+i] ^ k[i]
    return dec[:32]

def key_decrypt(c):
    dec = [0] * 32 + [i for i in c]
    for i in range(31, -1, -1):
        dec[i] = dec[31+i] ^ dec[30+i] ^ dec[15+i]
    return dec[:32]

with open('file.png', 'rb') as f:
    file = f.read()

flag = file[:file.find('IDAT')]
flag += 'IDAT'

p = file.find('IDAT')
length = int(file[p-4:p].encode('hex'), 16)
l = length - (length % 4)
cnt = p + 4 + length + 4

e_key = file[cnt - 4:cnt]
key = key_decrypt(bytes2reg(e_key))

data = file[p+4:p+length+4]
for i in range(0, l, 4):
    block = data[i:i+4]
    block = bytes2reg(block)
    d = decrypt(block, key)
    flag += reg2bytes(d)

flag += file[p + 4 + l:p + 4 + length]
flag += reg2bytes(key)
flag += file[cnt:]

with open('flag.png', 'wb') as f:
    f.write(flag)

復号すると、画像にフラグが書いてある。
f:id:satou-y:20170301205853p:plain

VolgaCTF{Th3r3_4r3_tw0_kind5_0f_crypt0gr4phy_in_7his_w0r1d}

Quiz (Joy 10)

クイズというかVolgaCTF 2017 Qualsの大会参加の意思表明みたいなものだった。

Yes

WhiteHat Challenge 01 Writeup

この大会は2017/2/25 11:00(JST)~2017/2/25 19:00(JST)に開催されました。
今回もチームで参戦。結果は135点で70チーム中7位でした。
自分で解けた問題をWriteupとして書いておきます。

For001 (For 20)

LSB.pngが与えられている。ファイル名から考えてもLSBにフラグが隠されているに違いない。
Stegsolveで開き、[Analyse]-[Data Extract]からExtract Preview画面を表示し、
Red, Green, Blueの0を選択して、Previewを見ると、ZIPフォーマットが見える。

Save Binでout.binとして保存。

$ file out.bin 
out.bin: Microsoft Word 2007+

Wordで開いてみると、モールス信号が書いてある。

. .- ... -.-- ..-. --- .-. . -. ... .. -.-.

デコードすると、easyforensic

$ echo -n easyforensic | sha1sum
1f0aa393d3e5369f391c35a793bcf1178b8299a0  -
WhiteHat{1f0aa393d3e5369f391c35a793bcf1178b8299a0}

Crypto002 (Crypto 20)

暗号化スクリプトと暗号化した画像ファいるが与えられている。スクリプトから8バイトの鍵でXORをとっていることがわかる。
そこでXOR鍵を求め、それから元の画像を復元する。

with open('out.png', 'rb') as f:
    data = f.read()

PNG_HEAD = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]

key = []
for i in range(len(PNG_HEAD)):
    key.append(ord(data[i]) ^ PNG_HEAD[i])

flag = ''
for i in range(len(data)):
    code = ord(data[i]) ^ key[i%len(key)]
    flag += chr(code)

with open('images.png', 'wb') as f:
    f.write(flag)

復号した画像にflagが書いてある。
f:id:satou-y:20170228194758p:plain
Too_easy_right?

$ echo -n "Too_easy_right?" | sha1sum
5356be1427d77ea27062cb5417c887b01a019e11  -
WhiteHat{5356be1427d77ea27062cb5417c887b01a019e11}

Re001 (Re 15)

jarファイルが与えられている。このファイルをJD-UGIで開くと、以下のコード部分がフラグに関係していそう。

         :
  Character[] ListChar = { Character.valueOf('a'), Character.valueOf('_'), Character.valueOf('y'), Character.valueOf('l'), Character.valueOf('_'), Character.valueOf('l'), Character.valueOf('a'), Character.valueOf('T'), Character.valueOf('_'), Character.valueOf('T'), Character.valueOf('_'), Character.valueOf('T'), Character.valueOf('e'), Character.valueOf('_'), Character.valueOf('y'), Character.valueOf('e'), Character.valueOf('r'), Character.valueOf('_'), Character.valueOf('S'), Character.valueOf('_'), Character.valueOf('_'), Character.valueOf('l'), Character.valueOf('r'), Character.valueOf('T'), Character.valueOf('F'), Character.valueOf('_'), Character.valueOf('Y'), Character.valueOf('_'), Character.valueOf('l'), Character.valueOf('e'), Character.valueOf('T'), Character.valueOf('T'), Character.valueOf('T'), Character.valueOf('a'), Character.valueOf('r'), Character.valueOf('T'), Character.valueOf('u'), Character.valueOf('A'), Character.valueOf('o') };
  int[] ListPos = { 11, 7, 14, 13, 26, 22, 4, 34, 15, 37, 3, 31, 19, 27, 23, 6, 18, 25, 30, 24, 17, 12, 9, 38, 28, 8, 0, 16, 21, 10, 32, 36, 33, 20, 5, 35, 2, 29, 1 };
         :
  public String generateFlag()
  {
    String flag = "";
    Character[] tmpListChar = { Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0'), Character.valueOf('\0') };
    int lenFlag = this.ListChar.length;
    for (int i = 0; i < lenFlag; ++i) {
      tmpListChar[this.ListPos[i]] = this.ListChar[i];
    }
    for (i = 0; i < lenFlag; ++i) {
      flag = flag + tmpListChar[i];
    }
    return flag;
  }
         :

プログラムでフラグを構成してみる。

list_c = ['a', '_', 'y', 'l', '_', 'l', 'a', 'T', '_', 'T', '_', 'T', 'e', '_', 'y', 'e', 'r', '_', 'S', '_', '_', 'l', 'r', 'T', 'F', '_', 'Y', '_', 'l', 'e', 'T', 'T', 'T', 'a', 'r', 'T', 'u', 'A', 'o']

list_pos = [11, 7, 14, 13, 26, 22, 4, 34, 15, 37, 3, 31, 19, 27, 23, 6, 18, 25, 30, 24, 17, 12, 9, 38, 28, 8, 0, 16, 21, 10, 32, 36, 33, 20, 5, 35, 2, 29, 1]

flag = ['\0'] * 39
for i in range(len(list_c)):
    flag[list_pos[i]] = list_c[i]

print ''.join(flag)

flagは You_are__really___really____FASTTTTTTTT

$ echo -n You_are__really___really____FASTTTTTTTT | sha1sum
1e69c12b7b2bb6b895d39c4776ef8b34489149ab  -
WhiteHat{1e69c12b7b2bb6b895d39c4776ef8b34489149ab}

BSides San Francisco CTF Writeup

この大会は2017/2/12 9:00(JST)~2017/2/14 9:00(JST)に開催されました。
今回もチームで参戦。結果は3527点で727チーム中23位でした。
自分で解けた問題をWriteupとして書いておきます。

[]root (Crypto 250)

pcapファイルが与えられている。No.11のパケットから証明書をエクスポートし、証明書(公開鍵)の内容を見てみる。

$ openssl x509 -in 11.cer -text -pubkey -inform DER
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 11416077129378495227 (0x9e6e0daa0910fafb)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=New York, L=New York, O=E Corp, CN=pki.e-corp.com/emailAddress=pki@e-corp.com
        Validity
            Not Before: Feb  1 00:39:00 2017 GMT
            Not After : Feb  1 00:39:00 2018 GMT
        Subject: C=US, ST=New York, L=New York, O=E Corp, CN=pki.e-corp.com/emailAddress=pki@e-corp.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4103 bit)
                Modulus:
                    72:6f:6f:74:00:00:00:00:00:00:00:00:00:00:00:
                    00:00:00:00:00:00:1b:00:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:ff:77:77:77:7b:00:00:00:
                    00:00:00:00:00:1f:ff:ff:ff:ff:ff:fb:00:00:00:
                    00:00:00:00:00:1f:ff:ff:ff:ff:fb:00:00:00:00:
                    00:00:00:00:00:1f:ff:ff:ff:ff:fb:00:00:00:00:
                    00:00:00:00:00:1f:ff:ff:ff:ff:ff:fb:00:00:00:
                    00:00:00:00:00:1f:ff:ff:22:22:22:2b:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
                    26:52:93:c4:42:2b:e3:53:26:38:fe:eb:2a:63:5e:
                    86:5e:5b:cc:d4:86:2d:14:91:f8:e4:6e:d4:1a:fd:
                    ab:32:ab:1e:91:3c:29:6c:45:a7:23:a3:71:cc:4a:
                    d2:18:d2:73:a4:94:ac:50:1a:1c:67:75:76:b8:4d:
                    3a:17:00:b2:4e:38:f3:d7:c8:09:0c:95:27:67:f8:
                    a9:da:53:2e:b4:49:6a:95:3f:a2:b2:64:1f:93:af:
                    58:32:1e:49:1a:d6:b3:e1:f6:60:0e:a1:75:76:35:
                    a2:d4:75:62:df:f2:f2:45:bf:c8:ed:51:14:20:93:
                    1d:e2:46:d5:63:34:d8:89:7d:64:65:b2:27:f6:c0:
                    95:ec:e1:ad:99:4c:75:51:f0:8d:bc:21:f8:b4:06:
                    91:ee:51:f5:f7:2d:05:2d:93:52:06:2f:90:b0:e7:
                    c5:2c:2e:b1:81:96:c2:c9:85:10:1a:f4:ea:c6:74:
                    99:39:6c:62:41:ad:4f:24:39:ed:11:f8:7d:67:e7:
                    3a:23:9b:86:5c:45:d6:5a:61:cf:0f:56:08:2d:e8:
                    31:b9:7f:b2:8a:e8:22:2a:71:95:e0:ec:06:c0:82:
                    81:ff:c1:6e:71:06:e7:7e:68:b8:c4:51:04:24:be:
                    eb:55:82:fe:21:cc:34:5f:53:53:46:82:b7:5c:36:
                    8d:73:c9
                Exponent: 31337 (0x7a69)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                4D:EC:FC:58:C3:9F:6B:A7:C9:0F:FC:0B:25:FD:46:F2:7C:AB:F8:44
            X509v3 Authority Key Identifier: 
                keyid:4D:EC:FC:58:C3:9F:6B:A7:C9:0F:FC:0B:25:FD:46:F2:7C:AB:F8:44

            X509v3 Basic Constraints: 
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         0d:f1:f7:4f:e1:a7:7d:0c:92:d7:29:69:09:0e:5a:49:2b:25:
         b5:95:1c:32:f6:6e:04:52:5e:fc:82:d1:9e:6a:6a:60:23:42:
         62:8a:37:24:7b:ac:f1:e6:d9:8b:d9:b7:53:a8:d5:c6:a9:9a:
         e8:7d:28:a2:41:74:1e:c5:1f:08:8c:de:7a:f1:28:f1:a9:ba:
         bf:fb:11:29:2a:3d:4f:d1:5b:a2:5f:86:ba:e8:09:30:d3:c4:
         40:67:b2:57:bd:80:b2:c9:bf:98:d2:9e:ab:2c:07:65:9f:5e:
         3f:44:8c:5f:d9:b7:a0:aa:85:5c:9d:f1:46:90:0c:7f:41:35:
         24:73:99:49:03:5f:a3:a8:45:26:c0:51:ce:0b:a5:e0:30:2a:
         59:4e:98:77:fb:4a:83:3c:af:09:e8:61:47:a5:80:1f:b0:8c:
         f0:7e:9a:b5:75:54:bd:b0:8f:05:9e:04:75:d8:c0:e6:4b:b5:
         6b:ba:20:0c:14:fb:4c:87:c3:e9:8f:47:ba:1e:23:70:9d:5b:
         bd:11:63:a3:45:e2:91:54:02:b2:af:f6:ff:cb:c7:bd:0e:b1:
         87:bf:19:11:59:93:77:1c:a0:f5:b7:1a:c1:24:d6:1d:b2:70:
         0b:96:ac:34:45:80:8d:27:53:45:15:d9:75:89:02:45:60:aa:
         ee:0e:8f:0a:a0:36:e8:2a:00:18:09:d9:0a:2d:78:bb:06:f4:
         14:b4:04:2c:f6:c0:b6:5c:a3:f8:28:1b:91:b5:2b:9e:e4:af:
         35:cf:fb:b8:7b:ed:9f:73:7b:b6:14:a8:5e:21:5f:a0:66:76:
         3d:25:65:07:ff:02:ed:24:1f:07:d9:6a:79:db:c1:7f:ce:83:
         2c:bd:2f:1c:3a:22:41:a3:f3:30:27:b4:01:59:49:32:90:32:
         96:f0:a2:8b:b7:36:61:64:cf:7e:c1:97:bd:7b:25:e8:74:65:
         f4:d4:71:21:24:ba:10:95:c0:f7:9c:4d:c9:e8:82:1e:71:4d:
         d6:3b:9b:5c:f2:72:01:41:cc:34:f7:42:e2:e8:f5:a2:9c:21:
         61:08:5c:d4:b5:bf:fe:f4:ce:9f:b8:0e:fc:a8:9d:9f:8e:0f:
         a3:f6:41:98:73:77:cc:0b:d9:7b:5a:1f:54:fd:1f:75:bd:ba:
         d0:a1:de:ac:6f:43:a9:64:31:07:91:de:b4:0e:53:da:0d:08:
         07:dc:0a:f1:8a:03:30:6b:75:f5:96:43:b3:75:30:79:a9:8e:
         fd:06:5e:d1:c4:54:09:c7:f3:2f:69:a9:5a:8d:33:02:09:9d:
         4e:a3:63:33:66:ca:9a:82:f8:5f:5b:dc:3f:45:16:35:de:68:
         d2:17:bf:0b:15:b9:d9:ae:8b
-----BEGIN PUBLIC KEY-----
MIICITANBgkqhkiG9w0BAQEFAAOCAg4AMIICCQKCAgFyb290AAAAAAAAAAAAAAAA
AAAAAAAbAAAAAAAAAAAAAAAAAB//+wAAAAAAAAAAAAAAAB//+wAAAAAAAAAAAAAA
AB///3d3d3sAAAAAAAAAAB////////sAAAAAAAAAAB//////+wAAAAAAAAAAAB//
////+wAAAAAAAAAAAB////////sAAAAAAAAAAB///yIiIisAAAAAAAAAAB//+wAA
AAAAAAAAAAAAAB//+wAAAAAAAAAAAAAAAB//+wAAAAAAAAAAAAAAAB//+wAAAAAA
AAAAAAAAAB//+wAAAAAAAAAAAAAAAB//+wAAAAAAAAAAAAAAAB//+wAAAAAAAAAm
UpPEQivjUyY4/usqY16GXlvM1IYtFJH45G7UGv2rMqsekTwpbEWnI6NxzErSGNJz
pJSsUBocZ3V2uE06FwCyTjjz18gJDJUnZ/ip2lMutElqlT+ismQfk69YMh5JGtaz
4fZgDqF1djWi1HVi3/LyRb/I7VEUIJMd4kbVYzTYiX1kZbIn9sCV7OGtmUx1UfCN
vCH4tAaR7lH19y0FLZNSBi+QsOfFLC6xgZbCyYUQGvTqxnSZOWxiQa1PJDntEfh9
Z+c6I5uGXEXWWmHPD1YILegxuX+yiugiKnGV4OwGwIKB/8FucQbnfmi4xFEEJL7r
VYL+Icw0X1NTRoK3XDaNc8kCAnpp
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
MIIFyzCCA7KgAwIBAgIJAJ5uDaoJEPr7MA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNV
BAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazERMA8GA1UEBwwITmV3IFlvcmsxDzAN
BgNVBAoMBkUgQ29ycDEXMBUGA1UEAwwOcGtpLmUtY29ycC5jb20xHTAbBgkqhkiG
9w0BCQEWDnBraUBlLWNvcnAuY29tMB4XDTE3MDIwMTAwMzkwMFoXDTE4MDIwMTAw
MzkwMFowfDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMREwDwYDVQQH
DAhOZXcgWW9yazEPMA0GA1UECgwGRSBDb3JwMRcwFQYDVQQDDA5wa2kuZS1jb3Jw
LmNvbTEdMBsGCSqGSIb3DQEJARYOcGtpQGUtY29ycC5jb20wggIhMA0GCSqGSIb3
DQEBAQUAA4ICDgAwggIJAoICAXJvb3QAAAAAAAAAAAAAAAAAAAAAABsAAAAAAAAA
AAAAAAAAH//7AAAAAAAAAAAAAAAAH//7AAAAAAAAAAAAAAAAH///d3d3ewAAAAAA
AAAAH///////+wAAAAAAAAAAH//////7AAAAAAAAAAAAH//////7AAAAAAAAAAAA
H///////+wAAAAAAAAAAH///IiIiKwAAAAAAAAAAH//7AAAAAAAAAAAAAAAAH//7
AAAAAAAAAAAAAAAAH//7AAAAAAAAAAAAAAAAH//7AAAAAAAAAAAAAAAAH//7AAAA
AAAAAAAAAAAAH//7AAAAAAAAAAAAAAAAH//7AAAAAAAAACZSk8RCK+NTJjj+6ypj
XoZeW8zUhi0UkfjkbtQa/asyqx6RPClsRacjo3HMStIY0nOklKxQGhxndXa4TToX
ALJOOPPXyAkMlSdn+KnaUy60SWqVP6KyZB+Tr1gyHkka1rPh9mAOoXV2NaLUdWLf
8vJFv8jtURQgkx3iRtVjNNiJfWRlsif2wJXs4a2ZTHVR8I28Ifi0BpHuUfX3LQUt
k1IGL5Cw58UsLrGBlsLJhRAa9OrGdJk5bGJBrU8kOe0R+H1n5zojm4ZcRdZaYc8P
Vggt6DG5f7KK6CIqcZXg7AbAgoH/wW5xBud+aLjEUQQkvutVgv4hzDRfU1NGgrdc
No1zyQICemmjUDBOMB0GA1UdDgQWBBRN7PxYw59rp8kP/Asl/UbyfKv4RDAfBgNV
HSMEGDAWgBRN7PxYw59rp8kP/Asl/UbyfKv4RDAMBgNVHRMEBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4ICAgAN8fdP4ad9DJLXKWkJDlpJKyW1lRwy9m4EUl78gtGeampg
I0Jiijcke6zx5tmL2bdTqNXGqZrofSiiQXQexR8IjN568Sjxqbq/+xEpKj1P0Vui
X4a66Akw08RAZ7JXvYCyyb+Y0p6rLAdln14/RIxf2begqoVcnfFGkAx/QTUkc5lJ
A1+jqEUmwFHOC6XgMCpZTph3+0qDPK8J6GFHpYAfsIzwfpq1dVS9sI8FngR12MDm
S7VruiAMFPtMh8Ppj0e6HiNwnVu9EWOjReKRVAKyr/b/y8e9DrGHvxkRWZN3HKD1
txrBJNYdsnALlqw0RYCNJ1NFFdl1iQJFYKruDo8KoDboKgAYCdkKLXi7BvQUtAQs
9sC2XKP4KBuRtSue5K81z/u4e+2fc3u2FKheIV+gZnY9JWUH/wLtJB8H2Wp528F/
zoMsvS8cOiJBo/MwJ7QBWUkykDKW8KKLtzZhZM9+wZe9eyXodGX01HEhJLoQlcD3
nE3J6IIecU3WO5tc8nIBQcw090Li6PWinCFhCFzUtb/+9M6fuA78qJ2fjg+j9kGY
c3fMC9l7Wh9U/R91vbrQod6sb0OpZDEHkd60DlPaDQgH3ArxigMwa3X1lkOzdTB5
qY79Bl7RxFQJx/MvaalajTMCCZ1Oo2MzZsqagvhfW9w/RRY13mjSF78LFbnZros=
-----END CERTIFICATE-----

nをFermat法で素因数分解してみる。

def isqrt(n):
    x = n
    y = (x + n // x) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x

def fermat(n):
    x = isqrt(n) + 1
    y = isqrt(x * x - n)

    while True:
        w = x * x - n - y * y
        if w == 0:
            break
        elif w > 0:
            y += 1
        else:
            x += 1
    return x - y, x + y

n = 0x726f6f7400000000000000000000000000000000001b000000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001fffff7777777b00000000000000001ffffffffffffb00000000000000001ffffffffffb0000000000000000001ffffffffffb0000000000000000001ffffffffffffb00000000000000001fffff2222222b00000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb00000000000000265293c4422be3532638feeb2a635e865e5bccd4862d1491f8e46ed41afdab32ab1e913c296c45a723a371cc4ad218d273a494ac501a1c677576b84d3a1700b24e38f3d7c8090c952767f8a9da532eb4496a953fa2b2641f93af58321e491ad6b3e1f6600ea1757635a2d47562dff2f245bfc8ed511420931de246d56334d8897d6465b227f6c095ece1ad994c7551f08dbc21f8b40691ee51f5f72d052d9352062f90b0e7c52c2eb18196c2c985101af4eac67499396c6241ad4f2439ed11f87d67e73a239b865c45d65a61cf0f56082de831b97fb28ae8222a7195e0ec06c08281ffc16e7106e77e68b8c4510424beeb5582fe21cc345f53534682b75c368d73c9
p, q = fermat(n)
print 'p =', p
print 'q =', q

実行結果は以下の通り。

p = 345709341936068338730678003778405323582109317075021198605451259081268526297654818935837545259489748700537817158904946124698593212156185601832821337576558516676594811692389205842412600462658083813048872307642872332289082295535733483056820073388473845450507806559178316793666044371642249466611007764799781626418800031166072773475575269610775901034485376573476373962417949231752698909821646794161147858557311852386822684705642251949742285300552861190676326816587042282505137369676427345123087656274137257931639760324708350318503061363031086796994100943084772281097123781070811610760735943618425858558459014484742232018933
q = 345709341936068338730678003778405323582109317075021198605451259081268526297654818935837545259489748700537817158904946124698593212156185601832821337576558516676594811692389205842412600462658083813048872307642872332289082295535733483056820073388473845450507806559178316793666044371642249466611007764799781626418800031166072773475575269610775901034485376573476373962417949231752698909821646794161147858557311852386822684705642251949742285300552861190676326816587042282505137369676427345123087656274137257931639760324708350318503061363031086796994100943084772281097123781070811610760735943618425858558459014484742232019973

pとqがわかったので、秘密鍵を作成する。

$ rsatool.py -f PEM -o secret.pem -p 345709341936068338730678003778405323582109317075021198605451259081268526297654818935837545259489748700537817158904946124698593212156185601832821337576558516676594811692389205842412600462658083813048872307642872332289082295535733483056820073388473845450507806559178316793666044371642249466611007764799781626418800031166072773475575269610775901034485376573476373962417949231752698909821646794161147858557311852386822684705642251949742285300552861190676326816587042282505137369676427345123087656274137257931639760324708350318503061363031086796994100943084772281097123781070811610760735943618425858558459014484742232018933 -q 345709341936068338730678003778405323582109317075021198605451259081268526297654818935837545259489748700537817158904946124698593212156185601832821337576558516676594811692389205842412600462658083813048872307642872332289082295535733483056820073388473845450507806559178316793666044371642249466611007764799781626418800031166072773475575269610775901034485376573476373962417949231752698909821646794161147858557311852386822684705642251949742285300552861190676326816587042282505137369676427345123087656274137257931639760324708350318503061363031086796994100943084772281097123781070811610760735943618425858558459014484742232019973 -e 31337
Using (p, q) to initialise RSA instance

n =
726f6f7400000000000000000000000000000000001b000000000000000000000000001ffffb0000
000000000000000000001ffffb0000000000000000000000001fffff7777777b0000000000000000
1ffffffffffffb00000000000000001ffffffffffb0000000000000000001ffffffffffb00000000
00000000001ffffffffffffb00000000000000001fffff2222222b00000000000000001ffffb0000
000000000000000000001ffffb0000000000000000000000001ffffb000000000000000000000000
1ffffb0000000000000000000000001ffffb0000000000000000000000001ffffb00000000000000
00000000001ffffb00000000000000265293c4422be3532638feeb2a635e865e5bccd4862d1491f8
e46ed41afdab32ab1e913c296c45a723a371cc4ad218d273a494ac501a1c677576b84d3a1700b24e
38f3d7c8090c952767f8a9da532eb4496a953fa2b2641f93af58321e491ad6b3e1f6600ea1757635
a2d47562dff2f245bfc8ed511420931de246d56334d8897d6465b227f6c095ece1ad994c7551f08d
bc21f8b40691ee51f5f72d052d9352062f90b0e7c52c2eb18196c2c985101af4eac67499396c6241
ad4f2439ed11f87d67e73a239b865c45d65a61cf0f56082de831b97fb28ae8222a7195e0ec06c082
81ffc16e7106e77e68b8c4510424beeb5582fe21cc345f53534682b75c368d73c9

e = 31337 (0x7a69)

d =
618caed447e3b3a23fe661970669b19fc8517f1affef47db561cb4eec562b589878940899882f490
236c017870796d86753252ae97d1d1b6869490ec30867fa71e7062aecf0057fcae6bfb324c5133d1
693cc566e44c48c1ee139f5fc079d203feebf1c911d1bcccb8b925e5adbc6a851c2072bebcea000c
8c4850736a69c0865e310824f9e7de36429cb3e32ff88bf7ef4ccb39e7585de9ed3a1feaea85d087
486ba35c521e0be928a478d51a5915f3672b673c2247383670ba5991427b3dcce8d2e5c4bd7e7c0f
0a3a96eff4a0de771767a8e20f46c97a8e5f9d7878d6f3116cce6bb8462014be21875d557137bd24
8eb3590d95fce7a17bdcbdd223465cc017d6fc76fbfe2e4b9ccc49241ba452fdf84d1c8185cad33a
83c5b5ac43d946df4c3648af4f7714cd584db1ecd14458c8827ac222c3ca08280c2ba687c19aa8df
77d498cfaf700c9019f505380a78ba43f2f1bcd82a15e19c4daa3b33051d31aec1a94e043f81b7fb
21af1975588fdaa0dbfb269f118e5c4e9e26922c1440ab85357aab110361662927b74f2fe27825ba
e9e9d7aa341d8341b93588eda2e780cd99ad790ac28146f113b3d09f470e64c07a0bd51d8b4b7470
c9a931414305a53fda0a168561a2b8906ce7ff4215c0912248d55ca3e0499af1f59877b78a07a377
e570f1b9fe70b9b5cd9461bf6bc39f8734ea07b4e3f6a71129179b4183d3e4f0a9

p =
ab28ba5dbd67a4b8b4c20b76958ad57ef5513ea01af2ad59b1691a4b60e7eee058aa4776bc96a3b7
b3b3ab98a743ff0e16c22033481dfd0c83654311e153b14d5067ea4664d419b97ba28a6ee5693b00
acb7c7046762b0d8ece2bdbdc4c784923178beb1c8c78fd123003f4c107f2aa772a7f22f3052ee69
561a265acf618513acd76321d2c3a6dcd6456152c4032d8fd285ee013746eb1439f4c9c66b9ffd90
3b63208bbb0bf82b52cfc6bd12df96f3d9fa12c96456fd94e7f5c1238b3d5089e6be64ac555f8468
3ede12cc1ffa1a66fbe5e4d2c830e14d6954c48747bc1cec60582a312ee97274a9f7211e3213ff20
81d9f69b07a7b0fa8f89edd037e730ff5

q =
ab28ba5dbd67a4b8b4c20b76958ad57ef5513ea01af2ad59b1691a4b60e7eee058aa4776bc96a3b7
b3b3ab98a743ff0e16c22033481dfd0c83654311e153b14d5067ea4664d419b97ba28a6ee5693b00
acb7c7046762b0d8ece2bdbdc4c784923178beb1c8c78fd123003f4c107f2aa772a7f22f3052ee69
561a265acf618513acd76321d2c3a6dcd6456152c4032d8fd285ee013746eb1439f4c9c66b9ffd90
3b63208bbb0bf82b52cfc6bd12df96f3d9fa12c96456fd94e7f5c1238b3d5089e6be64ac555f8468
3ede12cc1ffa1a66fbe5e4d2c830e14d6954c48747bc1cec60582a312ee97274a9f7211e3213ff20
81d9f69b07a7b0fa8f89edd037e731405

Saving PEM as secret.pem

Wiresharkで以下の設定によりSSLの復号をし、SSL Streamを見る。

  • IP address: 4.3.2.1
  • Port: 443
  • Protocol: http
  • Key File: secret.pem
GET /modulus.txt HTTP/1.0
Host: 4.3.2.1
User-Agent: E Corp PKI Modulus Fetch
Accept: */*

HTTP/1.0 200 ok
Content-type: text/plain

72:6f:6f:74:00:00:00:00:00:00:00:00:00:00:00:
00:00:00:00:00:00:1b:00:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:ff:77:77:77:7b:00:00:00:
00:00:00:00:00:1f:ff:ff:ff:ff:ff:fb:00:00:00:
00:00:00:00:00:1f:ff:ff:ff:ff:fb:00:00:00:00:
00:00:00:00:00:1f:ff:ff:ff:ff:fb:00:00:00:00:
00:00:00:00:00:1f:ff:ff:ff:ff:ff:fb:00:00:00:
00:00:00:00:00:1f:ff:ff:22:22:22:2b:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:00:1f:ff:fb:00:00:00:00:00:00:00:
00:00:00:00:1f:ff:00:ff:fb:00:00:00:00:00:00:
00:00:00:00:1f:00:00:00:fb:00:00:00:00:00:00:
00:00:00:1f:00:00:00:00:00:fb:00:00:00:00:00:
00:00:00:1f:00:00:00:00:00:fb:00:00:00:00:00:
00:00:1f:00:00:00:00:00:00:00:fb:00:00:00:00:
00:00:1f:00:00:00:00:00:00:00:fb:00:00:00:00:
00:00:00:1f:00:00:00:00:00:fb:00:00:00:00:00:
00:00:00:1f:00:00:00:00:00:fb:00:00:00:00:00:
00:00:00:00:1f:00:00:00:fb:00:00:00:00:00:00:
00:00:00:00:1f:ff:00:ff:fb:00:00:00:00:00:00:
00:00:00:00:00:00:1b:00:00:00:00:00:00:00:00:
00:00:00:00:00:00:00:00:00:00:00:00:66:6c:61:
67:3a:77:68:65:6e:5f:73:6f:6c:76:69:6e:67:5f:
70:72:6f:62:6c:65:6d:73:5f:64:69:67:5f:61:74:
5f:74:68:65:5f:72:6f:6f:74:73:5f:69:6e:73:74:
65:61:64:5f:6f:66:5f:6a:75:73:74:5f:68:61:63:
6b:69:6e:67:5f:61:74:5f:74:68:65:5f:6c:65:61:
76:65:73

最後の66:6c:61:からフラグのASCIIコードのようなので、デコードする。

enc = '66:6c:61:67:3a:77:68:65:6e:5f:73:6f:6c:76:69:6e:67:5f:70:72:6f:62:6c:65:6d:73:5f:64:69:67:5f:61:74:5f:74:68:65:5f:72:6f:6f:74:73:5f:69:6e:73:74:65:61:64:5f:6f:66:5f:6a:75:73:74:5f:68:61:63:6b:69:6e:67:5f:61:74:5f:74:68:65:5f:6c:65:61:76:65:73'

dec = enc.replace(':', '').decode('hex')
print dec

実行結果は以下の通り。

flag:when_solving_problems_dig_at_the_roots_instead_of_just_hacking_at_the_leaves
when_solving_problems_dig_at_the_roots_instead_of_just_hacking_at_the_leaves

nullcon HackIM Writeup

この大会は2017/2/11 1:30(JST)~2017/2/12 13:30(JST)に開催されました。
今回もチームで参戦。結果は1950点で363チーム中48位でした。
自分で解けた問題をWriteupとして書いておきます。

Programming Question 1 (Programming 200)

3色のデータが全部で528601個ある。
factordbで素因数分解すると、528601 = 569 × 929
幅、高さをこの長さにして画像にしてみる。

from PIL import Image

with open('abc.txt', 'r') as f:
    data = f.read()

data = data[2:-3]
colors = data.split('), (')

WIDTH = 929
HEIGHT = 569 
img = Image.new('RGB', (WIDTH, HEIGHT), (255, 255, 255))

i = 0
for y in range(HEIGHT):
    for x in range(WIDTH):
        rgb = colors[i].split(', ')
        img.putpixel((x, y), (int(rgb[0]), int(rgb[1]), int(rgb[2])))
        i += 1

img.save('flag.png')

画像の右下にフラグがある。
f:id:satou-y:20170217224554p:plain

flag{Pil_PIL_PIL}

Programming Question 3 (Programming 300)

何重にもいろんなアーカイブ方法で圧縮されている。都度対応する展開・解凍方法で戻していく。

import subprocess
import os

cmd_file = 'file %s'
cmd_lzma = 'xz -d %s'
cmd_tar = 'tar xvf %s'
cmd_xz = 'xz -d %s'
cmd_gz = 'gzip -d %s'
cmd_bz2 = 'bzip2 -d %s'
cmd_shk = 'nulib2 -x %s'
cmd_lz = 'lzip --decompress %s'
cmd_zpaq = 'zpaq x %s'
cmd_zoo = 'zoo x %s'
cmd_7z = '7z e %s'
cmd_arj = 'arj e %s'
cmd_zip = 'unzip %s'

filename_base = '26685'
filename_lzma = '26685.lzma'
filename_tar = '26685.tar'
filename_xz = '26685.xz'
filename_gz = '26685.gz'
filename_bz2 = '26685.bz2'
filename_shk = '26685.shk'
filename_lz = '26685.lz'
filename_zpaq = '26685.zpaq'
filename_zoo = '26685.zoo'
filename_7z = '26685.7z'
filename_arj = '26685.arj'
filename_zip = '26685.zip'

i = 1
while True:
    print '%d times' % i
    cmd = cmd_file % filename_base
    ret = subprocess.check_output( cmd.split(" ") )
    print ret
    if 'LZMA compressed' in ret:
        os.rename(filename_base, filename_lzma)
        os.system(cmd_lzma % filename_lzma)
    elif 'tar archive' in ret:
        os.rename(filename_base, filename_tar)
        os.system(cmd_tar % filename_tar)
        os.remove(filename_tar)
    elif 'XZ compressed' in ret:
        os.rename(filename_base, filename_xz)
        os.system(cmd_xz % filename_xz)
    elif 'gzip compressed' in ret:
        os.rename(filename_base, filename_gz)
        os.system(cmd_gz % filename_gz)
    elif 'bzip2 compressed' in ret:
        os.rename(filename_base, filename_bz2)
        os.system(cmd_bz2 % filename_bz2)
    elif 'NuFile archive' in ret:
        os.rename(filename_base, filename_shk)
        os.system(cmd_shk % filename_shk)
        os.remove(filename_shk)
    elif 'lzip compressed' in ret:
        os.rename(filename_base, filename_lz)
        os.system(cmd_lz % filename_lz)
    elif 'ZPAQ stream' in ret:
        os.rename(filename_base, filename_zpaq)
        os.system(cmd_zpaq % filename_zpaq)
        os.remove(filename_zpaq)
    elif 'Zoo archive' in ret:
        os.rename(filename_base, filename_zoo)
        os.system(cmd_zoo % filename_zoo)
        os.remove(filename_zoo)
    elif '7-zip archive' in ret:
        os.rename(filename_base, filename_7z)
        os.system(cmd_7z % filename_7z)
        os.remove(filename_7z)
    elif 'ARJ archive' in ret:
        os.rename(filename_base, filename_arj)
        os.system(cmd_arj % filename_arj)
        os.remove(filename_arj)
    elif 'Zip archive' in ret:
        os.rename(filename_base, filename_zip)
        os.system(cmd_zip % filename_zip)
        os.remove(filename_zip)
    else:
        break
    i += 1

254回解凍すると、次のテキストが得られる。

total 120
drwx------ 2 root     root     28672 Dec 23 21:01 apt-dpkg-install-kKBLWj
-rw-r--r-- 1 root     root     71259 Dec 23 19:50 apt-fast.list
-rw-r--r-- 1 root     root         0 Dec 23 19:50 apt-fast.lock
-rw-r--r-- 1 root     root         0 Dec 23 21:03 secr
drwx------ 3 root     root      4096 Dec 23 19:30 systemd-private-20af98806288452f91376e836938dc35-colord.service-hbUpEj
drwx------ 3 root     flag      4096 Dec 23 19:30 63336C756448746861486C35634442684C565A686353467566513D3D

flagグループの16進数のファイル名をデコードしていくと、フラグが得られる。

enc ='63336C756448746861486C35634442684C565A686353467566513D3D'
print enc.decode('hex').decode('base64').decode('rot13')
flag{nullc0n-Ind!a}

Crypto Question 2 (Crypto 350)

図にあるa, bの組み合わせを答える問題。
f:id:satou-y:20170217224929p:plain
総当たりでa, bの組み合わせを探す。

def search_log(g, ga, q):
    list_log = []
    for i in range(2, 1001):
        if pow(g, i, q) == ga:
            list_log.append(i)
    return list_log

q = 541
g = 10
ga = 298
gb = 330
list_a = search_log(g, ga, q)
list_b = search_log(g, gb, q)

for a in list_a:
    for b in list_b:
        if pow(g, a * b, q) == 399:
            print 'flag{%d,%d}' % (a, b)

実行結果は以下の4通り。

flag{170,268}
flag{170,808}
flag{710,268}
flag{710,808}

フラグが通ったのは、このうち一つ。

flag{170,808}

Misc2 (Misc 300)

$ file artefact 
artefact: XZ compressed data
$ mv artefact artefact.xz
$ xz -d artefact.xz
$ file artefact 
artefact: Linux rev 1.0 ext3 filesystem data, UUID=c6666f0c-f641-4958-be07-bcc6540fdafd (large files)

FTK Imagerで開く。
[unallocated space]の09837がJPEGのようだ。
ヘッダを書き換えFF D8 FF E0にし、FF D9より後ろを切り落とすと、JPEG画像になりフラグが書いてあった。
f:id:satou-y:20170217225435j:plain

flag{i_h@te_stupid_color$}