WiresharkでWifiでの通信を取れるか検証した話

某大学のWifiの学生認証が平文だったので、そのことを指摘する前に自室のWifiで平文通信をキャッチできるか検証してみました。公共の場所での許可のないキャプチャは違法となりますのでご注意を…

使用した機材

  • BUFFALO WI-U2-300DS
  • Kali Linux 2019.4 (VirtualBox)

手順

まずはKali Linuxを起動して、WI-U2-300DSを接続します。(VirtualBoxではUSBコントローラーが2.0以上でないと正しく動かないことがあった)
端末を起動して「iwconfig」を実行すると以下のような感じで子機が認識されているはずです。(wlan0は環境によっては異なるかもしれません。以降はwlan0と仮定します。)

wlan0     IEEE 802.11  ESSID:off/any  
          Mode:Managed  Access Point: Not-Associated   Tx-Power=20 dBm   
          Retry short  long limit:2   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off

次に稼働しているWifi関係のツールを止めます。

airmon-ng check kill

おそらくwpa_supplicantが停止させられます。
次に子機をモニターモードにします。iwconfigを使います。(間にifconfigでdownとupを挟まないとうまく行かない…?)

ifconfig wlan0 down
iwconfig wlan0 mode monitor
ifconfig wlan0 up

うまく行けば無言でプロンプトが帰ってくるので、そのまま作業を進めます。
次に

airodump-ng wlan0

を実行するとSSIDの一覧が出ますので、キャプチャしたいSSIDをみつけ、チャンネル(CH)をメモします。

次にWireSharkを起動します。
先に「表示」=>「無線ツールバー」より無線ツールバーを出しておきます。
今度はWPAの鍵を設定します。
「編集」=>「設定」=>「Protocols」=>「IEEE 802.11」=>「Decryption keys」より
鍵を入力します。
WPA2-PSKの場合はhttps://www.wireshark.org/tools/wpa-psk.htmlでSSIDとパスワードを入れ、生成されたキーを「+」=>「WPA-PSK」と選んで入力します。
OKを押して閉じていったあと、「キャプチャー」=>「オプション」より、wlan0を選択して、キャプチャを開始します。
無線ツールバーで先程メモしたチャンネルを接続後、別端末で該当Wifiにつなぎます。(最初のハンドシェイクが傍受できないと解読できないため、つないでいる場合は一旦切って再接続してください。)

うまく解読できれば、色付きのログが流れてくるはずなので、example.comでも接続するとHTTP通信内容が見れます。

感想

公共WifiなどのHTTP通信もダダ漏れなんでしょうね…恐ろしい。
あとセキュリティに詳しくなりたい。

Sakai19(Sakai Project)をインストールした

Sakaiというのは学習管理システムとかeラーニングとか言われてるシステムで、大学ではMoodleかこっちを使う所が多い(?)そうです。某所で古いバージョンのFork版が動いてたので、ふと思い立ってサーバー立て時の記録を残しておきます。Tomcatなどのいい勉強になったかな(半日潰れた)。

構築環境

  • Ubuntu 18.04 LTS
  • Google Cloud Platform Compute Engine n1-standard-1
  • RAM 3.75GB
  • HDD 10GB
  • Sakai 19.03

テストで立てたので環境も即席のものです。最初は別サーバーのDockerコンテナでやろうと思いましたが、URLをサブディレクトリにすることができず、サブドメインの設定をするのも面倒だったのでIPアドレスが降ってくるGCE使いました。JVMを使うからなのか、メモリは結構食いまして2GB以上は必要なのではないでしょうか(足りないと途中でエラー吐いて死ぬことがある)
https://confluence.sakaiproject.org/pages/viewpage.action?pageId=109772886
基本はここを見ながら進めます。

Tomcat導入

まずは、必要なパッケージを落としておきます。

apt-get install git openjdk-8-jdk maven mysql-server nginx

最初はOpenJDK-11-JDK入れていたんですが、うまく動かないので8を持ってきました(ドキュメントでもJava 1.8とあるし、JDKの互換性は結構ないんですね…)
つぎにTomcat 8系をひっぱってきます(ここらへんからsuなどでrootになってるほうが楽かも)
https://tomcat.apache.org/download-80.cgi でtarボールをダウンロードしてきて/opt/以下に展開します。(注意したいのはapt-getでのtomcatではだめで、tomcatのパッケージにSakaiのバイナリを追加する形で動かすようです。)
そしてリンクを張っておきます。

