つれづれなる備忘録

CTF関連の事やその他諸々

バイナリ勉強会 #1

池袋で行われているバイナリ勉強会に初めて、友人と参加させて頂きました。

確か去年も一緒に前期試験が終わった直後に勉強会に参加して、その時は八王子まで出向いた気がします。でもそこでの勉強会は失敗だったんだよな・・・orz

まぁそんな前のことはどうでもいいのですねww

 

まずは大体半年程度を通してのカリキュラムを見せて頂きました。

基礎編ではBrainf*ckのインタプリタの自作から始まり、Cコンパイラの自作、UNIX V6でカーネル入門等々と続きます。

今日はその第一回なので、最初の最初にGtk#(初耳)でBrainf*ckのインタプリタC#で作ります。

C#初めてで大丈夫かな・・・?とか思ったのですが、指示に従って進めていくとJavaの先代だけあって結構似通ったところがあって理解も進みます。

 

ひとまずこれがほとんど完成したところで昼食をはさんで後半戦に望みます。

お次の指示は、自分の好きな言語で何でもいいのでファイルから読み込んでBrainf*ckのインタプリタを作れとのこと。

ここで最初はC言語で作ろうと思ったのですが、気がついたら何故かC++で作ってましたww

 

今更なのですが、ここでBrainfuckの仕様を説明します。(引用:wikipedia Brainfuck

処理系は次の要素から成る: Brainfuckプログラム、インストラクションポインタ(プログラム中のある文字を指す)、少なくとも30000個の要素を持つバイトの配列(各要素はゼロで初期化される)、データポインタ(前述の配列のどれかの要素を指す。最も左の要素を指すよう初期化される)、入力と出力の2つのバイトストリーム。

Brainfuckプログラムは、以下の8個の実行可能な命令から成る(他の文字は無視され、読み飛ばされる)。

  1. >: ポインタをインクリメントする。ポインタをptrとすると、C言語の「ptr++;」に相当する。
  2. <: ポインタをデクリメントする。C言語の「ptr--;」に相当。
  3. +: ポインタが指す値をインクリメントする。C言語の「(*ptr)++;」に相当。
  4. -: ポインタが指す値をデクリメントする。C言語の「(*ptr)--;」に相当。
  5. .: ポインタが指す値を出力に書き出す。C言語の「putchar(*ptr);」に相当。
  6. ,: 入力から1バイト読み込んで、ポインタが指す先に代入する。C言語の「*ptr=getchar();」に相当。
  7. [: ポインタが指す値が0なら、対応する ] の直後にジャンプする。C言語の「while(*ptr){」に相当。
  8. ]: ポインタが指す値が0でないなら、対応する [ (の直後)にジャンプする。C言語の「}」に相当。

 

・・・開発始める前にちゃんと仕様読めば良かったなぁ。最初[には絶対に一回は入るように作っちゃうから失敗するんだよねww

そんな感じでなんだかんだで完成したのが以下になります。数ヶ月ぶりのちゃんとしたコーディングなので、完全に感覚が鈍っててコードが汚いのは勘弁してください。

[cpp]

include <iostream>

include <fstream>

include <cstdio>

using namespace std;

void func(char,char,int,int,int*); int loop[128]={};

int main(void){ ifstream ifs; char c,cmd[2048]={},mem[30000]={}; int i=0,cps=0,mps=0,lps=0;

ifs.open("text.bf",ios::in);

if(!ifs){ cout << "ファイルが存在しません。" << endl; return -1; }

for(i=0;!ifs.eof();i++){ ifs.get(c); cmd[i]=c; } while(cps<i-1) func(cmd,mem,&cps,&mps,&lps);

ifs.close(); return 0; }

void func(char cmd,char mem,int cps,int mps,int *lps){ int lev = 0;

switch(cmd[cps]){ case '>': ++mps; break;

case '<': --*mps; break;

case '+': ++mem[*mps]; break;

case '-': --mem[*mps]; break;

case '[': if(mem[mps]>0){ ++lps; loop[lps]=cps; } else{ int lev=1;

do{
 ++*cps;
 switch(cmd[*cps]){
  case '[':
   ++lev;
   break;

  case ']':
   --lev;
   break;
 }
}while(lev!=0||cmd[*cps]!=']');

} break;

case ']': if(mem[mps]>0) cps=loop[lps]; else --lps; break;

case '.': cout << mem[*mps]; break;

case ',': mem[mps]=getchar(); break; } ++cps; } [/cpp]

ここで初めは","に対して『cin >> mem[*mps]』を使ってたのですが、これだと改行コードが含まれないことが判明したのでgetchar()にしました。 途中break文ごとコメントアウトして何で正常に動かないのだろうとかいうミスをやらかしたりしましたが、結果的に完成したのでよしとしましょう。 ここに完成品を置いておきますね。これはファイル読み込みではなく標準入力にしておきます。

Brainfuckインタプリタ

さて、一通り済んだところで残り時間もわずかになりましたが、次の講座のためにMinGWを準備してbinutilsのインストールまでやっておきます。 ・・・ただここで『性能の違い』というものを見せ付けられました。自分のほう(Atom)が先にビルト始めたのに、友人のPC(i5)の方が完全に先に処理を終えるというwwww

 

まぁこんな感じで久しぶりに良い勉強会に当たったようなので、これから常連さんにでもなろうかと思っています。

これからもよろしくお願いします!

東工大受けてきました

あぁ、もうあれからまた一年が経ったんですね・・・

 

 

お久しぶりです、少し時間に余裕が出来たので3ヶ月ぶりの更新となります。

題名にあったとおり、本日東京工業大学の入試を受けてきました。

 

一通り全力は出し切ったつもりでいますが、なんというか数学がう~ん

後は結果を待つのみです。

あ、あと先日早稲田大学も受験したのですが、結果は『合格』の前に余計な二文字が付いていました。

正式な結果は来月の8日と18日に出るようですが、ちょっと望み薄感は否めないです。

 

まだ後期試験が残っているのでそこまで遊んではいられませんが、最近めっきり疎かになっていた開発を少し再開しようと思います。

短いですが、今日はこの辺でノシ

ブラインドSQLインジェクション

今日は久しぶりにセキュリティ関係について書き残そうと思います!

 

皆さん、世の中のサイトの何割位に脆弱性があると思いますか?

正解はなんと、9割方のページに何らかの欠陥があるという調査結果が出ているそうです、、、

今日はその脆弱性をつく手法の中で、『ブラインドSQLインジェクション』というものについてちょっとだけ説明しようと思います。

 

 

皆さんはSQLインジェクションについては知っていると思いますが、よく見かける文献にある実行例はどれもテーブル名等々が分かっている状態で実行するのがほとんど。ぺネトレーションテストを行う場合、当たり前ですが攻撃者はそんな中の情報は知らない前提で行うものです。

まずはSQLインジェクションについて少し。

これはアプリケーションのセキュリティーホールを利用して、任意のSQL文を注入(inject)し実行させ、データベースを不正に操作することを指します。

例えば、以下のようなSQL文があるとします。以下実行環境をMicrosoft社のSQLServerとします。

SELECT * FROM user WHERE id = '(会員ID)' AND pass ='(パスワード)';

ウェブのSQLインジェクションに対して未対策のログインフォームで、ID「testid」は分かっているがパスワードが不明な場合、ID欄に『testid'; --』と入力すると以下のような文ができます。

SELECT * FROM user WHERE id = 'testid'; --' AND pass ='(パスワード)';

『--』以降はコメントアウトとして処理されるため、パスワードの如何に関わらず「testid」さんとして問題なくログインできます。仮にパスワードの入力判定をしている場合でも、適当な値を入力さえしていれば通ってしまいます。

たとえIDが分かっていなくても、『' OR 1=1; --』と入力すれば、

SELECT * FROM user WHERE id = '' OR 1=1; --' AND pass ='(パスワード)';

となり、idカラムにどんな値が入力されようと『1=1』は常に真なのでuserテーブル内の全てのレコードが選択されます。

 

ここまで原理が分かってしまえば後は何でもし放題ですよね?w

試しに『'; UPDATE user SET pass=''; --』と入力したとすると、、、とんでもないですね。

SELECT * FROM user WHERE id = ''; UPDATE user SET pass=''; --

ログインは出来ず、一瞬失敗したかな?と思いますが、その裏では全てのパスワードが削除されているのです。あぁおそろしや・・・・・

 

 

ここで疑問が生じますよね?

『おい、なんでテーブル名がuserで、カラム名がpassということが分かってんだよ!』

・・・その通りです、ゴメンナサイ。ここで登場するのがブラインドSQLインジェクションです。

原理はとっても簡単で、『最初のテーブル名は1文字目がuか?2文字目はsか?』なんて事を延々と続けていけばいいんです。条件文にサブクエリを含ませて、その真偽によって判断します。

 

テーブル名を取得するためには

SELECT name FROM sysobjects WHERE xtype = 'U';

とすれば良いです。

試しに『' OR (SELECT count(name) FROM sysobjects WHERE xtype = 'U') > 0 --』を入力します。これは(テーブル数)>0は真かどうかを見ているので、テーブルがひとつでもあればログインできます。これを使えばサーバー内にあるテーブル数は確定できますね?(別に使うこと無いけどww)

 

では続いて先頭のテーブル名を得てみましょう。

' OR lower(substring*1 >= 'n' --

まず『SELECT min(name) FROM sysobjects WHERE xtype = 'U'』で先頭のテーブル名を取得し、これを以下'user'とします。substring('user',x,y)でx文字目からy文字取得し、ここでは'u'となります。lower()によって小文字へ変換されるため、決定が容易になります。

'u'は'n'以降なのでここでログインは成功します。次に'n'を't'として真、'x'として偽、'v'として偽、'u'として真なので1文字目が'u'と定まります。

それでも心配なら、『>= 'u' --』を『= 'u' --』として確実に確認してみるのもいいでしょう。

次は2文字目の確認です。substring()の引数を(x,y)=(1,2)として'un','ut'・・・としても間違ってはいませんが、毎回毎回'u'を打つのは非効率的です。なので、(x,y)=(2,1)とすれば'n'として真、't'として偽、'q'として真、's'として真より2文字目が's'と決定します。

これを繰り返して'user'まで求まったとします。しかし、ここで決定したぞ!と喜んではいけません。まだ4文字目も以降名前が続く可能性は十分あるからです。

' OR (SELECT count(name) FROM sysobjects WHERE xtype = 'U' AND name = 'user') > 0 --』として真なら'user'テーブルは存在し、晴れて先頭のテーブル名を決定することができました。

 

'user'の次のテーブル名を取得するには、

' OR lower(substring*2 >= 'n' 』として同じ事を繰り返せばOKです!ww

今回はSQL Serverを対象としましたが、それ以外は以下のようにすれば良いです。

Oracle select * from all_objects where object_type='TABLE';

PostgreSQL select * from pg_tables where not tablename like 'pg%' order by tablename;

H2 select * from INFORMATION_SCHEMA.tables;

では、今日はここまで~

*1:SELECT min(name) FROM sysobjects WHERE xtype = 'U'),1,1

*2:SELECT min(name) FROM sysobjects WHERE xtype = 'U' AND name > 'user'),1,1

