secskill
  • Introduction
  • 1.web应用漏洞
    • 1.1 SQL注入漏洞
      • 1.1.1 type注入利用
      • 1.1.2 mothod注入利用
      • 1.1.3 按照效果注入利用
      • 1.1.4 order,limit和from后的注入
      • 1.10.1 sqlmap使用
    • 1.2 目录遍历漏洞
    • 1.3 跨站脚本漏洞
      • 1.3.10 flash xss
      • 1.3.11 Uxss
    • 1.4 未过滤HTML代码漏洞
    • 1.5 数据库运行出错
    • 1.6 Flash安全配置缺陷漏洞
    • 1.7 编辑器漏洞
      • 1.7.1 kindeditor编辑器漏洞
        • 1.7.1.1 kindeditor<=4.1.5文件上传漏洞
      • 1.7.2 fckeditor编辑器漏洞
        • 1.7.2.1 fckeditor<=2.6.4文件上传漏洞
    • 1.8 URL Redirect漏洞
    • 1.9 任意文件上传漏洞
    • 1.10 敏感信息泄露漏洞
    • 1.11 未加密登陆请求漏洞
    • 1.12 后台弱口令漏洞
    • 1.13 后台口令暴力破解漏洞
    • 1.14 跨站请求伪造漏洞
    • 1.15 Unicode 编码转换漏洞
    • 1.16 Possible .Net Error Message
    • 1.17 发生内部错误漏洞
    • 1.18 旁站攻击漏洞
    • 1.19 后台登录页面绕过
    • 1.20 Possible PHP Error Message
    • 1.21 UrlPath Pollution
    • 1.22 File Operation-Web.xml漏洞
    • 1.23 短文件名泄漏漏洞
    • 1.24 OS注入漏洞
    • 1.25 SOAP注入漏洞
    • 1.26 SMTP注入漏洞
    • 1.27 LDAP注入漏洞
    • 1.28 命令执行漏洞
    • 1.29 HTTP消息头注入漏洞
    • 1.30 验证机制缺陷漏洞
    • 1.31 越权漏洞
    • 1.31 服务端请求伪造漏洞
    • 1.32 xxe漏洞
    • 1.33 逻辑漏洞
    • 1.34 支付漏洞
      • 1.34.1 支付漏洞
    • 1.35 cors漏洞
      • 1.35.1 cors
    • 1.36 jsonp漏洞
    • 1.37 点击劫持漏洞
    • 1.38 框架注入漏洞
    • 1.39 文件包含漏洞
    • 1.40 CRLF注入漏洞
    • 1.41 SSTI漏洞
  • 2.中间件漏洞
    • 2.1 IIS
      • 2.1.1 CVE-2017-7269
    • 2.2 Apache
    • 2.3 Axis2
    • 2.4 lighttpd
    • 2.5 Tomcat
      • 2.5.1 CVE-2017-12615
    • 2.6 Nginx
    • 2.7 WebLogic
    • 2.8 JBoss
    • 2.9 Websphere
    • 2.10 Struct2
    • 2.11 XAMMP
    • 2.12 LAMPP
    • 2.13 FastCGI
    • 2.14 PHPCGI
    • 2.15 JOnAS
    • 2.16 Joomla
      • 2.16.1 CVE-2017-8917
    • 2.17 Padding oracle
    • 2.18 Jenkins
      • 2.18.1 CVE-2019-1003000
      • 2.18.2 CVE-2017-1000353
    • 2.18 Drupal
      • 2.18.1 CVE-2019-6340l
    • 2.19 PHPGD
      • 2.19.1 CVE-2019-6977
    • 2.20 PhpMyAdmin
      • 2.20.1 CVE-2016-5734
      • 2.20.2 反序列化漏洞
      • 2.20.3 CVE-2018-12613
    • 2.21 PHP
      • 2.21.1 extract
      • 2.21.2 strcmp
      • 2.21.3 urldecode
      • 2.21.4 md5
      • 2.21.5 strpos
      • 2.21.6 is_numeric
      • 2.21.7 sha
      • 2.21.7 ereg
      • 2.21.8 creat
  • 3.系统漏洞
    • 3.1 DNS域传送漏洞
    • 3.2 SSH Services Port 22 Enabled
    • 3.3 NetBIOS Services Port 139 Enabled
    • 3.4 OpenSSL 漏洞
    • 3.5 docker remote API漏洞
    • 3.6 Samba远程代码执行漏洞
    • 3.7 Windows系统漏洞
      • 3.7.1 ms17-010
      • 3.7.2 ms08-067
      • 3.7.3 ms16-075
      • 3.7.4 CVE-2017-0213
      • 3.7.5 ms16-135
      • 3.7.6 CVE-2018-8120
      • 3.7.7 CVE-2018-0824
    • 3.8 linux系统漏洞
      • 3.8.1 ubuntu
        • 3.8.1.1 CVE-2015-1328
        • 3.8.1.2 CVE-2017-16995
    • 3.9 openssh漏洞
      • 3.9.1 cve-2016-6515
  • 4.网络漏洞
    • 4.1 ARP欺骗嗅探漏洞
    • 4.2 反弹shell的N种姿势
    • 4.3 DNS欺骗
  • 5.cms漏洞
    • 5.1 08cms
    • 5.2 74cms
    • 5.3 Appcms
    • 5.4 Aspcms
    • 5.5 Bluecms
    • 5.6 Cscms
    • 5.7 Dedecms
    • 5.8 Discuz
      • 5.8.1 Discuz任意文件删除
    • 5.9 Dkcms
    • 5.10 Ecshop
    • 5.11 Finecms
    • 5.12 Fscms
    • 5.13 Jeecms
    • 5.14 Ibcms
    • 5.15 Maccms
    • 5.16 Php168
    • 5.17 Phpcms
    • 5.18 Phpmywind
    • 5.19 Phpwind
    • 5.20 Phpweb
    • 5.21 Qibocms
    • 5.22 Seacms
    • 5.23 Shopex
    • 5.24 Thinkphp
      • 5.24.1 SQL
      • 5.24.2 RCE
      • 5.24.3 RCE2
    • 5.25 Typecho
    • 5.26 Wordpress
      • 5.26.1 Wordpress Plugin_sql
    • 5.27 Xycms
    • 5.28 Zabbix
    • 5.29 Zblog
    • 5.30 Zzcms
