0.前言

本篇博文是对SQL手工注入进行基础知识的讲解,更多进阶知识请参考进阶篇(咕咕),文中有误之处,还请各位师傅指出来。学习本篇之前,请先确保以及掌握了以下知识:

  • 基本的SQL语句
  • HTTP的GET、POST请求,URL编码

文中所有例题选自sqlilab,可以先配置好一起边看边操作。因为虚拟机炸了,所以我自己搭建了一个简陋的平台,sqlilab可自行进行搭建练习,在后面的博客也会写一些关于sqlilab的wp。

1.准备工作

在开始SQL注入之前,我们首要需要了解SQL注入的原理,对于一个新安装好的MySql数据库,你至少会包含三个已经建立好的数据库分别是user、infomation_schema、performance_schema如下图所示

而SQL注入要干的,这些系统数据库中存储了MySql各个数据库的属性以及用户信息,我们要做的就是绕过过滤再来利用这些系统表进行查询。

了解了这个之后我们还要了解一点就是PHP的GET方法和POST方法传参的区别,如果使用GET方法,则会自动进行一次url解码,例如传入%23实际得到‘#’,而POST则会将数据原封不动的传输。下面我们开始进入正式的SQL注入阶段。

2.判断注入类型

一般的对于SQL的查询语句,有字符型和数值型查询,而这两者的区别就是是否有单引号,这决定了我们接下来应该如何构造SQL注入语句。

  判断方法有如下几种,

  1. +-数值,如果是数值型的,你可以尝试使用1+1,1+2,这样的语句,例如  看网页回显是否正确。
  2. and 1=1,and 1=2,直接在后面添加“1 and 1=1”和“1 and 1=2”(前面有个空格)来进行查询,若1=1回显正确而1=2回显错误则为数值型。
  3. 加‘#,在后面添加'#进行查询,若回显正确则表明为字符型。

除了上述几种方法还可以用其他方法进行判断,但原理都是构造SQL语句进行判断。

3.查列数

  通过上述方法知道了注入类型之后,我们就可以进行下一步的操作了,在这里我搭建了一个简易的存在字符型查询漏洞的页面,大家可以在本地搭建一下一边学习一边练习。

SQL代码如下:

 /*
Navicat MySQL Data Transfer Source Server : Mysql
Source Server Version : 50553
Source Host : localhost:3306
Source Database : test Target Server Type : MYSQL
Target Server Version : 50553
File Encoding : 65001 Date: 2019-09-18 23:17:53
*/ SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Table structure for secret_table
-- ----------------------------
DROP TABLE IF EXISTS `secret_table`;
CREATE TABLE `secret_table` (
`fl4g` varchar(32) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of secret_table
-- ----------------------------
INSERT INTO `secret_table` VALUES ('flag_is_here'); -- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`class` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`note` varchar(16) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('', 'zhangsan', 'nss', '', '');
INSERT INTO `student` VALUES ('', 'lisi', 'nss', '', '');
INSERT INTO `student` VALUES ('', 'wangwu', 'nss2', '', '');
INSERT INTO `student` VALUES ('', 'zhaoliu', 'nss2', '', '');
INSERT INTO `student` VALUES ('', 'sunqi', 'nss2', '', '');
INSERT INTO `student` VALUES ('', 'qianba', 'nss', '', '');
INSERT INTO `student` VALUES ('', 'liujiu', 'nss', '', '');

PHP代码如下:

 <?php
if (!empty($_POST['st'])) {
$conn = mysqli_connect("localhost","root","root","test");
$name = $_POST['name'];
$sql = "select * from student where name='".$name."';"; $result = mysqli_query($conn,$sql); echo "<table border='1'>
<tr>
<th>Id</th>
<th>Name</th>
<th>Class</th>
<th>Age</th>
<th>Note</th>
</tr>"; while($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $row['id'] . "</td>";
echo "<td>" . $row['name'] . "</td>";
echo "<td>" . $row['class'] . "</td>";
echo "<td>" . $row['age'] . "</td>";
echo "<td>" . $row['note'] . "</td>";
echo "</tr>";
}
echo "</table>"; mysqli_close($conn);
}
?> <!doctype html>
<!-- flag in SQL -->
<form action="" method="POST">
<input type="text" placeholder="Input A Name" name="name" value="">
<button type="submit" name="st" value='1'>提交</button>
</form>
<div style="position: absolute;bottom:0;width:100%;display:flex;flex-direction:column;">
<hr >
<a style="align-self:center;" href="./source.txt">Source</a>
</div>