cd /opt/
tar xvf apache-tomcat-8.5.49.tar.gz
ln -nsf apache-tomcat-8.5.49 tomcat

次にドキュメントにあるようにtomcatのbin/setenv.shに以下の内容を追加します。

export CATALINA_HOME=/opt/tomcat
export JAVA_OPTS="-server -d64 -Xms1g -Xmx2g -Djava.awt.headless=true -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC"
JAVA_OPTS="$JAVA_OPTS -Dhttp.agent=Sakai"
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false"
JAVA_OPTS="$JAVA_OPTS -Dsakai.security=$CATALINA_HOME/sakai/"
JAVA_OPTS="$JAVA_OPTS -Duser.timezone=Asia/Tokyo"
JAVA_OPTS="$JAVA_OPTS -Dsakai.cookieName=SAKAI2SESSIONID"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8089 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

高速化のロジックがドキュメントでは乗っていますが、お好みに応じて行います。

Sakaiの起動

次にhttp://source.sakaiproject.org/release/よりSakaiのバイナリパッケージを引っ張ってきます。これをTomcatのディレクトリで展開します。

cd /opt/tomcat/
tar xvf sakai-bin-19.3.tar.gz

また、SakaiでMySQLを使うにはひと手間いるらしく、まず、https://dev.mysql.com/downloads/connector/j/より、「Connector/J」の「Platform Independant」のtarを持ってきて中にある「mysql-connector-java-.x.x.x.x.jar」をtomcat/lib/ の中に放り込みます。

次にmy.conf(Ubuntuでは /etc/mysql/mysql.conf.d/mysql.conf らしい)の[mysqld]以下に

default-storage-engine=InnoDB
lower_case_table_names=1

を追加します。(https://confluence.sakaiproject.org/display/DOC/Sakai+11+database+supportより)

次に tomcat/sakai/local.properties にhttps://confluence.sakaiproject.org/pages/viewpage.action?pageId=109772886に従って次の設定を書き込みます。(sakaiuserとsakaipasswordとsakaidatabaseは適宜置き換えてください)

username@javax.sql.BaseDataSource=sakaiuser
password@javax.sql.BaseDataSource=sakaipassword

## MySQL settings
vendor@org.sakaiproject.db.api.SqlService=mysql
driverClassName@javax.sql.BaseDataSource=com.mysql.jdbc.Driver
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
url@javax.sql.BaseDataSource=jdbc:mysql://127.0.0.1:3306/sakaidatabase?useUnicode=true&characterEncoding=UTF-8
validationQuery@javax.sql.BaseDataSource=select 1 from DUAL
defaultTransactionIsolationString@javax.sql.BaseDataSource=TRANSACTION_READ_COMMITTED

これに従って、mysqlで該当データベースとユーザを追加します。(ドキュメントを参考にすると良いでしょう)

次にnginxのリバースプロキシを設定します。
local.propertiesにserverURIを記載していても、NginxでHostをSakaiにパスしないと正常に動作しないので注意してください。(ここを忘れててうまく行かなかった)

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    ....
}

ここまですると、設定が終わっているはずなので、tomcat/bin/startup.shを叩くと起動が開始します。tomcat/logs/catalina.outを確認してエラーで死んでなければ、起動後(2分くらいかかります)、http://hogehoge/portal/にアクセスするとメイン画面が出てきます。(UserName:admin PassWord:admin で入れます)

だいぶ雑な説明でしたが、とりあえずinstall記です。

ibus-mozcのビルド記

ibus-mozcがないLinuxディストリビューション使ってるので、ビルドしてインストールしました。
今回はx86_64環境とします。

ビルドにはibus-develみたいなibusの開発用パッケージが必要とGTK+-2.0-develとQt5Base-develが必要です。
そんでももって以下のコードを実行します。

