sudoをしっかり読もう

あなたが初めてsudoコマンドを実行したときに出力されたメッセージを(読みました|覚えています)か?

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

以下の通り。

  1. 他人のプライバシーを尊重しよう
  2. 入力する前によく考えよう
  3. 「大いなる力には、大いなる責任が伴う」*1

sudoは何でもできてしまうということです。他人を傷つけてしまうかもしれないし、自分を殺してしまうかもしれない。

perl-5.18のhash randomizationについて

perl-5.18.0がリリースされました。

大きな変更点としてhash randomization(ハッシュのランダム化)が挙げられます。each(), keys(), values()の出力結果がランダムになるというものです。ちなみにprint %hash;したときもランダムになります。これによってテストがこけると言われていますが、ただテストがこけるだけなのか、そうではないとかというのが疑問だと思います。
実際にはほとんど問題ありません(テストがこけるだけかもしれません)。しかし、(ときどき)動かなくなるものも存在します。気をつけるポイントはひとつです。ハッシュはできる限りsortしてから扱うことです。

実例

Test::Difflet::is_deeply()にはhash randomizationに関するバグがありました。Data-Difflet-0.08ではすでにfixされています。

  • Data::Dumperの出力結果を比較することでデータ構造の比較を実現している
  • hash randomizationによってData::Dumperの出力結果がランダムになった
    • 配慮しているつもりだったが、SortkeysとするところをSortKeysとしていた
--- a/lib/Test/Difflet.pm
+++ b/lib/Test/Difflet.pm
@@ -41,7 +41,7 @@ sub _eq_deeply {
     my ($a, $b) = @_;
     local $Data::Dumper::Terse = 1;
     local $Data::Dumper::Indent = 0;
-    local $Data::Dumper::SortKeys = 1;
+    local $Data::Dumper::Sortkeys = 1;
     return Dumper($a) eq Dumper($b);
 }


蛇足ですが、Data::Dumperの出力がランダムになったのでデバッグするときにData::Dumperを使ってるんだよねーといった人は戸惑うかもしれません。
local $Data::Dumper::Sortkeys = 1;しておくようなsnippetを書いておくと捗りそうです。

snippet dumper
    use Data::Dumper; local $Data::Dumper::Sortkeys = 1; warn Dumper(${1:code});

特定のWi-Fiに接続したときにあることをしよう

335さんの記事(minilla を使って cocoa な xs module を書く - soh335 memo)を見て、手軽にCocoaなXS moduleが書けるようになったらしいことを知ったのでさらっと書いてみた。
akiym/Cocoa-NetworkChange · GitHub
自宅のWi-Fiに接続したらsyncしたいとか、認証するといったときに便利。

use strict;
use warnings;
use Cocoa::EventLoop;
use Cocoa::NetworkChange;

on_network_change(sub {
    my ($wlan) = @_;
    # on connected
    if ($wlan->{ssid} && $wlan->{ssid} =~ /aterm/) {
        # ...
    }
}, sub {
    # on disconnected
});

Cocoa::EventLoop->run;

メモ

  • minil buildするときにはgit addし忘れていないか確認する
  • XSUtilでいうcc_src_pathsを指定したいとき、Module::Buildではc_sourceを指定するが、.mに対応していないのでinclude_dirsとobjectsを個別に指定する

tkbctf1 writeup #2

fairy (Challenge 9)

割と解いた人が少なかった問題でした。

We need to access a thin client to get trade secret of rival company.
However the client needs to be unlocked at boot sequence. Can you unlock?
This file may help you.

中身はtcpdumpのキャプチャファイルです。

% file 250d3a31dee7f62d57ea3d17f544b5e4750e8039
250d3a31dee7f62d57ea3d17f544b5e4750e8039: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)

Wiresharkで開いてみたところ、TFTPでinitrd.gzとかを送信しているみたいです。
f:id:akiym:20130506165006p:plain
pxelinux.config/defaultにパスワードのハッシュがありました。
f:id:akiym:20130506165020p:plain

default menu.c32

label debian
	menu passwd $4$OVtcFw7z$9S2RpE0jMdbV1Z/+daXh2RGQtDM$
        kernel linux
        append initrd=initrd.gz

あとはjohn the ripperに投げるだけですが、このままの形では無理なのでうまく整形します。

use strict;
use warnings;
use utf8;
use MIME::Base64;

my $flag = '$4$OVtcFw7z$9S2RpE0jMdbV1Z/+daXh2RGQtDM$';

my ($salt, $hash) = $flag =~ /\$4\$(.+)\$(.+)\$/;
$hash = decode_base64($hash);
$hash = unpack 'H*', $hash;

print "\$SHA1p\$$salt\$$hash";
% john --format=sha1-gen --show password.john
?:goodluck

