ホーム » スタッフ » 斉藤徹 (ページ 98)

斉藤徹」カテゴリーアーカイブ

2025年6月
1234567
891011121314
15161718192021
22232425262728
2930  

検索・リンク

情報セキュリティ高度人材育成・夏休み講座

1608301101_320x288.JPG

情報セキュリティ講習会用環境構築

明日から2日間で、情報セキュリティ人材育成講習会が石川高専で開催され、 興味のある学生1名を連れて参加。 ただし、以下の様な環境を準備しておくようにとの連絡で、 学生のパソコンにソフトをインストール。

ネットワークキャプチャツール
  • Wireshark or NetworkMiner
Linuxコマンドの環境

file,strings,nkf,ncあたりのコマンドが実行できるもの

  • WindowsでLinux環境をエミュレートするCygwin or MinGW
  • 仮想環境でLinux OSを利用する VirtualBox or VMware
デバッガ
  • OllyDbg or IDAPro Free
プロキシツール
  • Fiddler or Burp or Owasp ZAP
バイナリエディタ
  • stirling
プログラム言語
  • Python(推奨), Ruby, Perl

今回参加の学生の場合、Wireshark, Cygwin, OllyDbg, Fiddler 等をインストールしてみた。 Cygwin に nkf が無いので、ソースから入れたけど、make などの話も少しできたので、丁度良かったかな。

ネットワークセキュリティ講習会

情報セキュリティ人材育成講習会…というのがあって、 参加希望者や、ネットワークに興味がある学生さん、 就職でネットワーク知識に必要な学生さんを募って、 数名でネットワークセキュリティの講習会を行った。

unix

  • ディストリビューション
  • ディレクトリ構造

ユーザの概念

  • /etc/passwd, group
  • sudo , suid

ネットワークの基本設定

  • /etc/network/interfaces
  • ifconfig
  • ping, telnet, netstat

リモート接続

  • slogin, ssh

デーモン

  • inetd , xinetd
  • デーモン , サービス
    • /etc/init.d
    • systemd

ファイアウォール

  • iptables

各種アプリケーションのセキュリティ

  • メール(smtp,pop3)
    • 不正中継
  • Proxy
    • OpenProxy
  • Web(apache)
    • 認証
  • Web(php)
    • URLトラバーサル
    • ディレクトリトラバーサル
    • フィッシング
    • コマンドインジェクション
    • SQLインジェクション

アプリ開発ハッカソン

ふくい産業支援センターさん主催で、アプリ開発ハッカソンを8/11に、電子情報の実験室で開催しました。

次週に実際の開発ハッカソンを行うので、アイデアを練る方法を中心で進みました。

1608212149_320x240.JPG

歯みがきロボコン工作教室

今年は、プッシュリベットを多用して、子供中心で作っても、早く組み立てができました。

1608212141_320x320.JPG

歯みがきロボコン工作教室マニュアル

例年、福井県歯科医師会さん主催で、お手伝いしている 歯みがきロボットコンテストでの夏休みの工作教室を明日に控え、 組み立てマニュアルを作成。

1608201059_449x488.PNG

おもしろフェスタinサンドーム

1608071134_640x640.JPG

Windows10 Anniversary Update で 0x80072ee2 エラー

Windows 10 Anniversary Update が 8/2 に公開され、 日が変わってインストールしてみる。

Surface Pro4 に入れてみると、開発環境でHDD容量不足。 Visual Studio 等をひとまずアンインストール。
# 20GBが必要という割には、30GB空けないとダメだったけど。

ようやく更新が始まったら、職場のウィルス対策ソフト "Symantec Endpoint Protection"は、サポート外とか言われ、 アンインストール。んで、アンインストールで再起動のあと、 続きを実行しようとしたら、0x80072EE2 のエラーで失敗。

調べてみると、"ERROR_INTERNET_TIMEOUT" みたい。 朝、多くの人が更新を開始しているために、サーバへの トラヒック集中により接続に失敗していると考えられる。