$ git clone https://github.com/google/mozc.git
$ wget https://raw.githubusercontent.com/PG-MANA/solus-ibus-mozc/master/files/mozc.patch
$ patch -p < mozc.patch
$ cd mozc/src
$ GYP_DEFINES="ibus_mozc_path=/usr/lib64/ibus-mozc/ibus-engine-mozc server_dir=/usr/lib64/mozc" \
        python build_mozc.py gyp
$ python build_mozc.py build -c Release unix/ibus/ibus.gyp:ibus_mozc server/server.gyp:mozc_server \
        gui/gui.gyp:mozc_tool renderer/renderer.gyp:mozc_renderer

Server_dirは/usr/lib/mozcにするとリンクのせいか(大抵x86_64は/usr/lib は/usr/lib64 にリンクされている)、起動に失敗するようでした。

そんでももってできたファイルをインストールします。
以下のコードをrootで動かしてください

pushd out_linux/Release
install -m 00755 -D ibus_mozc      /usr/lib/ibus-mozc/ibus-engine-mozc
install -m 00755 -D mozc_renderer  /usr/lib/mozc/mozc_renderer
install -m 00755    mozc_server    /usr/lib/mozc/mozc_server
install -m 00755    mozc_tool      /usr/lib/mozc/mozc_tool
install -m 00644 -D gen/unix/ibus/mozc.xml  /usr/share/ibus/component/mozc.xml
popd
pushd src/data/images/unix
install -m 00644 -D ui-alpha_full.png  /usr/share/ibus-mozc/alpha_full.png
install -m 00644    ui-alpha_half.png  /usr/share/ibus-mozc/alpha_half.png
install -m 00644    ui-dictionary.png  /usr/share/ibus-mozc/dictionary.png
install -m 00644    ui-direct.png      /usr/share/ibus-mozc/direct.png
install -m 00644    ui-hiragana.png    /usr/share/ibus-mozc/hiragana.png
install -m 00644    ui-katakana_full.png  /usr/share/ibus-mozc/katakana_full.png
install -m 00644    ui-katakana_half.png  /usr/share/ibus-mozc/katakana_half.png
install -m 00644    ime_product_icon_opensource-32.png  /usr/share/ibus-mozc/product_icon.png
install -m 00644    ui-properties.png  /usr/share/ibus-mozc/properties.png
install -m 00644    ui-tool.png  /usr/share/ibus-mozc/tool.png

これでとりあえず動くはずです
必要なことがあれば後で追記します。

OtakuAssembly 出版記

OtakuAssembly Vol.1が技術書典7で出ました。
https://techbookfest.org/event/tbf07/circle/5710683937177600
ここでは終了後の感想やOtakuAssemblyの成り立ちなどを書いておきます。

OtakuAssemblyの成り立ち

2019/4/14の池袋で技術書典6がありました。
当時上京したてで初めての東京らしい大規模イベントに参加しました。
セキュリティキャンプを超える1万人の人混みの中で今まで見たこともない数の技術書同人誌を見て多くの先端技術やニッチな技術を知りました。
そのときにセキュリティキャンプ2017に参加したときのあの熱さとともに当時思っていた「新たな視点でOSを作る人の支援をする」という目標を思い出しました。
「自分も本を出版して新たなOS自作をする人のお手伝いしたい」、そう熱い思いを抱えて帰宅し密かに文を書き出しました。ところがいざ書き始めると「本を書くのは思っていたより難しい…」「こんな初歩的なネタで受けるんだろうか…」「印刷費も高いし大損はしたくないな…」と多くの壁が立ちはだかりました。そんな不安でモジモジしていたときに@sksat_tty氏に会う機会があり、雑談の後ある話題を持ちかけました…「技術書を一緒に書いてみないか。そうすればボリュームも増えてクオリティーも上がるし印刷費も分担できてリスク回避にもなる。合同誌だとネタにもなるだろうし、もう少しメンバーを増やせばもっと面白くなりそう。」と。sksat氏の返事は芳しくなく「やるならちゃんとした内容でやりたいし今の自分ではその域に達していないから…」というごもっともな意見で話が終わりました。そんな話を聞いて自分も「OSがバリバリできるわけでもないし、やっぱり本を出すのはおこがましすぎるかな…」と技術書執筆の熱も冷めていきました。
執筆作業もおろそかになっていたとき突然sksat氏から声がかかりました。どうやら「『本を書きたい』と言っているうちは書かないんですよ。」と煽られたとのことで、sksat氏とたまたま一緒にいたCra2yPierr0t氏を巻き込んで「本を書こう!!」とSlackチームが結成されました。
その後にTwitterで募集をかけたらメンバー10人以上になったり、Otaku + Assemblyという安直足し算でサークル名が決まったり、脅威の300Pの本ができたり…とあっという間に時が過ぎていき、気づけば技術書典7でサークル側に立っていました。