続・濃度変換公式!

どうも!二ヶ月ぶりの更新となります、Shiftです。

続と言うからには元ネタがあるわけで、ここを参照くださいませw

 

なぜ一年ぶりにこの話題を持ち出したのかというと、なぜあの公式が導き出せるのかと言う質問が最近ちょくちょく来たからです。

では早速導出行きましょう!

溶液は分かりやすくする為に全てV[L]で計算させてもらいます。どうせ消えるから考えなくても結構ですw

 

容量モル濃度[mol/L]と質量百分率[%]の変換

cM=10ad

c[mol/L]:容量モル濃度、 M:[g/mol]:モル質量、 a[%]:質量百分率、 d[g/cm^3]:密度

質量百分率の定義に従って計算します。

  1. 溶質のモル質量に容量モル濃度と体積をかけて溶質の質量を求めます。
  2. 溶液の密度に体積をかけて溶液の質量を求めます。ただし、与えられた密度が[g/cm^3]の場合、10^3をかけて[g/L]に単位を変換する必要があります。
  3. 溶質の質量を溶液の質量で割ることで全体における溶質の割合が求まり、100をかけることで質量百分率となります。

$$\frac{McV}{10^3dV}$$×100=a

∴cM=10ad

 

質量モル濃度[mol/kg]を含めた相互変換

