お腹.ヘッタ。

関数型とかセキュリティとか勉強したい。進捗つらぽよ

進学って大変ですねっていうポエム

進学って大変ですね

 こんにちは。しくじり先生(?)です。進学なんか決まったぽいんで悔しさと浅はかさを込めて自戒のための記事を書きます。ぜひ笑ってください。
(単純に希望大学全部落として、第四希望ぐらいのAOでスルッと地元の私大の新設の情報学科に入ってしまったというオチ)

 あとこれから技術だけで受けようとする人に対してちゃんと考えて欲しいという気持ちで書きます。ぜひ受験生の人は考えてください。

お前ってどこ受けたの?

coinsと農工大電通(夜間)と地元の私大です。

お前ってなんで大学行きたかったの?

高校進学時は大学でも終着駅は就職なら就職でいいだろと思っていました。
ですが元カノに大学行こうぜって誘われ、そのうち自分自身が情報を学び進めて行くうちに、様々なことに興味が出てきて、関数型言語に興味があり、特に型理論(リファーメント型でのコンパイル時の安全性など。。。)を学びたくなったから。

お前にそれだけの頭あったの?

頭ありませんでした。地元の工業高校(偏差値は50前後だと思う)に在学で評定は安定して3.5でした。

お前技術力はあるの??

微妙なところです。高校プロコン優勝でITジュニア賞もらったり、サイバー甲子園で入賞して、2015のSECCON決勝大会に出場したり、iCANという国際大会の予選に出て奨励賞とか、地元のソフトウェアコンテストで一位になってみたり、機械学習が好きで遊んだり、関数型好きで勉強したり人並み以上だとは思ってました。

実際の受験フロー(しくじり部分ともいう)

 僕は三年時にパソコン部(名前は違いますが)で部長をやっていて10月の文化祭が引退でした。ですの本当は受験勉強で忙しい3年の夏も大会のために強制的に平均睡眠時間3時間ぐらいでマイコンをいじりプログラムを書いていました。そこで私は一般を早々に諦めて技術力だけでの勝負に切り替えました(つまり推薦やAOに切り替えた)
しかしそれでも大学に出願するには大変時間がありませんでした。(どれくらい時間がなかったかというと大学に間に合うのにのせなきゃいけない郵便配達の集荷の締め切り1時間前までやってたり、台風なのに高校まで行って調査書を取りに行くなど。。。。)



 さて微妙な出来の書類をまずはcoinsへ出しました。このとき、色んな人や先生、フォロワーさんに見てもらったりして大丈夫でしょと言われ自信満々でした。
 しかし落ちました。辛い。今思うに評定なのかなとか思います。
 さて農工にも出しました。実際に受かった人に見てもらっておそらく一次は確実に通るって言われたりしてたので、この時も自信満々でしたが。落ちました。
 



 さぁ困りました。次どうしよう。。。迷走します。センターとりあえず払いこむとか他の推薦やAOを探すとか色々手当たり次第探していました。



 迷走を経て次の進路を決めました。電通大の夜間を受けることにしました。
 理由は単純でお金の面を心配せず行え、やりたい研究室もあり、かつMMAに入れるから。
さてそれに向けて頑張りました。ちなみに夜間と言いながらも入試問題は一般の電通大の推薦入試と同一の問題です。ですので私の高校では開講していない基礎なしの物理や化学、数学Bなどを自力でやりました(必死)

 しかし、努力叶わず爆死しました。それは今年の問題がレベルが過去三年分と比べてえらく上がっていたということ。例えば電磁気が今までは電気回路だったのがいきなりコンデンサの静電容量がどれくらい貯めれるとかクーロンの法則が出たりなど、また僕がそれに対して絶対これだろというふうにある程度ヤマを張っていたこと。ちなみにヤマは全て外した記憶があります。本当にしくじりました。まさか融合問題が出るとは。。。。(頭抱え)


 その後とりあえず浪人はみんなに止められたので、やめようという方針を立て始めた失意の中、顧問の先生の助けを借り、第四希望の大学に出願したのがポーンと受かりました。(おそらくそれは面接に出した賞状で殴った感じだと思う。)
まぁそんなもんだろうみたいな感じ。

まとめと反省と僕みたいに失敗して欲しくないためのポエム

 受験をなめてた。正直夏休み明けの時点で高校選択間違えたなと、さえ思った。
中学の時にもう少し頑張って高専狙うとかできれば。。。とか評定がもう少し高ければ。。。とか就職であれば楽だったのに誘われてたとこに行けば。。。とか自分より実績がない部活の同級生が公立に受かるのを見て公立なら受かったのかな。。。とかIFばかり考えてしまう。本当に後悔後先立たずとはこのことなんだろうなと思う。
 

 だけどもこの経験は後悔してはいない。自分自身の足りないところや至らないところ。言葉ばかりでとり作ってきたところ。本当に色んなところに気がついた。精進が足りませんでした。過程があれば評価されると思っていた。本当に甘かった。


もしこの記事を読んでくれた中高生(特に工業高校の人)がいるならしくじった人並みのアドバイスをします。

高校生へ。
 一度将来をしっかりと考えましょう。このためになら1~2日潰しても構いません。ネットサーフィンしまくるなり、本屋さんに行くなりして何やりたいのか考えましょう。いつでも遅くありません。できるなら一年生の時からです。
 そしてもし就職なら評定を一生懸命上げましょう。
 進学ならば、1年生は今すぐ河合塾に行くなりスタディサプリ(科目の足りない学校にいるならなおさら。)を取るなりしましょう。最低限進学就職どっちに転んでもできるように知識をつけましょう。一年生なら評定もあげやすいですし一年生の科目だけを課す試験が就職にも進学にも多いです。
2年ならまずは模試を受けるべきだと思います。自分の実力によっては最悪頑張っても難しい場合があります。全統模試など全国クラスのにしましょう。自分が低く出た方が危機感が湧きます。
3年次の人で早い段階の入試を受ける場合で部活が忙しいなら部活をやめましょう。それくらい覚悟が必要だと思います。

