お腹.ヘッタ。

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

ステッピングモータ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()


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

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

こんにちは。エントリ書いてます。
MPU-6050についてずっと調べてました。

MPU-6050の概要。すごい安くて高性能な6軸ジャイロ加速度センサ。 InvenSense 製のI2C接続のジャイロ・加速度センサICです。 DMP (Digital Motion Processor) という機能を使うことで、補正済みのデータを簡単に利用できるのが特徴。ただしこれがひどい後述する。
アマゾンで買う時は日本在庫指定すると早く来るゾ。某林檎の会社の携帯端末に入ってる三軸加速度センサーと同系とも言われてるらしい(リーク情報重ねると)とあとはググって。

まず備忘録。
MPU-6050 6-axis accelerometer/gyroscope | I2C Device Library
ここからライブラリ持って行ってください。じゃないと動きません。もう一度言います。動かないんです。
何でうごかないかというと動かない方のライブラリは作ったときのarduinoバージョンが古くて型の名前が違うだとかそういうのでダメなのです。(詳しく知りたい方は古〜いライブラリを使ってみてね⭐️)
InvenSense のジャイロ・加速度センサ MPU-6050 を使うとか古くなってるから体験できる。(mainの部分は参考にするといい)



あとはやるだけペチペチ。

github.com


やっつけMPU6050(角度と生データ表示する)を置いておいたんでライブラリincludeして遊んでください。コメント振ってるんで読みやすいと思います

後で第二弾愚痴書きます()

Arduinoでのスレッドのお話。(pt.h)

こんにちわ。備忘録も兼ねてArudinoのスレッドのお話です。

別々のスピードでステッピングモーターの動作をやらせたいってことがあって、それ故Arudino上でスレッドを立ててみました。

github.com


以上今回のやっつけソースです。

そもそもArudinoにはスレッドの機構は存在はしないのですが、組み込み機器の考えの中にはRTOS(リアルタイムオペレーションシステム)を使うスレッドの組み込み機器とRTOSを使わない(ポーリング型(いわゆるイベント駆動型)プログラミング)の組み込み機器があります。その後者を簡単にするために"protothreads"というライブラリがあります。
protothreads
要参照。

要は今回のはprotothreadsをarudino向けにラップしたやつの紹介ということになります。



さてここからがこのエントリの本題で備忘録です(遠い目)

pt.hのinclude

Arduino Playground - TutorialList
から
build hardware and write code for it: protothread, a powerfull library
へ行って
Google Code Archive - Long-term storage for Google Code Project Hosting.
pt.hをダウンロードしてください。

その際includeすると

#include <lc-addrlabels.h>
#include <lc-switch.h>
#include <lc.h>
#include <pt-sem.h>
#include <pt.h>

ってでてくるので
削って

#include <pt.h>

に変えてコードを書く。やるだけ。




さてこいつの困ったのは意外に日本語情報あまり多くないんですね。。。
そしてぶっちゃけ二番煎じなんでオレオレメモ書きリファレンスも残しておきたいと思います。

(オレオレ)リファレンス

struct pt {
  lc_t lc;
};

構造体型pt。それだけ

PT_INIT(pt);
/*実態は
#define PT_INIT(pt)   LC_INIT((pt)->lc)
ってなっておりlc.hでincludeされている"LC_INIT(lc)"でその使用するスコープ変数の状態を初期化している
*/

Protothread を初期化する。

 PT_THREAD(name_args);
/*実態は
#define PT_THREAD(name_args) char name_args

名前を引数として呼ぶって感じですね。
*/

protothread (ちなみにCで記述されてる)の宣言部分らしい。

PT_BEGIN(pt)
/*実体は
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
"LC_RESUME(lc)"はlc.hで記述されてて意味どおりスレッドの再開をするってこと。つまるところスレッドの開始ということになる。
*/

protothread の開始の宣言。

PT_END(pt)
/*実体は
#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
                   PT_INIT(pt); return PT_ENDED; }
"LC_END(lc);"はlc.hで記述されててそのスコープでの使用の終了をマークしてる関数。
*/

Protothread の終了を宣言。

PT_END(pt)
/*実体は
#define PT_WAIT_UNTIL(pt, condition)	        
  do {						
    LC_SET((pt)->lc);				
    if(!(condition)) {				
      return PT_WAITING;			
    }						
  } while(0)
" LC_SET(lc);"はlc.hで記述されててそのスコープでの使用を設定する関数。正確に言うとその状態に保存をかける関数。
*/

protothread の宣言したスコープのスレッドで止まる。つまり機能的にはwait関数。

PT_EXIT(pt)
/*実体は
#define PT_EXIT(pt)				
  do {						
    PT_INIT(pt);				
    return PT_EXITED;			
  } while(0)
*/

protothread の宣言したスコープを終了させる。

PT_SCHEDULE(f)
/*実体は
#define PT_SCHEDULE(f) ((f) < PT_EXITED)
*/

protothreadをスケジュールをするために使うぽい。具体的にはprotothread が終了した場合0を返す。

PT_YIELD(pt)	
/*実体は
#define PT_YIELD(pt)				
  do {						
    PT_YIELD_FLAG = 0;				
    LC_SET((pt)->lc);				
    if(PT_YIELD_FLAG == 0) {			
      return PT_YIELDED;			
    }						
  } while(0)
*/

このprotothread(スレッド)が終わるまで待つ。
片方でデータ通信しててそのデータをもう一つのスレッドで仕事したい時に使うとでも言えばイメージがつく。

PT_YIELD_UNTIL(pt, cond)
/*実体は
#define PT_YIELD_UNTIL(pt, cond)		
  do {						
    PT_YIELD_FLAG = 0;				
    LC_SET((pt)->lc);				
    if((PT_YIELD_FLAG == 0) || !(cond)) {	
      return PT_YIELDED;			
    }						
  } while(0)
*/

このprotothread(スレッド)の指定した条件が true に評価されるまで待つ。

以上おまけでした。間違えがあったら教えてくれると助かります。