前两天发现的宝藏网站:https://php.mengsec.com/

在github上面找到了源代码:https://github.com/Xyntax/1000php,可以在自己的服务器上面搭建

跟数据结构学习一样,每天跟着上面前辈们的案例进行审计,打基础+学习思路

1,BlueCMS v1.6 sp1 ad_js.php SQL注入漏洞

使用seay自动审计工具

可以看到第一条可能出现的漏洞点就是ad_js.php

我们跟进去看,

经过getone函数在数据库里面查询出结果并赋值给$ad变量,同时可以看到$ad_id没有包裹引号

getone函数是在数据库里面进行查询的函数

mysqli_fetch_array() 函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有。也就是从数据库中查询。

我们往上看$ad_id变量的输入位置是否有过滤。

可以看到对于GET方法输入的ad_id变量仅仅是使用trim函数去除了输入值两边的空格,此外就没有另外的过滤了,所以该点确实存在SQL注入漏洞。

真实环境下利用很简单,使用union联合注入即可出数据

修复方法:$ad_id = !empty($_GET['ad_id']) ? intval($_GET['ad_id']) : '';

将输入的数据强行转换成整型

2,Discuz!7.2/X1 第三方插件SQL注入及持久型XSS漏洞

这里分析SQL注入漏洞,插件是由Discuz!认证的(http://addons.discuz.com/workroom.php)第三方开发团队“潮流少年工作室 Teen Studio”出品的心情墙插件(http://www.discuz.net/forum.php?mod=viewthread&tid=1632898)

因为去找漏洞插件太麻烦了,我这里直接贴上漏洞源代码吧

elseif($action == 'edit_mood' && moodid) {

          //moodid未初始化,直接代入sql查询

	  $check = $db->result_first("SELECT * FROM {$tablepre}moodwall WHERE id='$moodid' AND uid='$discuz_uid'");

	  if(!$check || !$moodid) {

		  showmessage('moodwall:moodwall_inc_php_2', 'plugin.php?id=moodwall&action=user_mood');

	  }

	  $sql = "SELECT * FROM {$tablepre}moodwall WHERE id='$moodid'";

	  $query = $db->query($sql);

	  $moodlist_edit = array();

	  while($mood_edit = $db->fetch_array($query)) {

		  $moodlist_edit[] = $mood_edit;

	  }

  可以看到$moodid变量在单引号包裹下代入$sql语句进行查询

$sql = "SELECT * FROM {$tablepre}moodwall WHERE id='$moodid'";

  但是在这里漏洞的发现者也说了,需要网站magic_quotes_gpc=off,在magic_quotes_gpc=On的情况下,如果输入的数据有单引号(’)、双引号(”)、反斜线()与 NULL(NULL 字符)等字符都会被加上反斜线。

不过实际上还可以有宽字节注入等特殊情况对网站进行注入

3,ecshop SQL注射漏洞

因为没有详细的ecshop版本信息,所以同样不进行源码的下载,在wooyun大大的基础上直接进行分析

在include_libcommon.php中存在如下函数,get_package_info函数

function get_package_info($id)
{
global $ecs, $db,$_CFG;
$now = gmtime();
$sql = "SELECT act_id AS id, act_name AS package_name, goods_id , goods_name, start_time, end_time, act_desc, ext_info".
" FROM " . $GLOBALS['ecs']->table('goods_activity') .
" WHERE act_id='$id' AND act_type = " . GAT_PACKAGE;
  $package = $db->GetRow($sql);
  /* 将时间转成可阅读格式 */
  if ($package['start_time'] <= $now && $package['end_time'] >= $now)
  {
    $package['is_on_sale'] = "1";
   }
  else
  {
    $package['is_on_sale'] = "0";
  }
  $package['start_time'] = local_date('Y-m-d H:i', $package['start_time']);
  $package['end_time'] = local_date('Y-m-d H:i', $package['end_time']);
  $row = unserialize($package['ext_info']);
  unset($package['ext_info']);
  if ($row)
  {
    foreach ($row as $key=>$val)
    {
      $package[$key] = $val;
    }
  }
$sql = "SELECT pg.package_id, pg.goods_id, pg.goods_number, pg.admin_id, ".
    " g.goods_sn, g.goods_name, g.market_price, g.goods_thumb, g.is_real, ".
    " IFNULL(mp.user_price, g.shop_price * '$_SESSION[discount]') AS rank_price " .
    " FROM " . $GLOBALS['ecs']->table('package_goods') . " AS pg ".
    " LEFT JOIN ". $GLOBALS['ecs']->table('goods') . " AS g ".
    " ON g.goods_id = pg.goods_id ".
    " LEFT JOIN " . $GLOBALS['ecs']->table('member_price') . " AS mp ".
    "ON mp.goods_id = g.goods_id AND mp.user_rank = '$_SESSION[user_rank]' ".
    " WHERE pg.package_id = " . $id. " ".
    " ORDER BY pg.package_id, pg.goods_id";
  $goods_res = $GLOBALS['db']->getAll($sql);
  $market_price = 0;

  可以看到$sql语句里面代入了输入的$id,我们再定位谁调用了get_package_info函数,在系统的lib_order.php中。

function add_package_to_cart($package_id, $num = 1)
{
$GLOBALS['err']->clean();
  /* 取得礼包信息 */
  $package = get_package_info($package_id);
  if (empty($package))
  {
    $GLOBALS['err']->add($GLOBALS['_LANG']['goods_not_exists'], ERR_NOT_EXISTS);
    return false;
  }

  可以看到调用get_package_info函数赋值给了$package变量,而$package_id变量是传递给add_package_to_cart函数的,在该函数中也没有看到有对变量的过滤,寻找调用add_package_to_cart函数的文件

在flow.php中存在可控的输入源

$package = $json->decode($_POST['package_info']);
/* 如果是一步购物,先清空购物车 */
if ($_CFG['one_step_buy'] == '1')
{
     clear_cart();
  }
  /* 商品数量是否合法 */
  if (!is_numeric($package->number) || intval($package->number) <= 0)
  {
    $result['error'] = 1;
    $result['message'] = $_LANG['invalid_number'];
  }
  else
  {
  /* 添加到购物车 */
    if (add_package_to_cart($package->package_id, $package->number))
    {
      if ($_CFG['cart_confirm'] > 2)

  而在这里$package->package_id是我们可以控制的输入源,根据刚才函数调用的过程,对于我们的这个输入并没有其余的过滤,可知存在SQL注入漏洞

4,Discuz!漫游插件API本地包含漏洞

先上代码 manyou/api/class/MyBase.php

128: function parseRequest() {

131: $request = $_POST;

132: $module = $request['module'];

133: $method = $request['method'];

...

174: return $this->callback($module, $method, $params);

175: }

177: function callback($module, $method, $params) {

...

191: @include_once DISCUZ_ROOT.'./manyou/api/class/'.$module.'.php';

  在parseRequest函数里面,可以看到最后return调用了callback函数,并且传入的三个参数都是我们可以控制的输入,而callback函数里面使用include_once函数包含了当前路径下的传递的$module.php文件

PHP中文件包含函数有以下四种:

    require()

    require_once()

    include()

    include_once()

 include和require的区别在于include在包含的时候出现错误的时候,会抛出一个警告,然后程序继续运行,而require函数在出现错误的时候,会直接报错并且退出程序的执行

require_once和include_once这两个函数与前两个不同的地方在于,这两个函数只包含一次,适合于脚本执行期间同一个文件可能被包括一次以上的情况时,你想确保它只包含一次以避免函数重定义,变量重新赋值等问题

参考自:https://www.freebuf.com/articles/web/182280.html

在这里我们可以控制$module变量,但是这里是有限制的文件包含,因为在后面加上了.php的后缀,当我们想包含当前文件夹任意文件的时候,如果magic_quotes_gpc = Off php版本<5.3.4,我们可以使用%00截断的方式,当然还有其他很多的方式可以绕过这个限制,如果在这里还存在目录穿越漏洞的话,我们就可以包含服务器任意文件了,而不是限制在这个文件夹下。

5,PHPCMS通杀XSS

这里是一个反射型XSS漏洞,在我要报错功能页下,过滤不严格

http://**.**.**.**/error_report/error_report.php?title=1&contentid=1"><script>alert(/xss/)</script>

  反射型XSS漏洞比较容易通过扫描器黑盒直接发现,只需要将尖括号,单双引号等提交到web服务器,检查返回的HTML页面里面有没有保留原来的特殊字符即可判断。

在白盒审计中,我们只需要寻找带有参数输出函数,然后根据输出函数对输出内容回溯输入参数,观察有没有进行经过过滤

6,phpcms 2008 sp4 爆路径及任意文件删除漏洞

漏洞文件是corpandresize/config.inc.php

$tmp = $_COOKIE['tmp'];

define("TMP_PATH", $tmp);

  在cookie参数中获取tmp,同时定义TMP_PATH等于变量tmp的值

使用到TMP_PATH的位置是corpandresize/process.php

@unlink(TMP_PATH.'/'.$thumbfile);

  这里使用unlink函数删除文件,我们可以使用%00截断删除我们想要删除的任意文件

如在cookie中添加tmp=../index.php%00,按照上面的分析过程,就可以删除首页文件

7,phpcms2008本地文件包括及利用(执行任意SQL脚本)

漏洞文件存在于wap/index.php

代码如下:

<?php

include '../include/common.inc.php';

include './include/global.func.php';

$lang = include './include/lang.inc.php';

if(preg_match('/(mozilla|m3gate|winwap|openwave)/i', $_SERVER['HTTP_USER_AGENT']))

{

header('location:../');

}

wmlHeader($PHPCMS['sitename']);

$action = isset($action) && !empty($action) ? $action : 'index';

if($action)

{

include './include/'.$action.'.inc.php';

}

$html = CHARSET != 'utf-8' ? iconv(CHARSET, 'utf-8', $html) : $html;

echo str_replace('<br/>', "<br/>\n", $html);

wmlFooter();

?>

  可以看到在这一段代码里有:

$action = isset($action) && !empty($action) ? $action : 'index';
if($action)
{
include './include/'.$action.'.inc.php';
}

  isset() 函数用于检测变量是否已设置并且非 NULL。在这里即检测$action是否设置,同时检测$action是否为空,空的话就赋值为index,非空即传入值,接着就是包含传入的$action.inc.php文件,对于输入的$action没有进行过多的检测

可以包含存在sql语句的php文件,执行任意sql语句来对漏洞进行利用

例如包含目录include\fields\areaid 下任一文件,执行任意SQL脚本。

比如field_add.inc.php文件,我们只需要传入的$action=fields/areaid/field_add,field_add.inc.php文件代码为:

<?php

if(!$maxlength) $maxlength = 255;

$maxlength = min($maxlength, 255);

$sql = "ALTER TABLE `$tablename` ADD `$field` VARCHAR( $maxlength ) NOT NULL DEFAULT '$defaultvalue'";

$db->query($sql);

?>

  在这里我们只需要传入$tablename变量就可以执行$sql语句进行查询

最后的payload为:http://www.phpcms.cn/wap/index.php?action=../../include/fields/areaid/field_add&tablename=xx

8,Ecshop2.7.2持久型XSS(可获得管理员帐号)

可以看到当POST传输的数据extend_field_index没有任何的过滤就进入数据库进行更新了。

这里的输入是密码保护问题这一项,我们可以在密码保护问题里输入XSS,但是后台查看会员资料是不显示密码保护问题的,所以这里必须要网站后台添加了新的 “会员注册项”时,后台查看资料就会显示了,显示了之后就可以进行XSS攻击了。

这里不懂的地方是原漏洞作者导入外部js的时候,js文件里面的内容是Ajax:

Ajax.call('privilege.php?act=update','id=1&user_name=heihei&email=10001@**.**.**.**','',"POST","JSON");

而不是写入外部js盗取管理员cookie,以后明白了再补充这里。

乌云1000个PHP代码审计案例(1)的更多相关文章

  1. 渗透系统虚拟机----win7(渗透工具包)

    今天把自己用的win7渗透虚拟机和渗透工具脚本整合到一起备份传网盘了: D:\渗透工具包>dir 驱动器 D 中的卷是 DATA 卷的序列号是 0D74-084B D:\渗透工具包 的目录 // ...

  2. 74CMS3.0储存型XSS漏洞代码审计

    发现一个总结了乌云以前代码审计案例的宝藏网站:https://php.mengsec.com/ 希望自己能成为那个认真复现和学习前辈们思路的那个人,然后准备慢慢开始审计一些新的小型cms了 骑士cms ...

  3. 关于jquery插件模板的两个案例

    /** * jquery tips 提示插件 jquery.tips.js v0.1beta * * 使用方法 * $(selector).tips({ //selector 为jquery选择器 * ...

  4. 闲谈:乌云上那些 web-based 的 QQ 漏洞

    0×00 起始 昨日凌晨,看到爱尖刀团队发布了一条“腾讯客户端XSS,已第一时间提交至TSRC”的微博,心想,腾讯又出此类漏洞了.今日,由于有一位名叫“阿布”的同学将该漏洞发布到了乌云,引来不少争吵甚 ...

  5. [转]C#编程总结(三)线程同步

    本文转自:http://www.cnblogs.com/yank/p/3227324.html 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可 ...

  6. Android(java)学习笔记195:三重for循环的优化(Java面试题)

    1.首先我们看一段代码: for(int i=0;i<1000;i++){ for(int j=0;j<100;j++){ for(int k=0;k<10;k++){ testFu ...

  7. C#线程同步(转)

    线程同步 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应.对于服务器应用程序,多线程处理提供了用不 ...

  8. 几个例子弄懂JS 的setInterval的运行方式

    这篇文章主要介绍了js的setInterval方法的用法以及示例,非常的有用,这里推荐给小伙伴们. setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口 ...

  9. JSAP106

    JSAP106 一.clientX.clientY 点击位置距离当前body可视区域的x,y坐标 二.pageX.pageY 对于整个页面来说,包括了被卷去的body部分的长度 三.screenX.s ...

随机推荐

  1. 01 . Vue简介,原理,环境安装

    简介 vue是一个JavaMVVM库,是一套用于构建用户界面的渐进式框架,是初创项目的首选前端框架.它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计.它是轻量级的,它有很多独立的功能或库 ...

  2. 多级iframe中,获取元素相对于浏览器左上角的坐标(非当前frame)

    搜索了好多文章,都不是自己想要的,所以在此贴下自己的解决方案,做个笔记. 1.常规需求:获取当前元素距离左边.顶部的距离 1 var x = $(div).offset().left; 2 var y ...

  3. ASP.NET Core 中基于工厂的中间件激活

    IMiddlewareFactory/IMiddleware 是中间件激活的扩展点. UseMiddleware 扩展方法检查中间件的已注册类型是否实现 IMiddleware. 如果是,则使用在容器 ...

  4. 快速熟悉 Oracle AWR 报告解读

    目录 AWR报告简介 AWR报告结构 基本信息 Report Summary Main Report RAC statistics Wait Event Statistics 参考资料 本文面向没有太 ...

  5. centos7单独编译nbd内核模块

    前言 centos7默认内核没有带nbd的模块,可以通过下载跟当前版本匹配的内核源码,编译源码指定的模块,然后加载到系统 步骤 判断版本 [root@lab201 linux-3.10.0-957.e ...

  6. 用rsync备份一台linux服务器上的数据

    rsync是安装完linux后都会自带的,在机器上运行rsync命令看是否有安装即可 备份到远程服务器 这里介绍的rsync的用途是备份一台linux服务器上的数据到另外一台机器 环境 将需要备份机器 ...

  7. 对图片进行Base64转码和解码

    Base64代码 base64.c #include <stdlib.h> #include <stdio.h> #include <string.h> #incl ...

  8. 《.NET 5.0 背锅案》第7集-大结局:捉拿真凶 StackExchange.Redis.Extensions 归案

    第1集:验证 .NET 5.0 正式版 docker 镜像问题 第2集:码中的小窟窿,背后的大坑,发现重要嫌犯 EnyimMemcachedCore 第3集-剧情反转:EnyimMemcachedCo ...

  9. win10,ubuntu时间不对问题

    sudo apt-get install ntpdate sudo ntpdate time.windows.com   # ntp2.aliyun.com      然后将时间更新到硬件上: sud ...

  10. Vim常用按键