中学生へ。
 もし工業高校に行きたいとか思う人がいたとしてもやめておくべきだと思う。少なくても大学に行くのがお金的に無理とか家を継ぐとかない限り。もしくはそこの高校でしかできないとかない限り。初め進学なんてしねぇよと思っても、専門分野を深く学ぶうちにやっぱ大学進学したいと思うようになると思います。特に大学数学などが必要だったり化学が好きだったりとかだと特にその可能性が高くなります。(正直工業高校の化学は実用よりで大学の範囲までは言わないので)
それでも専門分野を学びたいと思うならば高専か理数科を目指すべきです。高専であれば3年次編入があり、それは高専生向けである場合多く、進学時学んでないなどでのカリキュラムで困ることが少ないと思います。理数科であれば特に物理系の部活や化学系の部活などで工業高校でやれる部分と同じ理論基礎に対して取り組めます。また、もしそのような取り組みをした場合、理数科目でのバフになり得ることが多く点数が取りやすくなり、さらにはその学校が科学オリンピックなどに力を入れてる場合が多いです。

高いレベルの高校に行く意味はあります。先生の質も変わります。是非頑張ってください。


これらは人によってはそんなことないみたいな顔するかもですけど少なくても僕がすればよかったなと感じたことなので書きました。


 僕はこれから大学生活をするわけなんですが足りない科目を自力で埋めなきゃいけません。辛いです。ですが一つやろうとしていることで大学での編入を目指そうと思っています。そのためには一度高専に行くとかしなきゃいけないんですけど。。。自分のやりたいことをするために賭けてみたいと考えています。


以上ポエムでした。

何かあれば@takemioIOにメンションをください

Arukas-CLIをbrewで入れる

 こんにちは今回はクジラさんではなくイルカシャチさんに(イルカに見えたんだもん)簡単にお世話になろうという話です。

 仮想化技術、皆さんは使っていますか?VMとかVagrant とかdocker使っていますか?使ってますね。僕もお世話になっています。



・・・ではもう一つ知っていますか?「Arukas
arukas.io

なんと純国産の仮想化コンテナ技術を提供するサービスである。ちなみに今ならベータ版という理由で使い放題無料なので今のうち使いましょう!

本題:Arukas-CLIbrewで入れる

 さてそんなArukasをじゃんじゃん使おうぜということでArukas-CLIを簡単にbrewで入れようという記事です><
 ちなみにですが今は公式だと手動(バイナリDL)大変なのです><
github.com
qiita.com
上のqiitaには入れ方があります。



brewとは。
Homebrew — OS X 用パッケージマネージャー

 正式名称はHomebrew。詰まる所Macintosh用のパッケージマネージャーです。これを入れると簡単に様々なライブラリ、フレームワークやソフトウェアを入れて便利って感じのものです。これは入れてあるものとして進めます。(入れてない方はbrewインストールとかで調べて戻ってきてくださいね><)


インストール(brewで)をする。

 

Go言語でつくったツールをHomebrewで配布する · THINKING MEGANE


などを参照するとわかるのですがHomebrewに独自リポジトリを実は入れることができます。


上のブログのことをやると brew tap [リポジトリ] , brew install arukasが可能になります。


ただ面倒なので私は直で作ったFormulaファイルを/usr/local/Library/Formulaに投げてbrew install arukasを行いました。



では実際に入れていきましょう。




まずは投げる前に
github.com
からarukas.rbを拾ってきましょう。



拾ってきたら/usr/local/Library/Formulaを参照してarukas.rbを突っ込みます。



そしたらbrew install arukasをしましょう。終わり(早い!!)
これを手動で入れるとめんどくさいのにこんなに簡単ヾ(・ω・*)ノ ワーイ


CLIを入れれた人へ

arukas.io

(力尽きたので上見てやってください(時間があればエントリ書きます)><)

ステッピングモータSTP-42D108の覚え書き

 この前STP-42D108というステッピングモータをちょっとした理由で手に入れた。しかし残念ながらネットを探してもデータシートがなく大変な目にあった。特にとりあえずこれで回るよって言われた経緯で手に入れたものであったので、心置きなく使ったところモータドライバが壊れる壊れる。合計5個ぐらい使った。。。。><。 しびれを切らしてこの販売元のシナノケンシ社に連絡を投げてみました。返答は「外注で作ったものなので教えません(意訳)」どうしても使いたいので交渉をしてトルク特性等以外を聞くことは成功しました。
 以下に記述する。 

STP-42D108のデータ

 STP-42D108: シナノケンシ
 ステップ角 : 1.8 deg / full step
相 数   : 4
 定格電圧  : 2.4 V D.C.
定格電流  : 1.2 A / 相
 サイズ   : 42×42×31(mm)
 口出し線の色: 白→Acom,黒→Bcom,橙→A,赤→B,青→ba-A,黄→ba-B,

こんな感じです。
 

  • とりあえず電流が高いのでモータドライバをFETで自作しないで使う場合はmaxアンペアに注意してください。
  • 2相励磁だと2.4Aとかいうひどいものなので気を付けましょう。
  • また使う際はクラット抵抗やセメント抵抗で端子間に入れるとか外部抵抗に入れるをすると良かった。

セキュリティ・キャンプ全国大会2016の応募用紙を晒す(後編)

自信がないなぁ。。。。後編は選択問題についてです。選択問題は4つ 選択でした。多分間違っていますしボロボロです。。。がそれよりも多くやってしまってたので提出してない分も晒す。(提出したのは4,5,6,11)
以下本文〜〜まんま載せます。

【選択問題】

選択問題.1: 以下は変数hogeとfugaのメモリアドレスを表示するプログラムと、その実行結果です。実行結果のhogeとfugaのメモリアドレスを見て、思うことを説明してください。
・ソースコード
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char **argv){
 int hoge[10];
 int *fuga;
 
 fuga = malloc(1);
 
 printf("hoge address = %p\n", hoge);
 printf("fuga address = %p\n", fuga);
 
 free(fuga);
 return 0;
}
 
・実行結果
hoge address = 0x7fff539799f0
fuga address = 0x7fca11404c70 

スタックに積まれたhogeは上位のアドレスに積まれて、fugaはヒープ領域の下位アドレスに積まれています。
先頭の0x7fというのは7ビットの部分を表しているのかと考えています。以前にGCCXcodeでヒープ領域がどこに割り振られるのか見たことがあるのですがその際、先頭アドレスが前者は0x7fで後者が0x10であったので処理系によって変わっているのではないかと感じました。