100c=(100-a)mBd

mB[mol/kg]:質量モル濃度

今回は質量モル濃度の定義に従って導出します。

    1. 溶質の容量モル濃度に体積をかけることによって溶質の物質量を求めます。
    2. 溶液の密度に体積をかけて溶液の質量を求めます。但し書き略
    3. 溶質の物質量にモル質量をかけて溶質の質量を求め、これを溶液の質量から引くことで純粋な溶媒の質量が求まります。
    4. 溶質の物質量を溶媒の質量で割ることで質量モル濃度が求まります。ただし、3で求めた質量の単位は[g]なので、質量モル濃度に10^-3をかけることで[mol/g]として単位をそろえます。
    5. 計算式中のcMには、上式より10adを代入しましょう。

$$\frac{cV}{10^3dV-McV}=10^{-3}m_B$$

$$10^3c=m_B(10^3d-10ad)$$

∴$$100c=(100-a)m_Bd$$

 

導出はこんな感じですかね!

これからもよろしくお願いします~ww

久しぶりの再会!

前々から計画していたことが、今日やっと実現しました!!

 

事の発端は自分が自動車教習所に通っていたころ、学校の友達を誘って同じ教習所に通っていたんです。そのころから、卒業したらどこかにドライブにでも出かけようと話していたのですが、他にも人を誘ったり行き先を決めていたりしていたら、あっという間に時間が流れてしまったんですねorz

