ctfshow学习记录-web入门(php特性99-108)

目录

    • web99
    • web100
    • web101
    • web102
    • web103
    • web104
    • web105
    • web106
    • web107
    • web108


web99

解答:题目解析一下:

$allow = array(); //设置为数组
for ($i=36; $i < 0x36d; $i++) {   
    array_push($allow, rand(1,$i)); //向数组里面插入随机数
} 

#判断n是否传参,判断$allow数组中是否存在$_GET['n']的值。
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){   //in_array()函数有漏洞 没有设置第三个参数 就可以形成自动转换
    file_put_contents($_GET['n'], $_POST['content']); 
} 

in_array是弱类型比较,所以可以用数字+".php"的方式绕过判断,并写入一句话木马。

wp提供的一个思路是前面循环注入的随机数,会有一些数据必然会出现。
比如1-36的随机数在每次循环里都被包括了,他们基本就可以认为必然会出现。视频wp里二分法测试到469,意思是前469的数字应该都有。
但实际应该不是,我测试了一下,比如在下面的这次执行结果中,到56就存在不连续点了。(每次结果都不一样)
ctfshow学习记录-web入门(php特性99-108)_第1张图片
基本上循环中覆盖较多的数值,每次出现的概率是很大的,比如1、2等数字都是会出现的,或者就算没出现,重复多试几次刷新一下,也能碰上。

所以按照这个思路,就写入一句话木马到1.php文件,内容是
ctfshow学习记录-web入门(php特性99-108)_第2张图片
然后执行命令获取flag。
ctfshow学习记录-web入门(php特性99-108)_第3张图片ctfshow学习记录-web入门(php特性99-108)_第4张图片


web100

解答
v0赋值,赋值=的优先级高于逻辑运算。所以只要让is_numeric($v1)返回true即可满足if判断,and后面的无论结果如何都不影响。

eval()执行里有一段('ctfshow'),可以用/**/注释掉,或者--注释。

继续看判断,v2不能含有分号,v3可以含有。

    if(!preg_match("/\;/", $v2)){     //v2不含分号
        if(preg_match("/\;/", $v3)){       //v3含分号
            eval("$v2('ctfshow')$v3");     //字符串需要注释掉

payload?v1=21&v2=var_dump($ctfshow)/*&v3=*/;


web101

解答:这次特殊符号基本都被禁了,利用ReflectionClass建立ctfshow类的反射类,new ReflectionClass($class)获得class的反射对象(包含了元数据信息)。

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

反射返回的对象是class的元数据对象(包含class的所有属性/方法的元数据信息)。
ctfshow学习记录-web入门(php特性99-108)_第5张图片


web102

解答
1)代码分析:v2必须是数字,以满足v4的if判断。

call_user_func($method,$a)调用的参数是,v2第3位及之后的数字。那么我们需要在后面的数字着手,必须满足数字,科学计数e是唯一可以在is_numeric中不会影响判断数字的字符。所以可选字符只有0-9和e。

7.1以下版本,0x的字符串也是可以作为数字的,但是当前的版本是7.3,并不支持。
(可以通过Wappalyzer插件查看,或者phpinfo查看。)
get:v2=111&v3=1
post:v1=phpinfo
ctfshow学习记录-web入门(php特性99-108)_第6张图片

2)利用进制转换,hex2bin可以把十六进制值转换为 ASCII 字符。我们的要写入的这串十六进制,
在0-9和e能组合的字符里,能构成的字符有:(space)、!"#$%&'()@、反撇号、0-9、A-IP-Ya-ip-y,还有与e的组合可选择一个(.~Nn>^)。

file_put_content();可以写入文件,根据已有内容,不能直接写php语句,因为<不能用,那么就需要编码,以实现写入php语句。所以v3的内容是利用伪协议写入,编码形式采取base64。

3)确定写入内容。
先测试一个开头(PD9waHAg)和 (PD89)均是可以的。
测试了几个命令执行的函数均不能在限定字符内实现,但是还有一个反撇号。单独只使用反撇号的话,不能用,只能使用短标签。就是说:

#下面这个是不会在页面输出结果的。
<?php `cat *`

因为短标签是echo() 的快捷用法,所以它会把结果输出出来。

ls命令不能用,base64后有z字符。
cat和tac命令可以用。
f*不行,那么就直接用cat *把当前目录下的文件都输出。

最后汇总一下思路:v1是hex2bin;v2里先加上两个随意的数字,如11,然后加上php语句的base64转16进制的内容;v3是php伪协议语句。

payload

GET:
	cat(

ctfshow学习记录-web入门(php特性99-108)_第7张图片


web103

解答:只是限制了php字符串,我们上个题用的是短标签,而且是用*全部输出,并不影响,所以上题的payload可用。


web104

解答:sha1弱等于的,找加密后0e开头的即可。这里没有判断v1和v2,两个参数输入同样的值也是可以的。

aaK1STfY ==>0e76658526655756207688271159624026011393

aaO8zKZF ==>0e89257456677279068558073954252716165668


web105

解答:存在两个$的等式,可以使用php的变量覆盖,就是说可以输出flag 的变量从 f l a g 单一一个变量,变成 ‘ flag单一一个变量,变成` flag单一一个变量,变成suces或者$error`也存放了flag值。
实例:

$a='b';$c='d';
$b=1;$d=0;
echo $$a; #输出1,就是$$a==》$b==》1
echo $$c; #输出0

分析代码:那么尝试让$suces或者$error存放flag值,两个foreach语句后都里一个$$key=$$value,可以让参数名是suces或error,值传递flag,则$$key$suces$error$$value$flag

因为get限制了key不能error,所以参数名为suces,由于post里value值不能是flag,所以用get传递。post的代码在get之后执行,可以让$error的值为$suces,这样三个变量都是flag值,那么后面的语句,无论判断结果如何,都会输出flag。

payload
​ GET: ?suces=flag
​ POST: error=suces
ctfshow学习记录-web入门(php特性99-108)_第8张图片


web106

解答:sha1弱等于的,v1和v2不能相等,使用web104的payload即可,找加密后0e开头的。

aaK1STfY =>0e76658526655756207688271159624026011393
aaO8zKZF =>0e89257456677279068558073954252716165668
ctfshow学习记录-web入门(php特性99-108)_第9张图片


web107

解答
parse_str(string,array)把查询字符串解析到变量中。如

parse_str("a=1&b=2",$array);
print_r($array);
#输出:Array([a]=>1 [b]=>2)

所以v1传递内容是v1=flag=??,具体传递的值根据v3确定,v3经过md5后弱等于v2,那么md5后0e开头即可,让v2的flag变量值为0。
post:v1=flag=0
get:v3=QNKCDZO
ctfshow学习记录-web入门(php特性99-108)_第10张图片


web108

解答:ereg:正则表达式匹配。
第一个条件要求:输入的值必须是大小写字母。
第二个条件要求:输入的值反转后,转整数,值为0x36d,转十进制是877。

ereg函数存在NULL截断漏洞,可以绕过正则过滤,使用%00截断。
c=a%00778

你可能感兴趣的:(ctf-web,#,ctfshow-web,php,学习)