選択問題.3 :RAMは主記憶装置、HDDやSSDなどは補助記憶装置と呼ばれます。一般にCPUは主記憶装置上のプログラムしか実行できません。ではなぜ、私たちは普段から補助記憶装置に書き込んだプログラムを実行できているのでしょうか?パソコンの電源を入れてからのストーリーを考えてみてください。

電源を入れハードウェアの初期設定が行われ、ブートストラップローダを動かしてBIOSが起動する。(ブートストラップローダはROMに用意されてる可能性もある)Power On Self Testが行われ、CPU、RAM、割り込みやHDD、GPUハードウェアの初期化が行われる。次にBIOSは起動デバイスに設定された記憶装置を探し、。ブートローダが起動する。ブートローダには段階がありプログラムからプログラムを呼び出し、初めてOSを呼び出すことができる。一次ブートローダ、二次ブートローダと細分化できる。この場合は二次ブートローダーでありBIOSは1次ブートローダーである。上でもあるが補助記憶装置に書き込んだプログラムを実行するにはRAM上にROMのデータを展開して起動する。その際できるだけ高速で使うためにキャッシュメモリと呼ばれる使用頻度の多い命令データを保存したりして処理装置と記憶装置を本来の速度を隠蔽したりする。また補助記憶装置をメモリのように振舞わせる仮想メモリはあくまでスワップであり稼働してないものを充てがうのが普通だと考えている。

選択問題.4

突然だが、RH Protocolで用いられるRHパケットのフォーマットを以下に示す。なおRH Protocolは実在しないプロトコルであり、その内容について特に意味は無い。
Format of RH Packet

———————— —————...— ———————…— ———————...— ———————...—
 Magic (2byte)      Source(20byte) Destination(20byte) Data Length(4byte) Data( variable )      
———————— —————...— ———————…— ———————...— ———————...—

 
char Magic [2];
char Source[20]; /* null(‘\0’) terminated ascii strings */
char Destination[20]; /* null(‘\0’) terminated ascii strings*/
uint32_t DataLength; /* min 0, max 4,294,967,295 */
char Data[DataLength]; /* null(‘\0’) terminated ascii strings */
 
バイトオーダーはbig endian(network byte order)とする。
添付するバイナリは、とあるRHストリームのうち片方向のみを抽出したものである。このバイナリストリームを読み込み、1つのRHパケットが以下の条件のすべてにマッチするときに標準出力に文字列”PASS”、 それ以外の場合は”REJECTED”と表示するCもしくはC++のプログラムを記述し、実行結果と共に提出せよ。また、マッチングにかかるCPUサイクル及びメモリ使用量を計測し記載した場合、評価に加味する。
 
Condition(条件)1: Magicがchar[0] = ‘R’、 char[1] = ‘H’であること。
Condition 2: Sourceが”rise-san”または”cocoa-san”であること。なお、”RiSe”や”Cocoa”など、小文字大文字が混ざっていても、マッチさせること。
Condition 3: Destinationが”Chino-chan”または”Chino"であること。なお、cond. 2と同じく、小文字大文字が混ざっていても、マッチさせること。
Condition 4: Sourceが”cocoa-san”かつDestinationが”Chino”の場合はREJECTする。
Condition 5:  Dataに下記の文字列を厳密に含むこと。
char** valid_order_brand =
{
    “BlueMountain"
    “Columbia”,
    “OriginalBlend"
};
Condition 6: Dataに下記の文字列を厳密に含まないこと。なお、cond. 4よりも、cond. 5が優先される。
char** invalid_order_brand =
{
    “DandySoda"
    “FrozenEvergreen”
};

以下送ったやつ

・実行結果 
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
PASS
PASS
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
REJECTED
PASS
REJECTED
REJECTED
ソースコード

////
////  main.cpp
////
////  Created by 〜〜〜on 2016/05/06.
////  Copyright © 2016年 〜〜〜. All rights reserved.
////
//

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cstring>
#include <sys/time.h>
#include <sys/resource.h>
using namespace std;

int Mstricmp (const char *s1, const char *s2)
{
    int cmp;
    
    while (*s1)
    {
        //toupper:大文字小文字に変えれる関数
        if ((cmp = toupper (*s1) - toupper (*s2)) != 0){
            return cmp;
        }
        s1++;
        s2++;
    }
    return (*s2) ? -1 : 0;
}
int main(){
    char outfile[] = "/Users/HayasakaTakeru/Desktop/RH_secamp/pyonpyon.rh";  //読み込むファイルの指定
    char Magic [2];
    char Source[20]; /* null(‘\0’) terminated ascii strings */
    char Destination[20]; /* null(‘\0’) terminated ascii strings*/
    uint32_t DataLength; /* min 0, max 4,294,967,295 */
    char Data[256] ; /* null(‘\0’) terminated ascii strings */
    string buf;

    ifstream fin( outfile, ios::in | ios::binary );
    //  ファイルを開く
    //  ios::in は読み込み専用  ios::binary はバイナリ形式
    
 //  ファイルが開けなかったときの対策
    if (!fin){
        cout << "ファイル:pyonpyon.rh が開けません";
        return 1;
    }
    
    //文字列ではないデータ
    
    while(!fin.eof()){  //ファイルの最後まで続ける
        //データを読みこむ
        fin.read( ( char * ) &Magic, sizeof( Magic ) );
        fin.read( ( char * ) &Source, sizeof( Source ) );
        fin.read( ( char * ) &Destination, sizeof( Destination ) );
        fin.read( ( char * ) &DataLength, sizeof( uint32_t ) );
        size_t DataLengther = htonl(DataLength);//ホストバイトオーダーからネットワークバイトオーダーに変換
        
        int i=0;
        do{
            fin.read( ( char * ) &Data,  DataLengther);
            buf+=Data;//一時保存
        }while (256<DataLengther-(256*i++));
        
        
       //paternmach
        //Condition1
        if (Magic[0]!='R'&&Magic[1]!='H') {
            goto False;
            
        }else if((0!=Mstricmp("RISE-SAN",Source))&&0!=Mstricmp("COCOA-SAN",Source)){//Condition2
            goto False;
            
        }else if((0!=Mstricmp("CHINO-CHAN",Destination))&&(0!=Mstricmp("CHINO",Destination))){//Condition 3
            goto False;
            
        }else if ((0==Mstricmp("Chino",Destination))&&(0==Mstricmp("cocoa-san",Source))){//Condition 4
            goto False;
            
        }else if (string::npos != buf.find("DandySoda")||string::npos != buf.find("FrozenEvergreen")){//Condition 6
            goto False;
            
        }else if (string::npos == buf.find("BlueMountain")||string::npos == buf.find("Columbia")||string::npos == buf.find("OriginalBlend")){//Condition 5
            goto False;
            
        }else{
            printf("PASS\n");
            buf="";
            continue;
            }
       
       
    False:printf("REJECTED\n");
        buf="";
    }
    
    fin.close();  //ファイルを閉じる
    return 0;
}