OtakuAssembly Vol.1を売ってみて

びっくり、ただただびっくりです。
当初も思いもよらなかった300Pの分厚い「薄い本」ができたと思ったら、43秒で一冊売れる勢いで売れてしまって5時間近くダウンロードカードを渡す作業をして、空いた口が塞がらないほどの驚愕です。
終わった後で原稿を読み返してみたら、圧倒的ボリュームで自分が知らないこともサークルメンバーがたくさん書いてくださってました。
OtakuAssembly Vol.1が成功したのは本当にメンバー皆様のおかげです。
こんなリーダー性のかけらのないオタクと一緒に進んでくれて、最終的に二人原稿を落としてしまいましたが「8人分のゴチャゴチャに低レイヤーネタが詰め込まれた分厚い本」というインパクト抜群の本を出版できましたし、そのおかげで売ることができたと思います。
自分の書いた記事が果たしてどんな評価を受けるかわかりませんが、「技術書を書きたいんだ」という思いのたくさん詰まったOtakuAssembly Vol.1を大切にしたいと思います。
次回が出るかわかりませんがその時はどうか皆さんよろしくお願いします。

OtakuAssemblyの良かった点・悪かった点

良かった点

  • ネタ盛りだくさんのボリューミーな本が作れて話題を呼び完売できた
  • 印刷費のリスクヘッジができた
  • 校閲作業をみんなでできた(文章下手な自分にとって大変ありがたい)
  • 作業が分担できたり、様々な知見を頼りにできた

悪かった点

  • お金の話では少し揉めた(しっかり取り決めて厳重に扱うべき)
  • お金の受け渡しに難がありそう(金銭やり取りは最小限にすべき)
  • 意思疎通がうまく行ってない点もあった(これは自分がリーダーを決めたり、役割を指定しなかったのが悪いです…)

終わりに

BOOTHなどでの販売も予定しているのでよかったら購入してください。
購入してくださった皆様、心から感謝します。またどこかでお会いしましょう。

Thermaldの設定の仕方

熱暴走(?)気味のノーパソを手に入れてしまい、Windowsはなんとか使える範囲だけどLinux入れて並行作業すると動作カクカクなので悲しい(親との相談の上大学用のWindows機として使うことにしました)。Core i5なんだけどなぁ…今回はメーカを冒険してみましたが、Linux機を買うときはメーカもしっかり選びましょう。

そんなわけで、Thermaldを入れて発熱を抑えようと思いましたがその時の設定方法をメモしておきます。thermaldは導入済みとします。
設定ファイル作る方法は

$ git clone https://github.com/intel/dptfxtract.git
$ cd dptfxtract
$ sudo acpidump > a
$ sudo acpixtract a
$ sudo ./dptfxtract *.dat
$ sudo cp /etc/thermald/thermal-conf.xml.auto /etc/thermald/thermal-conf.xml

としたら環境にあった設定ファイルができます。(acpiutilがないとacpidumpあたりは動かないかも)
あとは設定ファイルをお好みでいじってsystemctlでenableしてやるといいと思います。

セキュリティキャンプ2019参加記(チューター)

ドッタンバッタン大騒ぎして結局今までろくにまとめられなかったセキュリティキャンプの参加記。
感想も交えて詳しく書けたらいいなと思っています。

セキュリティキャンプ2017参加記

こんなことを書いて早2年、セキュリティキャンプにチューターとして参加ささせていただくことができました。というわけで前回と同じようにまとめたいと思います。
セキュリティキャンプの様子を知りたい方は、セキュリティキャンプ2017参加記も参考にされると良いと思います。
注意
この記事では大量のツイート埋め込みを行っていますので、ロースペックPCなどで重くなることがございます。ご了承ください。

