年間レポート 〜2015年版〜

ぐだぽよ~、おきなわです。

先ほどメールチェックをしていたら jetpack から 2015年 の年間レポートなるものが見れるようになったので、自分用にもメモとして掲載しておこうと思います。

2015年のブログ

自分で Facebook にこのブログのことを投稿したことはないため、トップリファラーサイトとして Facebook があるのが謎です、、、

まぁ眺める分には面白かったので、興味がある方はぜひ見てみて下さい。

5 秒くらいは暇つぶし出来ます(*^_^*)

ではでは〜

FreeBSD Ports Collection からユーザ権限でインストール

ぐだぽよー、おきなわです。

最近、一ユーザとして利用しているサーバにて、いろいろソフトをインストールしたくなり、root 権限を使えなくても ports を利用出来るように設定しました。今後また同じことをしたくなった時のために、今回やったことをメモっておきたいと思います。

やりたい事

FreeBSD サーバにて、root 権限を持っていなくても Ports からソフトウェアをインストールできるようにしたい。

設定手順

以下のサイトを参考にしました。

otsune’s FreeBSD memo :: ユーザー領域にFreeBSD portsをインストールする方法

設定ファイルの作成

まず ports のインストール先などを環境変数の指定により変更します。

僕は .bash_profile に以下の用に環境変数を記述しました。


# setting for ports to install by user privileges
export __MAKE_CONF=/dev/null
export INSTALL_AS_USER=yes
export PREFIX=${HOME}/usr/local
export LOCALBASE=${HOME}/usr/local
export PKG_DBDIR=${LOCALBASE}/var/db/pkg
export PORT_DBDIR=${LOCALBASE}/var/db/pkg
export DISTDIR=${LOCALBASE}/tmp/dist
export WRKDIRPREFIX=${LOCALBASE}/tmp/work
export PORTSDIR=${HOME}/usr/ports
export PKGTOOLS_CONF=${LOCALBASE}/etc/pkgtools.conf
export DEPENDS_TARGET='install clean'
export LDCONFIG="/sbin/ldconfig -f ${LOCALBASE}/var/run/ld-elf.so.hints -i -R ${LOCALBASE}/etc/ld-elf.so.conf"
export LD_LIBRARY_PATH=${LOCALBASE}/lib
export LD_RUN_PATH=${LOCALBASE}/lib
export PATH=${LOCALBASE}/bin:${LOCALBASE}/sbin:${PATH}
export MANPATH_MAP="${LOCALBASE}/bin ${LOCALBASE}/man"
# enable .bashrc
source ~/.bashrc

view raw

.bash_profile

hosted with ❤ by GitHub

なお、各環境変数やその値の示す意味は以下の通りです。

(説明は ports/Mk/bsd.port.mk 等を参考にしています。)

  • __MAKE_CONF : make コマンドを実行する際に参照する make.conf のパスを明示的に指定します。デフォルトでは /etc/make.conf を参照するため、そちらに環境変数の記述があるとその値を使用します。そのため、今回は /dev/null を指定してシステム全体での設定が記述されている make.conf を参照しないようにします。
  • INSTALL_AS_USER : root アクセスを利用せずに現在のユーザとしてインストールを行うために利用します。
  • PREFIX : ports からのファイルのインストール先を指定します。デフォルトでは USE_LINUX_PREFIX がセットされていれば ${LINUXBASE} を、されていなければ ${LOCALBASE} を適用します。
  • LOCALBASE : ports からのファイルのインストール先を指定します。デフォルトでは /usr/local です。
  • PKG_DBDIR : どのパッケージをインストールしたかの記録を保存する場所を指定します。デフォルトでは /var/db/pkg です。
  • PORT_DBDIR : port の設定オプションを保存する場所を指定します。デフォルトでは /var/db/ports です。
  • DISTDIR : ダウンロードしたソースコードの保管場所を指定します。デフォルトでは ${PORTSDIR}/distfiles です。
  • WRKDIRPREFIX : コンパイルなどを行う際に利用する一時的な作業用ディレクトリの場所を指定します。
  • PORTSDIR : ports tree のルートディレクトリを指定します。デフォルトでは /usr/ports です。
  • PKGTOOLS_CONF : pkgtools の設定ファイルの場所を指定します。
  • DEPENDS_TARGET : 依存する ports をインストールする際の挙動を設定します。デフォルトでは install です。
  • LDCONFIG : リンカに利用可能な共有ライブラリを伝えるための変数のようです。
  • LD_LIBRARY_PATH : 共有ライブラリの場所を指定します。
  • LD_RUN_PATH : プログラム実行時に利用する共有ライブラリの場所を指定します。
  • PATH : 実行可能なコマンド群の場所を指定します。
  • MANPATH_MAP : PATH にある各ディレクトリに対して、man ページファイルの検索パスに追加すべきディレクトリを一つづつ指定します。

なお、LD_RUN_PATH の LD_LIBRARY_PATH との違いですが、

LD_RUN_PATH で指定したパスは実行ファイルに埋めこまれますが、LD_LIBRARY_PATH はダイナミックリンカ ld-elf.so が利用します。コンパイル時に共有ライブラリの検索パスを指定するのが LD_RUN_PATH で、実行時に指定するのが LD_LIBRARY_PATH。

FreeBSD-users-jp 60135

らしいです。

必要なディレクトリやファイルの作成

設定ファイルに記述したディレクトリを作成します。

$ mkdir -p ~/usr/local/etc ~/usr/local/lib ~/usr/local/tmp/dist ~/usr/local/tmp/work ~/usr/local/var/db/pkg

ライブラリの場所を記述したファイルを作成します。

$ ldconfig -r | awk '/search/ {print $3}' | tr ":" "\n" > ~/usr/local/etc/ld-elf.so.conf
$ echo ${HOME}/usr/local/lib >> ~/usr/local/etc/ld-elf.so.conf

僕の環境の場合は

$ sysctl -n kern.osreldate

が実行出来たのでここまでですが、上記のコマンドが実行出来なかった場合は環境変数にさらなる追加記述が必要のようです。(ここでの記述はめんどくさいので省略します。参考元サイトの方にきちんと記述されていたため、そちらを参考にしてください。)

ports の展開

github にも公開されているため、そちらからダウンロードして来ても良いかもしれません。

freebsd/freebsd-ports · GitHub

$ git clone --depth 1 github:freebsd/freebsd-ports.git ~/usr/ports

もし既にシステム全体で使用している ports があるなら、そちらを利用した方が早いと思います。

.bash_profile に記述した環境変数のうち、PORTSDIR を記述しなければデフォルトの ports (/usr/ports)を利用します。

Let’s インストール

ここまでくればあとは通常通り

$ cd ~/usr/ports/editors/vim
$ make install clean

とかやるとインストールすることが出来ます。やったぜ!

 

簡単!にゃんぱす Bot を作ろう!

にゃんぱすー、おきなわです。

ついに待ちに待ったのんのんびより りぴーとの放送が始まりました!!!いぇーい!

ということで Twitter のタイムラインをにゃんぱすーで賑やかにするために、Twitter に「にゃんぱすー」と自動投稿する Bot プログラム、にゃんぱす Bot を作っていきたいと思います。

環境の事前準備

今回は Python を使って Bot プログラムを書いていきます。Python にも Twitter API を簡単に使えるように有志が作成したライブラリが多くあるのですが、ここでは tweepy を使用します。なので事前に Python の実行環境を用意し、tweepy をインストールしておいてください(pip を利用すると簡単に tweepy をインストールできます)。

では環境が既に準備されているという前提で、まずは Bot を作るために必要な情報を用意しましょう。

Bot を Twitter Apps に登録する

まず最初に Bot を動かしたいアカウントで Twitter にログインし、ログインが出来たら Twitter Application Management にアクセスします。

スクリーンショット 2015-07-09 5.23.12

Create New App をクリックします。(上の画面だと既に幾つか登録してあったため登録済みのアプリが表示されていますが、一度も登録したことがないと何も表示されず、Create New App ボタンが真ん中に表示されます。)

スクリーンショット 2015-07-09 5.28.41

