黑白名单的概念
在PHP中,"黑名单"(Blacklist)的概念通常用于过滤或禁止某些输入或操作,"白名单"(Whitelist)通常用于指定允许的内容,以提高安全性。黑白名单涵盖多个方面,包括输入数据、文件上传、函数调用等。
编写黑名单过滤SSRF漏洞
什么是SSRF漏洞
ssrf漏洞:SSRF(服务端请求伪造)服务器会根据用户提交的 URL 发送一个 HTTP 请求。使用用户指定的 URL,Web 应用可以获取图片或者文件资源等,例如百度识图功能。
如果没有对用户提交 URL 和远端服务器所返回的信息做合适的验证或过滤,就有可能存在“请求伪造”的缺陷。“请求伪造”,顾名思义,攻击者伪造正常的请求,以达到攻击的目的。
SSRF漏洞常见的利用方式
内网访问
使用http协议对内网的Web应用进行访问
伪协议读取文件
file:// — 访问本地文件系统
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
端口扫描
根据服务端的状态去探测开放了哪些端口
?url=http://127.0.0.1:80 ---》(远端服务器)
?url=http://127.0.0.1:3306
?url=dict://127.0.0.1:3306?url=http://10.10.10.1:22
简单的php代码编写过滤SSRF漏洞的黑名单(以picachu靶场为例)
源码
if(isset($_GET['url']) && $_GET['url'] != null){
//接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
$URL = $_GET['url'];
$CH = curl_init($URL);
curl_setopt($CH, CURLOPT_HEADER, FALSE);
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
$RES = curl_exec($CH);
curl_close($CH) ;
//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
echo $RES;
}
简单的过滤
if(isset($_GET['url']) && $_GET['url'] != null){
//接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
$URL = $_GET['url'];
$blacklist = array( 'file', 'ftp', 'zlib', 'data', 'glob', 'phar','ssh2','rar','ogg',
);
$parsedUrl = parse_url($URL);
if (isset($parsedUrl['scheme']) && in_array($parsedUrl['scheme'], $blacklist)) {
return false; // 伪协议在黑名单中,拒绝访问
}
// URL 安全,允许访问
return true;
$CH = curl_init($URL);
curl_setopt($CH, CURLOPT_HEADER, FALSE);
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
$RES = curl_exec($CH);
curl_close($CH) ;
//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
echo $RES;
}
编写白名单过滤SSRF漏洞
(以picachu靶场为例)
源码
if(isset($_GET['url']) && $_GET['url'] != null){
//接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
$URL = $_GET['url'];
$CH = curl_init($URL);
curl_setopt($CH, CURLOPT_HEADER, FALSE);
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
$RES = curl_exec($CH);
curl_close($CH) ;
//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
echo $RES;
}
白名单过滤:
利用explode函数将传递进来的URL通过切分.将其切分成两部分,其次将切分之后的第二部分限定为只有为时php的时候才能正常进行后续操作。
explode()
函数是 PHP 中用于将字符串分割成数组的函数。其具体作用是将一个字符串根据指定的分隔符拆分成多个子字符串,并将这些子字符串存储在一个数组中。这在处理一些由特定字符或字符串分隔的数据时非常有用。
简单的白名单过滤
if(isset($_GET['url']) && $_GET['url'] != null){
//接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
$URL = $_GET['url'];
$octet= explode(".",$URL);
if($octet[1]!="php"){
die("You can not do that!");
}
$CH = curl_init($URL);
curl_setopt($CH, CURLOPT_HEADER, FALSE);
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
$RES = curl_exec($CH);
curl_close($CH) ;
//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
echo $RES;
}