“セキュリティキャンプ2019参加記(チューター)” の続きを読む

ドメインをDynadotにTransferした

このドメインですが、某名前ドットコムが嫌すぎたので、別ドメインを保持しているdynadotに移管したので、記録しておきます。

まず、移管元で移管ロックをはずしてAuth Codeを手に入れます。
この時にやらかしたのですが、移管元に「Whoisプロテクトメール転送オプション」ってありまして、WhoisプロテクトをかけておきながらTransfer転送メールが受け取れると思い、それができるかどうかホームページで読んだのですが、これまた文章がわかりにくて…まあやれるだけやってみようと食費を削ってオプションに申し込みましたが、結局できませんでした。Transferは即座に拒否されて失敗しました。
というわけでドメインのTransferはWhoisプロテクトを外すしかないようです。

認証に失敗したためDynadotさんに英語で連絡して、「認証に失敗したためTransferを一旦キャンセルしてほしい」と頼んだところ、「向こうからキャンセルの連絡がないとできないんだ…メールは届いてるみたいだけど、こっちには連絡きてないね…確認するからもうちょっとまって」というやり取りをして、結局移管元の連絡待ちになったわけですが、幸い数時間後に連絡が来たようで、やり直しになりました。

まず、ドメイン移管ロックとWhoisプロテクトを外して、Auth Codeを手に入れます。
次にDynadot側でAuth Codeを入れてWhoisプロテクトを有効にして購入作業を行った後に、移管元から確認メールが来ますので指定されたURLにアクセスします。

購入画面
色々隠しているけど、どこのレジストラかまるわかり…

承認すると、上位レジストラの承認待ちになるのでしばらく待ちます。自分は数時間で通りました。そうするとDynadotから完了通知メールが飛んできて即座にWhoisも書き換えられてプロテクト状態になります。

完了通知メール

というわけで、なんだかんだ言いながらできました…

SiFive HiFive 1 Rev Bで遊んだ

セキュリティキャンプ2019にチューターとして参加しているときにhikalium先生からHiFive1 RevBというものを借りて、https://github.com/PG-MANA/RuscV (Rustで書かれたOSもどき)を試してみようとビルドしたので記録します。

まずHiFive1はRISCV-32 IMACなアーキテクチャなのですが、RuscVはRISCV-64 IMAC向けに書いていたので(というよりテストしていたので)、大幅に書き換えました。

地味にメモリ配置もHiFive1とHiFive1 Rev Bで違うのでつまづきました。

まずriscv32-unknown-none.jsonを作成して以下の内容にします。

{
  "abi-blacklist": [
    "cdecl",
    "stdcall",
    "fastcall",
    "vectorcall",
    "thiscall",
    "aapcs",
    "win64",
    "sysv64",
    "ptx-kernel",
    "msp430-interrupt",
    "x86-interrupt",
    "amdgpu-kernel"
  ],
  "llvm-target": "riscv32-unknown-none",
  "data-layout": "e-m:e-p:32:32-i64:64-n32-S128",
  "linker-flavor": "gcc",
  "cpu": "generic-rv32",
  "target-endian": "little",
  "target-pointer-width": "32",
  "target-c-int-width": "32",
  "arch": "riscv32",
  "os": "none",
  "features": "+m,+a",
  "disable-redzone": true,
  "panic-strategy": "abort",
  "relocation-model": "static",
  "atomic-cas": true,
  "max-atomic-width": "32"
}

次にリンカスクリプトをconfig/riscv32/hifive.ldとして

MEMORY {
    rom : ORIGIN = 0x20010000, LENGTH = 0x6a120
    ram : ORIGIN = 0x80000000, LENGTH = 0x4000
}

ENTRY(_main)

SECTIONS {
    .boot_entry : {} > rom
    .text : {*(.text*)} > rom
    .rodata : {*(.rodata*)} > rom
    .bss : {*(.bss*)} > ram
} 

としてください。(サンプルなどを漁って適当に作ったので実用化のときはもっとちゃんとしてください…)