作成するアプリの情報を適当に入力します。

  • Name:アプリの名前です。ほかのユーザからも見ることが出来ます
  • Description:アプリの説明です。10 文字以上 200 文字以内で書くことが出来ます
  • Website:アプリのホームページとして登録するサイトの URL を入力します
  • Callback URL:今回は使用しないため、入力しなくても大丈夫です

スクリーンショット 2015-07-09 5.28.55

アプリの情報を入力後、規約に同意するというチェックボックスをチェックし、Create your Twitter application をクリックします。

スクリーンショット 2015-07-09 5.40.11

アプリが作成出来ました。次にアプリ名の下に表示されているタブのうち、Keys and Access Tokens をクリックします。

スクリーンショット 2015-07-09 5.49.28

Consumer Key (API Key) と Consumer Secret (API Secret) が表示されると思うのでメモっといてください。あとで使用します。(上の画像ではわざと消しています。)

スクリーンショット 2015-07-09 5.49.44

下の方に Create my access token というボタンがあるので、それをクリックします。

スクリーンショット 2015-07-09 5.56.26

Access Token と Access Token Secret が表示されますのでこれもまたメモっといてください。あとで使用します。(上の画像ではわざと消しています。)

これで準備が整いました。それでは早速 Bot プログラムを書きましょう。

にゃんぱす Bot のプログラムを書く

では Python で次のようなプログラム simple_tweet.py を書きましょう。


#!/usr/bin/env python
#-*- coding:utf-8 -*-
import tweepy
# infomation to access twitter api.
consumer_key = 'XXXXXXXXXXXXXXXXXXXXXXXXX'
consumer_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
access_token = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
access_token_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
# authenticate the twitter account by OAuth
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth_handler=auth)
# tweet
api.update_status(status="にゃんぱすー")

view raw

simple_tweet.py

hosted with ❤ by GitHub

7 行目から 10 行目の consumer_key などのところはそれぞれ Bot を登録した際にメモったものを書いてください。その情報を使用して 13 行目から 15 行目でアカウントの認証を OAuth 認証で行います。最後に 18 行目でツイートを行います。「にゃんぱすー」と書かれた部分を変更することでさまざまなことをつぶやくことが出来ます。

では早速動かしてみましょう。ターミナルで以下のように実行します。

$ chmod 744 simple_tweet.py
$ ./simple_tweet.py

すると以下のようにツイートができます。

上記のプログラムを決まった時間に実行することで時報などの定期的につぶやく Bot が作れるわけです。簡単ですね。

では今度は「にゃんぱすー」と挨拶されたら「にゃんぱすー」と返事をするボットを作ってみましょう。次のようなプログラム simple_bot.py を書きましょう。


#!/usr/bin/env python
#-*- coding:utf-8 -*-
import tweepy
import simplejson
import random
# infomation to access twitter api.
consumer_key = 'XXXXXXXXXXXXXXXXXXXXXXXXX'
consumer_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
access_token = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
access_token_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
# authenticate the twitter account by OAuth.
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth_handler=auth)
# get bot name
bot_name = api.me().screen_name
# create streamlistener class to modify action in userstreaming.
class myStreamListener(tweepy.StreamListener):
# define the action when data come from twitter.
def on_data(self, data):
# the style of data which come from twitter is json, so start with "{".
if data.startswith("{"):
# convert json to Python dictionary, because it is very useful.
data = simplejson.loads(data)
# define the action when catch any tweet.
if "text" in data:
# if the tweet is reply to bot and it contains keyword, return a greeting.
if data['in_reply_to_screen_name'] == bot_name and "にゃんぱすー" in data['text']:
Tweet = "@" + data['user']['screen_name'] + " にゃんぱすー" + " " * random.randint(0,10)
api.update_status(status = Tweet, in_reply_to_status_id = data['id'])
# set information to start streaming
stream = tweepy.Stream(auth=api.auth, listener=myStreamListener(), secure=True, timeout=None)
# start userstreaming
stream.userstream()

view raw

simple_bot.py

hosted with ❤ by GitHub

上記のプログラムでは userstream を使用しています。そうすることでリアルタイムで返答を返すことが出来ます。7 行目から 10 行目の consumer_key などのところは先ほどと同じように、それぞれ Bot を登録した際にメモったものを書いてください。20 行目で Bot 自身の名前を取得し、それを元に 33 行目で自分へのツイートかどうか、またツイートに「にゃんぱすー」というキーワードが含まれているかどうかを判断しています。34 行目では返事のツイートを作成しているのですが、ツイートの最後に全角スペースをランダムで付けることでツイートが重複して呟けなくなることを防いでいます。ではコマンドラインから動かしてみましょう。このプログラムは一度動作させると接続が切られるまでずっと動作し続けるので、& を付けてバックグラウンドで動作させるのがよいでしょう。

$ chmod 744 simple_bot.py
$ ./simple_bot.py &

ではボットに話しかけてみましょう。

挨拶をすると自動で返答してくれました。より Bot らしくなりましたね。

より複雑な Bot への発展

より複雑な挙動を行う Bot を作成したい場合は、上記の simple_bot.py プログラムの myStreamListener クラスの 32 行目以下を書き換えることで作ることが出来ます。なお userstream における 1 つのツイートが持つ情報ですが、例えば

というツイートだと、以下のように情報が流れてきます。


{
'lang': 'ja',
'possibly_sensitive': False,
'geo': None,
'contributors': None,
'in_reply_to_status_id_str': None,
'truncated': False,
'user': {
'profile_link_color': '00B4CC',
'following': None,
'default_profile': False,
'utc_offset': 32400,
'friends_count': 419,
'statuses_count': 57898,
'time_zone': 'Tokyo',
'listed_count': 38,
'geo_enabled': True,
'default_profile_image': False,
'favourites_count': 1551,
'profile_background_image_url': 'http://abs.twimg.com/images/themes/theme19/bg.gif',
'profile_sidebar_border_color': 'FFF8AD',
'verified': False,
'description': "九州工業大学 学生です\r\nクズです☆(ゝω・)vキャピ\r\nLet's begin FX! \r\n\\カーニバルダヨ!/",
'profile_background_tile': False,
'id': 215645258,
'profile_text_color': '333333',
'profile_background_color': 'FFF04D',
'profile_sidebar_fill_color': 'F6FFD1',
'notifications': None,
'name': 'ふぃりぴん∅おきなわ',
'followers_count': 438,
'created_at': 'Sun Nov 14 14:38:03 +0000 2010',
'protected': False,
'profile_image_url_https': 'https://pbs.twimg.com/profile_images/564047755547377667/r7uHX8kc_normal.png',
'profile_image_url': 'http://pbs.twimg.com/profile_images/564047755547377667/r7uHX8kc_normal.png',
'id_str': '215645258',
'location': '福岡/飯塚',
'is_translator': False,
'screen_name': 'take01x',
'lang': 'ja',
'profile_use_background_image': True,
'contributors_enabled': False,
'follow_request_sent': None,
'profile_background_image_url_https': 'https://abs.twimg.com/images/themes/theme19/bg.gif',
'url': 'http://www.take01x.okinawa',
'profile_banner_url': 'https://pbs.twimg.com/profile_banners/215645258/1400589127'
},
'place': None,
'source': '<a href="http://sites.google.com/site/yorufukurou/" rel="nofollow">YoruFukurou</a>',
'id_str': '618913474677059584',
'text': 'This is sample\nこれはサンプルです',
'in_reply_to_user_id': None,
'timestamp_ms': '1436395445876',
'in_reply_to_screen_name': None,
'created_at': 'Wed Jul 08 22:44:05 +0000 2015',
'favorite_count': 0,
'entities': {
'urls': [],
'hashtags': [],
'trends': [],
'user_mentions': [],
'symbols': []
},
'in_reply_to_status_id': None,
'filter_level': 'low',
'id': 618913474677059584,
'favorited': False,
'retweet_count': 0,
'in_reply_to_user_id_str': None,
'retweeted': False,
'coordinates': None
}

view raw

tweet.py

hosted with ❤ by GitHub

