トップ 最新 追記

yoggy's diary

〜せかいのすみっこから〜


2008-06-02

CTF08 Quals Challenge

参戦されたみなさま、お疲れさまでしたー

2543753765_c9b1d73dcd_m.jpg

また、参戦中いろいろな差し入れをいただきました。ありがとうございました。m(_ _)m

2544580780_f1b31f9de3_m.jpg

今年の問題の傾向としては、Web系の問題がなくなったため、全般的に問題の難易度が高くなっていたような気がします。

結果はともかく、限られた時間の中で知恵を絞ってさまざまな問題にチャレンジでき、非常に有意義な時間を過ごせたと思っています。

また来年もチャレンジしたいですねー


2008-06-03

CTF08予選の結果分析

去年作った集計用スクリプトを修正して、今年の結果を集計するスクリプトを作成しました。

上位7位、上位30位、全体、チドリのジャンル別得点平均はこんな感じでした。

dcc2fecdb18940b1452b28c0fc0432e6.png

  • チドリとしては…
    • Binary, Real World, Potentの200点問題が取れてないのが、ボディーブローのように効いているなあ…という感じ。
  • 全体的にRealWorldとPotent Pwnablesの平均点が低いのは…
    • 予選中にreal400,real500,pw400,pw500の問題が開かなかったのが原因。
      • CTFのルールでは、誰かが問題を解かないと次の問題が開かないようになっている。
    • 例年に比べて、今年の問題は難しかったのが原因だと思います。
  • 今年の問題の傾向としては…
    • 下記のような過去に登場したことがない分野からの出題がありました。
      • 生パケット送信ネタ
      • 参加者のコミュニケーション用MUDを使った問題
      • Javaが初登場。でもあんまり関係なかったりw
      • XML-RPCクライアントを作って攻略する問題
      • 実は、Twitterに答えが隠されていた問題
    • 一般的な監査・解析技術だけではなく、幅広い知識が要求される予選だったと思いました。

CTFって何?という方は、チドリサイトに掲載しているこちらの記事もあわせて読んでみてください。

追記

今年もこちらに模範解答が掲載されています。現地点ではTriviaとForensicsの解答だけみたいですが、他のジャンルの解答もそのうち掲載されるはずです。


2008-06-08

Chumbyで日本語を表示できるテキストビューアーを作ってみました

こんな感じで、Webサーバ上においてあるテキストファイルを表示できるwidgetを作ってみました。UTF-8のテキストファイルを表示できることを確認しています。

さきほどpublicでChumbyのサイトに登録してみたのですが、まだwidget一覧には表示されていないみたいです。

2560675760_be005bf62d_m.jpg

使い方はChumbyのMy Channnelに"textviewer widget"を追加したあと、"customize"で表示したいテキストファイルのURLを設定してください。

bd47767c093131f903abce0cf2e3a8fe.png

次に、テキストファイルと同じディレクトリに、次の内容のcrossdomain.xmlファイルを置いてください。

<?xml version="1.0" ?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
    <site-control permitted-cross-domain-policies="all"/>
    <allow-access-from domain="www.sabamiso.net" to-ports="80" />
</cross-domain-policy>

domain="www.sabamiso.net"な理由は下記の通りです。

  • swfファイルの実体(textviewr.swf)はwww.sabamiso.net上に置いているため。
  • Chumbyのサイトに登録しているのは、実体(textviewr.swf)をロードするloader.swf
  • 本体はIPAゴシックを含んでいてサイズが大きいため、2段ブート(?)になっています

ファイル一式はこちら。

追記

こちらに登録されたようです。

ProxyみたいなCGIを経由してテキストを読めばcrossdomain.xmlはいらないかな?と思ったのですが、Chumbyからのリクエストだけを判別して許可するのは難しいので、crossdomain.xmlを置いてChumbyから直接読みに行く実装にしました。

あと、loader.swf(ローダ)からテキストファイルのURLをtextviewer.swf(本体)へ渡す方法が非常にダサいのですが、その理由は時間があればまた後日ということで…w


2008-06-15

そろそろ暑くなってきそうなので、Chumbyに室温を表示してみる

PCにUSBで接続できる温度センサを仕入れてみたので、これを使って室温を記録して、Chumbyにグラフを表示してみました。

2577562227_06b28f13e8.jpg

センサと温度を取得するためのプログラムはこちらを使いました。

RRDtoolを使ってデータを蓄積・グラフの描画を行って、それをLoad Image from URLを使って表示しています。