・メモリ/CPUサイクル使用量計測
環境:MacBook Pro Retina2014(Core i5-4308U &RAM 8G)、GCCコンパイルしたもので行った。
#include をincludeし、 getrusage関数による最大消費メモリ量のチェックを行った。
Max RSS : 684.000000 MB

rdtsc命令を使用して計測を行った。
CPUCycle(10回計測):
1443299938,
1133714246,
766179364,
3249800630,
2473480668,
3753169854,
4201688936,
1112906710,
3299073340,
420707638

10回の平均値:2185402132.4

最後に計測に使用したソースコードを添付します。

// 最大消費メモリ量のチェック
    int chk;
    struct rusage usage;
    chk = getrusage(RUSAGE_SELF, &usage);
    if(chk != 0){
        printf("error\n");
        exit(-1);
    }
    printf("Max RSS = %lf MB\n", usage.ru_maxrss / 1024.0);    // このプロセスが消費した最大メモリ領域

  //CPUサイクル取得
static inline uint64_t get_cycles()
{
    uint64_t t;
    __asm volatile ("rdtsc" : "=A"(t));
    return t;
}
  cout<<get_cycles()<<endl;

てかstricmpはXcodeにないのな。。。いじめだ急遽作ったわ。。。

選択問題.5 :PCなどに搭載されているOSは「汎用OS」と呼ばれますが、それに対して、家電やAV機器などの「組込みシステム」に搭載されているOSは「組込みOS」と呼ばれます。組込みOSと汎用OSの違い、「OSが無い」や「ベアメタル」という環境、そもそもOSとは何なのか?など、あなた自身はどう考えているのかを、あなた自身の言葉で自由に説明してください。(「正しい答え」を聞いているわけではありません。あなた自身の考えを教えてください)

組み込みOSは必要がない機能を削除する事が容易で、それ故にいらないものを削ることにより小さい構成にしてリソースを確保してるもの、汎用OSは使われそうな機能はすべて盛り込んでおいているものでアップデートで汎用性をもたせているものと思います。
 そもそもOSというものは今までそれぞれ独自の仕様を持っていたハードウェアとのインターフェースとなりアプリケーションやソフトウェアを作るのに一定の指針を持たせたものであり、逆に言えば今日の多様なプログラムが使われているのはOSがあるからと言えると考えています。またアプリケーションとハードウェアのインターフェースだけではなくユーザーとのインターフェースでもあると言えて操作方法が統一されるので、1つの操作方法やシステムコールを覚えれば他の場所でもそのノウハウをそのまま生かすことができます。他にもデスクトップリビューションを組み込むことによりそのOSのブランド性というものも演出できると考えれます。このようにOSというのはアプリケーションとハードウェアだけではなく多くに対するインターフェースと私は捉えています。
 しかし逆にOSがないとどうなるのでしょうか、一般的にベアメタル実行やベアメタルコードなどと呼ばれるのですが具体的には直接ハードウェアを叩いていることを指しています。OSやフレームワークがなくて何が嬉しいかというと自分の手で高速化をすることとだと言えます。普通はメモリを意識しないようなライブラリやフレームワークAPIを使わせてそれを使えばどこでも簡単に駆動を可能に設計しています。しかし高速なIOをしたい時やコンパイルされたプログラムの容量を削りたい時などはレジスタを意識して必要最低限のコードに自力で最適化することにより高速に出来ます。実際Arduinoを高速で使いたくてIOをライブラリではなくポートをいじってあつかった際は数倍速度の向上がありました。このようにレジスタを意識するということだけでもチューニングが出来るようになります。
 違うOSに観点を移すと、例えば組み込みOSは「実時間制約を保証のOS」という言い方も可能であり、RTLinux やART-Linuxが有名です。実際にロボットなどを制御する場合,通常は一定の時間間隔でセンサ信号を読み取り,制御演算を行い,アクチュエータに指令を出します。外部との情報の入出力の可否は,ソフトウェア上では一般にI/Oポートの操作 とメモリの読み書きの可否 でありそのタイミングの周期的な制御動作を達成すれば実際に動かすことも可能だとも言えると思います。組み込みOSでなくても普通のLinuxカーネルで時刻を指定して行いたい処理の直前で、タイマ割り込みの直後などで目的の実行時刻と現時刻の差を指定し、休眠システムコールを行うなどプロセスの優先度を高めておくなどで周期動作は得ることができると考えています。あえて問題を挙げるとすればART-Linuxなど、ある特定のハードウェアでは対応してないなどということがあるのでもっとマルチに作成することが望まれると考えています。
 自分自身のまとめとするとOSは現在のエンドユーザーの手にソフトウェアを私たちエンジニアが届けるのに必要不可欠のもだと思います。しかしそれは今の潤沢なマシーン環境と高レイヤーな考えがあるからであり環境が変わればそれを維持するためにどれだけ高速にチューニングするかというのが勝負に踏んでいます。また今ある資源をうまく使うのもOSの仕事でありリソースの管理を行い、必要に応じてはポーリング、スレッド、メモリの処理もするものだと思っています。例えばスレッドであれば、windowsのThreadやiOSのGCDなどが挙げられ、実際これらの処理は簡単でGCDであればキューに投げ込むだけでそれをOS側が入れられたものの優先度とFIFOで実行していくという形で成り立っています。しかし並列であるならばデッドロックが起きる可能性もありえます。チューニングしていく上で仕方がないことではありますがOSだけではエンドユーザに良いソフトウェアを届けることはできないと言えるところだと思います。つまるところの結論というものはまだ未熟な私には出せませんが一番感じていることはOSはという考え方があったからこそ潤沢なアプリケーションがあり我々はハードウェアに苦悩しないのだと感じています。