1 password hash cracked, 0 left

となるので、goodluckがflagでした。

tkbctf1 writeup

tkbctf1にikachanとして参加してきました。こういったCTFに参加するのは初めてでしたが、とても楽しめました。
運営の皆様大変お疲れ様でした。

Good Old Days (Challenge 7)

個人的にツボでした。問題文はこちら。

[ADVANCED]
I need the "Message" to continue my game but I forgot the secret command!!!
Can you get the "Message"? I remember that the "Message" was alphanumeric characters.

渡されたファイルの中身はなんとファミコンのROMでした。

% file cb0c3d0f55b9b627b831f4fbbc153846
cb0c3d0f55b9b627b831f4fbbc153846: iNES ROM dump, 2x16k PRG, 1x8k CHR, [Vert.], [SRAM]

f:id:akiym:20130506005116j:plain
キー入力ができるようになっていて、それに対して出力される文字が変化する。
f:id:akiym:20130506005224j:plain
f:id:akiym:20130506005240j:plain
おもむろにデバッガ起動。
f:id:akiym:20130506005811j:plain
ブレークポイントを設定、上方向キーを入力。
f:id:akiym:20130506005838j:plain
f:id:akiym:20130506005906j:plain
上方向キーを入力した場合、0xC9でXORされていますね。すべてのキーで調べたところ、

A: 0x36でXOR
B: 0x5CでXOR
↑: 0xC9でXOR
↓: 0xA3でXOR
←: 左ローテート
→: 右ローテート

となっていることがわかりました。
$6000-$6007が順番にキーの入力によって変わるみたいですね。
f:id:akiym:20130506010239j:plain
キー入力後:
f:id:akiym:20130506005347j:plain
大体のことは分かったので、ちょろっとスクリプトを書きます。条件として、メッセージは英数字なのである程度の見当はつくはずです。

use strict;
use warnings;
use utf8;

my %control = (
    a     => sub { $_[0] ^ 0x36 },
    b     => sub { $_[0] ^ 0x5c },
    up    => sub { $_[0] ^ 0xc9 },
    down  => sub { $_[0] ^ 0xa3 },
    left  => sub { $_[0] << 1 },
    right => sub { $_[0] >> 1 },
);

for my $c (0xbe, 0x60, 0xa4, 0xa5, 0x88, 0x64, 0x03, 0x6a) {
    for my $key (keys %control) {
        my $output = chr($control{$key}->($c));
        if ($output =~ /^[A-Za-z0-9]$/) {
            print "$key\t: $output\n";
        }
    }
    print "\n";
}

実行すると、いくつか候補が出てくるのでいい感じに組み合わせると "w0RlD256" がflagだとわかります。
f:id:akiym:20130506010152j:plain

LWP::UserAgent@6.05でX-Meta-Twitter:cardがヘッダに含まれているページがうまく取得できない

詳しくはlwp-download fails with HTTP::Message 6.06 · Issue #3 · libwww-perl/http-message · GitHubに書かれていますが、要約すると

X-Meta-Twitter:cardのような:がヘッダに含まれているとIllegalであると判断されるようになってしまった

use strict;
use warnings;
use utf8;
use LWP::UserAgent 6.05;

my $ua = LWP::UserAgent->new();
my $res = $ua->get('http://www.youtube.com/watch?v=9Y6H-YjsE9Q');
print $res->content, "\n";
print $res->header('X-Died'), "\n";

例えば、みんな大好きYouTubeのページはうまく取得できません。X-Diedヘッダ(LWP内部での例外メッセージが覗けます)を見ると、なるほどーという感じですね。

Illegal field name 'X-Meta-Twitter:card' at HTML/HeadParser.pm line 207.

はてなブログX-Meta-Twitter:cardがヘッダに含まれているので、うまく取得できませんね。

LWP::UserAgent@6.04を使う

割と困るので、6.05ではなく6.04を使うと幸せになれます。(いつ6.07がリリースされるんでしょうね)

akictfのはなし

最近CTFというものを知って、結構面白いなーと思いながらksnctfをちょこちょこやっています。
先日、とある方に「セキュリティについてもっとよく知りたい、これから先ステップアップするにはどうすればいいか」と聞いたところ、問題を作るのがいいよと言われたのでなるほどと思い、自分で問題を作ってみるのも面白そうだったのでちょろっと作ってみました。

akictf

もう動いている→akictf

個人的に好きな問題はHorizontal lineで、ぱっと見た感じはよくわからなくて、CTFをやったことがなくても解けてしまう感じがいいです。ほかはfrom login formもおすすめです。

問題を作るのは楽しいけど、基本的に自分の知っている技術に偏ってしまいがちなので、幅広く網羅できるようになっていきたいですね。