Practical attack and defense of one-time stored XSS

王林
Release: 2019-12-03 17:42:52
forward
3517 people have browsed it

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:

Copy after login

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:

Practical attack and defense of one-time stored XSS

Write an xss script generated by the platform:

Copy after login

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

Practical attack and defense of one-time stored XSS

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:

Copy after login

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:

Practical attack and defense of one-time stored XSS

After submission, the system will automatically refresh the page and a pop-up box will appear:

Practical attack and defense of one-time stored XSS

After clicking OK, you will find that the message content and the message sender are both empty.

Practical attack and defense of one-time stored XSS

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.

Practical attack and defense of one-time stored XSS

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

Copy after login

As for the principle , because the js script is in the form of 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)

Practical attack and defense of one-time stored XSS

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']);//昵称
Copy after login

上面这个str_replace()函数的意思是把script替换为空。

可以看到,script被替换为空,弹框失败。

Practical attack and defense of one-time stored XSS

那么黑客该如何继续进行攻击呢?

答案是:大小写绕过

Copy after login

Practical attack and defense of one-time stored XSS

因为js是不区分大小写的,所以我们的大小写不影响脚本的执行。

成功弹框!

Practical attack and defense of one-time stored XSS

0×02、使用str_ireplace()函数进行不区分大小写地过滤script关键字

作为一名优秀的开发,发现了问题当然要及时改正,不区分大小写不就行了嘛。

后端代码修正如下:

$nickname = str_ireplace("script", "", @$_POST['nickname']);//昵称
Copy after login

str_ireplace()函数类似于上面的str_replace(),但是它不区分大小写。

那么,黑客该如何绕过?

答案是:双写script

alert(1)
Copy after login

Practical attack and defense of one-time stored XSS

原理就是str_ireplace()函数只找出了中间的script关键字,前面的S和后面的cript组合在一起,构成了新的Script关键字。

弹框成功!

Practical attack and defense of one-time stored XSS

0×03、使用preg_replace()函数进行正则表达式过滤script关键字

$nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @$_POST['nickname']);//昵称
Copy after login

显然,弹框失败。

Practical attack and defense of one-time stored XSS

攻击者如何再一次绕过?

答案是:用img标签的oneerror属性

Practical attack and defense of one-time stored XSS
Copy after login

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);//昵称
Copy after login

那么,攻击者该怎么办呢?

答案是:编码绕过

a
Copy after login

当点击页面上的超链接时,会弹框。

Practical attack and defense of one-time stored XSS

但是为什么呢?

这种编码方式为字符编码

字符编码:十进制、十六进制ASCII码或unicode 字符编码,样式为“&#数值;”, 例如“j”可以编码为“j”或“j ”

上述代码解码之后如下:

a
Copy after login

你能明显感觉到限制:由于使用到了a标签,所以只有点击时,才会弹框。

作为一个大黑阔,我们当然是不满意的,能不能让所有进入这个页面的人都弹框?

当然可以了:用iframe标签编码