しかしどうしたことか、初め行こうと約束していた友達は都合がつかず、結局自分含めた3人で千葉在住の友達のお宅に突撃することに。

あ、カテゴリーに『中等教育学校』が選択されてますが、ただ単に学校の友達と、ということなのであんまり学校は関係していません、ご了承をw

 

 

父には長野から帰ってくる最中に車を使って良いか訊き、もしだめならレンタカーでも借りようと思っていたのですが、ルートをちゃんと説明して家のプリウス君を無事に借りることが出来ました!

今日は朝の8時に九段で集合ということで、7時に田園調布を出発~

しばらく中原街道を走り、それから国道1号線、通称桜田通りをひたすら走ります。

皇居の内堀まで来ると、懐かしのマラソンコースが目の前に!去年までここを6年間走ってたことを思い出すと、その横を車で走ってるのがなんだか不思議な気分ですw

靖国神社を横目に見て、母校の横に停車すると、どうやら今日から夏休み明けだったらしく、Yシャツやセーラー服の後輩たちがいっぱいです。

 

約束の8時になっても友達が来ません。

・・・・5分・・・・10分・・・・15分・・・・

おいっ、遅いよ!!二人とも20分遅れてやっと来ましたよ。

ここまで時間にルースというのもどうかと、、、 まぁ女の子だから許すwwww

いやはや、やはり半年振りに会えてとても嬉しい限りです!

 

これからが大変ですよ・・・

