ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

クロスサイト”プリンティング”の応用-Webからローカルにファイルを書き出す

2008-01-15 20:08:09 | Weblog

 昨日のクロスサイト”プリンティング”のテクニック、本当ならWebアプリの世界が広がる気が。。で、調べてみるね!と書いたこと報告。

 たしかに、IEで、Formタグに書いた内容とファイル名で、ローカルにファイルを書き出せました
(もちろん、セキュリティレベルを一切変えずに!です)。

 その方法と、コードを説明しますね。




■方法の概要

・ローカルに、Socketサーバーで、ポート5050番で、以下の機能を持った
 サービスを立ち上げる
  ・POST形式で受け取った内容をもとに、引数
     fnameで指定されたファイル名で、
     fdataの内容を書き出す

・フォームタグでmethod=POST action="http://127.0.0.1:5050" を指定、
 このフォームタグ内に、fname、fdataを用意しておく。
 このファイルを保存し、ローカル以外の別のサーバーに置く

・上記ファイルにアクセスし、fname、fdataをいれ、Submitボタンをクリックすると、
 ポート5050のサービスが実行され、fnameに指定したファイル名で、
 fdataの内容が書き出される。




■ソース

 エラー処理とか、日本語化とか、一切抜いて、簡単に書いてあります。

●別のサーバーに置いたHTMLファイル
 これなのですが、中身は、こんなかんじ

<html>
<head><title>クロスサイトプリンティング応用テスト</title></head>
<body>
<form method="post" action="http://127.0.0.1:5050">
<input type=text name=fname><BR>
<textarea name=fdata>
</textarea><BR>
<input type=submit value="実行"><BR>
</form>
</body>

(上記< > ¥は、本当は半角です)




●ローカルに置くソース
 ローカルにおくプログラムは、起動するプログラムと、1セッション分(1スレッド分)のプログラムの2つに分かれます。
 だいたいの書き方は、ここと同じです。

<<1.起動するプログラム>>

 とくに、起動するプログラムに関して言うと、まったくおなじです。
 以下のプログラムをtest.javaとします
import java.io.*;
import java.net.*;

public class test {
	/*
	 * 	メイン処理(呼び出し元)
	 */
	public static void main(String[] args) 
	{
		try
		{
			// サーバーを生成
			ServerSocket serverSocket = new ServerSocket(5050);
			while(true)
			{			
				// ソケットを生成
				Socket socket = serverSocket.accept();
				TestThread tr1 = new TestThread();
				tr1.setSocket(socket);
				tr1.start();
			}	

		}
		catch(Exception e)
		{
			e.printStackTrace();
		}	
	}

}

(上記< > ¥は、本当は半角)

<<2.スレッドのプログラム>>

 そいつは、こんなかんじ。「処理」のところがちがっていてて、ファイル保存します。
 以下のプログラムをTestThread.javaとします
import java.io.*;
import java.net.*;

public class TestThread extends Thread {
	Socket socket = null;

 	
  	public void setSocket(Socket socket)
  	{
  		this.socket	=	socket;
  	}
  	