そのため、例えば上記の simple_bot.py プログラムの myStreamListener クラスの 32 行目以降において、ツイートしたユーザの名前にアクセスするには data[‘user’][‘screen_name’] 、ツイート本文にアクセスするには data[‘text’] と書けば良いわけです。なお、詳しいデータ構造や各値の意味については以下のサイトを参考にしてください。

Streaming message types | Twitter Developers

さいごに

だいぶ説明を省きましたが、以上のように、単純に特定のキーワードに反応して特定のツイートを行うという Bot なら比較的簡単に書くことが出来ます。

Python をこれから勉強したいという方、Twitter の Bot を作ってみたいという方はぜひ自分の Bot を作ってみてください。楽しいですよ♪

ネットエージェント新卒採用 CTF Writeup 〜後編〜

ぐだぽよー、おきなわです。

前編の記事を書いてからかなり日数があいてしまいましたが、ぼちぼち後編を書いていこうかなと思います。

以前の writeup は以下。

ネットエージェント新卒採用 CTF Writeup 〜前編〜 | おきなわのぶろぐ

 

では早速書いていきましょう。

mondai6

問題もやっと折り返しを迎えました。さて、6 問目ですが問題文には以下の URL のみ記載されていました。

http://49.212.84.208/cgi-bin/hode7hb376dgeas6df783gr4/mondai6.cgi

どうやら次は Web 問題のようですね。curl コマンドを使って早速アクセスしてみます。

$ curl http://49.212.84.208/cgi-bin/hode7hb376dgeas6df783gr4/mondai6.cgi
<HTML><BODY>use R4000
</BODY></HTML>

use R4000 と言われました。何のことや!ってことで検索してみると、どうやらマイクロプロセッサのことっぽい。

R4000 – Wikipedia

指定のマイクロプロセッサを使えってことか?と思い立ち、R4000 のエミュレータっぽいやつを探し、実行環境を整え、動かしてみました。(迷走して色々調べてたので何処のサイトを参考にしたかすら覚えていない、、、)

動かした際のスクショは以下。

よっしゃ!動いた!!と思ったのも束の間、ネットワークの設定が上手くいかない、、、繋がらない、、、もぅマヂ無理。

しかし、ここでふと、僕はある事に気づきました。

「でもサーバ側から見て判別できそうなのって User-Agent とかくらいじゃね?ってことはそこを偽装すればいいんじゃね???」

ということで早速 R4000 について再度調べ直すことに。すると以下の様な情報にたどり着きました。

 MIPSプロセッサはデジタルTVやDVDレコーダー、ネットワーク機器、プリンタなどの組み込み機器で広く利用されている。身近な例としては、米MIPS Technologiesの「R4000」コアプロセッサを2つ内蔵した、ソニーの携帯ゲーム端末「PSP(プレイステーションポータブル)」が挙げられる。

世界で最も多く出荷されたRISCプロセッサMIPSのサバイバル戦略 - TechTargetジャパン システム開発

なるほど、PSP か!!ってことで PSP の User Agent を調べる。

●PSP (PlayStation Portable)
Mozilla/4.0 (PSP PlayStation Portable); 2.00)

userAgent一覧/ユーザーエージェント一覧

ということらしいので早速 User Agent を偽装してみる。

$ curl -A "Mozilla/4.0 (PSP PlayStation Portable); 2.00)" http://49.212.84.208/cgi-bin/hode7hb376dgeas6df783gr4/mondai6.cgi
<HTML><BODY>de la Bucure?ti
</BODY></HTML>

お、なんかメッセージが変わった!!

どうやらルーマニア語で「ブカレストから?」という意味らしい。

という事はブカレストからアクセスすれば良いのか?と思い、ブカレスト付近のプロキシサーバを探し、プロキシを通してアクセスしてみるも変わらず。使用したプロキシサーバが悪いのか?!と考え、その後もプロキシを使用するという線から色々試してみるも上手くいかず。じゃあ位置情報とかか?!と思い、無理やり位置情報を投げてみたりしましたが、やっぱり上手くいかず、、、

そこでふと「最初は User Agent の偽装だったし、もしかして HTTP ヘッダーで何とかするんじゃね?」と思いつき、調べた結果 Accept Language とかじゃね?と言う事で Accept Language をルーマニア語(ro)にして再度実行。

$ curl -A "Mozilla/4.0 (PSP PlayStation Portable); 2.00)" http://49.212.84.208/cgi-bin/hode7hb376dgeas6df783gr4/mondai6.cgi --header "Accept-Language: ro"
<HTML><BODY>key: Minesweeper1990
</BODY></HTML>

上手くいった!!!

と言う事で答えは Minesweeper1990 でした。

mondai7

解凍後、以下の様な構成のディレクトリが。

mondai7
├── hint7.txt
├── mondai8.zip
└── normal.exe

次はバイナリの問題のようです。

まずは何も考えずに strings コマンドで文字を抜き出して眺めてみます。

$ strings normal.exe

特にこれといってそれっぽいものは見つからなかったため、バイナリを解析する必要があるようですね、面倒くさい。

正直 exe ファイルの解析はあまり得意ではないので、この問題は一緒に問題を解いていたなーが君に丸投げする事にしました。なので僕は直接は解いてません。

なーが君曰く、最初は動的解析を行ったところ、なかなかうまく行かなかったらしいです。その後 exe ファイルがデバッガ判定を行ってデバッガ経由で起動された時とそうでない時で動作を変えているのが上手くいかない原因ではないかと考え、静的解析に切り替えて解析を行ったところ上手くいったとのことでした。具体的(?)には正解である文字列を作成してるっぽい処理をしているところがあったため、そこの処理を追っていったとのこと。ちゃんとどうやって解いたか聞いたのですが、殆ど覚えてないです、、、やる気があればちゃんと解いて追記しようと思います。

ちなみに今回の答えは TochuKasou だったらしいです。

mondai8

解凍後、以下の様な構成のディレクトリが。

mondai8
├── mondai8.tc
├── mondai8.txt
└── mondai9.zip

そして問題は以下の文章のみ。

TrueCrypt pass:mondai8

漢字8文字

どうやら mondai8.tc が TrueCrypt で暗号化されたイメージファイルのようなので、まずはそれを素直にマウント。マウントすると何枚かの画像ファイルなどがありました。

mondai8/
├── $RECYCLE.BIN
│   └── desktop.ini
├── Beale_1.svg
├── Crete_-_Phaistos_disk_-_side_A.JPG
├── Dorabella-cipher-image.png
├── Linear_A_tablets_filt.jpg
├── dagapeyeff_cipher.jpg
└── gold_bar.jpg

基本的にイメージファイル等を扱う問題では消されたデータを復元して解いていく流れのものが多いため、見えている画像ファイル達はどうせダミーだろうなぁと思いながらも一応 google 画像検索で検索をかけてみると以下の記事がヒット。

いまだ解読されていない歴史的な10種の暗号 – GIGAZINE

画像ファイルは全てこのサイトから辿れるものと全く同じだったため、ダミーだと確認出来ました。次に消されたファイルの復元を行います。私は Autopsy を使って復元を行いました。まずおもむろに Autopsy を起動します。

$ autopsy
============================================================================
Autopsy Forensic Browser
http://www.sleuthkit.org/autopsy/
ver 2.24
============================================================================
Evidence Locker: /usr/local/var/lib/autopsy
Start Time: Fri May 22 20:59:31 2015
Remote Host: localhost
Local Port: 9999

Open an HTML browser on the remote host and paste this URL in it:

http://localhost:9999/autopsy

Keep this process running and use <ctrl-c> to exit

その後ブラウザで http://localhost:9999/autopsy にアクセスすると以下の画面に。

スクリーンショット 2015-05-22 21.03.45

まずは解析を行うための準備を行う。NEW CASE を選択。

スクリーンショット 2015-05-22 21.08.07

上の画像のように Case Name、Description、Investigator Names を適当に入力し、NEW CASE をクリック。

スクリーンショット 2015-05-22 21.10.12

リストから先ほど作った CASE を選択し、ホストを追加するために ADD HOST を選択。

スクリーンショット 2015-05-22 21.11.13