ここ九段下から、友達の住む新千葉まで一般道で行きます!

途中台場を横に見て、夢の国やら夢の島やら、名前は似てても埋まってるものは対照的なところを通過し、東関東自動車道の側道を走り、千葉に到着です~

皆さんにとっては、たった二時間ほどの運転はそんなに大変なものではないとは思いますが、私は腰に来ちゃいましたorz

 

 

ちょっと迷いながらも無事友達宅に到着、さすが男子の下宿先っていう感じの物件ですねw

ジェンガやらUNOやらで一息つき、昼食に千葉駅らへんに歩いていってみました。

なんか聞くところによると、温泉に行く予定があるとか。まじ裏山!!!w

 

その後、海を見ようかということになって、皆を車に乗せて稲毛海浜公園に出発!

しかし、、、ひとつめの駐車場いっぱいorz

次の駐車場もいっぱいでもう諦めムード・・・

もう半ばやけでまた走り出したら、次の駐車場は妙に空いてるではないか。

そこに入って駐車し少し歩くと、眼前には一面の海!

水着でも持ってくれば良かったかなww

 

着替えも無いので、そこまで濡れない程度に海でお遊びw

砂浜の熱量ハンパねぇっす・・・ 真剣に火傷しそう・・・

でも、海に入りゃこっちのもんで涼しいもんです♪