選択問題.6 :IDとパスワードを入力してユーザの認証を行うWebアプリがあります。あなたがこのアプリに対してセキュリティテストを行う場合、まず、どのようなテストをしますか? なぜそのテストを選択したのか、その背景や技術的根拠と共に記載してください。アプリの内部で使われている技術やシステム構成に、前提を置いても構いません

今回使われているのはバックにDBがありNoSQLとSQL系の2パターンと想定して、その際使われているのはApacheサーバ(PHP、Laravelやcakephpといったフレームワーク)や他のサーバフレームワーク(node.jsなど)という想定でテストを考えた。

まず使用しているものバージョンを確認し、node.jsであればnpmのパッケージに脆弱性があったりなどosinjectionの危険を回避したいのでバージョンが古い際は最新版にできるだけ変更します。
次にWiresharktcpdumpなどを開いてパケットを見ながらレスポンスを確認を行います。その際PHPのバージョンの隠蔽などを確認し、Cookieにhttponlyの属性を付けるなどもしておくべきと考えます。(その際ヘッダ周りを見るべきでX-Content-Type-Optionsなどが叩かれる恐れがありえます)。またワンタイムトークンなどを導入するなどでCSRF などの対策をすべきで、他にもXSSの対策について確認を行い、バインドして『”’<>&』などを文字実体参照・数値文字参照に置き換え、弾くようにします。
その次にDBに対してチェックを行い、NoSQL系であれば演算子インジェクションやSSJI(Server Side JavaScript Injection)、JSONを使ったinjectionなどで攻撃が可能なので、対策としてはSSJIであればバインド機構を入れたり動的なJSを避けたり、演算子インジェクションであれば型にキャストするなどで対策ができ、ホワイトリストを入れたりしてパラメータをを追加されるのを阻止するのも有効だと考えれます。
SQL系であればSQLinjectionがあるのでバインド機構を入れてサニタリーングをしたりホワイトリストを入れるのも有効だと言えると思います。
他にもSQLmapなどを使って脆弱性の確認などをするのも有効だと言えます。
次にサーバの権限の制限を確認し、トラバーサルができないようにしておくなど、またidなどをパラメータに入れて投げるときはすでに許可してるものをキーとしている時などに気をつけるべきだと思います。それを含むとトラバーサルできてしまうので、気を付けたいところと考えれます。

選択問題.11 :2015 年に発行された CVE の内、あなたが興味を持った”サーバに存在した”脆弱性について1つ提示してください。その脆弱性を悪用した攻撃を検知する方法について詳細に記述してください。また、興味を持った理由を記述してください。 CVE番号:CVE-2015-◯◯◯◯

CVE-2015-1793について
攻撃を検知する方法:
 この脆弱性はOpenSSLの証明書チェーンのチェック機構に不備があったというものです。この脆弱性を利用した際に想定されるのはman-in-the-middle attackが想定されます。証明書の検証において初めの証明書チェーンの構築に失敗した場合、代替の証明書チェーンの構築を試みますが、この処理の実装に不備がありました。その結果、例えば CA フラグが FALSE とされている証明書を使って発行された証明書を、不正なものであると検知せず、バイパスして信頼している CA によって発行された証明書として扱ってしまう可能性があります。
 具体的に効率的な対策を思いつかなかったのですが、今回考えられるのは中間者攻撃なので直接サーバーにつなぐのではなくサーバを経由して別サーバでのチェックとサーバーでのIPのチェックをするという手を取るのが良いかと考えました。
 具体的にはAが接続者、Bがサーバ、Cが別サーバとした際に攻撃者がAB間、AC間のどこかに接続をしなくてはなりません。流れとしては、まずAC間およびBC間の確認を行います。
A->B: CのIPアドレス->B:認証、
B->A: CのIPアドレス->A:認証
これにより、Aの確認者とBの確認者のIPアドレスが一致しなければ、 AC間またはBC間に攻撃者がいることが判明します。
次にAB間の確認をします。
A->C:BのIPアドレス、C->B:AのIPアドレスをCに送る、B->C:AのIPアドレス、C:認証、C->A: 認証結果、C->B: 認証結果。
これにより攻撃者がいない通信経路が成り立っていることが確認できたなら通信が窃盗されるということはないと思います。
弱点としては攻撃者がAB間およびAC間に同時に割り込むことで迂回される恐れがあると考えます。その際はCを動的に変え続けるなどして接続を乱すことで対応できるかなと思っています。

せっかくなので脆弱性のコードを見てみました。”openssl-1.0.2c/crypto/x509/x509_vfy.c”が攻撃される原因のところです。

// CAが追加されるところのソースです。
        // continue to construct the chain of certificate(add issuer)
        for (;;) {
            // self-sign and exit
            if (cert_self_signed(x))
                break;
            // look for the issuer in the trust chain
            ok = ctx->get_issuer(&xtmp, ctx, x);
            // error
            if (ok < 0)
                return ok;
            //  not found
            if (ok == 0)
                 break;
            x = xtmp;
            // add the issuer for the untrusted certificate to the chain of verification
            if (!sk_X509_push(ctx->chain, x)) {
                X509_free(xtmp);
                X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                return 0;
            }
            num++;
        }
// CAのチェック機構です
        // verify the issuer chain in for (;;) 
        i = check_trust(ctx);
        if (i == X509_TRUST_REJECTED)
            goto end;
        retry = 0;
 // 代替チェーンを検証
        // verify the alternative chain
        if (i != X509_TRUST_TRUSTED
            && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
            && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
            while (j-- > 1) {
                xtmp2 = sk_X509_value(ctx->chain, j - 1);
                 // return when get a “reasonable-like” certificate,in fact look for the issuer based on CN domain
                ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
                if (ok < 0)
                    goto end;
                // alternative chain exists
                if (ok > 0) {
                    X509_free(xtmp);
 
                    // remove the part above the alternative chain
                    while (num > j) {
                        xtmp = sk_X509_pop(ctx->chain);
                        X509_free(xtmp);
                        num--;
                        // 信頼できない証明書を削除
                        // the problem is 
                        ctx->last_untrusted--;
                    }
                    retry = 1;
                    break;
                }
            }
        }
    } while (retry);