ということで、もう少し経ってから、再チャレンジだな。
自宅PCは、更新中の再起動まで進んでから、出勤なので、 そろそろ終わってるかな。

今日のプログラミング応用のテスト問題

今日の、本科3年のプログラミング応用のテスト問題。
# テスト後、「先生、ポケモンGOやってるんですか?」

今から、明日の専攻科2年オブジェクト指向プログラミングの問題作るぞ。 当然、ポケモンの「進化」ネタだよな。

1607271053_859x300.png

安全な入力とdefineマクロ

ファイル処理の最後の説明で、バッファ・オーバーフローと、安全な入力について説明。

安全な入力

一般的なC言語での文字列入力のプログラムは、以下の様なものがテキストにも書かれている。

// memory
// [局所変数str][戻り番地][..........]
void foo() {
   char str[ 10 ] ;
   scanf( "%s" , str ) ;
}

バッファオーバーフロー

しかし、こういった処理は極めて危険である。 入力の際に、10文字以上のデータが入力された場合、 一般的な処理系では、str[] の配列の近辺に 「関数foo()の実行後に戻る処理の番地」が格納されている場合が多く、 文字列をはみ出るような入力があった場合、処理番地を書き換えられる可能性がある。 悪意のあるプログラマーは、はみ出す領域に、戻り番地を書き換えるデータと、悪意のある処理を 書くことで、想定外の処理を動かすかもしれない。 このテクニックをバッファオーバーフローと呼ぶ。

このため、最大文字制限の機能を使い、以下のように記述すべきである。

char str[ 10 ] ;
scanf( "%9s" , str ) ;

しかし、scanf() には、空白を読み飛ばす機能により「入力が無い場合…」といった 処理が書きにくい、%d入力で実数の"."や文字列を間違って入力したときの処理などの 問題があって、scanf() 単体で複雑な入力に対応することは極めて難しい。

fgets() + sscanf()

このような場合によく使われるのが、fgets()とsscanf()である。

fgets() は、文字配列に1行分のデータ(行末文字"¥n"まで)を、文字配列に読み込む関数である。 また、sscanf() は、文字配列のデータから、scanf() と同じようにデータを読み込む。

FILE* fp ;

if ( (fp = fopen( "data.txt" , "rt" )) != NULL ) {
   char buff[ 100 ] ;
   while( fgets( buff , sizeof( buff ) , fp ) != NULL ) {
      int x ;
      double y ;
      char z[100] ;

      if ( sscanf( buff , "%d%lf%s" , &x , &y , z ) != 3 )
         break ;
      // x , y , z を使った処理
   }
   fclose( fp ) ;
}

fgets() は、第一引数に、読み込み先の配列アドレス、第2引数に最大読み込みバイト数、第3引数に 読み元のファイルを指定する。文字配列への読み込み時には、第2引数のサイズを超えて 読み込むことはしないので、バッファオーバフローの心配はない。 また、入力データが無い場合には、NULL を返す。
sizeof()は、引数部分の変数のバイト数を返す演算子。

sscanf() は、データの入力が、第一引数の文字列から読み込む以外は、 scanf(),fscanf() と同じ使い方。

注意:fgets では、入力が最大バイト数以下の場合、行末文字まで読み込む。


Tips: 入力が無かったら(空行なら)、標準入力(通常キーボード入力)なら

char buff[ 1024 ] ;

while( fgets( buff , sizeof( buff ) , stdin ) != NULL ) ) {
   // stdin は、標準入力(通常キーボード)
   if ( buff[ 0 ] == '¥n' ) {
   // 入力が空行だった場合
   }
}

fscanf()にfprintfがあるように、sscanfに対してsprintfもある。

char buff[ 1024 ] ;

sprintf( buff , "%d %5.1lf %s" , 12 , 34.5 , "abc" ) ;
// buff = "12  34.5 abc"となる。

#defineマクロ

scanfで"%d"で数字を入力する際に、文字を入力されると、あとの処理が書きにくい場合が多い。 この場合、fgetsで入力し入力データが正しい文字を使っているかチェックしてから、 sscanf()を使うなどの対処をとることが多い。 ここで、#define マクロを使ってみる

#include <stdio.h>
#define isdigit(C) ((C)>='0' && (C)<='9')
void main() {
   char buff[ 1024 ] ;
   while( fgets( buff , sizeof( buff ) , stdin ) != NULL ) {
      char* pc ;
      for( pc = buff ; *pc != '¥0' && isdigit( *pc ) ; pc++ )
         /*nothing*/ ;
      if ( *pc == '¥n' || *pc == '¥0' ) {
         int x ;
         sscanf( buff , "%d" , &x ) ;
      }
   }
}

#define は、通常プログラム中の定数を分かりやすく使う場合に、使われる。

#define PI 3.14159265

ただし、#で始まる行は、C言語によって特殊で、C言語の解析の前に「プリプロセッサ」 でプログラムの内容を書き換える機能。

C言語のプログラムが機械語になるまで:

 C言語(#行を含む)
  ↓ プリプロセッサ
 C言語(#行なし)
  ↓コンパイル
 中間コード(printfなどの標準関数などが未解決)
  ↓
 リンク処理ライブラリ(標準関数などの中間コードをまとめたもの)
  ↓
 機械語

#define マクロでは、isdigit() の引数? C が、呼び出し部の *pc となり、 isdigit( *pc ) の部分は、以下のように書き換えられる。

((defineマクロ宣言))
#define isdigit(C) ((C)>='0' && (C)<='9')

((デファインマクロを使ったら))
isdigit(*pc)
↓ C ← *pc
((*pc)>='0' && (*pc)<='9')

ただし、#defineマクロは、プログラムのコンパイル前に、文字列として書き換えを行う。

// 例1
#define begin {
#define end }
void main() // まるでPASCALのような記述(^_^;
begin
   printf( "Hello¥n" ) ;
end         // 正しく動くよ
// 例2
#define ADD(X,Y) X + Y
#define MUL(X,Y) X * Y
void main() {
   printf( "%d" , MUL( 3 , ADD( 4 , 5 ) ) ) ;
}
// 3 * 4 + 5 に書き換えられるので、17になる。
// 3 * (4+5) の27にはならない。
// 普通の関数のように27の結果が欲しいなら、
// #define ADD(X,Y) ((X)+(Y))
// #define MUL(X,Y) ((X)*(Y))
// と書くべき。

開いた関数と閉じた関数

#defineマクロは、定義しておいた命令への書き換えなので、関数と同じように思うかもしれない。 ただし、機械語を生成する処理の前に書き換えるので、#define マクロで書き換えられる処理が 長い場合は、生成される機械語が大きくなる場合がある。 一方で、#defineマクロを使うと引数の受け渡しが無いので、 isdigit()のような簡単な処理の場合、 生成される機械語の処理が少し速い。

// 開いた関数FOO
#define FOO(X) Xを使った処理
void main() {
   int x ;

   FOO(x) ;  // xを使った処理
   FOO(x) ;  // xを使った処理
   // FOOの中身が長い場合、FOOの機械語が2個作られる。
}
// 閉じた関数foo
int foo(int z) {
   zを使った処理
   :
   :
}
void main() {
   int x ;
   foo(x) ; // z←x,fooを呼び出し
   foo(x) ; // z←x,fooを呼び出し
   // fooの機械語は1個だけ,引数の受け渡し処理が2個
}

#defineマクロのADD,MULの優先順位の問題が、"醜い"と思う人は、 C++で新しく導入された、"inline"関数を勉強すること。 #defineマクロを使わずに、開いた関数を簡単に記述できる。

システム

最新の投稿(電子情報)

最近の投稿(斉藤 徹)

アーカイブ

カテゴリー