	/*
	 * 処理部分
	 */
	public void run()
	{
		if ( socket	==	null )
		{
			return;
		}

		try
		{
			//--------------------
			//受信する
			//--------------------
			InputStream	is1	
				=socket.getInputStream();
			InputStreamReader	ir1
				= new InputStreamReader(is1);
			BufferedReader		br1	= new BufferedReader(ir1);

			//	よみこめるまでまってる
			while(is1.available()	==	0);
		
			
			//	1行読み込む
			int	c;
			String  header = "";
			while((c = br1.read()) != -1 )
			{
				header = header + (char)c;
				if (( header.indexOf("¥n¥n") > 0 ) ||
					( header.indexOf("¥r¥n¥r¥n") > 0 ) )
				{
					break;
				}
			}
				
			//	データ部分の長さを取得
			String[] line = header.split("¥n");
			int datalen = -1;
			for(int i = 0 ; i < line.length; i ++ )
			{
				if ( line[i].indexOf("Content-Length:")	>=	0 )
				{
					String lenbuf = 
                                                  line[i].substring("Content-Length:".length());
					try{
						datalen = Integer.parseInt(lenbuf.trim());
					}catch(Exception e){
					}
				}	
			}

			//	データがある場合、データ取得
			String data = "";
			if ( datalen	>	0 )
			{
				char[] datachar = new char[datalen];
				br1.read(datachar);
				StringBuffer databuf = new StringBuffer();
				databuf.append(datachar);
				data	=	databuf.toString();
			}

			//--------------------
			//	処理
			//--------------------
			//	データがある場合、ファイル名、データ取得
			String fname="";
			String fdata= "";
			if ( data.length()	>	0 )
			{
				// 改行をカットする
				data=data.replaceAll("¥r","");
				data=data.replaceAll("¥n","");

				//	ファイル名とデータきりだし
				String[] dline = data.split("&");
				for(int i = 0 ; i < dline.length ; i ++ )
				{
					String[] cell = dline[i].split("=");
					if ( cell[0].compareTo("fname")	==	0 )
					{
						fname	=	cell[1];
					}
					else if ( cell[0].compareTo("fdata")	==	0 )
					{
						fdata	=	cell[1];
					}
				}					
			}

			//	ファイル書き出し
			if (fname.length()	>	0 )
			{
				try
				{
					File f = new File(fname);
					FileOutputStream fo = new FileOutputStream(f);
					fo.write(fdata.getBytes());
					fo.close();			
				}
				catch(Exception e)
				{
				}			
			}

			//--------------------
			//送信する
			//--------------------
			OutputStreamWriter	ow1
				= new OutputStreamWriter(socket.getOutputStream());
			BufferedWriter bw1 = new BufferedWriter(ow1);

			bw1.write("OK");
			bw1.flush();
			
			
			//	クローズ
			bw1.close();
			ow1.close();
			br1.close();
			ir1.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}

}

(上記< > ¥は、本当は半角)




■うごかしかた

で、2つのjavaプログラムをコンパイルして、同じフォルダにおいて、
testのクラスを実行すれば
(Eclipseだったら、同じプロジェクトに入れて、testのクラスを指定して
 Runすれば)、
プログラムが開始します(しますけど、その時点では、何もおきません、見かけ上)

で、あらかじめ、どっかのサーバーにおいておいた、HTMLファイルをIEで開いて、
上にファイル名、下に書き出しデータを適当に入れて、実行ボタンを
クリックすると、ファイル書き出しします。

だだし、話を簡単にするため、コード変換とかはしてないので、日本語を入れると
日本語では書き出されませんが・・・


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

植物警備隊

2008-01-15 10:54:34 | Weblog

 前に書いた、植物による防犯装置ができるってこと?と、「ナノチューブでできた極小ラジオの開発に成功」軍事の市街戦に使われたら・・ を、あわせると、植物(農作物)を警備する&植物で警備することが出来そうな気がする・・

こんなかんじ。
・農作物や植物の生体電位をはかる
  →はかることは出来るようだ。
・その電位情報を、ナノチューブとまではいかないが、小型の発信機で、近くの中継局に送り、
・中継局は、電気信号に変えて、インターネットで処理設備までおくる。
・そーすると、動物によって植物(農作物)が食べられたとか、踏みつけられたりしたら、
 電位が変わりそうだ・・
・変わった電位情報が、インターネットを経由して届いてくるから、特徴検出して
 (電位変化に特徴がある?)食べられたり、踏まれたようであれば、警告を発する。

こーいうシステムなら、作物に付けておいて、いのししとかきたら、警告を発してくれる(小型の発信機はラジオになっていて、大きな音を鳴らしたりするものいいとおもうし、場所が分かるので、ロボットが軽微に言ってもいい)ので、農作物あらし対策にいいし、家の窓辺に人が入ってきたら、この装置??によって、警告を発してくれる。

 ・・・って、どお?


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする