セキュリティ・キャンプ2016の思い出

ポンコツ過ぎるし、頭大丈夫じゃない気がする…

応募まで

気づいたら締め切り3日前だった。
土日寝ないで書いたから文章がヤバい。
応募するだけでもためになると思う。

選考結果発表

授業中に結果のメールがスマートウォッチに来た。
かると思ってなかったので嬉しすぎてその日は授業に身が入らなかった。
去年の発表は6/14だったので今年もそろそろですね。
/* この日からはtwitterとかで「セキュキャン」とか「セキュリティ・キャンプ」とかで検索しないほうが良い。 妬みは非常に見苦しいのでやめましょう */

前日

正直当日起きれるか微妙だったので夜行バスで東京に行くことにした。
しかし、夜行バスに乗り遅れて死

1日目

早朝に新宿に到着し時間まで東京をふらつく。
(当時流行っていたアニメ「NewGame!!」の聖地巡礼で阿佐ヶ谷へ行ったり秋葉原行ったりしてました)

時間ギリギリになりつつも会場に到着し名刺交換等…

3日目

寝坊した。
運営からのモーニングコール(絶望)で飛び起き、急いで支度して部屋を出ようとしていたところに運営の人が部屋まで来た。

5日目

貰いました

修了証書授与の時に「眠い?」って聞かれた。(大丈夫です。ちゃんと起きてます。) このあと適当に東京ふらついて赤羽の宿へ

X日目(コミックマーケット90)

二回目のコミケ参加。

セキュリティキャンプ関係者のサークル等を廻る。
その後新幹線で帰路へ

グループ「おねぇちゃぁん(裏声)」の人たちへ

クソ無能で本当に申し訳ありませんでした

BrainFu*kインタプリタを書いた

この記事は#一人GWハッカソン 5/3の記事です

今日のテーマはなんかのインタプリタを作るです

最初は自分で言語作る気満々でした

11:00~12:00 言語仕様の妄想

  • 四則演算ができる
  • スタックが用意されていて自由に使える
  • 変数は予め定められた8つ
  • 配列なんてなかった
  • 標準で用意されている関数はprintのみ
  • if,while,breakが使える
  • for文なんてなかった

12:30~13:55

AbemaTVで「変態王子と笑わない猫。」一挙放送やってたので見ました。
脳が溶けました。

13:00 ~ 14:00 感覚でコードを書き始める

javascriptで作った四則演算のプログラムを参考にprintとかを実装し始めるものの、
途中でわけわからなくなって死。

14:00 ~ 調査

流石に感覚で書くには無理があると感じ、ネットの情報を漁り始める。
一般的なインタプリタでは字句解析と構文解析というものが行われているらしい。
そして構文解析によって生成された構文木を元にプログラムが実行される。
なるほどなるほど。構文木とかどうやって実装したら良いのか全くわからないんですけど…ウケる…

15:00~16:00 (:3 」∠ )

17:00~ BrainがFu*ck

結局何もできてねーなとか思いながら微妙な気分になる。
何も成果物が無いのは流石にアレなので最終手段として考えていたBrainFu*ckを書き始める…

BrainFuckの実装は[,]さえ実装してしまえば後は簡単だった。

BrainFu*k f:id:akkkix:20170504084158j:plain

なんの捻りもないただのBrainFuc*kが完成した。

反省…

昔四則演算のプログラム書いたことあるしいけると思ってた 実装力がなくてつらいなぁ…
GW後半らへんにネタ切れになったらまた挑戦したい…

参考:

Brainfuck - Wikipedia

http://www.hpcs.cs.tsukuba.ac.jp/~msato/lecture-note/comp-lecture/

プログラミング言語を作る

四則演算(昔書いたやつ。再帰下降構文解析っていうらしい。):

sisokuenzan

OSなしでHelloWorld

この記事は#一人GWハッカソン 5/2の記事です

本日のテーマはOSなしでHelloWorldをするです

最初はOSを作ろうと思っていましたが一日では無理でした。

10:00~12:00 環境構築

Windowsで環境を構築しようとしたけど上手くいかない… 仕方なくVirtualBoxの上のLinuxを使用する

OSはXubuntu16.04、アセンブラはnasm、仮想マシンにはqemuvirtualboxを使用

12:00~13:00 初めてのプログラム

 [BITS 16] 
ORG 0x7C00
BOOT: 
CLI
HLT 
TIMES 510 - ($ - $$) DB 0
DW 0xAA55

起動した後にブートセクタがメモリの0x7C00に読み込まれるらしいのでORGで0x7C00をセット(GASではORGは使えないみたいですね)
CLIで割り込み禁止、HLTでプログラム終了
最後に位置合わせに0x00を出力しブートセクタ終端の0xAA55
C言語でいう

#include ‹stdio.h›
int main(void){
   return 0;
}

みたいなプログラムらしい。

13:00~14:00 いろいろ

スタックとかセグメントとか

14:00~15:00 INT10