デフォルトで値が入っているので、そのまま ADD HOST を選択。

スクリーンショット 2015-05-22 21.11.28

確認画面が表示されるので、解析するイメージを選択するために ADD IMAGE をクリック。

スクリーンショット 2015-05-22 21.43.36

ADD IMAGE FILE をクリック。

スクリーンショット 2015-06-07 21.15.11

解析したいイメージファイル(今回は TrueCrypt で複合化したイメージファイル)のパスを上の画像のように絶対パスで記入し、Type と Import Method を選択し、NEXT を選択。今回は Type は Disk、Import Method は Symlink を選択。

スクリーンショット 2015-06-07 21.15.46

ディスクイメージの種類を選択するよう言われるため、Volume Image を選択し、OK をクリック。

スクリーンショット 2015-05-22 22.04.43

MD5 ハッシュを計算するか聞かれるので Ignore を選択し、マウントポイントを適当に /Volumes/c/ とかにして ADD を選択。

スクリーンショット 2015-05-22 22.04.53

確認メッセージが出るので OK を選択。

スクリーンショット 2015-05-22 22.05.24

これで解析を行う準備が整いました。早速やっていきましょう。ANALYZE を選択。

スクリーンショット 2015-05-22 22.05.41

上のタブの FILE ANALYSIS を選択。

スクリーンショット 2015-05-22 22.06.34

すると普通のファイルが青色で、消されたファイルが赤色で表示されます。

ここでファイル名を眺めていると、今日の本.xlsx という如何にも怪しいファイルを発見。ファイル名をクリックするとファイルをダウンロード出来るため、今日の本.xlsx  をクリックします。すると autopsy というファイル名でダウンロードできます。ダウンロード後、適当に book.xlsx などと名前を変更し、開いたところ、エラーを吐いて開けず。そこでバイナリエディタでファイルを開いてみましょう。私はバイナリエディタとして 0xED を使用しました。

スクリーンショット 2015-06-07 22.20.53

ファイルの先頭に余計な部分(PK の前までの部分)があったため、その部分を削除・保存して再度開くと無事開くことが出来ました。

開いた Excel ファイルには 3 つのシートがあり、1 つ目のシートには a から z に対応する数字が、2 つ目のシートには奇談クラブという小説(?)の一部が、3 つ目のシートには password という key が書かれていました。どうやら暗号のようなのですが、最初はどうやって解いていけば良いのか全く思いつきませんでしが。ところが一緒に解いていたなーが君が「これって 1 つ目のシートに書かれた a から z に対応した数字がそれぞれ行番号と何番目の文字かを表してるんじゃない?」的なことを言い出しました。つまり “a” は 2 シート目の 62 行目の 11 文字目である “気” に対応して居るのではないか、ということです。そのように解釈すると a から z の対応表は以下のようになります。

この表を見ながら key である password を各文字置き換えると 意気揚揚明鏡止水 となりました。それが答えでした。

mondai9

解答後のディレクトリ構成は以下の通り。

mondai9
├── mondai10.tc
└── mondai9.pkt

file コマンドを使ってファイルを調べてみます。

$ file mondai9.pkt
mondai9.pkt: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)

今度はキャプチャされたパケットを眺める問題のようです。というわけでおもむろに wireshark を立ち上げて読み込んで眺めてみましょう。

スクリーンショット 2015-06-08 7.27.43

とりあえず http 通信でサーバに向けた通信のみを見てみます。

スクリーンショット 2015-06-08 8.39.42

何かファイルをアップロードしているようなので、パケットからアップロードしているファイルを取り出します。すると zip ファイルが 1 つ、docx ファイルが 1 つ、xls ファイルが 2 つの合計 4 つのファイルを抽出することが出来ました。

meast_ecn_notes_fill.zip
空港代码.xls
صحيفة.docx
第一批基地名单.xls

まずは zip ファイルを解凍しようとしたのですが、パスワードが設定されていたため、再度パケットを眺めながらそれらしい文字列を探して試してみましたが解凍できず、、、次にその他のファイルも開いてみましたが、どのファイルも何も書かれていませんでした。他に思いつく事も無かったため、おもむろに docx を解凍し、pass という単語で文字列検索をしてみました。

$ unzip -q صحيفة.docx
$ grep -R "pass" .
./docProps/core.xml:<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title><dc:subject></dc:subject><dc:creator>user</dc:creator><cp:keywords></cp:keywords><dc:description><strong><strong>password: lastonemile</strong></strong></dc:description><cp:lastModifiedBy>杉浦 隆幸</cp:lastModifiedBy><cp:revision>4</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2013-12-13T12:04:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2015-03-20T02:31:00Z</dcterms:modified></cp:coreProperties>

お、パスワード書いてある!ってことで答えは lastonemile でした。

結局パスワードの掛かった zip ファイルはダミーだったみたいだけど、中には何が入ってたんだろ、、、

mondai10

ついに最終問題です。最後の問題は実際に指定された場所まで行って問題の入った SD カードを回収しないといけないとのこと。場所は 4 箇所あり、関東に 2 つ、関西に 2 つありました。しかし私が最後まで解いた時には既に関東に置かれたものは回収され、関西に置かれたものしか残っていませんでした。関西と言えど、さすがに福岡から行くのは大変なため、関西に居る知り合いに頼むことにしました。誰に頼もうかと思っていたところ、僕となーが君の共通の知り合いであるおわたん君なら行ってくれるのではないかということで頼んでみたところ、行ってくれる事になりました。下記は彼が取りに行った時のことを書いた記事です。

あの日 kansai1 で起こったできごとをボクたちはまだ知らない – にゃるにゃる

どうやらすでに回収されていたようでした、、、ごめんねおわたん、、、ということで最後に残った kansai2 を回収することに。しかし再度おわたん君に頼むのはちょっと可愛そうだし、結構遠いようだったので、別の方に頼むことにしました。大学の講義で知り合った人達がいる Slack のグループに誰か取りに行ってくれないか投げてみたところ、りらっくま君という子が行ってくれる事に。下記は彼が取りに行った時のことを書いてもらった記事です。

ネットエージェント – SDCardFindingBattle【kansai2】 | larufa’s blog @ テキトー

kansai2 の SD カードは無事回収してもらうことが出来ました!!!やったぜ!!!!!!!

さて、SD カードを送ってもらい、無事問題に取り組むことができるようになりました。まずはカードを Read only でマウントすると、入っていたのは Truecrypt で暗号化されたイメージファイルのみ。ということで、イメージファイルを渡された時の常套手段である削除されたファイルの復元を試みますが、それらしいファイルは出てこず、、、しかしこの時、復元したファイルの中に Mac でマウントすると自動で作成されるディレクトリがあり、ある可能性に気づきました。

「もしかして、書き込んでしまって復元できなくなった、、、??????」

実は SD カードを郵送して貰う前に、取りに行ってくれた人に中身のデータだけ先に送って貰っていたのです。もしかしたらその時に、、、

「いやでも、一度しくじったら解けなくなるような問題出すかなぁ、、、」と思い、その後はファイルの復元ではなく、他の解き方を模索しましたが結局進まず、色々試しましたが解けず。やっぱりファイルの復元だったのかな、、、

これはもう分かんないわ、、、ってことでソーシャルエンジニアリング(?)の出番です。既に最終問題まで解いてその write up を書いている方が居たので、その記事を参考に解くことにしました。

ネットエージェント最終面接問題 Write-up エクストリームCTF編 – 犬アイコンのみっきー

この記事によると、どうやら最後の問題はやはり削除されたファイルを復元して解くようです。この方が解いた問題の場合、答えは山名+最高点の標高を英数字で9文字だったようなので、それを参考にしました。今回 SD カードが置いてあった高雄山という名前とその標高である428 をくっつけた takao428 でイメージファイルが複合出来ました。

これで全問突破です!やったぜ!!!!!!!

さいごに

問題を解いた感想ですが、解くのにかなり時間が掛かったので、CTF ってやっぱり普段からリハビリしてないとダメなんだなと実感しました。ですが、仲間とワイワイ言いながら問題に取り組むのはやっぱり楽しかったので、時間は掛かったけど挑戦して良かったなと思いました。ただ一つ残念だったことは僕自身が実際に山に登って SD カードの回収に行かなかったことです。他の友人も誘ってみんなでキャッキャ言いながら回収しに行きたかったな、、、