Powered by GitBook
On this page
  • is_numeric()
  • 示例代码
  • PHPYun二次注入.
  • php比较

Was this helpful?

  1. 2.中间件漏洞
  2. 2.21 PHP

2.21.6 is_numeric

is_numeric()

is_numeric()函数语法:

is_numeric — 检测变量是否为数字或数字字符串 

bool is_numeric( mixed $var)

如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE。

示例代码

<?php
$a= '23333333abc';
if(is_numeric($a)){
    echo "6";
}else{
    echo "flase";
}
if($a>1000){
    echo "666";
}

?>

因为在php中如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行,所以就绕过了is_numeric()函数。

我们下面来看一下is_numeric()函数造成的sql注入问题。

示例代码如下:

<?php

$conn = mysql_connect('127.0.0.1','root','root'); 

mysql_select_db('fendo',$conn);

$user = addslashes($_GET['user']);

$flag = is_numeric ($user) ? true : false;

if($flag){

$sql = "SELECT id,username,password FROM user WHERE username=$user"; 

$res = mysql_query($sql);

if($res){ 

while($row = mysql_fetch_array($res)){

var_dump($row);

}

}else{

echo '----------数据库没有符合此条件的用户记录----------';

echo '<br />';

}

}else

{

var_dump ($flag);

}

?>

这个代码的逻辑其实很简单,接收user的值,判断是否为数字,若为数字,则带入到数据库进行查询,否则不查询。

那么我们再来看下数据库的结构:

可是我们的username是一个字符型,但是参数又只能为数字型,理论上来说是没有办法进行注入的 。

但是在is_numeric()函数中,不仅仅是十进制的数字,如:

<?php
echo is_numeric(233333);       # 1
echo is_numeric('233333');  # 1
echo is_numeric(0x233333);  # 1
echo is_numeric('0x233333');   # 1
echo is_numeric('233333abc');  # 0
?>

我们可以看到,它是支持是hex编码的,同样,mysql也支持hex编码,所以这里就就导致我们可以使用hex进行注入,如:

admin=0x61646d696e

则:

我们来看一个二次注入的例子:

示例代码:

<?php


$conn = mysql_connect('127.0.0.1','root','root'); 

mysql_select_db('dvwa',$conn);

$user = addslashes($_GET['user']);

$flag = is_numeric ($user) ? true : false;

if($flag)