画面入出力とかディスクの読み書きとかするためにはBIOSが提供している機能を使う
画面入出力をするためにはINT 0x10を使う。

INT0x10を使って文字を出力するためには
AHに0x0E
ALに文字のASCIIコード
BHにビデオページ番号
(よくわからないけど0x00で良いらしい)
BLに色を指定

 [BITS 16] 
ORG 0x7C00
BOOT: 
CLI
MOV AH, 0x0E
MOV AL, 0x41 ;'A'
MOV BH, 0x00
MOV BL, 0x07 ;グレー
INT 0x10
HLT 
TIMES 510 - ($ - $$) DB 0
DW 0xAA55

色が変わらないと思ったらビデオモードというのを変えないといけないらしい
グラフィックモードを指定するためにはAXに0x4f02を入れてBXにビデオモードを入れる ビデオモードは VESA BIOS Extensions - Wikipedia で解説されている

 [BITS 16] 
ORG 0x7C00
BOOT: 
CLI
MOV AX, 0x4f02
MOV BX, 0x0102 ;800x600 16色モード
INT 0x10

MOV AH, 0x0E
MOV AL, 0x41 ;'A'
MOV BH, 0x00
MOV BL, 0x0A ;ライトグリーン
INT 0x10
HLT 
TIMES 510 - ($ - $$) DB 0
DW 0xAA55

AHに0x13を入れてINT 0x10すると文字列が表示できるらしいです f:id:akkkix:20170503100750j:plain
なんかちょっと感動

15:00~16:00 寝

昼寝

16:00~ ゚Ω\ζ°)チーン

ディスクの読み書きにハマる
解決方法が分からず終

反省とか

またいつか挑戦したい
こんな感じであと5日浅く広く色々やれればと思う
INT0x10しただけだしハッカソンじゃなくね!?

参考:

http://softwaretechnique.jp/OS_Development/scratchbuild.html

https://en.wikipedia.org/wiki/INT_10H

VyOSでルーターを作る

お久しぶりです。

訳あって家のネットワークを分ける必要がでてきたので、今日はVyOSを使ってルーターを作ってみます。

VyOSとは

今日の目標

トポロジ
f:id:akkkix:20170127173204j:plain
いわゆる2重ルーターです

ファイアウォール

送信元 送信先 操作
192.168.2.0/24 192.168.1.0/24 DROP

ポート開放

受信ポート 送信先 送信ポート
1234 192.168.2.2 22

インストール

https://vyos.io/
stableをダウンロードしました。(v1.1.7)

イメージから起動し、ログインします。

install image

インストールが始まるので少し待ちましょう。

インターフェイスへのIPアドレスの割当

インストールが終わったら、起動させてログインします。

configure

設定モードへ入ります。
eth0を192.168.1.2/24、eth1を192.168.2.1/24にします。

set interfaces ethernet eth0 address 192.168.1.2/24
set interfaces ethernet eth1 address 192.168.2.1/24

NATの設定

外部側がeth0、内部側がeth1です。

set nat source rule 1 outbound-interface eth0
set nat source rule 1 source address 192.168.2.0/24
set nat translation address masquerade

これで192.168.2.0/24内のホストがNATされて192.168.1.0/24側に出られるようになりました。

デフォルトゲートウェイの設定

このままでは192.168.2.0/24側のホストはインターネットに出られません。
次に経由するルーター(トポロジのPR-S300NE)を指定します。

protocols static route 0.0.0.0/0 next-hop 192.168.1.1

※systemのgateway-addressでも設定できるみたいです

set system gateway-address 192.168.1.1

ファイアウォールの設定

今回は192.168.2.0/24から送信されたパケットの宛先が192.168.1.0/24だった場合のみDROPします。

set firewall name private-public default action accept
set firewall name private-public rule 1 destination address 192.168.1.0/24

お好みでログを設定します。

set firewall name private-public rule 1 log enable

インターフェイスファイアウォールを設定します。

set interfaces ethernet eth1 firewall in name private-to-public

ポート開放

内部のホストにsshできるようにしておきます。

set nat destination rule 1 inbound-interface eth0
set nat destination rule 1 protocol tcp
set nat destination rule 1 destination address 192.168.1.2
set nat destination rule 1 port 1234
set nat destination rule 1 translation address 192.168.2.2
set nat destination rule 1 port 22

2重ルーターになっているのでインターネットからアクセスしたい場合はインターネットに接続しているルーターもポート開放します。

VyosにSSHで接続できるようにする

面倒なのでSSHでどこからでもVyOSを設定できるようにします。

set service ssh port 22

NTPの設定

ログ等に正確な時間が記録されるようにVyOSをNTPで時刻合わせします。

set system ntp server ntp.jst.mfeed.ad.jp

DNSIPアドレスの設定

DHCP等は特に設定していないのでホスト名を解決できるようにDNSを設定します。

set system name-server 8.8.8.8

設定の反映と保存

設定を変更したら忘れずに

commit
save

やりましょう。

静的ルーティングの設定

最後に192.168.1.0/24から192.168.2.0/24にアクセスできるように静的ルーティングを設定しておきます。
(PR-S300NEの例)
f:id:akkkix:20170127184035j:plain

まとめ

ネットワークの勉強がてらVyOSでルーターを作ってみましたが案外簡単に設定できて拍子抜けでした。
BGPやOSPF等にも対応しているそうなので別の機会にそちらも試してみたいです。
わざわざ高いルーターを買わなくてもこのような形で勉強できるのは素晴らしいと思います。

RTX1000のIPアドレス割り当てとファームウェア更新

ちょっと前のことですが某所でRTX1000を買いました。

(下のやつです)

IPアドレスの設定

初期状態ではIPアドレスを持ってないので設定にはコンソールケーブルかRARPIPアドレスを設定して上げる必要がある。

コンソールケーブルなんて持ってないのでRARPIPアドレスを設定することにした。

早速手持ちのPC(ArchLinux)でrarpdを動かそうとしたらよくわからないエラーがでてこけるので仕方なくArchのインストールメディアを引っ張り出してきてRARPを動かしたところ無事IPアドレスが設定された。

f:id:akkkix:20160626200943p:plain

> vim /etc/ethers
00:A0:DE:xx:xx:xx xxx.xxx.xxx.xxx
> rarpd -dvae

ここでRTX1000を起動するとIPアドレスが割り当てられる

早速telnetでログインして管理者権限へ

> telnet xxx.xxx.xxx.xxx
> administrator

文字化けしまくってるので文字コードをASCIIにしておいた。

> console character ascii

忘れないうちにIPアドレスを設定しておく

> ip lan1 address xxx.xxx.xxx.xxx/xx

保存

> save

ファームウェアの更新

YAMAHAのサイトで確認したところ、ファームウェアが最新ではなかったのでファームウェアも更新しておく。

http://www.rtpro.yamaha.co.jp/RT/firmware/index.php

ファームウェアのアップロードには RT-Tftp Client という便利なソフトがあったのでありがたく使わせてもらった。

http://www.rtpro.yamaha.co.jp/RT/utility/rt-tftp.html

f:id:akkkix:20160626185413p:plain

ファームウェアを指定しアップロードしたところ…

f:id:akkkix:20160626185423p:plain

なぜか「転送は失敗しました」と出てかなりヒヤッっとしたが無事アップデートされた。

f:id:akkkix:20160626201228p:plain

セキュリティキャンプ2016の応募用紙

セキュキャン何故か受かりました。クソ雑魚なので当日に向けて精進します。

 

締め切り前の土日で急いで書いたので日本語がおかしいところがあるかもしれないですが、せっかくなので無知を晒したいと思います。応募用紙と簡単に問題を解いた感想を書いておきます。

 

来年以降応募する人の参考に少しでもなれば幸いです。

続きを読む

C言語の関数の引数の評価順序

あらすじ

( ^o^)<ショートコーディング楽しい!
( ^o^)<よーしprintfの引数の中でポインタの参照とインクリメント同時にやっちゃおう!
(;^o^)<あれ…期待した通りに動作しないぞ…
( ˘⊖˘) 。o(待てよ、引数の評価順序ってどうなってるんだ)
|C/C++|┗(☋` )┓三
( ◠‿◠ )☛未定義だ
▂▅▇█▓▒░('ω')░▒▓█▇▅▂うわあああああああああああ


C言語の関数の引数の評価順序に見事に引っかかった。
C言語では関数の引数の評価順序は未定義で処理系によって異なるらしい。
そこで、ちょっと気になったので手元で使えるGCCとVisualStudioで検証してみることにした。

検証コード

#include <stdio.h>
int a;
int func(int arg){
  a=arg;
  return arg;
}
int main(void){
  printf("%d %d\n",func(1),func(2));
  printf("a:%d",a);
  return 0;
}

関数funcに渡された引数を変数aに入れてから引数をそのまま返します。
その後2行目に変数aを出力します。
出力された変数aが1だったら右→左の順、2だったら左→右の順になります。

実行結果

GCC6.1.1場合

1 2
a:1

VisualStudio2015場合

1 2
a:1

どちらともaの値は1になっており引数の評価は右→左の順で行われている様です。

まとめのようなもの

結果はどちらとも右から左だったので普通は右から左に評価されてくのでしょうか。
どちらにしろ未定義とのことなので使わないほうがいいんですが、知っておくと何か役に立つのかもしれないですね。
あとは左から右に評価されてく処理系とかあったりするのか気になります。
その辺も含めて又の機会にもうちょっと詳しいところを調べてみたいと思いました。


参考
引数として関数を渡したときの実行順序 - mooz deceives you
BohYoh.com-C/C++ FAQ 関数に渡される実引数の評価順序はどうなっていますか。
javaの場合は左から右に統一されているんですね。
引数の評価順序 - Togetterまとめ
↑(x=3)+(x+4)の様な部分式の場合も同じようなことになるみたいです。

P.S.
今日外を歩いてたら鳥の糞が直撃しました
すごくつらいです