通过上面的判断我们知道是字符型注入,现在我们需要查出这个数据表的列数来为后面的联合查询做铺垫。

当查询语句最后为where xx 的时候我们使用order by num;

当查询语句最后为limit xx的时候我们使用into @,@;

对于第一种order by num; num代表数值,语义就是以第几列进行排序,当列不存在是就会报错,我们就可以用二分的方法找出正确的列数。如下

对于lisi' order by 6#,lisi是数据库中的正常数据,单引号是为了闭合前面的select语句,#是mysql的单行注释语句,提示报错,换成5则正确,说明该表有5列。

对于limit xx的情况,我会在另一篇额外讲解。

4.确定字段位置

  当我们获得表的列数之后,就可以通过联合查询获得数据库的信息,但在此之前,我们还需要确定每个字段显示在网页上的位置,方便查看后面的数据。

  对于例题,我们知道列数为5之后,构造参数lisi' and 1=2 union select 1,2,3,4,5#即可知道每个字段的位置

  完整的SQL语句就是select * from student where name = ‘lisi’ and 1=2 union select 1,2,3,4,5#';

  and 1=2是为了避免一些只显示一行的页面过滤掉后面的联合查询的数据,所以让前面的查询条件永远为false,这里你不加这个,但为了方便我们都加上这个。

  union就是合并操作,完整语义就是使用union合并两个select的结果集,前者为空,后者结果为1,2,3,4,5,所以就会把这些结果合并然后显示到对应的字段。

5.获取数据库信息

  当列数和字段位置都知道后,我们就可以通过进一步的查询来获取数据库信息了,下面提供一些常用的数据库函数。

  database():查看当前数据库名称
  version():查看数据库版本信息
  user():返回当前数据库连接的用户
  char():将ASCII码转化成字符,用于分隔每个字段的内容

  使用方法就是将函数放在列的位置,例如提交lisi' and 1=2 union select 1,user(),database(),4,5#,结果如下:

  

  同样在最开始的时候我们提到了MySql的几个系统表,我们也可以从这些系统表中获取所有表名,列数,字段名等数据。

  例如查询所有表名,提交lisi' and 1=2 union select 1,2,3,4,TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='test,结果如下

  

  第五个位置也就是查询INFORMATION_SCHEMA.TABLES表中数据库为test的所有表名,MySql的表属性会存储在这个表中,因为后面还有一个单引号,所以这里右边就不要单引号了。

  这样我们就查询到了所有的表名,现在我们发现有个表叫做secret_table,猜测flag隐藏在其中,那么我们再来获取这个表所有的字段名。

  提交lisi' and 1=2 union select 1,2,3,4,COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='secret_table。结果如下

  

  语义同上,这里就不在做解释了,现在我们可以看到这个表有一个叫fl4g的字段,那flag就藏在这里没错了。

  接下来要做的就简单了,我们只需要提交lisi' and 1=2 union select 1,2,3,4,fl4g from secret_table#

  

  到此我们就找到了最终的flag。

6.总结

  SQL手工注入的基础知识道驰就结束了,推荐看完了这篇再去学习SQLmap的知识,可以很快上手也可以了解其本质的东西,不推荐直接学习SQLmap成为脚本小子。

  再梳理一遍上述知识,首先找到注入点,注入点一般是网页的某个提供查询的地方,然后确定是字符型还是数值型,当确定了注入类型之后,就是进行确定一些数据表的信息,方便后面的盲注,最后在从这些注入点得到我们想要的信息。

  对于CTF题目来说,一般不是让你盲注,会将代码给你,这时候注入点肯定是会有诸多的过滤,这时候我们就不能直接执行上述语句了,我们就需要构造一些语句去绕过执行,但最终要达到的效果和上述内容是一致的。

  对于更多的SQL注入知识,以及一些绕过技巧我将会在后面的进阶篇详解阐述。