こちらが温度の取得・蓄積を行うスクリプト。cronで5分に一回実行してます。

#!/usr/bin/perl
use strict;
use warnings;
use DateTime;

# configuration
my $rrd_path     = '/path_to_rrd_file/rrd_temp.rrd';
my $rrdtool_path = '/usr/bin/rrdtool';
my $usbrh_path   = '/usr/local/bin/usbrh';

# check rrd file
if (!(-f $rrd_path)) {
  my $c = "$rrdtool_path create $rrd_path --start `date +%s` --step 300 DS:Temperature:GAUGE:600:U: U RRA:AVERAGE:0.5:3:2880";
  system($c);
}

# get temperature & humidity
open my $usbrh, '-|' or exec $usbrh_path or die $!;
my $str = <$usbrh>;
my ($temp, $humi) = split /\s+/, $str;

my $epoch = DateTime->now(time_zone=>'local')->epoch();

my $cmd = "$rrdtool_path update $rrd_path --template Temperature $epoch:$temp";
#print $cmd . "\n";
system($cmd);

こちらがグラフを作成するスクリプト。15分に一回実行しています。

#!/usr/bin/perl
use strict;
use warnings;
use DateTime;

# configuration
my $rrd_path     = '/path_to_rrd_file/rrd_temp.rrd';
my $rrdtool_path = '/usr/bin/rrdtool';
my $png_path     = '/var/www/yoggy/temprature/rrd_temp.png';

# check rrd file
die "rrd file not found...$rrd_path" if (!(-f $rrd_path));

# create graph
my $et = DateTime->now(time_zone=>'local');
my $st = $et->clone->subtract(days => 1);

my $et_e = $et->epoch;
my $st_e = $st->epoch;

my $cmd = "LANG=C $rrdtool_path graph $png_path --title temperature --start $st_e --end $et_e --x-grid HOUR:1:DAY:1:HOUR:4:0:%H --alt-autoscale --alt-y-grid --font TITLE:18 --font UNIT:18 --font AXIS:18 --width 320 --height 240 DEF:temp=$rrd_path:Temperature:AVERAGE LINE3:temp#FF0000 >/dev/null 2>&1";
#print $cmd . "\n";
system($cmd);

…実はこの温度をChumbyで表示するというのは、はじめは先日作ったtextviewer widgetと簡単なCGIを作って表示していたのですが、 温度変化が知りたいなあと思ったので、グラフを表示してみたのでした。

2576394571_5ebf18bdba_m.jpg


2008-06-18

ocvcap.c

OpenCVを使って、1フレームだけキャプチャするプログラムを試しに作ってみたのでメモ。

//
// ocvcap.c - camera capture program using OpenCV
//
//  gcc -I/usr/local/include/opencv -L/usr/local/lib -lhighgui -lcv -lcxcore -o ocvcap ocvcap.c
//
#include <stdio.h>
#include <cv.h>
#include <highgui.h>

int
main (int argc, char **argv)
{
  CvCapture *cap = 0;
  IplImage  *img = 0;

  if (argc == 1) {
    printf("usage: cvcap camera_index save_filename\n");
    exit (0);
  }

  int camera_idx = atoi(argv[1]);
  cap = cvCreateCameraCapture (camera_idx);
  if (cap == NULL) {
    printf ("cvCreateCameraCapture() failed...\n");
    exit (0);
  }
  cvSetCaptureProperty (cap, CV_CAP_PROP_FRAME_WIDTH, 640);
  cvSetCaptureProperty (cap, CV_CAP_PROP_FRAME_HEIGHT, 480);

  // capture image from camera
  img = cvQueryFrame (cap);

  // save image file...
  cvSaveImage (argv[2], img);

  //cvReleaseCapture(&capture);
  cvReleaseImage (&img);

  return (0);
}

実行はこんな感じで。

$ ./ocvcap 0 capture.jpg

cronで定期的にキャプチャしてChumbyで表示すると面白いかも?


2008-06-22

Wi-Fi環境がない場所でChumbyのデモをしたいときのTips

Chumbyは通常Wi-Fi環境がないとwidgetを見ることすらできないのですが、 自作のswfをChumbyに表示したいだけならこんな感じで動かすことができます。

まずUSBメモリを用意してこんな感じでファイルを配置します。 自作のswfはhoge.swfと仮定しています。