考察:今までのOpenSSLは代替チェーンの検証をサポートしていない古いバージョンであったのでバグらなかっけれどもある程度まともにサポートしたせいでバグが出てきたのかなと推測してます。

興味を持った理由:
 なぜこの脆弱性に興味を持ったかというと中間者攻撃は通常はSSLが正常に動いていれば不可能な攻撃なのですが、今回は肝心要のSSLに問題がありました。ですので実際ゼロデイとかで叩かれたら大変だと強く感じたのでこれを選択しました。
 この脆弱性が出た時他のOpenSSLの脆弱性もかなり多く一緒に公開されました。しかもほぼ緊急度が高めのばかりでそれで大変印象に残っていたからです。例えば2015-1792であればcrypto/cms/cms_smime.cのdo_free_upto関数には、signedDataメッセージの処理に脆弱性が存在し、攻撃者によって細工されたsignedDataメッセージを処理することでサービス運用妨害(無限ループ)状態にされる可能性がある。などかなり怖いものばかりです。しかしあまりその時は知識もなかったので詳しく見るということをしませんでした。(ベンダー情報しか見てなかった)ですので今回見てみました。(かなりガバガバこと&多分ソース読み違えたことしか書いてませんが。。。)

感想

楽しかった!!

自分自身こうやって知見を広げれるのはやはり大きな強みだなぁと感じた。でもかなりボロボロなことばかり書いてるのでもし受かったら気合って感じで通ったって感じですね。。。
あと機種依存文字今度は死なないように
機種依存チェッカー | さぶみっと!JAPAN

を置いておきますね。来年も同じパターンならこれ使って提出してください><

セキュリティ・キャンプ全国大会2016の応募用紙を晒す(前編)

今年が本当に最初で最後かもしれないけど誰かのためになったらいいなと思って晒します。そしてブログ一年記念(?)をブログを始めた動機に関わるものでやれてよかったです。
以下本文〜〜><

【共通問題】

共通問題.1

(1)あなたが今まで作ってきたものにはどのようなものがありますか? いくつでもいいので、ありったけ自慢してください。

コンテストや大会に応募したもの。
・高校生プログラミングコンテストでの競技クライアント。
・仙台弁翻訳&辞書ソフト。
・アーチェリーのリアルタイム対戦システムのiosのクライアント。
倒立振子の機構を用いた杖。
その他の作品
・冷蔵庫の中をメモして賞味期限を通知してくれるアプリ(iosapp)
・パケット可視化ツール(pythonとQtとOpenGLで記述)
以上のものなどを作成しました。

(2)それをどのように作りましたか?ソフトウェアの場合にはどんな言語で作ったのか、どんなライブラリを使ったのかなども教えてください。

高校生プログラミングコンテストでの競技クライアント
 C++で記述した。幅優先探索などのアルゴリズムを使い最短距離を求めて移動する動作を組み込んだりその際効率化を求めて、巡回セールスマン問題と呼ばれるn以上の点における合計の最短路問題をを解いたりしました。

仙台弁翻訳&辞書ソフト
 C#で記述した、Linqなどのライブラリを使い文字列のマッチングなどをしました。

アーチェリーのリアルタイム対戦システムのiosのクライアント
 Swiftで記述した。socket.ioやcoreprotなどのライブラリを使いました。

倒立振子の機構を用いた杖(球の上に倒立するロボット)
 ハードウェアはarduinoやesp-wroom、加速度、ジャイロセンサー等を用いて作成しました。コードはC++で記述しました。倒立振子の制御はPD制御と呼ばれる古典制御で行い、角度を求めるためにはカルマンフィルタを使用しました。また杖には温湿度センサと大気圧センサを組み込み、体感温度や天気予報の機能を作成しました。
 その杖を制御するに当たっては、iOSアプリと連携した。通信はesp-wroomと呼ばれるwifiモジュールで行い、プロトコルはwebsocketで接続をしました。また杖を音声コマンドで動作をするためにOpenEarを用いて音声で動作させました。

冷蔵庫の中をメモして賞味期限を通知してくれるアプリ
 swiftとsqlite3を使って作りました。

パケット可視化ツール
 pythonでpypcapを動かしながらそこから拾いました。OpenGLレンダリングして表示しました。
 

(3)開発記のブログなどあれば、それも教えてください。コンテストなどに出品したことがあれば、それも教えてください。

ブログ:http://takeio.hatenablog.com/
出場大会および結果
高校生プログラミングコンテストでの競技クライアント→高校生プログラミングコンテスト:優勝
仙台弁翻訳&辞書ソフト→宮城県産業振興教育ソフトウェアコンテスト:最優秀賞
アーチェリーのリアルタイム対戦システム→U22プロコン(賞は頂けなかったが、高体連アーチェリー部から感謝状をいただき、インターハイでの活用が検討されている。)
倒立振子の機構を用いた杖→ナノマイクロアプリケーションコンテスト:奨励賞
サイバー甲子園→3位
SECCON intercollege 決勝大会(18チーム中17位)

共通問題.2

(1)あなたが経験した中で印象に残っている技術的な壁はなんでしょうか?(例えば、C言語プログラムを複数ファイルに分割する方法)

1:esp-wroomにiOSappでwebsocket通信をした際にsocket.ioを使って通信ができなかった。
2:iOSの画面レイアウトを作る際にオートレイアウトがとっつきにくくわかりにくかった。
3:iOSのナビゲーションコントローラのでの画面の順番を変えたかった。
4:倒立振子の機構を用いた杖を作る際にその倒立振子の機構は球乗りの機構を採用したかった。
5:高校生プログラミングコンテストで最短経路を求めるプログラムを実装するとき苦労した。
6:XSSとSQLiがよくわからなかった。(ブラインドSQLインジェクションとか表連結で叩くとか蓄積型XSSなど)
7:Q学習を学習する際用語や意味が理解できなかった。(マルコフ性など)