{

//保存最大user_id

$max_id;

//保存导出的playload

$playload;

//查出数据库中最大的user_id

$query_max_id = "select max(user_id) from users";

$res = mysql_query($query_max_id);

if($res)

{ 

$rows = mysql_fetch_array($res);

$max_id = $rows['user_id'];

//echo $max_id;

echo '----------max_id查询成功----------';

}

else

{

echo '----------max_id查询失败----------';

}

//更新最大user_id行的用户名

$gx = "update users set user=$user where user_id=$max_id";

$res = mysql_query($gx);

if($res)

{ 

echo '----------用户数据更新成功----------';

echo '----------插入十六进制成功----------';

}

else

{

echo '----------用户数据更新失败----------';

echo '----------插入十六进制未成功----------';

}

//导出插入的playload

$playload = "SELECT user FROM users WHERE user_id=$max_id";

$res = mysql_query($playload);

if($res)

{ 

$rows = mysql_fetch_array($res);

$playload = $rows['user'];

echo '----------playload成功导出----------';

}

else

{

echo '----------playload导出失败----------';

}

//将导出的playload拼接到select语句中执行

$play = "SELECT user_id,user,password FROM users WHERE user=$playload"; 

$res = mysql_query($play);

if($res)

{ 

$row = mysql_fetch_array($res);

var_dump($row);

echo '----------注入已成功----------';

}

else
{

echo '----------输入数据不是数字或者数字字符串----------';

}

?>

这段代码实现对max(user_id)行的用户名实现十六进制playload的写入,然后,通过select语句又将写入的十六进制playload查询出来,从而实现了二次注入。

PHPYun二次注入.

问题代码如下:

# /app/public/action.class.php
function FormatValues($Values){
    $ValuesStr='';
    foreach($Values as $k=>$v){
        if(is_numeric($k)){
            $ValuesStr.=','.$v;
        }else{
            if(is_numeric($v)){
                $ValuesStr.=',`'.$k.'`='.$v;
            }else{
                $ValuesStr.=',`'.$k.'`=\''.$v.'\'';
            }
        }
    }
    return substr($ValuesStr,1);
}

多个数据表模型都用到了这个函数,基本都是Update操作。现在的思路是利用接口将恶意代码Update进数据库,再通过其他接口,从数据库读恶意数据,在再次存到数据库的时候,进行注入

从DB层(friend.model.php)可以找到GetFriendInfo():

function GetFriendInfo($Where=array(),$Options=array()){
    $WhereStr=$this->FormatWhere($Where);
    $FormatOptions=$this->FormatOptions($Options);
    $row=$this->DB_select_once('friend_info',$WhereStr,$FormatOptions['field']);
    if($row['pic']==''){
        $row['pic']=$row['pic_big']=$this->config['sy_weburl'].'/'.$this->config['sy_friend_icon'];
    }else{
        $row['pic'] = str_replace("../",$this->config['sy_weburl']."/",$row['pic']);
        $row['pic_big'] = str_replace("../",$this->config['sy_weburl']."/",$row['pic_big']);
    }
    return $row;
}

跟进member_log函数:

function member_log($content,$opera='',$type=''){
    if($_COOKIE['uid']){
        $value="`uid`='".(int)$_COOKIE['uid']."',";
        $value.="`usertype`='".(int)$_COOKIE['usertype']."',";
        $value.="`content`='".$content."',";
        $value.="`opera`='".$opera."',";
        $value.="`type`='".$type."',";
        $value.="`ip`='".fun_ip_get()."',";
        $value.="`ctime`='".time()."'";
        $this->DB_insert_once("member_log",$value);
    }
}

跟进DB_insert_once函数:

function DB_insert_once($tablename, $value){
    $SQL = "INSERT INTO `" . $this->def . $tablename . "` SET ".$value;
    $this->db->query("set sql_mode=''");
    $this->db->query($SQL);
    $nid= $this->db->insert_id();
    return $nid;
}
INSERT INTO `phpyun_atn` SET `uid`='2',`sc_uid`='1',`usertype`='1',`sc_usertype`='1',`time`='1444726415'
INSERT INTO `phpyun_friend_state` SET `uid`='2',`content`='关注了<a href=\"http://127.0.0.1/phpyun0625/ask/index.php?c=friend&uid=1\">\'\"</a>',`type`='2',`ctime`='1444726415'
INSERT INTO `phpyun_sysmsg` SET `fa_uid`='1',`content`='用户 bb2 关注了你!',`username`='bb1',`ctime`='1444726415'
INSERT INTO `phpyun_member_log` SET `uid`='2',`usertype`='1',`content`='关注了'"',`opera`='',`type`='',`ip`='127.0.0.1',`ctime`='1444726415'
1

php比较

php在转码时会把16进制转化为十进制

<?php
error_reporting(0);
function noother_says_correct($temp)
{
$flag = 'flag{test}';
$one = ord('1'); //ord — 返回字符的 ASCII 码值
$nine = ord('9'); //ord — 返回字符的 ASCII 码值
$number = '3735929054';
// Check all the input characters!
for ($i = 0; $i < strlen($number); $i++)
{
// Disallow all the digits!
$digit = ord($temp{$i});
if ( ($digit >= $one) && ($digit <= $nine) )
{
// Aha, digit not allowed!
return "flase";
}
}
if($number == $temp)
return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp);
?>

首先分析代码,函数要求变量$temp不能存在1~9之间的数字, 最后,又要求$temp=3735929054;利用php在转码时会把16进制转化为十进制.于是把 3735929054转换成16进制为0xdeadc0de,记得带上0x; 构造payload

?password=0xdeadc0de

Previous2.21.5 strposNext2.21.7 sha

Last updated 6 years ago

Was this helpful?

先尝试通过hex编码写入测试信息,如图所示 。刷新后,成功写入!

测试二次注入的接口,在DB_insert_once()打印SQL语句 POST: id=2 返回结果如下:

http://127.0.0.1/phpyun0625/friend/index.php?c=info
http://127.0.0.1/phpyun0625/ask/index.php?c=friend&a=atnuser