$ ls -al
total 128
drwxrwxrwx  1 yoggy  yoggy  16384  6 22 01:17 ./
drwxrwxrwt@ 5 root   admin    170  6 22 01:15 ../
-rwxrwxrwx  1 yoggy  yoggy     62  6 22 01:13 debugchumby*
-rwxrwxrwx  1 yoggy  yoggy  17063  6 22 01:10 hoge.swf*

debugchumbyファイルの中身は、こんな感じのシェルスクリプトを記述しておきます。

$ cat debugchumby
#!/bin/sh
/usr/bin/chumbyflashplayer.x -i /mnt/usb/hoge.swf

次にこのUSBメモリをChumbyに刺して起動すると、スタートアップの画面が表示された後、 Chumbyはいきなりhoge.swfだけが再生される状態になります。

通常はChumbyを起動するとコントロールパネルのswfが再生されるのですが、 debugchumbyという名前のファイルがUSBメモリにあると、コントロールパネルが起動する前にこのファイルを実行する仕掛けが/etc/init.d/rcSに用意されています。 そこでdebugchubmyの中でむりやりhoge.swfを表示することで、 コントロールパネルを置き換えているような感じになります。

debugchumbyファイルとかの詳しい仕掛けについては、 起動時に実行される/etc/init.d/rcSの内容を参照してください。

 

…これでとりあえずはswfが再生できるかもしれないけど、よく考えたらChumbyはネットワークにつながってるところで使わないと、魅力が半減しちゃうような気がしないでもなかったりw


2008-06-23

任意のコードが実行される脆弱性について(www.ruby-lang.org)

※注: 見てたところが違ってたので、下のほうに追記してます。

パッと見て何が問題か理解できなかったのでソースを見てみる。

$ svn export http://svn.ruby-lang.org/repos/ruby/tags/v1_8_6_229/ v1_8_6_229
$ svn export http://svn.ruby-lang.org/repos/ruby/tags/v1_8_6_230/ v1_8_6_230
$ diff -d -r diff -d -r v1_8_6_229 v1_8_6_230
diff -d -r v1_8_6_229/ChangeLog v1_8_6_230/ChangeLog
0a1,4
> Fri Jun 20 18:24:18 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
>
>       * string.c (rb_str_buf_append): should infect.
>
diff -d -r v1_8_6_229/string.c v1_8_6_230/string.c
6c6
<   $Date: 2008-06-20 15:53:16 +0900 (金, 20  6月 2008) $
---
>   $Date: 2008-06-20 18:24:53 +0900 (金, 20  6月 2008) $
781c781,783
<     return str_buf_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
---
>     str_buf_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
>     OBJ_INFECT(str, str2);
>     return str;
diff -d -r v1_8_6_229/version.h v1_8_6_230/version.h
5c5
< #define RUBY_PATCHLEVEL 229
---
> #define RUBY_PATCHLEVEL 230

ソースコードの中で変わっているのは、strings.cのrb_str_buf_append()の内容だけ。

OBJ_INFECT()とはなんだろ?ということで、ruby.hを見ると

#define OBJ_INFECT(x,s) do {if (FL_ABLE(x) && FL_ABLE(s)) RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT;} while (0)

という感じ。汚染フラグを伝染させるマクロな様子。なるほど。

で、rb_str_buf_append()がどこで使われているかというと…

$ cd v1_8_6_230
$ grep rb_str_buf_append *
ChangeLog:      * string.c (rb_str_buf_append): should infect.
ChangeLog:      * string.c (rb_str_buf_append): fixed unsafe use of alloca,
array.c:            rb_str_buf_append(result, sep);
array.c:        rb_str_buf_append(result, tmp);
array.c:        rb_str_buf_append(str, s);
error.c:    rb_str_buf_append(str, klass);
error.c:    rb_str_buf_append(str, exc);
eval.c:     rb_str_buf_append(str, rb_inspect(data->klass));
eval.c:     rb_str_buf_append(str, rb_inspect(v));
eval.c:     rb_str_buf_append(str, rb_inspect(data->recv));
eval.c:     rb_str_buf_append(str, rb_inspect(v));
file.c:         rb_str_buf_append(result, sep);
file.c: rb_str_buf_append(result, tmp);
hash.c:    rb_str_buf_append(str, str2);
hash.c:    rb_str_buf_append(str, str2);
hash.c:     rb_str_buf_append(str, i);
intern.h:VALUE rb_str_buf_append _((VALUE, VALUE));
re.c:            rb_str_buf_append(source, v);
string.c:rb_str_buf_append(str, str2)
string.c:           return rb_str_buf_append(str, str2);

