学习笔记:入门SQL靶场注入(1) 前言由于专业的问题导致我最近一直在忙学习的事从而疏忽了对网安的学习但好在暑假给了我一个新的机会重新开始所以我干脆重新找一个靶场把网安的基础知识重新在串一遍。引导关——报错注入1.报错注入原理通过输入特殊符号数据库在处理这些特殊符号时产生语法错误并且将错误信息返回给前端攻击者据此获取敏感信息。注意当数据库报错时通常意味着存在SQL注入风险因为执行了预期以外的内容。然后请看一个报错样例由此我们可以发现后端执行了的SQL语句select * from users where username {输入内容}且报错信息在小明处。2.SQL注入判断当然光凭一个报错信息很难判断是否存在SQL注入那么我们可以用一个很简单的方法分别注入小明‘ and 11 #和小明’ and 12 #。and的作用只有连接的所有条件都为TRUE真时整个表达式结果才为TRUE只要有一个条件为FALSE假结果就为FALSE。当两个语句返回的结果不同则说明我们的输入被当作SQL代码执行而不是字符串证明此处存在SQL注入。1-3 union select 语句MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合并去除重复的行.说明UNION 操作符必须由两个或多个 SELECT 语句组成每个 SELECT 语句的列数和对应位置的数据类型必须相同。这里有一个要点就是union select 后面列要和前面的列要一样。例如select * from users where username {输入内容} union select xxxx;1-4 如何判断select是几列上面已经提到了UNION的使用须知那么这关我们介绍另一个非常重要的语法order byMySQL 的 ORDER BY排序 子句可以让你按照一个或多个列的值进行升序ASC或降序DESC排序。语法示例select * from users order by 1(列);其中order by 1表示按照第1列排序。你也可以是 order by 2、order by 3以此类推。以及最重要的一点如果 order by 后写的数字超过了当前 select 能查出来的列数MySQL 会报错而就是说order by 的列数不能超出 select 查出来的列数。想必你已经知道为啥要讲这个语法了我们可以利用这个特性来「猜」当前 select 语句到底查出了多少列然后我们通常使用二分法来进行测试首先我们输入 order by 4 #如果没报错就输入 order by 8 #如果报错则在这个4到8区间进行测试直至报错。1-5 union select 如何判断显示位置在上文我们已经讲过了union selectd的作用在得知库的所用列之后我们可以通过注入获取敏感信息例如一个库有四个字段那么我们可以这样构建-1 union select 1,2,3,4 #。然后根据爆出来的信息获取我们想要的东西。1-6 查询数据库看到这里想必你已经能查询一些简单的内容这里我们将介绍一个新的语法——DATABASE()它的作用是返回当前数据库名。当然如果你在做靶场就没关系如果是在做真实的渗透测试一定要注意度做到这一步就不要继续获取数据了所以结合上一步的union select我们可以构建一个新的SQL语句-1 union select 1,DATABASE(),3,4 #然后我们就可以获取这一列的数据库返回的信息。ps除了这个你还可以使用其他的函数你可以在这个网站进行查询和学习MySQL 函数 | 菜鸟教程1-7 information_schema这个数据库是MYSQL5.0以上一个系统自带的数据库。information_schema数据库里包含了这几张表schemata、tables、columns。这三张表依次分别存放着字段(schema_name)、(table_name、table_schema)、(table_schema、table_name、column_name)我们简单用一个图表示换句话说,数据库里的所有的表字段都会在这里保存一份。1-8 查询当前数据库的所有表这里我们继续引入一个新的函数——group_concat它是 MySQL 中用于将分组内多行数据连接成一个字符串的聚合函数。可以一次性查询所有的被他包裹的内容。结合union select我们可以构建出以下语句-1 union select 1,group_concat(TABLE_NAME),3,4 from information_schema.tables where TABLE_SCHEMAmydb #此时我们就可以查出指定数据库的所有表。1-9 查询当前数据库某张表里的字段有哪些首先我们要继续使用上面的方式此处我们要使用到information_schema里columns这张表。它包含了数据库里所有的列。其中table_schema、table_name、column_name这三个字段分别代表库、表、字段。如果我们想在columns 表里查询 table_schemamydb 并且 table_nameusers 的数据并且只要显示 column_name。那么我们只需要构建如下语句select column_name from columns where table_schemamydb and table_nameusers #如果要使用union select 以及 group_concat则是构建-1 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schemamydb and table_nameusers #1-10 查询数据库的数据假设我们已经拿到了一个名为mydb数据库里的users表字段那么我们该如何进一步获取它的数据呢例如我们可以查询id1的用户名和密码select username,password from users where id 1如果我们在注入时加上 union select可以这样写-1 union select username,password,3,4 from users where id 1 #当然还有一个小技巧可以一次获取所有数据 —— 使用 group_concat-1 union select 1,group_concat(name),3,4 from books #如果想查询其他表也是一样的。总结知识点回顾第1关报错注入原理通过输入特殊符号如让数据库报错判断是否存在SQL注入漏洞。报错说明执行了预期以外的内容。第2关SQL注入判断实践使用小明 and 11 #和小明 and 12 #测试通过页面返回差异判断注入点是否存在。第3关UNION 操作符UNION 用于连接多个 SELECT 语句。要点union select 后面的列数和类型必须与前面一致。第4关ORDER BY 判断列数利用order by n判断 SELECT 的列数。当 n 超过实际列数时会报错据此确定列数。第5关探测显示位使用-1 union select 1,2,3,4 #探测页面显示哪些字段位置主查询用 -1 使其无结果。第6关查询数据库名使用DATABASE()函数获取当前数据库名称。示例-1 union select 1,DATABASE(),3,4 #第7关information_schemaMySQL 5.0 自带的系统库包含schemata库名、tables表名、columns字段名三张关键表。第8关查询所有表名从information_schema.tables查询表名配合group_concat()一次显示所有表。第9关查询所有字段名从information_schema.columns查询字段名指定 table_schema 和 table_name 筛选目标表。第10关获取数据利用已知的表名和字段名通过 union select 直接获取目标数据。如-1 union select 1,username,password,4 from users #SQL注入完整流程总结判断注入点单引号报错 / and 11 与 and 12 差异确定列数order by 二分法探测显示位union select 1,2,3...获取数据库名DATABASE()获取表名information_schema.tables获取字段名information_schema.columns获取数据union select 目标字段 from 目标表