ネットエージェント新卒採用 CTF Writeup 〜前編〜

にゃんぱすー、おきなわです。

何番煎じか分かんないですけど、せっかくなので以前解いた CTF の Writeup でも書いてみようかなと思います。

題名から察しがつくかもしれませんが、今回書くのはネットエージェント株式会社の 2016 年度新卒採用で出題された問題の Writeup です。これは全ての問題を解くと最終面接から選考を始めることが出来ると言うとてもおもしろい取り組みです。

詳しくは下記のサイトを見て下さい。

さて、では早速解いていきましょう。
※ちなみに僕は Mac ユーザなのでこの記事におけるコマンドの例は全て Mac での実行例です。

mondai1

まず最初の問題です。

問題:LzYxMDIvcGouaGJwLy86cHR0aA==

もうこれは見ただけでわかりますね。そう、base64 です。末尾に == が付いてるのが特徴的ですね。というわけで Let’s デコード♪

$ echo "LzYxMDIvcGouaGJwLy86cHR0aA==" | base64 -D
/6102/pj.hbp//:ptth

どうやら逆になってるURL のようなので再度以下のようにコマンドを実行

$ echo "LzYxMDIvcGouaGJwLy86cHR0aA==" | base64 -D | rev
http://pbh.jp/2016/

上記の URL にアクセスすると zip で固められた問題がダウンロード出来ました。どうやら今度はそれを解いていくようです。

mondai2

ダウンロードしてきた zip ファイルを解凍すると次のような構成のディレクトリが出来ました。

mondai
├── hint2.txt
├── mondai2.txt
└── mondai3.zip

どうやらどんどん zip ファイルを解答していけば良いようです。では 2 問目を解いていきましょう。

2016の平方根の小数点以下2016桁目から20桁をパスワードにしました。

ガリガリ計算させれば良いじゃん!ということで僕は普段大学で matlab を使っているため、matlab で以下の m ファイルを実行させて解きました。


str = char(vpa(sqrt(2016), 2038));
str(2019:end-1)

view raw

calculate.m

hosted with ❤ by GitHub

簡単ですね。ちなみに他の解き方としては bc コマンドを使う方法もあります。bc コマンドを用いる事で複雑な数値計算も行えます。

$ echo "scale=2035;sqrt(2016)" | bc | tr -d "\n" | tr -d "\\" | cut -c 2019-
74571026133060730881

というわけで答えは 74571026133060730881 です。

mondai3

さて、3 問目です。

ハッシュパスワード問題

答え:3つの答えをつなげて

0f1aae8b8398c20f81e1c36e349a7880c9234c63

01821f5469967540a5a774197463e8c4d658f588

264f39cab871e4cfd65b3a002f7255888bb5ed97

ハッシュから元の文字列を求めないといけないようですね。本来ハッシュは不可逆なので元の文字列を求めることは出来ないのですが、インターネット上に単語とそのハッシュ値を紐付けたデータがごまんとあるので大概検索をかければヒットします。と言う訳で Google 先生の出番です。それぞれのハッシュを検索するだけ。

0f1aae8b8398c20f81e1c36e349a7880c9234c63 → tokyo
01821f5469967540a5a774197463e8c4d658f588 → ueno
264f39cab871e4cfd65b3a002f7255888bb5ed97 → line

ということで答えは tokyouenoline です。

mondai4

さて、4 問目ですが、ディレクトリ構成は次のようになっていました。

mondai4
├── hint4.txt
├── mondai4.png
└── mondai5.zip

どうやら次は画像の問題のようですね。入っていた png ファイルは以下のようなものでした。

mondai4

とりあえず画像ファイルに含まれる文字列を下記のようにコマンドを実行して見てみます。

$ strings mondai4.png

実行結果を眺めてみましたが、特にめぼしいものはなかったため、画像に書かれているヒエログリフを読む必要があるみたいですね。さっそく読んでみましょう。ただし僕はもちろん古代エジプト人では無いので日本語との対応表が無いと全く読めません。ということで以下のサイトを参考にしました。

ヒエログリフで五十音図

上記のサイトを参考に画像に書かれているヒエログリフを日本語にすると

のらかちいくち てちのちんちもちみら もにみちもにみら もにとちのにみちもちい のらもらまみ

となりました。ちょっと何言ってるのか良く分かんないですね。とりあえず2つ目の文字列である「てちのちんちもち」で Google 検索をかけた所、以下のサイトが最上位に来ました。

「かな入力」のままローマ字打ちで会話するスレ

ここでかな入力なのか?!と思い、所有している JIS 配列のキーボードを見ながらアルファベットに変換したところ、

kotaeha wakayamano minamino misakinamae komoji

答えは和歌山の南の岬 名前小文字

となりました。ここで岬の名前を検索した結果、潮岬(shionomisaki)ではないかと思ったのですが、解凍出来ず。しょうがないので和歌山の全ての岬の名前で試したりしましたがダメでした。その後も特に思いつかなかったため、ここで同じく問題を解いているらしいなーがに協力を仰ぎました。しかし二人でも特に思いつかなかったため、なーがが彼の先輩であるティマ先輩に協力を仰ぎました。そして三人で試行錯誤していた矢先、ティマ先輩がついに答えを見つけました!

答えは ushiomisaki でした。

ティマ先輩曰くとりあえず漢字の読み方を変えてみようと思って試したら上手く行ったとのことでした。圧倒的感謝🙏🙏😄😄

mondai5

5 問目です。問題ファイルは以下の様なものでした。