む、結構いろんなところで使われているのね…

とりあえず脆弱性の原因としては、$SAFE=4とかのオブジェクトの汚染モデルをあてにしているプログラムで、意図しないところで汚染フラグが外れて困ることがあるよという認識でいいのかな?

追記

見てたところがちょっと違ってました(汗

1.8.6-p228のChangeLogを見たら

Wed Jun 18 22:25:10 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>

        * array.c (ary_new, rb_ary_initialize, rb_ary_store,
          rb_ary_aplice, rb_ary_times): integer overflows should be
          checked. based on patches from Drew Yao <ayao at apple.com>
          fixed CVE-2008-2726

        * string.c (rb_str_buf_append): fixed unsafe use of alloca,
          which led memory corruption. based on a patch from Drew Yao
          <ayao at apple.com> fixed CVE-2008-2726

        * sprintf.c (rb_str_format): backported from trunk.

        * intern.h: ditto.

ということみたいなので、1.8.6-p227と1.8.6-p228の差分をみると関係ありそうなのは下記のところかな?

$ svn export http://svn.ruby-lang.org/repos/ruby/tags/v1_8_6_227/ v1_8_6_227
$ svn export http://svn.ruby-lang.org/repos/ruby/tags/v1_8_6_228/ v1_8_6_228
$ diff -d -r v1_8_6_227 v1_8_6_228 | lv
      ・
      ・
      ・
diff -d -r v1_8_6_227/array.c v1_8_6_228/array.c
      ・
      ・
      ・
> #define ARY_MAX_SIZE (LONG_MAX / sizeof(VALUE))
123c124
<     if (len > 0 && len * sizeof(VALUE) <= len) {
---
>     if (len > ARY_MAX_SIZE) {
296c297
<     if (len > 0 && len * (long)sizeof(VALUE) <= len) {
---
>     if (len > ARY_MAX_SIZE) {
360a362,364
>     else if (idx >= ARY_MAX_SIZE) {
>       rb_raise(rb_eIndexError, "index %ld too big", idx);
>     }
369,371c373,374
<       new_capa += idx;
<       if (new_capa * (long)sizeof(VALUE) <= new_capa) {
<           rb_raise(rb_eArgError, "index too big");
---
>       else if (new_capa >= ARY_MAX_SIZE - idx) {
>           new_capa = (ARY_MAX_SIZE - idx) / 2;
372a376
>       new_capa += idx;
978a983,985
>       if (len < 0 || len > ARY_MAX_SIZE) {
>           rb_raise(rb_eIndexError, "index %ld too big", beg);
>       }
2381c2388
<     if (LONG_MAX/len < RARRAY(ary)->len) {
---
>     if (ARY_MAX_SIZE/len < RARRAY(ary)->len) {

  ※lenがでかいとlen * sizeof(VALUE)とかnew_capa * (long)sizeof(VALUE)とかが負になる可能性がある

      ・
      ・
      ・
diff -d -r v1_8_6_227/string.c v1_8_6_228/string.c
6c6
      ・
      ・
      ・
782a776,778
>     if (len < 0 || (capa+1) > LONG_MAX / 2) {
>       rb_raise(rb_eArgError, "string sizes too big");
>     }

  ※ rb_str_buf_append()関数の中で、

       if (capa <= len) {
           while (len > capa) {
                capa = (capa + 1) * 2;
           }
           RESIZE_CAPA(str, capa);
       }

     とappend先のstrのバッファをリサイズしているところがあるが、
     ここで先の(capa+1) > LONG_MAX / 2のチェックをしていないと
     capa = (capa + 1) * 2が負になり、RESIZE_CAPA()がおかしくなる可能性。

2008-06-24

iPod touch unboxing

iPhoneに期待してちょっと待ってたけど、ソフトバンクは7,280円からでemobileと比べるとちょっと割高感あるし、ドコモは期待できなさそうだしということで、iPod touchを買ってしまいましたw

2604574212_0d3db18cec_m.jpg 2603745823_9eff1a05b9_m.jpg 2603746009_77d8bbab48_m.jpg 2604574792_dc6f84ce42_m.jpg 2604574962_8a504b8f19_m.jpg

EMONSTER+WMWifiRouterと組み合わせて使ってみたけど、なかなか快適。

本日のツッコミ(全2件) [ツッコミを入れる]

tessy [あぁー]

yoggy [ひょっとして買うタイミング間違えた?(汗]


トップ 最新 追記

2003|01|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|
2010|01|02|03|