・・・うっちーは廣瀬の肩を掴んで一体なn(ry

 

さすが千葉の内房、東京スカイツリーが良く見えますね~

うん、あれはこうやって見るだけで十分なものだなw

 

 

そしてここから帰るとき、免許を取りたて(一週間とか言ったかな?)の川村氏に運転を託します~w

う~ん、良い意味でも悪い意味でも安全運転ですね!!

良い意味?そりゃもちろん、制限速度を遵守して安心できる丁寧な運転でございます。

悪い意味?後ろの車に超責っ付かれてますけど、、、

 

あぁ、そういえば川村には謝らなきゃなぁ

俺が道案内を間違えたせいで、大幅な遠回り運転を余儀なくさせてしまったことをお詫びします。。

 

 

そんなこんなで十二分に千葉で楽しませてもらい、帰りは再び俺の運転ですよ~

うっちーとはここでお別れ、といえどもまた明日クラス会で会うんだけどねw

気がついたら燃料ゲージが残り1だったのでセルフ給油。手際良いね~と言われてまんざらでも無い俺ですwww

途中渋滞でノロノロしてたところもありましたが、事故渋滞を抜ければあとはスカスカだったので、28m/sで気持ちよく走ってたら後部座席のお嬢さんから窘められるという・・・

 

このあと用があるということで、東銀座で廣瀬とはお別れです。また今度遊びましょうね!w

のち、川村となんとなく母校訪問。久しぶりに九段でお世話になった先生方と話が出来て、とても良かったです~

 

 

・・・そういえば、なんだかアポなしで突撃訪問する輩(卒業生)がいるらしいですよ?

事前にアポイントメント取ってから行くのは当たり前と思っていたのですが、そのことを褒められてちょっと不思議な気持ちですw

九段の卒業生の皆さんも、もし学校に顔を出す際はちゃんと事前確認取りましょうね♪

APASECに行ってきました!

こんばんは、Shift-Cropsです!

今回は久しぶりにこのブログの本来の趣旨関連の記事です。

とはいうものの、勉強会に参加してもメモも取らずに聞いていただけなので、全然まともなこと書けませんので予め謝っておきます。すみません!

 

 

てなわけで、今日は[東京]第一回首都圏勉強会に参加してまいりました!

毎年、IPA主催のセキュリティ&プログラミングキャンプ、通称セプキャンが催されていました。

しかし今回はお偉いさんの決定かどうかは知りませんが、名称からプログラミングが抜け落ちて、略称もセキュキャンと言うなんとも読みにくい名称に・・・

 

話が脱線しました。

今回の勉強会は、このセキュキャン2012参加者の希望で、サイボウズさんが快く会場を提供してくださり開催されたようです。皆さんに感謝です!

開催場所は懐かしの飯田橋と水道橋の間です。

発表内容は以下の通りです。

  • セキュリティぼっちのモチベーション維持法(rizaudo)
  • 自作OSについてなにかしら発表(gumumuさん)
  • OSの不正実行防止機能について(weaselさん)
  • Kinect!(haru2036さんとshiftkyさん)
  • 「刺身の上にタンポポをのせる仕事」(TAKESAKOさん)
  • 自作のJava RMIについて(Furinさん)
  • プログラミング言語に関するなにか(takuto_hさん)
  • C言語初心者向け静的解析ツールの開発」(uchan_nosさん)
  • 分散ファイルシステム的な何かについて(nakamuさん)
  • 自己紹介とプログラムの高速化について(川合 秀実さん)
  • 組み込みOSでの不正実行の検出(amamamaさん)
  • 自作ECMA262 engineについて(Constellationさん)
  • 卒論の内容について(nhirokinetさん)
  • 「最底辺エンジニアの日常」(kitokeyさん)

 

いつもお世話になってる自作OSの著者川合先生は、世間に真っ向から歯向かう機種依存大好きなようですw 教授のアルゴリズムを腐ってると切り捨てて、何倍も早く処理させるなんてマジかっけー!

 

あと、マイコンの自作って、あんなにシビアだとは思いませんでした・・・

数センチの導線の長さのずれで信号の届く時間のラグが生じるから、そこらへんも考慮して設計しないといけないと言うのは、想像を超えて遥かに大変そうですよ、、

題名の『最底辺エンジニア』って俺のことかよ、とか思ってたら、レベルじゃなくてレイヤの話だったよwww

 

TAKESAKOさんの、PerlWin32::GuiTestを用いたマインスイーパー攻略的な

見てるだけで圧巻ですよ。マウスが勝手に動いて次々に解いていって、自動的にハイスコアの入力までしてくれるという親切設計www

開発段階でのプロセス暴走はどうしよう!キーボードもマウスも使えないから・・・と悩んだ結果、はじき出したのはUSBメモリのAUTORUNでプロセスをkillするというw

 

 

いやぁ、面白かったです!

発表の後の懇親会でもいろんな人と話すことが出来て楽しかったです。

今日はお疲れ様でした~

初めてのロングドライブ

一昨日17日の深夜から今朝にかけて、我々清水一家は父の実家の長野に帰省していました。

 

まだ夜の運転にはあまり慣れていないということもあり、長野に帰るときは父の運転に揺られながらゆっくりと帰ろうと思っていたのですが、まさかの運転のお誘い(?)ですww

てなわけで自宅から中央自動車道に乗り、石川SAまで運転させてもらいました。このブログは馬鹿発見器ではないので詳細は言いませんが、40m/sは出してた気がします・・・

その後は一度父と交替し、そのあとにもう一度だけ私に替わって、そのあとは長野まで熟睡しておりましたw 着いたのは明け方の3時でしたね。

 

長野では久しぶりに祖母と会ったのみで他には特にすることも無く(勉強は!?)、土曜日は飯食って本読んで寝ましたorz

翌19日、早速東京に帰る準備をして出発です。疲れたら行きと同じように父と交替するつもりだったのですが、何をどう間違えたのか、途中で一回サービスエリアで休んだ以外は連続ぶっ続けで東京まで突っ走ります!

42m/s出てたかも・・・・ いや、そんなことは決してないはず!(空目

なんだかんだで無事に事故も無く、ほんの二時間ほどで母方の祖母の国立に到着です。

ここで昼食を取った後、さすがに疲れもピークだったので後は父に運転してもらって帰宅の途につきました。

 

 

いやはや、慣れないことばかりで疲れたけれども、だいぶ良い経験にはなったと思います♪

感謝、感謝!