VjFjeFYySnRSbGhPUjJSUFlXeEZkMU5WVFhkVE1WSlVXa1pzVlZFeWFHNVRha1pLWTBWc2NsWlVR
bHBTTUVwU1ZrUkdRazVXU25GawpSVXBRVWxWS2JsTldXazlXTVVwVVZsUmtVZ3BoV0UxeVZqSndR
azlWZUZWWFYyaFRVa2RrTTFNeFZrSk9VWEJNWVZkek1sUnFRbUZVCk1WcEZWV3RhVDJGV1drdFdN
bXhIVVRGT1VtTkZOVXRXVlZwVFZqRlNhMU13ZUhOU2EwNU1DbEV4V2tOVVZWVTFWbXhvTlZKWVds
SlIKTWxKVFZFUkJOVnBzVGtkYU0wcFhUVlJzVWxkRldrTlhSa0pXVmxSc1MyVllUakpEYkZKSFZt
dDRUMUpGTldsVmExVXhXbFY0Y0ZacwpUbGtLWVd4S1MxUnNWbFpPUmxKeVpVWlNSR0Y2UW5sWFJs
WlBWR3hXY21WRmFGTldSWEJZVmxod1ZrMVdWalZUVXpsVVlUSjRTMVV4CldrTlNNVkpYVTIxV1VG
SlhZM2RYUlZweVRVVTFSQXBWYkZsTFZraHZOR0pGTlZkTlZXUk9ZV3N4Y0ZRd1VuSmlSbFpXVVZS
U1MyRXoKYUc1VWJYUmhVbXhXY2xGVGRFdFJNR3hNVmtaV1lWWnNVbkJVYTA1UFVrVXhjVlZXVWpS
VlZYQlhDbVJIWkV0Uk0yTjZWakowZGsxcwpUWGhPVms1UlVtdEdlVll6YkVwalFYQk5ZVmhvVFZk
RlduSk5iR1J3VmxSa1VHSkVVWGRWYTFKMlkwVTFSMlJHYkZCaVNHTXlWakZTCk5GbHJlRlVLWTNw
S1VXVldSWGxVVjJSM1ZHeFdWMDFEZEZWU1JVcFpWakowVmsxck5WWk9SM0JQVlRKak1GUnJUakJa
TUhod1ZtdFMKVEZKclJubERiRVY1VVdzeFZXRllaSEJXTVZaNlRteG9SZ3BTYTBaUVVURnNiMVZG
VlRCaWEyeHhVbTFXVmxKWFpIUlhSRUkwV2pCdwpWazFWUmxoU2JtTjNWVlZhUW1Nd1RuSk5SR1JN
VW14R2VWTnNXbGRhUmtaV1VXMWtURkpWUmpKV2Jtd3pDbUZXWkVkUlZ6aExWVlZPClMxWXhSbkpO
UjJ4UVZUQmFUbGRHV25OWFJrWjBVVzFLVGsxRlJYaFZWVTAwWkRCdmQxWnRSbGRoVkVaQ1ZESndO
Rk5WZERaak0xSlMKVFZaV2NsVlhiRE1LVGxac1JsSlZkRlZXUkZFd1YwWk9WazVXU2tSVldFcFRV
bXBvTTFOdWJGcGxaM0JOVW1wc1FsUldUWGhaVld4eQpUVlYwV1dWWVFsQlZSbHB2VkdzNWMwMVdT
bFZpUjAweFZrVk9id3BXTVZKd1l6TnNWVkpGUm5CVlJsa3dUbXhDTlZwR1NsZFdiV1EyClZFVmFl
bVJXWkVkVGJWSlBaRE5DVDFWRlRtRmFiRTV6Vm10b1RHSklVbXREYXpseldUSm9UbFpFVmtSVldI
QktDbVJXUmxaTlZYQlMKWWtoa2IxTlhkRE5OYkVKd1lYcEtVVlpzYkRaVE1uUk9ZekI0Y1U1SVJs
RmhiRXBVVTFaV2QxWnNRbkJQVjA1WVZrZDBjVlpFUW1GYQpWWGhIVGtkMFZXRlhUVEVLVVRKemVG
VnNaRlpTV0ZGTFZIcENUMXBHUm5KVGJVWldZa2hvYkZOWWF6VlZNREZYWkhrNVRrMVhaREJXCk0z
QjJUbFU1VkZWc1FsbGlSVnBWVm01d1ZtRnJOSGhPUkU1TFlXcFdVUXBWTTJ4R1pGWldjR1ZHVmxC
V1ZVcEtWRzEwYjFKR2JFZFAKU0U1UlVsaFNURlJFUWpOVGQzQlZWVEJhV1ZSRlRsWmhNV1J4VlZS
S1ZVMUdjRk5WTUZrMVdXeENjVlZzU2xGTlJ6bHlDbFZYYXpCagpNVnB3WWtWS1dVMVdXa1pXYTFw
dlZrVjBjMU5ZV2xkbGJVNTVWMGQwUmsxRmVFWmxSMHBRVWtaS1NWUkdWakJYUmtKRVlqSjBUbEp0
Ck9EUkRiRlpGVVd4S1VHUXpRazhLVmtaYU5Ga3dNWEJVVjNCWVZsYzVlRlZFUVhkaFZrWnhZM3BL
VTAxVldrOVZNVlp5WkRGS1YxTlUKYUZGbGJFWnhWMGQzTVZKR1FrZFBTRkpZVWtSc2JWWkdXbGRV
VmxwR1lYcG9XQXBOVlZwS1ZtMXNWMUpXUmpaWmVsVkxWMFpWTkV3dwplRFppUm14WlpWWktiVkV5
YzNkaWEzUlhWbXRhVDAxWFRYbFdla1UwWTJ4QmVFNUlWbFZpUm5CV1YwVlZNVlJHU1hkUFYxcFJD
bUpGClZqSlVSbFY0VjFaYVJsTlRkRTVSTTFKdFZGUkNTa3d3ZEVSUFJFWk1WbXN4ZUZSWWJEQlZk
M0JYWVdzMVlWZEdWVEZUTVZaeVVsYzUKVDFKWVRuVldNVlpHVXpGU1YxVnJSbGNLVlROU1QxWXpj
SGRWVmxsNFRrZDBUMDFYVFRWV01uaE9UMVV3ZUdORk9WbGhhbXhSVm01dgpkMk14U2tSbFJXaFVa
VzVvVUZOcldqUldSbVJXV2tkV1ZGSkhhR3BEYXpGVlVtMVdWUXBSTW5oVlZXcENNRnBGT1Vaa1JY
QkxaVmQ0ClRWVldVWGRrVmtwU1kwVTFWVkp0Y3pCVk1WcGhVa1pTUlU1SVdreE5TRUpSVmtkc2Qx
TkdSbFZYYkU1VFlYcHNZVlZXVlRSTU1VRjQKQ2xac1NsbE5SRUoyVlROck5WTkZOVWROUkZWTFUz
cEdORkpzVmpaUmJHUlNUVlV3TVZaRVJtRmFhemgzWTNwa1ZWVXhjRU5WYlhoTwpaRlpDTm1SNlVr
Umhla0o0VlRGYVlWa3dlRFlLWlVaa1NsWlhhRmxXYWtKUFYwVjRjMDFIYUU5V1JteDVVMjVyZUZK
c1JuQmlNMHBYClVteEdNbFF3VlRGYVozQlpUVlJvZFZOdGJEQlhWWGQzVDBoS1ZXVlhUakpVVkVV
MFpFWm9WQXBqUms1WllrWndTMWRIZEhwUFZUazIKV2pOU1VXRldWa3hXUmsxNFZqRkNWMW96UWxk
U2JVNDFVekozTVZVeFdrZFBWbWhPVWxka01sVkdWbk5TUm1kNFYxTjBWbVZVUmxORAphelZ6Q2xr
elNsWmlSR2d3VkVWV05GZHJjM2RPUjJ4WFRVZFNURlpZYkZkYWJHUlhZMFZXVVZaSVRURlZNMnMw
U3pGYVZtSkZOVmhOClZrcFJWVWhrZDFScmNFWmhSazVRWWtoa2NGUlhlRk1LVlVaYVJtTjZRbFZT
YkVZd1ZFWlJkMDVHU2xSalJtOUxWa2R3VW1Oc1RsWloKTTA1TVlUTkNSMVl4Vm5wT01VcHlWMWhh
VEUxVVVuRlVSVnBhWVd4R1ZsUlVaRmxoV0UxNVZsVmFRd3BhUm1RMlRVTjBURlY2YUhwVwpla0pD
VFRCT2NrMVZaRmhpUmxWMlUydFdWMUpHVmtWUmJHaFNaVmRTVVZWVldsTlNkM0JMWWtaV05WWkdU
VFJpTVU1R1drZEtWRlpICk9ESlhSMjh3Q21SRk9VUmhNMUpSWVZkek0xUnRkSFpsYkVwWFkwVmtW
V0V5VG5GVGVrWlBXVlphVlU5WFZsSmhNR3g2VmxkcmVGZHIKTUhoWFZYUlZWa2RTVUZWdWJ6Uk9i
RWwzVTFkc1ZHVnJNRE1LUTJ4R1ZFOURkRmxOVm14MFZHdGFVMVpHU2paYVJXUlJUVlJzU0ZWVwpV
bnBqTUd3MlZteHdUVTFHV20xVVJVNVdZakE1Y0U1V1JrMVNWMmhHVkVaYVUxUXdkM2hTYkZaV1lW
UkJOQXBXYm1zd1QxVTFSMDlJCmFGWmtNMEpQVmpGV1UxVkdVa1ZhTTFsTFZsZDRXazVGT1RWaU0y
aFpWVEprTmxWNlJsTlZhekUyWkRKNFdWSkVSbWhWVjNOM1RtdDAKY21SRlVsTmxWbkJaQ2xRemJG
WlBSbVExVmxkd1VGSlhZelZWVjNCelZVVnNWV1I1T1ZGU2JtaFZVekZWTlZKc1RsZE9WMXBMVVhw
VwpVbEV5YzNoVmQzQlFZVEZ3V1ZaclVucE9Sa3B3VGxWMFZsSlZXbW9LVmpKd1Exa3hTbkJTVkd4
WlVrVndWVlZYY0hOVFZXdDNWbXh3CldGSnFWbEpVTTNCTFZGWk9WMWt6V2xWaGFteElWa1ZPVTFN
eFRuTlRXRkpVWlZSc2ExWXllRmRYVlRSM1lrWnNWd3BoYTFwcVEydHcKUjFrd2RGVldSR2h5VlVa
T01GcHJjRlZoUm1SVVRWWnJNbFZzVlRGV01XUkVXa2RXVkZKdGRIVlRWazVQVkd4Q1ZGTlhlRlZX
YWxaRQpWRVpPVTFJeFpIRmxSa1pUQ21FeU9EVlZWM2g2WXpGVmVFNVZiRmxTYWtaSlZVZDNNVlJG
YTNkUmJWbExWak5zYmsweFpGWlhXRXBUClpETkNUMVp0ZEhkYWJFSTFUMVZ3VUdWdFRuSldWM1F3
VjFaa05XTXlkRTBLWVZkU1dGZEhhM2hWYkZKWFYxZDBVRkp0T0hoVVJsSnEKVFVaV1IwMUlSbGRX
YlhNMFZFZHJkMk14Vmtka2VrcFZWbTVOZVZVeWRISmhkM0JRVW14R2QxWnRkM2hYYXpsWVVXdFNX
UXBXUkVKMwpVVEp6ZDJGR1RuSmhlVGxZVlRCck1WVXdVa2RYYkU1SFZHeHdVVlpyYkRGVVNIQnFU
V3hLYzFwNWRFcGlSRVpTVjBaYVFtTnNUWGRUClZHaFJVbFpyZUZSclVrSk9WWFJWQ2xGck9WRmhN
amg2UTJ4R1ZWZFlXbFpoZWtFelZsVlNkbUZHVGxkU2JIQlVZVEpTVlZReFVuSlQKTVZKVVdUSXhX
RTFGTUhsVE1VNXJWbXhDUjJONU9VeFdWVEF5VTFoc2ExWkZOVVlLWTBaS1VHRXdXbFZVU0hCdlV6
Rk9jVlJzY0ZWVwpibWhaVkZkemVGUXdPVFpOUjNkTFZVVldXazVzYUZaa2VrSlpWbXRHZUZWVVFU
QmtSWGQzWlVWS1ZXSkhlR3hWVkVacVRVWk9iZ3BqClJUVk1ZVE5DVDFWNlFqQlZiRlpYVDFad1Qx
WllhR3RYUjNCNlkxVXhWMU50V2xaaGF6RTJWV3RXTTJGcmNISmllWFJRWVZkU1RWTXoKY0c5YVVY
Qk1Va1JzUTFVeFRqQlhSVFZ3Q2sxRVZsaFNNRVUxVjBkc1VrMVdTa1ZoZWtKVlpWVTFWVll4Vmtw
bFZrcFhWRzFPUkdGNgpSbFJVYkZKRFZEQTVjbHBIVGxGV2EzQnBWa2QwVm1SR1duSk9SRXBVWVZS
b2RsVXhVazhLVmtWME5XUXpiRTloVjFKdFEyeFdWMkpIClNrMVNWbkJQVldwQ1IxVXdNWEJpUjFK
UVZrVlZNMVZVUlhka01VcHlWbXhLV0ZaSGRESlRWM0J6VmtaVmQxTlhkRkZTYWtKTVZrWlYKZUFw
VFJtUlhXa1ZLVkZKRlZUVlRiRll3Vkd0d1IxZFlSazFOUlVWM1ZFZHNVMUpXVmpaT1YwMUxWRVpW
TkdOc1dsVk9WVXBZWld0RgpjbFp1Y0hOVmJHaFhVMWhXVlUxV1dreFZWbG96Q21SVmNITlVhemxa
WVc1a05WWXhVVFJrVmtweFdrWktWMlZXYTNoVlJrWjNWR3R2CmVGSnJhRlZXVjNNeVZsZHNlazFz
YURWT1ZWSlBWbTFPY0ZacldtcE1kM0JLWlc1Tk5WWlljRFFLVjBaU2NGZFlRazVsYTFwdFZsZHMK
TUZGcmJIQmpSWEJXVFZjNWVWUlVRbUZUYkdSWFQxWldUVkp1WkhoV01WWnpWMFpLVlZreU1WaFNS
bkJKVjBkc1IxZEZUbkpOVlhSVApWa2hTVEFwVWExSXdVVEJyZDFkdFVrMVZNVXBoUTJ4V1JrNVZh
RTFoTTJONFUxZHdhbVJzVW5KamVsWlFZVzVDYkZNemJFOVViRlp6CllrVjBVMkY2VmxwVVNIQktU
VlpTTldFelVsbFNWbXQ2Q2xSR1dtcGhWazVXVW0xYVQwMVVhREZWTW5oWFYwVTVjVTVGZEZWVk1t
UnkKVjBSQ1RrNUdUbkpOVlhOTFYwVmFORlJyZERWV1ZHUlZWbTFTVTFNeFdtNU5Sa0p4VGxWU1Ux
SklUbmtLVkVkc2IxcEZOVVZUYldSTgpWbXRzTVZSWWF6UmtNSGh5VGtSU1UxWkdSbk5VYlhSdlYx
Wk9SVkZYTVZOV1ZVWjJWVVZXTTJKR1pGVlViV1JXV2pOQ1IxUlhiRTVoClVYQk1VbGhvU0FwV2JG
bDRVMFprVkZKc2JGSlNSVlowVlVaT1QxVkZiRlpYVkZaUVVYcFdTbFF3VWxwa01IUkVVbFJzVEdF
d1drMVQKTWpGRFVUQnNjbEZYYkZGV1JHeFZWREJWZUZWV2JFVlZiV1JhQ2xJd1NtNVhWVVozV2pC
T2RGWnVWbUZSVnpnNVEyYzlQUW89Cg==