合計7つ挙げた

(2)また、その壁を乗り越えるために取った解決法を具体的に教えてください。(例えば、知人に勧められた「○○」という書籍を読んだ)

上に対応するやつ
1:リファレンス読んでもわからず自力で治そうとパケットキャプチャをしました。通信パケットを読むとただGETをしているだけだったので純粋にwebsocketだけのライブラリに変えました。また仕様書を読み、”Sec-Websocket-Version:13”ではなく古い”Sec-Websocket-Version:8”だったのでそこを変えて通信を行いました。

2:オートレイアウトは”SwiftではじめるUI設計&プログラミング「操作性」と「デザイン性」を兼ね備えたアプリの開発手法”という本を読み、ある程度オブジェクト間の間隔を作るときはViewを噛ませるなどをして対応しました。

3:質問サイトで質問してその答えをもとにナビゲーションコントローラの仕様書を読みこれのスタック構造を理解したのでそれを入れ替えるなどをして対応しました。

4:自分のやりたい球乗りのことをしている大学の先生の論文を読み、その際数学がわからなかったので線形代数解析学ラグランジュ方程式を学びながら論文を読み進めました。しかしそれでもわからなかったところがあり、例えばPD制御をなぜ採用したかなどその数式やゲインの同定試験がわかりませんでした。なので大学の先生にアポイントメントを取り、実際に実機を触らせてもらい同定試験のコツをお聞きしました。

5:手法として幅優先探索を実装して行いました。

6:XSSはXSSchallengeで理解しました。SQLiはハリネズミ本と呼ばれるCTFチャレンジブックスで理解し、深いところを知ったのはSQLmapというオープンソースのSQLinjectionの脆弱性診断のソースを読んで理解しました。また他の手法ということでwriteupを見ながら学んだ(SECCONの箱庭XSSや0CTFのwriteupなど)

7:機械学習の本を読み他にスライド等を読みセミマルコフ決定過程を理解し、ε-greedy手法とQ学習を用いエージェントを学習させました。

(3)その壁を今経験しているであろう初心者にアドバイスをするとしたら、あなたはどんなアドバイスをしますか?

