読者です 読者をやめる 読者になる 読者になる

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

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

 

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

 

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

 

共通問題

検閲により削除が多いです。許して

共通問題1

Q1.

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

A1.

(検閲により削除)なので学校で作成したソフトウェアと個人で作成したソフトウェアがあります。
学校で作成したソフトウェアはandroidiosクロスプラットフォームで動く単語帳とwindowsで動く時計があります。
個人で作成したソフトウェアはtwitterbotや地元を走るコミュニティバスの時刻表に基づく現在位置を表示するwebアプリケーションがあります。
ハードウェアの部分ではarduinoを用いてマトリクスLEDに首都圏のJRの駅によくある発車時期表示器を再現するものを作りました。


Q2.

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

A2.

単語帳はcoronasdkというsdkで開発しました。sqliteを使って単語を管理しています。
動作は自分で単語と読みを登録して順番に表示していくという単純なものです。
友人らと3人で開発しましたが事前に打ち合わせをあまりしていなかったので2人が書いたコードを取り纏めるのに非常に苦労した記憶があります。共同開発の大変さを思い知りました。
windowsで動く時計はC#のWindowsFormApplicationとして作成しました。今一番開発に力を入れているソフトウェアです。みんなが使いたいと思うようなソフトウェアになるように意識して作っています。今のところの機能としては現在時刻の表示、ストップウォッチ、アラーム、鉄道路線の運行状況表示、読み上げ、天気の表示、読み上げを行う機能がついています。鉄道路線の運行情報と天気の取得はwebの情報をスクレイピングすることにより実現しています。html文書を解析するためにhtml agility packライブラリを使用しました。運行情報や天気の取得のためのURLなどの情報はxmlファイルとして保存することでxmlファイルを入れ替えるだけで情報のソースを変更でき、鉄道路線の開業、廃止に対応しています。またユーザ自身が任意のwebサイトの情報をxmlに追加することでユーザ自身でのソースの変更、追加に対応しました。今回webから情報を取得するようにしたことでwebの情報は有用な情報が大量にあると感じました。権利的な問題もありますがwebの情報は積極的に利用すべきだと思います。読み上げは棒読みちゃんというソフトウェアに文字列を渡して読み上げさせることで実現しています。また棒読みちゃんに文字列を渡す際にソケット通信を使っているので読み上げだけ別のPC上で行うというちょっと変わった運用もできます。アラーム機能を用いることで定期的に読み上げさせることができるのでこの時計ソフトウェアを用いてデジタルサイネージを作ろうと思っています。デジタルサイネージといえどずっと画面を点灯させているのは無駄なのでICカードを用いた入退室管理を実装して部屋にいる時だけ点灯させているという処理もついでに実装したいと考えています。機能を追加しているうちにソースコードがかなり汚くなってしまったのでリファクタリングを実施して引き続き開発を継続させようと思っています。
twitterbotは私がプログラミングを初めて間もないころにrubyで作りました。機能としては文章を読み込ませて文章を解析し、単語ごとにsqliteに保存して定期的に保存された単語の中から自動的に文章を生成して投稿するというものです。当時そのようなbotが流行っていて見よう見まねで作った思い出があります。文章を解析するライブラリとしてmecabを使いました。
地元を走るコミュニティバスの時刻表に基づく現在位置を表示するwebアプリケーションはphpで開発しました。機能は予めsqliteに時刻表を保存していおいてwebのリクエストが来たら路線図と現在位置を返すというものです。時刻表の隣り合ったバス停の停車時刻が同一時間の箇所があり、処理に困りました。
arduinoを用いてマトリクスLEDに首都圏のJRの駅によくある発車時期表示器を再現するものは昔購入した列車の運賃表示器をどうにか活用できないかということで作成しました。運賃表示器のマトリクスLEDの部分を単体で使用しています。このマトリクスLEDは回路図が公開されていなかったので自分で基板のパターンやICの役割を地道にを追って自分で回路図を作成しました。これに関してブログ(http://akkkix.hatenablog.com/entry/2016/03/28/205129)の方に簡単にまとめておきましたのでぜひ御覧ください。

 

Q3.

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

A3.

コンテスト等に出品した作品は特にありません。
ブログはあまり記事が多くありませんが、気が向いた時に気になったことや作っているものを簡単に書き綴っています(http://akkkix.hatenablog.com/)

 

(共通問題1の感想)

内容はともかく書くネタがあってよかった。

あと発車時期表示機じゃなくて出発時機表示機だった…

 

共通問題2

Q1.

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

A1.
マ トリクスLEDの制御でダイナミック制御というものがあります。これは一気に全部のLEDを点灯させるのではなく一行ずつ点灯させていき、それを高速で繰 り返すことで人間の目には点灯しているように見えるというものです。一旦LEDを消灯させてから行を変えてLEDを点灯させるという処理で動作が早すぎて 次の行に前の行の残像が写ってしまうという問題に出会いました。
マトリクスLEDつながりでは電源をUSBからATX電源に変更して電源容量に余裕が出てきたので一列全点灯を試してみたところ、マトリクスLEDの基盤のトランジスタから煙が出てしまうという問題にも出会いました。

 

Q2.

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

A2.

(検閲により削除)に 相談してみたところ、動作が早すぎてピンがHIGHからLOWになる前に行が切り替わってるのではないかというアドバイスを頂いたので試したところ、無事 改善しました。その後ダイナミック制御を割り込みにすることでメインの処理を開放しマトリクスLEDの店頭パターンの処理を行えるようにしたところ負荷に よって店頭間隔にばらつきが出てしまったので、そちらの問題を現在対処しています。
後者の問題はダイナミック制御で普段は全点灯を連続して行わないため単純に定格の電流以上の電流が流れてしまったと思われるのであまり負荷をかけないことで今のところは対処しています。(検閲により削除)

 

Q3.

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

A3.

前者の問題は単純に遅延を挟めばいいよとアドバイスします。
後者の問題は私も知識があまりないのでなんとも言えないのですが、とりあえず新しいことを試すときは十分注意して異常がないか確認を怠らないようにとアドバイスします。
や はりハードウェアはソフトウェアと違って故障した時に復旧ができないことが多いので慎重になるべきだと感じています。しかし、慎重になりすぎても進歩が出 なくなってしまうので今から電子工作を始める人には「安いものはどんどん壊して学ぶべきだけど高いものや貴重な者を扱うときは慎重に」とアドバイスすると 思います。
あとはやはりわからないことを聞ける人がいると心強いので人脈を作ることも一緒にアドバイスすると思います。私もいままで様々な人から教わってきたので、わからないことを聞かれたらできるだけ教えてあげられる人間でありたいと思います。

 

(共通問題2の感想)

あとからもう一回調べてみたら残像は遅延の問題じゃなかったとさ...(行を変えるときに点灯をオフにしてなかった)

トランジスタ燃やしたのは結局無抵抗でつないでたからでした...アホすぎ...

 

共通問題3

Q1.

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

そこで、どのようなことを学びたいですか?なぜそれを学びたいのですか?

A1.

数が多くなってしまったので箇条書きで書かせていただきます。
-サーバ運用におけるパスワード管理
-ID連携基礎
私は自宅でサーバーを構築しており様々なパスワードを管理しています。また、(検閲により削除)ので、セキュリティにおいて最も基本的だと思う「IDとパスワード」という視点からの知識を深め、セキュリティの意識を高めたいと思ったからです。

-USBメモリからブートしてみよう
windowns などのOSを介さずにプログラムを動かすということに非常に興味がわきました。自分でプログラムを書いてみることでキーボードから入力がなぜできるか、な ぜ画面に文字が表示できるのかを勉強したいと思います。また、機械語を扱うということなので機械語に関する知識も合わせて深めたいと思います。

-AVRマイコンで作るBadUSB自作
今 までパソコンのUSBに関するセキュリティについてはだいぶ前に問題になったオートランで悪意のあるソフトウェアが実行されるくらいだと思っていたので、 USBでキーボード操作などがエミュレートされるというのは考えてもいませんでした。入出力装置のセキュリティ対策ということで今まで私があまり気にして いなかった分野のセキュリティなので非常に興味があります。例えば中古で買ったキーボードにキーロガーが仕込まれていてパスワードなどが筒抜けになってい たら怖いと思います。新しい視点からセキュリティを見つめることで自分の知識が広がればいいなと思います。

-公開鍵暗号のハードウェア実装と攻撃~ICカードが持つ脆弱性とその対策~
前 年のセキュリティキャンプに参加した人の話を聞いて非常に興味深いと思ったからです。ハードウェアをオシロスコープで解析し暗号を解読すると聞いた時は非 常に衝撃的でした。このようなハードウェアの動作を解析して暗号を解読するのは不可能だと思っていたからです。もし参加が決定したら必ず受講したいです。 今までソフトウェア面でのセキュリティにばかり目を向けていたので、ハードウェアのセキュリティと言う新たな視点からのセキュリティを考えてみることで自 分の視野が広がると思うからです。

-.NET プログラムの解析
(検閲により削除)。ILコードも簡単なものを読みました。プログラムが解析できるとプログラムが動く仕組みが理解でき、それを自分の物にできるため大きく成長できそうだと感じています。難読化されたプログラムの解析も行うということなので(検閲により削除)よりも一歩進んだ知識を身に着けたいと思います。

-システムに新機能を追加したときのセキュリティを考えよう
プログラムが大規模になってきた時に困ることはやはり変数の管理だと思います。
講 師の方がC言語を拡張して永続変数を言うものを実装したようですが、便利な反面セキュリティ的には非常に扱いずらいと感じました。永続変数を持つプログラ ムの他のプログラムから変数にアクセスできるということはかなり攻撃者にとって有用だとおもいます。値を変更できるのでそのプログラムをバグらせたりする ことができるため便利ですが処理が面倒になってしまうとも感じました。たとえば文字列の変数を永続変数とした時に外部から変数が参照され、変数のサイズよ り大きいサイズの文字列に変更されたらバッファオーバーフロー脆弱性となりかねないと思います。受講できたら一緒に受講している方々とセキュリティと便 利性の両立について意見を交換したいと考えています。それにより自分の思ってもいないような問題や便利性が見つかるかもしれないと思うからです。

-インフラセキュリティ・ブートキャンプ
(検閲により削除)

-作って学ぶ低レイヤーネットワーク
最近arduinoで電子工作を初めて低レイヤーの面白さに気づきました。低レイヤーのことがわかると高レイヤーのことがどんどんわかる気がするからです。ぜひ受講して普段私達が何気なく使っているイーサネットに関する知識を深めたいです。

 

Q2.

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

自由に答えてください。

A2.

私がセキュリティキャンプでやりたいことは大きく分けて2つで、セキュリティに関する基本的な知識を固めることと一歩進んだ知識を習得することと互いに切磋琢磨できる仲間を見つけるということです。
(検閲により削除)の でそうならないためにもネットワークやサーバーに関するセキュリティの知識を習得したいです。また、今年の春に基本情報技術者試験に合格したのでそれで学 んだ知識を活かしたいというのもあります。今はネットワークスペシャリスト試験の勉強をしているのでそれに役立つ知識も習得したいと考えています。情報化 が進む現代でセキュリティに関する知識は年々重要度を増していると感じます。まだ将来の進路は決まってないですが、どのの分野の職業に就職してもセキュリ ティの知識は生かせると思います。将来身につけた知識を活かしてセキュリティの重要さを広める活動をしたいです。また、(検閲により削除)
後 者については,やはり1人で勉強してるよりも人と関わりながら勉強した方が習得が早いと思うからです。お互いに刺激しあい技術を高め会えるような仲間に出 会いたいです。また、講師の方々との繋がりを作ることで普段は知ることができない情報も知ることができると思います。そのようなつながりがあると例えば自 分が管理しているシステムに重要な脆弱性があった時により早い行動ができると思います。結果として被害を少なく済ませられると思います。私はセキュリティ は情報戦だと思っています。だからこそ幅広い人脈を作り情報を共有しあうことで強固なシステムを構築できるようになると思います。
---
応募フォームがなぜ会員制サイトでもないのにセッションタイムアウトがあるのか疑問に思って少し調べてみたのですが答えらしき答えが見つからなかったので参加することができたらそちらも講師の方に聞きたいと思います。

 

(共通問題3の感想)

重要だと思ったので結構頑張って書いた。

 

選択問題

3,4,5,8を選択しました。

選択問題3

Q.

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

A.

ま ずパソコンの電源を入れるとマザーボード上のROMからBIOSが主記憶上に読み込まれます。そしてBIOSが設定されている起動ディスクのMBRと呼ば れる領域からGRUB等のOSを起動するためのブートローダーを主記憶上に読み込みブートローダからOSを起動します。OSを起動するとブートローダーは 不要になるのでその部分の主記憶は開放されると思います。BIOSは入出力に必要だと思うのでそのまま残ります。応用ソフトウェアを起動するときはOSが その都度主記憶上に読み込み実行します。ここまで主記憶上にある情報は下位からBIOS,OS,応用ソフトウェアとなると思います。応用ソフトウェアを多 数起動すると次第にメモリが足りなくなります。それを防ぐためにOSは起動しているあまり使用していない応用ソフトウェアを最低限の情報をメモリに残し補 助記憶上に退避させると思われます。
動画編集ソフト等で重いファイルを読み込むと途端にパソコンの動作が重くなるのでおそらく使用中の応用ソフト ウェアの情報はすべて主記憶上に保存されていると思います、主記憶が少ないパソコンでは読み込むことすらできなかったことがあるので私が知らないだけかも しれませんが副記憶のデータを直接扱うことができるようになればいいなと思いました。

 

(選択問題3の感想)

 完全に自分の思い込みで書いた。後で正しいことを調べておかないとと思った。

 

選択問題4

Q.

突然だが、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. 5よりも、cond. 6が優先される。

char** invalid_order_brand =

{

    “DandySoda"

    “FrozenEvergreen”

};

A.

/*某木組みの街の喫茶店の店員とバリスタが注文を取るために使うプロトコルでしょうか*/
========ソースコード========
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct RHpacket {
char source[21];
char destination[21];
int dataLen;
char* data;
}RHpacket;

char* valid_order_brand[3] =
{
"BlueMountain",
"Columbia",
"OriginalBlend"
};
char* invalid_order_brand[2] =
{
"DandySoda",
"FrozenEvergreen"
};

int match(char* text, char* pat,int textlen ,int patlen) {
int ptop,i,j;
for (i = 0; i <= textlen - patlen; i++) {
if (*(text + i) == *(pat)) {
for (j = 1; j < patlen; j++) {
if (*(text + i + j) != *(pat + j)) {
break;
}
if (patlen - 1 == j) {
return 1;
}
}
}
}
return 0;
}

char* lower(char* text) {
int i = 0;
for (i = 0;; i++) {
if (*(text + i) == '\0') {
break;
}
if (65 <= *(text + i) && *(text + i) <= 90) {
*(text + i) += 32;
}
}
return text;
}


int main(void) {
FILE *fp;
int i,j,k;
unsigned char buf[2800];
int size;
int dataIndex = 0;
bool flg = false;
bool flg2 = false;
bool pass = false;
RHpacket pac;
fp = fopen("pyonpyon.rh", "rb");
if (fp == NULL) {
printf("error");
exit(1);
}
else {
size = fread(buf, sizeof(unsigned char), sizeof(buf), fp);
}
while (1) {
pac.dataLen = buf[42 + dataIndex] * 16777216;
pac.dataLen += buf[43 + dataIndex] * 65536;
pac.dataLen += buf[44 + dataIndex] * 256;
pac.dataLen += buf[45 + dataIndex];
pac.data = (char*)malloc(pac.dataLen + 1);
//条件1の検証
if (buf[0+dataIndex] == 'R'&& buf[1+dataIndex] == 'H') {

//条件2の検証
for (j = 2, k = 0; j < 22; j++, k++) {
if (buf[j + dataIndex] == '\0') {
break;
}
pac.source[k] = buf[j + dataIndex];
}
pac.source[k] = '\0';
if (strcmp(lower(pac.source), "rise-san") == 0 || strcmp(lower(pac.source), "cocoa-san") == 0) {
//条件3の検証
for (j = 22, k = 0; j < 42; j++, k++) {
if (buf[j + dataIndex] == '\0') {
break;
}
pac.destination[k] = buf[j + dataIndex];
}
pac.destination[k] = '\0';
if (strcmp(lower(pac.destination), "chino-chan") == 0 || strcmp(lower(pac.destination), "chino") == 0) {
//条件4の検証
if (!(strcmp(lower(pac.destination), "chino") == 0 && strcmp(lower(pac.source), "cocoa-san") == 0)) {

//条件5の検証
for (j = 46, k = 0; j < 46 + pac.dataLen; j++, k++) {
if (buf[j + dataIndex] == '\0') {
break;
}
*(pac.data + k) = buf[j + dataIndex];
}
*(pac.data + k) = '\0';
for (j = 0; j < 2; j++) {
if (match(pac.data, invalid_order_brand[j], pac.dataLen, strlen(invalid_order_brand[j]))) {
flg = true;
}

}
if (!flg) {
for (j = 0; j < 3; j++) {
if (match(pac.data, valid_order_brand[j], pac.dataLen, strlen(valid_order_brand[j]))) {
flg2 = true;
}
}
}

if (!flg&&flg2) {
printf("PASS\n");
pass = true;
}

}
}

}

}

if (!pass) {
printf("REJECT\n");
}

 

dataIndex += 46 + pac.dataLen;
free(pac.data);
flg = false;
flg2 = false;
pass = false;
if(dataIndex == size) {
break;
}
}

fclose(fp);
scanf("");

return 0;
}
==========実行結果==========
PASS
PASS
REJECT
PASS
REJECT
PASS
PASS
REJECT
PASS
REJECT
PASS
REJECT
PASS
REJECT
REJECT
PASS
REJECT
PASS
REJECT
REJECT
REJECT
PASS
REJECT
PASS
REJECT
REJECT
REJECT
REJECT
PASS
REJECT
PASS
REJECT
REJECT
REJECT
REJECT
REJECT
PASS
REJECT
PASS
REJECT
REJECT
REJECT
REJECT
REJECT
REJECT

 

(選択問題4の感想)

送信しようとしたらインデントが消えたのでそのままで。

コードが汚いのと無駄な処理が多い。

とりあえず構造体作ってみたけどあまり活用できなかった。

VSでデバッグ用に最後につけてたscanf("")を消し忘れた。

"REJECTED"って出力しろって言われてるのに"REJECT"...問題をちゃんと読みましょう。

 

選択問題5

Q.

PCなどに搭載されているOSは「汎用OS」と呼ばれますが、それに対して、家電やAV機器などの「組込みシステム」に搭載されているOSは「組込みOS」と呼ばれます。

組込みOSと汎用OSの違い、「OSが無い」や「ベアメタル」という環境、そもそもOSとは何なのか?など、あなた自身はどう考えているのかを、

あなた自身の言葉で自由に説明してください。(「正しい答え」を聞いているわけではありません。あなた自身の考えを教えてください)

A.

ま ず汎用OSは汎用と名のつく通り様々なことができるOSです。汎用に使えるのが汎用の最大のメリットだと感じます。それに対して組み込みOSは用途に特化 したOSです。汎用OSは組み込みOSに比べて様々なことができますが、様々な処理が内部でされているのでハードウェアのパフォーマンスが最大限に発揮さ せることができないと思います。例えばゲーム機のPS3と同程度のパソコンではゲームを実行させるための処理能力がPS3の方が高いと聞いたことがありま す。組み込みOSのメリットはハードウェアの資源を最大限に活かせることだと思います。これによりハードウェアの資源があまりなくても同じハードウェアと 汎用OSの組み合わせに比べて快適に動作する事ができます。そしてハードウェアを製造する費用を下げることができます。そもそも組み込みOSと汎用OSの 境界は非常に曖昧だと思います。上記ではPS3のOSを組み込みOSとしましたが、プログラムを書けばPS3でも様々なソフトが動き、汎用につかえると思 うからです。しかしPS3のプログラムを書く人はあまりいないので実質ゲーム専用のOSになっています。このことから組み込みOSか汎用OSかの基準は開 発キットが公開されていてある程度開発者人口がいるかということが一つにあると思います。そもそもOSとは何なのかということですが、ハードウェアの資源 管理やユーザー管理ができるなどいろいろ基準はあったと思いますが、私はoperation(操作)system(システム)という言葉の通り操作ができ ればOSだと思います。例えばマイコンでボタンを押すとLEDが光るという様なものも「ボタンを押すとLEDが光る」という操作ができるのでこれも一種の OSだと思います。パソコンはOSが無いとBIOSが起動したままですが上記によりBIOSもOSの一種だと考えるとパソコンのOSがないという状況はほ とんどありえないと思います。BIOSはハードウェアを制御する等の組み込みOSだと考えるとパソコンは組み込みOSの上で汎用OSが動いてることになり ます。組み込みOSの上で汎用OSが動いているというのはひょっとしてすごいことではないかと思いました。

 

(選択問題5の感想)

これも完全に思い込みで書いた。あとで正しいこと(ry

 

選択問題8

Q.

以下のダンプはあるプログラムのobjdumpの結果である。このプログラムが行っていることを調べ、その結果を記述してください。完全には分からなくても構いませんので、理解できたところまでの情報や調査の過程で使ったツール、感じたこと等について記述してください。
==

$ objdump -d challenge00

 

challenge00:     ファイル形式 elf64-x86-64

 

セクション .text の逆アセンブル:

 

0000000000400080 <.text>:

 400080:    68 19 01 40 00           pushq  $0x400119

 400085:    6a 01                    pushq  $0x1

 400087:    68 06 01 40 00           pushq  $0x400106

 40008c:    68 19 01 40 00           pushq  $0x400119

 400091:    68 29 01 40 00           pushq  $0x400129

 400096:    6a 3c                    pushq  $0x3c

 400098:    68 02 01 40 00           pushq  $0x400102

 40009d:    68 10 01 40 00           pushq  $0x400110

 4000a2:    48 b8 36 15 1b 25 67     movabs $0x63391a67251b1536,%rax

 4000a9:    1a 39 63 

 4000ac:    50                       push   %rax

 4000ad:    68 02 01 40 00           pushq  $0x400102

 4000b2:    6a 00                    pushq  $0x0

 4000b4:    68 06 01 40 00           pushq  $0x400106

 4000b9:    68 14 01 40 00           pushq  $0x400114

 4000be:    68 0c 01 40 00           pushq  $0x40010c

 4000c3:    68 02 01 40 00           pushq  $0x400102

 4000c8:    68 26 01 40 00           pushq  $0x400126

 4000cd:    68 14 01 40 00           pushq  $0x400114

 4000d2:    6a 07                    pushq  $0x7

 4000d4:    68 0a 01 40 00           pushq  $0x40010a

 4000d9:    6a e0                    pushq  $0xffffffffffffffe0

 4000db:    68 08 01 40 00           pushq  $0x400108

 4000e0:    68 19 01 40 00           pushq  $0x400119

 4000e5:    6a 08                    pushq  $0x8

 4000e7:    68 04 01 40 00           pushq  $0x400104

 4000ec:    6a 00                    pushq  $0x0

 4000ee:    68 1c 01 40 00           pushq  $0x40011c

 4000f3:    6a 00                    pushq  $0x0

 4000f5:    68 06 01 40 00           pushq  $0x400106

 4000fa:    6a 00                    pushq  $0x0

 4000fc:    68 02 01 40 00           pushq  $0x400102

 400101:    c3                       retq   

 400102:    58                       pop    %rax

 400103:    c3                       retq   

 400104:    5a                       pop    %rdx

 400105:    c3                       retq   

 400106:    5f                       pop    %rdi

 400107:    c3                       retq   

 400108:    5d                       pop    %rbp

 400109:    c3                       retq   

 40010a:    59                       pop    %rcx

 40010b:    c3                       retq   

 40010c:    48 01 ec                 add    %rbp,%rsp

 40010f:    c3                       retq   

 400110:    48 39 06                 cmp    %rax,(%rsi)

 400113:    c3                       retq   

 400114:    80 34 0e 55              xorb   $0x55,(%rsi,%rcx,1)

 400118:    c3                       retq   

 400119:    0f 05                    syscall 

 40011b:    c3                       retq   

 40011c:    48 89 e6                 mov    %rsp,%rsi

 40011f:    41 5a                    pop    %r10

 400121:    c3                       retq   

 400122:    48 89 f1                 mov    %rsi,%rcx

 400125:    c3                       retq   

 400126:    48 ff c9                 dec    %rcx

 400129:    75 01                    jne    0x40012c

 40012b:    c3                       retq   

 40012c:    41 5a                    pop    %r10

 40012e:    c3                       retq   

==

A.

40080~4009d:スタックにそれぞれ16進数値をプッシュしている
400a2:raxに16進数値をロードしている
400ac:スタックにrax($0x63391a67251b1536)をプッシュしている
400ad:スタックにそれぞれ16進数値をプッシュしている
-----
この時点でスタックはプッシュした順に以下のようになっていると思われる
$0x400119
$0x1
$0x400106
$0x400119
$0x400129
$0x3c
$0x400102
$0x400110
$0x63391a67251b1536
$0x400102
$0x0
$0x400106
$0x400114
$0x40010c
$0x400102
$0x400126
$0x400114
$0x7
$0x40010a
$0xffffffffffffffe0
$0x400108
$0x400119
$0x8
$0x400104
$0x0
$0x40011c
$0x0
$0x400106
$0x0
$0x400102
-----
400101:retqによりスタックポインタの指す値(400102)に飛ぶ 以下 jmp 場所と表す
400102:スタックからポップした値(0x0)をraxにセットしている 以下 pop (rax = 値)と表す
400103:jmp 400106
400106:pop (rdi = 0x0)
400107:jmp 40011c
??_40011c:スタックポインタの値をrsiの値に変更しているようだがわからないので無視
以下40011cを無視して読み進めた
40011f:pop (r10=0x0)
400121:jmp 400104
400104:pop (rdx = 0x8)
400105:jmp 400119
400119:syscall read 標準入力から10文字読み込む? rsi=文字列?
40011b:jmp 400108
400108:pop (rbp = 0xffffffffffffffe0)
400109:jmp 40010a
40010a:pop (rcx = 0x7)
40010b:jmp 400114
400114:xorb
400118:jmp 400126
400126:rcxの値を1減算
400129:jne
以下flagレジスタの値がわからないので分岐を網羅してトレースした
-----
if flag /=
40012c:r10 = 400102
40012e:jmp 40010c
40010c:add rbp rsp
40010f:jmp 400114
400114:xorb
400118:jmp 400106
400106:rdi = 0x0
400107:jmp 400102
400102:rax = 0x63391a...
-----
if else
40012b:jmp 400102
400102:rax = 40010c
400103:jmp 400114
400114:xorb
400118:jmp 400106
400106:rdi = 0x0
400107:jmp 400102
400102:rax = 0x63391a...
400103:jmp 400110
400110:cmp rax rsi
400113:jmp 400102
400102:rax = 0x3c
400103:jmp 400129
------
ここから合流し、また分岐
if if flag /=
40012c:r10 = 400119
40012e:jmp 400106
400106:rdi = 0x1
400107:jmp 400119
400119:syscall rax = 0x3c(exit) rdi = 1(異常終了)/////
------
if if else
40012b:jmp 400119
400119:syscall rax = 0x3c(exit) rdi = 0(正常終了)////

400114は0x55と(rsi,rcx,1)のxorをとっている
結果がフラグレジスタに入る。
40010cはベースポインタrbpにrspの値を加算しているが詳しいところはわからなかった
40019から標準入力から文字列を読み込むと思われる
rsiに文字列を読み込んでる?のでraxとの比較は文字列の比較だと思ったが、63391a6725161536をasciiコードで置き換えてみたところ「c9[sub]g%[SYN][SI]6」となったのでどうやら違う?
2回目の条件分岐でraxとrsiが同じかxorで0が出る異常終了するのでcmpで比較する値とxorで演算する値は違う値でないと行けないらしい
r10レジスタはプログラムの進行の調整用として使われている様な気がする

 

(選択問題8の感想)

かなり苦しかった。

調べ方が悪いのかgoogle先生に聞いても詳しいことはわからなかった。

アセンブラ意味わからん。

アセンブラに強くなりたい。