view raw

mondai5

hosted with ❤ by GitHub

どうやらまた base64 のようです。なのでとりあえず一度デコードしてみたところ、また base64 がでてきました。そこで何度か base64 でエンコードされてるのか?!と思い、以下の様なスクリプトを書いて実行させてみました。


#!/bin/sh
cp mondai5 mondai5_2
for i in `jot 20 1`
do
base64 -D mondai5_2 > mondai5_tmp 2>/dev/null
if [ $? -ne 0 ]
then
rm mondai5_tmp
break
else
cp mondai5_tmp mondai5_2
fi
done

view raw

dec_base64.sh

hosted with ❤ by GitHub

上記のスクリプトを動かすと mondai5_2 という以下のファイルを生成します。


begin 644 –
M'XL(`'R)"E4“POP9F;A8@`!SVE%;B+>Z0=-6!D80)@9*):7FNT4E6%IZ!BI
M%AQY7J.QB(%A0OU_!/@'Q/O_HX+W_P\PW=E='+/LUK43[DN^.%R^4I5E8NLS
M+]CMRLGE2VS55S"?JIIIPFMR^8H4\Y44$UO?%5]F23"89%Q@8&L`6FER@>$"
MFUN#B43#A<P%[`$,7ZJ6K^R<P+[").,K\Y6Z%;:^4D:)4[X:\:Y<[-;6?$62
MQ]>L0WZE65N#5(84+\.%C(P+C`LN,"YK:\A@8&!<N'"1^PH&_L`%M@X\4@P,
M;(T+%U]A@`(@/W,"XP(@"VBM"9!L]YWB`[3@5@/0'EZV-@:<H+;-CU$B,9`A
M>8]%9D$+D_0'&3,_@1-Z"MJ_*N=XM:]QNW9L(VN+2L0"=^:?'QUX3,[.XR]7
M<&_JUG*[]:W!1>BC2.AMIB\!"L6>)6=V3*C,.>*>4R!JU>/\Y9#OF^,^$N'9
MQYA-;C]BBZR\^#/R1\?3X-[:99$O^QSW5#7^7&>OK!.R,T9@H6HC`_,<KJ/L
M!W,%$Z46OFQH_[>4Q?J$B.,V)A_UDTXS*R/W7+^A4,L[84G-KW<*$0Z<P0Q;
MM\\2##YJ*?M"B;6GQMII0ER<?4#^^C<_-X?_MULTI<[QHV%DC79]O?/9X_$_
M')UE7W6[_+?^.NVT\NKGO_>Q/-MXTB>0+_3B?(/5)S*3+RV3Y]NJRA(4K'YA
MT@U+M[:PW^$7W=ZS=3ZN^?OW=,D,GK<N$\SYG^H8\11^L)SGK]8KI')KA=.E
MLY8IVCL>/+JON*GA6RFOYAO??UQ_M(K/G4]9+\ES0VCS9OV_;K;M&AFS.?<8
M*IV\/<V!HWWCW.]!56+'-EB*+TT/8N___'&+X/O+O'/3_-]*R^VI^K=;8->%
M-V=X)TW2*^RT_W0H/=IC_V>S-Q6W+R_-,LY+N"WGJS%_YZD=;9K/>UIM[TO?
M$HR:\"2TOTK4LT–=8E*YN4+IG,*JEYK;FF/+^#,V#AC;^+6PP][=>)/,[@7
MFZU?$ECP0WC'O@TF&U2M/(HG[I::^>-8)->);6J3EZFNG#+SZU?^BB,R-Y3V
M7NG?:GB"K3;A/>_V&4TSG7F?_FA;,#5Y/E_,%(:.P,HD-TN/QTR-<W.=4_1S
MYDOL8/RV8;*1](3KTQ3<%\=ZBM:*KCG&W;%<[%#8H=B9O!<?<\S)OEI^_$.P
MR:FWT;8F.JPA\Z0\F!=\2SB9H#EYX^P;2LIW/N?FL$JJR-K/]ZUX7IXV1\$W
M?$=+_%8VKV:ENVX'^HY'!#M="%M^B-$FZ<PFJ=B[,S^H\]G>^K#@_[(7YF+G
MVJ_?/I;7$RKX[+$.'V^-QMV$8Z5-74P]*UY<.-,P\6M[6JI$8T)V]Y9`C]=)
M!JI?Y"9H1YHSY=R./76FX>"]P]P+KB<<F5409)0N>J7A6/RM;P:!IQYJGS99
M'&[C6)'U<[?)C:#'S4JQ:AS/8JJ3YM\W2MN;=%<F:]L4]P*CN-/LANY^CW4J
M*JMKKQQ_Y5L]^;*1R_R33DL#&J>:'K+8^(?AI+W6-9X`=^$5D94O#SYB2ES\
MR50N:G\=R[NE-VN6J/(I3S+,26'_QY[,FMGAR2)]91;C]0FEQY9/"9SSB$<]
MMGYWAH1=%KM$V*/@4.$DS>\-O+U>A[0>W9Q]R.OUJA\.&SN^<2Y?.F7QW&5=
M'QGMI:R+6_.C5W"TW?#;=S<WN&)31_R+A"*ISZ+3FIY_T,\*YIWE7&X6G^!W
MJE;J4;B#F]-$YPNG.L5"7/NK9::^+#MRYJFNX/25O)-\F7-W"IA_7_.JUW:>
M($_C8JMJ\\M+%;MWQ)X4>>CD;+.(]42`-R.3/0.N8E4%6HXH0&E@(<L%Y3`R
E2#"(LFU]GY!X@1&=#O!F98.H860(!=*AK*`B"@"=?S8MP`4““`
`
end

view raw

mondai5_2

hosted with ❤ by GitHub

begin で始まり end で終わっているあたりから uuencode でエンコードされたファイルだと分かったので以下のようにデコードします。

$ uudecode -o mondai5_3 mondai5_2

そして得られたファイルについて、どんなファイルなのか file コマンドを用いて調べます。

$ file mondai5_3
mondai5_3: gzip compressed data, from Unix, last modified: Thu Mar 19 17:31:56 2015

どうやら gzip ファイルのようなので素直に解凍。

$ gzip -dc mondai5_3 > mondai5_4

作成したファイルに対して再度 file コマンドを実行。

$ file mondai5_4
mondai5_4: Zip archive data, at least v1.0 to extract

zip ファイルなので再度解凍。

$ unzip mondai5_4
Archive: mondai5_4
extracting: nek 

再度 file コマンドを実行。

$ file nek
nek: bzip2 compressed data, block size = 900k

またまた解凍。

$ bzip2 -dc nek > mondai5_5

またまた file コマンドを実行。

$ file mondai5_5
mondai5_5: 7-zip archive data, version 0.3

解凍して出てきたファイルに対して file コマンド(ry

$ file n
n: RAR archive data, v1d, os: Win32

解凍して出てきたファイルに対し(ry

$ file ne
ne: LHarc 1.x/ARX archive data [lh0]

解凍して(ry

$ file nex
nex: xz compressed data

解(ry

$ file nex-1
nex-1: data

やっと圧縮ファイル以外が出てきたのでとりあえずバイナリを vim で眺めてみます。

$ vim -b nex-1

ファイルの最初に MSWIM と書いていたのでその単語でググった結果、どうやら Windows Imaging Format ではないかと分かりました。7-Zip で解凍出来るようなので解答して得られたファイルに対して file コマン(ry

$ file QRcode
QRcode: Sun raster image data, 123 x 123, 8-bit, RGB colormap

そのままだと表示出来なかったのでとりあえず jpeg ファイルに変換。

$ convert QRcode QRcode.jpg

以下がそのファイルです。

QRcode

どうやら名前の通り QR コードなので適当に携帯のアプリで読み込んだところ

+BCcENQQxBEMEQAQwBEgEOgQw-

という文字列が出てきました。調べた所、UTF7 でエンコードされた文字だということがわかったため、以下のサイトを使ってデコードしました。

Encode/Decode_Tool

デコードした結果 Чебурашка でした。ドイツ語でチェブラーシカという意味だそうです。これがそのまま答えでした。

 

 

とりあえず疲れたので今回はここまでです。mondai6 以降は次の機会に。

ではでは〜

終了ステータスを見える化しよう!

やっはろー、おきなわです。

皆さんは普段プログラムやコマンドを実行した後、ちゃんと終了ステータスを確認したりしてますか?

確認しないよ〜って人はプログラムやコマンドが正常に動作した事をどうやって確かめてますか?

私は作業中は基本的に終了ステータスを確認するようにしています。そうしておいたほうが経験上、何かと便利なので。そんな終了ステータスですが、もちろん毎回

$ echo $?

と打って確認している訳ではありません。見える化をしてひと目で分かるようにしています。

というわけで今回はこういう風に見える化してるよ!という紹介をしたいと思います。ちなみに私は普段 bash を使っているので今回は bash での設定の話になります。

他のシェルを使ってる方はまぁ、頑張ってください(*^_^*)

とまぁ前置きが長くなってしまいましたが、私がやっている見える化は .bashrc に以下の一文を追加しているだけです。

PS1="[ \`if [ \$? = 0 ]; then echo \[\e[1m\e[32m\]\u\[\e[0m\]; else echo \[\e[1m\e[31m\]\u\[\e[0m\]; fi\` @ \[\e[1m\e[31m\]\h\[\e[0m\] \[\e[33m\]\[\e[1m\]\w\[\e[0m\] ]\$ "

詳しくは説明しませんが PS1 を設定することでシェルの表示を変更する事が出来ます。コレを上手く利用することで、コマンドの終了ステータスが 0 以外ならユーザ名が赤色に、0 なら緑色になるようにしています。

ちなみにこんな感じで表示されます。

表示例

これで正常終了したかそうじゃないかが一目でわかりますね。

またホスト名やカレントディレクトリの表示色も変えて目立つようにしています。よく複数のホストにまたがって作業を行うので、サーバを間違えないように目立つようにしています。

地味に便利なので一度お試しあれ☆(ゝω・)vキャピ

ブログ初めたよ

初めまして。

これまでに何度かブログを作っては消し作っては消しをしてきました、おきなわです。

今まではこれといって書く事がなかったためにブログを作っても更新せず、結局消してしまうといった流れが確立していたのですが、最近になってブログがないと備忘録とか Write up とかを書く場所が無いな〜と思い始めたため、なんとなく気の向くままにまた作ってみました。

これからはちゃんと更新して続けていけるように頑張ります(*^_^*)

よろしくね☆(ゝω・)vキャピ