ツールチェーンはビルドしても良いですが、公式(https://www.sifive.com/boards)からPrebuilt RISC‑V GCC Toolchainを持ってきてください。(riscv64のバイナリだがriscv32も扱えるみたい)。またexportでもしてパスを通してください。

Makefileを以下のようにします。

#環境設定
##名前
NAME = ruscv

##ターゲット
TARGET_ARCH = $(2)
ifeq ($(strip $(TARGET_ARCH)),)
    TARGET_ARCH = riscv32
endif
RUST_TARGET = $(TARGET_ARCH)-unknown-none
#RUST_TARGET_FILE_FOLDER = target-json/ # https://github.com/japaric/xargo/issues/146

##ディレクトリ
SRC = src/
MAKE_BASEDIR ?= $(shell pwd)/
MAKE_BINDIR = $(MAKE_BASEDIR)bin/
MAKE_IMGDIR = $(MAKE_BINDIR)img/
MAKE_TMPDIR = $(MAKE_BASEDIR)tmp/
MAKE_OBJDIR = $(MAKE_TMPDIR)obj/
MAKE_CONGIGDIR =  $(MAKE_BASEDIR)config/$(TARGET_ARCH)/

##ソフトウェア
STRIP= riscv64-unknown-elf-strip
##↑変更
MKDIR = mkdir -p
CP = cp -r
RM = rm -rf
LD = riscv64-unknown-elf-ld -n --gc-sections -Map $(MAKE_TMPDIR)$(NAME).map -nostartfiles -nodefaultlibs -m elf32lriscv -nostdlib -T $(MAKE_CONGIGDIR)hifive1.ld
CARGO = cargo
QEMU = qemu-system-riscv32 --nographic -machine sifive_e

##ビルドファイル
KERNELFILES = kernel.elf
RUST_OBJ = target/$(RUST_TARGET)/release/lib$(NAME).a
BOOT_SYS_LIST = $(RUST_OBJ)

#初期設定
export TARGET_ARCH
export MAKE_BINDIR
export MAKE_TMPDIR
export MAKE_OBJDIR


#各コマンド
##デフォルト動作
default:
	$(MAKE) kernel
	-$(STRIP) $(MAKE_BINDIR)*.elf #できなくてもいい

##初期化動作
init:
	-$(MKDIR) $(MAKE_BINDIR)
	-$(MKDIR) $(MAKE_TMPDIR)
	-$(MKDIR) $(MAKE_OBJDIR)

clean:
	$(RM) $(MAKE_TMPDIR)
	$(CARGO) clean

kernel:
	$(MAKE) init
	$(MAKE) $(KERNELFILES)

#run:
#	$(MAKE) kernel
#	$(QEMU) -kernel bin/kernel.elf

# ファイル生成規則
kernel.elf : $(BOOT_SYS_LIST)
	$(LD) -o $(MAKE_BINDIR)kernel.elf $(BOOT_SYS_LIST)

$(RUST_OBJ) :  .FORCE
	$(CARGO) xbuild --release --target $(RUST_TARGET_FILE_FOLDER) $(RUST_TARGET)

.FORCE:

そんなわけでmakeする(make runは動きません)とkernel.elfができるので

riscv64-unknown-elf-objcopy  -O ihex kernel.elf kernel.hex
とするとhexファイルができるので、HiFive1をUSB接続してUSBメモリとして認識されたのちにkernel.hexを放り込むとフラッシュされて再起動します。
リセットと同時にcuコマンドなどでUSBシリアル通信をすると「Hello, RISC-V!」と表示されると思います。

もとのWelcome表示に戻すにはサンプルをビルドしないといけないのですが、ビルドチェーンは配布されてるバイナリを利用してnano.specsの記述を削除するなり、色々手間が必要だったので注意してください。せっかくなので、Welcomeサンプルの
HiFive1 RevB用のHexファイルを上げておきます。(Apache Licence 2.0)
https://repo.taprix.org/pg_mana/riscv/hifive1revb/

Elixirハンズオン

ドリコム社さんが開催してくださった【サーバーサイド講義&実技】Elixirハンズオンに参加してきました。そこでの感想やElixirの感想などを書こうと思います。

Elixirとは

Elixirは拡張性と保守性の高いアプリケーションを構築するためにデザインされた、動的で関数型のプログラミング言語です。

https://elixir-lang.jp/

ElixirはErlang VM上で動く言語で、フォールトトレランスやホットスワップが可能なErlangをRuby風の言語で利用しようと設計されたものらしいです。
サーバーサイド言語ではPHPしか扱ったことしかなかった私は、Elixirを使ってみたいなぁと思ってたわけですが、Ruby風の記述がどうも苦手で(つまり{}を使わない言語系)、手こずっている間に色々しないといけないことに追われて後回しになっていたのですが、幸いドリコム社さんのElixir ハンズオンに参加させてもらえることになり参加しました。

やったこと

Elixirはmixというパッケージ管理システムを使ってます。
アプリを新規作成するときは
$ mix new test_app
とやります。
こうすることで

test_app
├── README.md
├── config
│   └── config.exs
├── lib
│   └── test_app.ex
├── mix.exs
└── test
    ├── test_app_test.exs
    └── test_helper.exs

と言うような構成になります。
設定ファイルがmix.exs で実際にコードを書くのが lib/test_app.ex らしいです。
mix.exsには依存ライブラリなどの記述をします。

今回のハンズオンでは大量のJSONデータを処理するコードをやりました。
JSONの取扱はPoisonというライブラリを使うらしいのでmix.exsに

  defp deps do
    [
      {:poison, "~> 4.0"},
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end

と記述します。
依存関係をダウンロードするために
test_app $mix deps.get
としてlib/test_app.exのdefmodule test_appの中に

def main do
  json_text = File.stream!("d.json")
  json_data = Enum.map(data, fn d -> Poison.decode!(d) end)
  result = Enum.filter(json_data, fn d -> d["age"] <= 20 end)
  Enum.count(result)
end

と書きtest_app/d.jsonを

{"age":39,"name":"aaa"}
{"age":47,"name":"bbb"}
{"age":46,"name":"ccc"}
{"age":13,"name":"ddd"}
{"age":45,"name":"eee"}
{"age":18,"name":"fff"}
{"age":22,"name":"ggg"}
{"age":15,"name":"hhh"}
{"age":24,"name":"iii"}
...

と置きます。
その後、ターミナルにて
test_app $ iex -S mix
iex(1)>test_app.main
と打つと、20歳以下の人数が出てきます。

さて、Elixirにはパイプ演算子というのがあるらしく、前の関数の返数を第一引数として渡したい時に使えるらしいです。上のコードは以下のように書き直せます。

def main do
  "d.json"
  |> File.stream!
  |> Enum.map(fn d -> Poison.decode!(d) end)
  |> Enum.filter(fn d -> d["age"] <= 20 end)
  |> Enum.count
end

まあ、このように色々教えてもらってEnumじゃなくてStreamやFlow使うと良いよなど教えてもらいました。

感想

Elixir本を読んだときは、「他言語とは違うぞ〜」ということが非常に多く書かれてましたが、ドリコム社さんのおかげでスムーズに理解できました。もちろんElixirの一角だと思いますが、少しずつやっていこうと思います。
ただ、関数っぽい部分とそうでない部分とが妙に突っ掛かると言うか…まあ慣れかな…

あと今回の件で、map=>filterを行いましたが、filter一個でも行けるんじゃないかなと思って少し疑問…具体的には

  def is_adult (json_text) do
    data = Poison.decode!(json_text)
    data["age"] <= 20
  end

  def main do
    "data.json"
    |> File.stream!
    |> Enum.filter(fn d -> is_adult(d) end)
    |> Enum.count
  end

て書いても動くのでどうかな〜と、よく分かってない。
まあ、これからボチボチやっていきます。

OS自作のネタ集

この文章はセキュリティキャンプ2019 Y-I OS開発ゼミ用に書かれたものです。
セキュリティキャンプが終了次第公開する予定です。主にOS自作のネタを提供するのが目的な文章ですので、参加者の皆様が強い目標をお持ちなら、ぜひそれを実現させてください。(全員そうだったらこの文章は無駄になるわけですが…それはそれで)
そうでなくとも、セキュリティキャンプに応募する際に何らかの目標を持って応募はされているとは思いますが、+αという感じや、より目標が具体的になるように役立ててもらえると幸いです。

RustでOS自作

これは自分がセキュリティキャンプ2017に参加したときの目標です。

Rustは安全性、速度、並行性の3つのゴールにフォーカスしたシステムプログラミング言語です。 ガーベジコレクタなしにこれらのゴールを実現していて、他の言語への埋め込み、要求された空間や時間内での動作、 デバイスドライバやオペレーティングシステムのような低レベルなコードなど他の言語が苦手とする多数のユースケースを得意とします。

https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/

とあるように、Rustは低レイヤを得意とする言語で安全性に重きを置いています。おかげで最初は「エェ…そんくらい許してくれや…」というエラーがガツガツ出ます。しかしながら、これらを丁寧に潰していけばほぼ100%期待通りに動いてくれます。セキュリティキャンプ2017では割り込みのバグを潰すのに時間がかかったわけですが(参照:セキュリティキャンプ2017参加記)、Rustが原因であることは少なかったです。
RustでのOS自作で参考になりそうなサイトは以下の通りです。

NimでOS自作

Nim (旧称Nimrod) とは命令型、マルチパラダイム、コンパイル言語という特徴を持つプログラミング言語であり、アンドレアス・ランプフにより設計・開発された。Nimは「効率的で表現豊かで優雅」であるように設計されている。

https://ja.wikipedia.org/wiki/Nim

NimはRustより少し早めに出てきた言語で、Python風に優美にコードがかける…らしいです。よく言語比較サイトでRustと喧嘩してます。
NimはCのコードを吐けるのでこれを利用してOSを自作することも可能のようです。ただRustに対してネットでの情報が少なく難航するかもしれません。でも折角のセキュリティキャンプなので挑戦してみるのも良いかと思います。(自分も気になります。)
NimでのOS自作で参考になりそうなサイトは以下の通りです。

ZigでOS自作

Zig is a general-purpose programming language designed for robustnessoptimality, and maintainability.

https://ziglang.org/

かなり新しい言語のようですが、低レイヤも扱えるようです。が、日本語の情報がほとんどありません。どうしたもんでしょう…Nim同様挑戦してみるのも良いかと思います。

はりぼてOSを64bit対応してセキュアにしてみる

言わずとしれた30日OS自作本のはりぼてOSですが、今や時代遅れのOSと言われるようになりました…悲しい。
昨今のOSは64bit対応でページングを採用していますので、32bitOSでセグメンテーションなはりぼてOSとは大違いです。
しかしながらはりぼてOSはGUIもしっかりしてますし初心者向けにわかりやすくできているので、これを参考にしてUEFIブートなどに対応するのも良いかなと思います。
また30日OS自作本では、LDTなどを使ってメモリ保護などを行っていますが、全然セキュアではないのです。例えば

void HariMain(void){
    api_boxfilwin(0, 8, 36, 141, 43, 3);
    api_putstrwin(10000, 28, 28, 0, 12, "hello, world");
    api_end();
}

というアプリでも作ろうもんならたちまちOSがぶっ壊れてしまいます。第一引数のwinをOS側で検証してませんから、適当な値を打ち込めばすぐやられます。これらを改善するにはどうしたらいいか考えるのもセキュリティらしいネタかもしれません。

別アーキテクチャでのOS自作

(もしx86環境という条件付きのキャンプでしたら以下のネタは利用できません)
世の中にはx86-64なCPUだけではなく、様々なISAがあります。
身近なものでは、スマートフォンでよく採用されているARMアーキテクチャや話題沸騰中のRISC-Vなど様々なものがあります。
QEMUでも実装されているCPUも多くありますので、実機では動かせなくともエミュレータで動くOSも作れます。
他のISAと比較することでx86-64がどのような性質を持って、セキュリティ的にどうかがわかるかもしれません。(自分はRISC-Vをいじって少しわかった…気がする…多分)
https://github.com/PG-MANA/RuscV RustでRISC-Vベアメタルをやったときのコードですが役に立つかもしれません。

終わりに

少ない量でしたが、何か役に立てたなら幸いです。これをみて全く別のことを思いついてもらっても構いません。
OS自作の分野は日本語の情報が(他に比べて)少ないですが、テーマは色々あると思うので、有意義なテーマを見つけて、頑張ってみてください。