SQL手工注入基础篇的更多相关文章

  1. SQL手工注入进阶篇

    0.前言 上一篇我们介绍了SQL手工注入的流程以及步骤,但在实际的安全问题以及CTF题目中,查询语句多种多样,而且是肯定会对用户的输入进行一个安全过滤的,而这些过滤并不一定是百分百安全的,如何利用一些 ...

  2. 【新手篇】搭建DCN漏洞靶机及简单的SQL手工注入

    很多新手小白入门后发现想要学好“网安”技术,除了掌握基础理论知识,更需要经常模拟不同的漏洞环境,但是如果使用外网服务器练习,会存在一定风险,因此能够搭建一个本地的模拟环境去测试漏洞将是一个不错的方案. ...

  3. 讲讲Linq to SQL映射(基础篇)

    讲讲Linq to SQL映射(基础篇) 这篇主要讲Linq to  SQL基于属性的映射.即映射数据库,映射表,映射列,映射关系,映射存储过程, 映射函数.然而创建这种映射有三种方法,他们分别是OR ...

  4. Kali学习笔记42:SQL手工注入(4)

    前三篇文章都是在讲发现SQL注入漏洞 如何查询得到所有的信息 那么另一条思路还未尝试过:能否修改数据? 例如这样: '; update users set user='yiqing' where us ...

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

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

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

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

  7. 小白日记39:kali渗透测试之Web渗透-SQL手工注入(一)-检测方法

    SQL手工注入(一) SQL注入:通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.[SQL注入原理] ##服务端程序将用户输入参数作为查询 ...

  8. (后端)sql手工注入语句&SQL手工注入大全(转)

    转自脚本之家: 看看下面的1.判断是否有注入;and 1=1;and 1=2 2.初步判断是否是mssql;and user>0 3.判断数据库系统;and (select count(*) f ...

  9. python辅助sql手工注入猜解数据库案例分析

    发现存在sql注入漏洞 简单一点可以直接用sqlmap工具暴库 但是如果想深入理解sql注入的原理,可以尝试手工注入,配合python脚本实现手工猜解数据库 首先hachbar开启 获取cms登录后的 ...

随机推荐

  1. https理论及实践

    什么是https协议? http协议以明文的方式在网络中传输,安全性难以保证,https在http协议的基础上加入SSL/TLS层.TLS是SSL协议的最新版本,SSL使用SSL数字证书在通信两端建立 ...

  2. 驰骋工作流引擎ccflow-流转自定义功能使用说明

    流转自定义功能使用说明 关键字: 驰骋工作流程快速开发平台 工作流程管理系统 工作流引擎 asp.net工作流引擎 java工作流引擎. 节点跳转 节点流转自定义 应用背景: 有一些流程在运行过程中是 ...

  3. (转载)分享常用的GoLang包工具

    分享常用的GoLang包工具 包名 链接地址 备注 Machinery异步队列 https://github.com/RichardKnop/machinery Mqtt通信 github.com/e ...

  4. 由于Microsoft\VisualStudio\14.0\Designer\ShadowCache导致的一个异常问题

    本文引用了一个DynamicDataDisplay和DynamicControl两个类库,本来使用的时候都时正常的,愉快的运行着. DynamicDataDisplay:这是一个用于动态数据可视化的W ...

  5. 线上调试工具 jvm-sandbox使用

    jvm-sandbox使用 1 快速安装 1.1 下载解压 # 下载最新版本的JVM-SANDBOX wget http://ompc.oss-cn-hangzhou.aliyuncs.com/jvm ...

  6. jQuery实现发送验证码30s倒计时,且刷新页面时有效

    在这里讲一讲这个案例的实现思路吧(个人见解)..核心思想:为防止页面刷新时倒计时失效的解决方案是:当每次刷新一次页面时都执行一个函数 即下面讲到的 setStyle() 函数.这个函数会根据当前的 c ...

  7. Python中绘制场景热力图

    我们在做诸如人群密集度等可视化的时候,可能会考虑使用热力图,在Python中能很方便地绘制热力图. 下面以识别图片中的行人,并绘制热力图为例进行讲解. 步骤1:首先识别图像中的人,得到bounding ...

  8. Storm 系列(五)—— Storm 编程模型详解

    一.简介 下图为 Strom 的运行流程图,在开发 Storm 流处理程序时,我们需要采用内置或自定义实现 spout(数据源) 和 bolt(处理单元),并通过 TopologyBuilder 将它 ...

  9. Flink的Job启动TaskManager端(源码分析)

    前面说到了  Flink的JobManager启动(源码分析)  启动了TaskManager 然后  Flink的Job启动JobManager端(源码分析)  说到JobManager会将转化得到 ...

  10. MyBatis_Generator (MBG)逆向工程的四种方式

    mybatis是目前很流行的持久层框架,其逆向工程更是大大缩减了我们的开发时间.有兴趣的可以看文档. 文档地址: http://www.mybatis.org/generator/index.html ...