1:やはり通信周りがあるのものは基本的にWiresharkなどでパケットを読むのは基本と考えます。また困ったときは仕様書を読むのも良いかと思っています。
 2:オートレイアウトは今のiOSアプリ作成には鬼門なので本を買い読むのが良いと考えます。また実際にQiitaがオートレイアウトの記事が多いので記事を読むのが良いと思います。
 3:質問サイトで聞くのも煮詰まった場合は有効だと思います。ただし自分でやりこみ今どんな過程を踏んで今どういう状態と言えるぐらいまでにやり込んでから聞く方が自分のためにもなり、自分の質問したいことが明確になると考えています。
 4:やはり自分でやり込んでこれでもかというほど煮詰まるまでやるべきだと思う。また論文等があればその先生にお願いをしてメールを出し、それでも理解できないのであれば研究室まで行かせてもらうのも手だと思います。自分の熱意があればお願いは伝わると思っています。私は嬉しいことにそれが伝わり、何度か研究室の見学をさせていただけました。実際に技術としては古典制御をしっかり学ぶべきだと思います。PIDこれらの要素はどんな動きをするのかを理解するべき、また制御の指令をトルクではなく加速度制御にするとかなりロバストな動きになりました。
 5:実際に紙に書くとわかりやすくできました。煮詰まった際や理解できないときは紙に書くが良いと思います。
 6:writeupを読んでみて実際に頭にイメージを作って問題を解いてみることや、またSQLiであればSQLmapのソースコードを読んでみるのが一番良いと思います。
 7:”強化学習”(http://www.amazon.co.jp/exec/obidos/ASIN/4627826613/kivantium-22/)という本がおすすめで、大変詳しく載っているのでしっかり読み込むのがおすすめです。またある程度理解できたと感じたら一度書いてみると良いと思います。また何度か試行を増やしたり割合を変えることで動作が変わるので作ったら何度も起動をしてε-greedyと呼ばれる確率手法の値を何度も確認するとどんなものなのか掴めると思います。

共通問題.3

(1)あなたが今年のセキュリティ・キャンプで受講したいと思っている講義は何ですか?(複数可)

そこで、どのようなことを学びたいですか?なぜそれを学びたいのですか?
私がセキュリティを学びたいと思った動機は、自分の普段使ってるウイルス対策ソフトの期限がが切れて仕方がなくフリーのものに変える際、親から勧められた”comodo”というものを使い始めました。しかしフリーのものということでその対策ソフトは大丈夫なのかと調べたところホワイトリスト制でのチェックを行っているという記述をネットで読みました、では他のウイルス対策ソフトはどんなことをしているのだろうという疑問から私はセキュリティについて興味を持ち学び始めました。そこから私は去年の夏頃の終わりごろからCTFを通じてセキュリティについて学んできた。
 勉強を進めていく中で”サイバー甲子園”というものに出場した際にもっと高度なこと、セキュアコーディング、ファジングなどをしたいとチューターの方に相談をしたところセキュリティキャンプを勧められたので今回応募しました。
 今回私がセキュキャンで受けたいと思っている講義はDAY2:TLS徹底演習、DAY3:Webアプリケーションの脆弱性の評価と発見、オンラインゲームアタック&ディフェンスチャレンジ、みんなでクールなROPガジェットを探そうぜ、DAY4:リバースエンジニアリングを自動化せよ、組込みリアルタイムOSとIoTシステム演習の講義を受けたいと思っています。
DAY2:TLS徹底演習:あまりSSL/TLSの通常証明書周りは触れることが少なく、あまり知識がないです。私は普段使っているものを是非知見を深めたいと思っています。また今回の暗号方式はChaChaというGoogleが推奨してるもので現在時点でTLS1.3のドラフトに出てるものを使うので最新の知識を揃えたいという意味でも是非実装してみたいです。
DAY3:Webアプリケーションの脆弱性の評価と発見:Webアプリケーションは基本的にXSSやSQLi、セッションの書き換えぐらいしか触ったことしかないので実際の脆弱性を探す時の着眼点や具体的な方法、考え方を生でプロの力に触れて力を是非養いたいと考えています。
 オンラインゲームアタック&ディフェンスチャレンジ:ここでは運営として体験してみたいと思っています。理由は例えば通信の際に間に何か噛ませてそこで通信した攻撃力データを変えるとかバイナリエディタでセーブデータ弄って00をFFなどにするなど攻撃側はあまり何も考えずとも案は出るが、運営側というのは方法が思いつかず、それらを知れると考えるとワクワクするので是非体験してみたいと考えています。
 みんなでクールなROPガジェットを探そうぜ:私はあまり命令を使った周りのことはGOTで使う簡単な知識ぐらいしかわからなく、アセンブラも各種の命令もあまり得意ではないです。だからこそみんなでクールなROPガジェットを探そうぜを受けてこの講義を受けて知見を深めたいと考えています。
DAY4:リバースエンジニアリングを自動化せよ:あまりデコンパイルは苦手でいまだによく分からない分野です。ですがそれを自動化というのは大変心惹かれるものだと感じています。今時のマルウェアは複雑であったりRing0上で動いたりとかなり多岐にに分かれるので知見を得たいです。

組込みリアルタイムOSとIoTシステム演習:私は非常にIoTには興味があってかつリアルタイムOSにも興味がありますこれは受けるしかありません笑。実際にesp-wroomというwifiのモジュールを扱って触ったりなどをしたこともあります。ですがこれはハード中心でこれの説明にはソフトウェア中心と書いてあるので是非参加して違う角度から知見を得たいと思っています。

(2)あなたがセキュリティ・キャンプでやりたいことは何ですか?身につけたいものは何ですか?(複数可)

自由に答えてください。
私は共通問題3の(1)で行いたい講義を述べましたがそれらはすべてここでなければ私には身につかないであろうものだと思っています。私はこのセキュリティ・キャンプで多くの人と繋がり、多くのこと最新の知識、知らなかったを学びたいです。例えばインフラであれば今のクラウドが最新のトレンドで、様々なところで事業展開が行なわれています。今さくらインターネットでは売り上げの一位がさくらのクラウドというサービスだが以前はクラウドではありませんでした。むしろクラウド事業を展開する際は他の売り上げが減るだけでコストがかさむのではないかなど反対の声があったそうです。しかし社長が展開すると決めて5年で売り上げ一番の部分がクラウド事業だそうです。このように情報分野は成長が早く考え方が刻々と変化し、そのときによってベストが変わります。しかしトレンドの流れをつかんでいる今だから実践を持って学べることがベストだと思っています。
 私はセキュリティ・キャンプは飽くまで情報科学に携わる若年者の後押ししてくれる場所であり、本質的にはキャンプへ参加し、何をつかみたいかということを見ているのだと思っています。キャンプに参加しただけで、飛躍的に技術力は上がるわけではなく、自分で行動しなければ何も得られないと私は感じています。それ故にセキュリティキャンプで一人では身につかない生きた知識を身に付け、吸収したことを昇華して私自身の血肉としたいと考えています。また私は工業高校生で、大半が就職の進路を考える学校でもあるので、家庭の事情もあるが進路は就職になる可能性もあると考えています。そうなれば来年からは学生ではなくなってしまうので最後のチャンスになんとしてでも参加したいと思っています。


(改変しました。本当に落ちそうなので。。。やけくそです)
後編へ続く

ブログ始めて一年らしい。

こんにちは。お久しぶりです。忙しくて本当にエントリ書いてませんね最近。(やる気の問題)

Haskell早くとか言われそう。。。そのうちラムダ計算も書くから許して。。。書きたいこと溜まっているのに書く暇がない。。。

ブログ始めて一年らしい。

さっきメールを見たら
”1年以上の長きにわたってブログを継続いただいているユーザー様を対象に、 過去の同じ時期に投稿した記事を振り返るメールをお送りします。 ”
と着てて少し感じたものがありました。

まぁなので今回立てたのは少し自分を振り返りたかったからです。

そもそも私がブログを始めたのは1年前に私の先輩がセキュキャン応募落ちたの見ていて嗚呼セキュキャン私も応募したかった(別大会のせいで顧問に止められた)というのがあり、私自身自分の甘々だったしコミュニティも知らなかった。なのでアウトプットしようということで始めました。

そしてタイミングがいいのかセキュキャン締め切りが今日でした。なるほど確かに一年だ。この一年たくさんのことがあった。たくさんの強い人たちと出会えた。もっと上がいて井の中の蛙大海を知らずという自分を見てしまった。さて私はこれから何を残せるのか。何に向かうのか。

私は一つ理念に持っているのは技術は人を幸せにすべきだと思っています。私は多くの人にお世話になっています。この一年で交換した名刺が100枚以上であるあたりが物語っていると思います。ぜひ私は自分が受けた恩恵を返していきながら新しい技術を身につけていきたいと思います。

色々辛いこともありますが優しくしてくだされば嬉しいです。

MPU-6050よお前のDMPは何様だ(2)

愚痴です。

MPU-6050 は InvenSense 製のI2C接続のジャイロ・加速度センサICで、 DMP (Digital Motion Processor) という機能を使うことで、補正済みのデータを簡単に利用できるのが特徴。

内部情報がない!使わせる気ないでしょこれ(半ギレ)


なのでざっとまとめた(私が触った限りで)

まとめ

//使うときの初期化
/*
その際内部では 
setXGyroOffset();、setYGyroOffset();、setZGyroOffset();(初めのズレを直すオフセットを読みだす関数)
やsetFIFOEnabled等のオーバーフロー周りが動く。*/
dmpInitialize();
// DMPで使う6軸のバッファーオーバーフローしてないかどうかの判定(Xは0〜5まで6ある)
bool getDMPIntXStatus()
//DMPを使うかどうか
setDMPEnabled(bool)
//オーバーフロー時の割り込みで通知してくる関数
getIntStatus()
//  DMP パケット サイズを取得します。
 mpu.dmpGetFIFOPacketSize()


使いづらいなぁ。。。サンプルなかったらみんな触らないと思うぞ。。。