One
使用docker 拉取环境 docker-compose.exe  -f .\docker-compose.yml  up -d
进行访问 
首先看到从上而下看到一个 base64 编码的数据 
 然后就是 引入lib.php
然后就是输出一个 编码过的flag 
对第一行的base64 编码进行解密操作 ,进行反向解密操作
对每一个函数进行解释
:::info
base64-encode()   进行base64加密 
hex2bin  16进行转换为 ASCII 码  
strrev  进行反转 
bin2hex  ASCII 码转为 16 进制
:::
  编写PHP 脚本 
对其进行反转操作就可以了  我们最终的数据是ASCII码 不是 16 进行 所以这里不要按照直的顺序进行编码
得到flag 
如果按照纯顺序来做会报错
Two

| 1 |  | 
 
参数 time 
第一个if  不能为数字 
第二个判断
必须大于
>>> 606024302
5184000
第三个判断  必须小于 
>>> 606024303
7776000
第四个判断  
sleep(int())
必须要在 5184000 和 7776000 之间
然后这里又是sleep 函数  必须是整数 
在中间的值取个整数 6000000 
但是这样的话他会执行 6000000秒 这不行 
这里可以使用科学计数法 
6e6
———————————————————————————————————–
1、当一个字符串被当作一个数值来取值,其结果和类型如下:如果该字符串没有包含’.’,’e’,’E’并且其数值值在整形的范围之内,该字符串被当作int来取值。其他所有情况下都被作为float来取值,该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0。
2、在进行比较运算时,如果遇到了0e这类字符串,PHP会将它解析为科学计数法。(也就是说只靠最前面的进行判断)
3、在进行比较运算时,如果遇到了0x这类字符串,PHP会将它解析为十六进制。
Three

三个传参值 id  a  b 
前两个好绕过 
and $id==0
利用php弱类型比较,数字与字符串等值比较时,字符串取开头的有效数字,无则为0,结合id不为0或null,id可取值开头不带有效数字的字符串,$id=a0
绕过 a
if(stripos($a,’.’))
$a要么没有. 要么.在字符串的第一位
$data = @file_get_contents($a,’r’); if($data==”1112 is a nice lab!”
data 可以使用php伪协议  php://input 
当$a=php://input,即file_get_contents(‘php://input’,’r’)时
$data取请求原始数据流,即post的内容,$a=php://input
$data取post的数据,post 1112 is a nice lab! 即可
绕过 b 
eregi(“111”.substr($b,0,1),”1114”) and substr($b,0,1)!=4

%00能截断substr,但注意get传递时会自动解码一次
strlen($b)>5
$b 长度大于 5 12345
substr($b,0,1)!=4)
b 的 第一位不能为4
eregi(“111”.substr($b,0,1),”1114”)
111与$b字符串被截取的第一位字符连结后形成的字符串能在1114中匹配到,即连结后的字符串可以是111也可以是1114
利用%00截断,使substr截取$b字符串时被截断,从而形成eregi(“111”,”1114”),匹配成功,同时%00不会对strlen截断,$b=%0012345
完整的payload
| 1 |  | 
Four

首先看见eval  应该是可以执行php代码的 
@_REQUEST[‘hello’]
一个超全局变量,可以接收_get,_post,_cookie发送的数据
eval(“var_dump($a);”);使用了双引号,意味着,会先计算$a的值(也可以理解为先解析$a)再执行eval函数
利用先计算$a的值再执行eval函数这一特点,通过gpc传递给$a特殊的字符串,经过计算后与原本的var_dump();组合造成拼接效果,形成一个新的字符串,使eval函数执行我们预期的php代码
GPC(GET、POST、COOKIE)
- var_dump()方法是判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型.
此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。
这里是将变量a的值打印到界面中。
单双引号
PHP对于双引号包裹起来的字符串要进行扫描计算,单引号则不管内容如何都会原样输出而不会进行计算。
所以’比”执行快
先使用eval 执行phpinfo 看是否执行成功
http://172.18.52.58:23114/challenge4.php?hello=);eval(phpinfo()

是可以成功执行 的 
那就可以写一句去连shell
http://172.18.52.58:23114/challenge4.php?hello=);eval($_POST[cmd]


Five

就没见过 sha1 === sha1 这种
但是尝试一下md5 弱比较绕过 
就绕过了 …. 
我也没想到 。。。。
“分析代码逻辑,发现GET了两个字段name和password,获得flag要求的条件是:name != password & sha1(name) == sha1(password),乍看起来这是不可能的,其实可以利用sha1()函数的漏洞来绕过。如果把这两个字段构造为数组,如:?name[]=a&password[]=b,这样在第一处判断时两数组确实是不同的,但在第二处判断时由于sha1()函数无法处理数组类型,将报错并返回false,if 条件成立,获得flag。
这里是因为sha1 无法处理数组就可以绕过成功了
Six
拉取不了 参考一下其他师傅的
https://blog.csdn.net/CliffordR/article/details/104276924/
Seven

查看源代码也没有发现啥数据 
扫描目录也没有发现啥 发现了 flag.php  和 index.php 但是没有数据 
后面才才发现 代码在docker 启动目录下 
| 1 |  | 
定义了两个变量   
$_403 $_200 
这里如果不是 POST去 访问 就会BugsBunnyCTF is here :p…
所以一开始 是 GET  就会出现 BugsBunnyCTF is here :p…
首先传入的参数 是flag
flag =1  
会报 Access Denied  拒绝访问
我们的目的是 Welcome Admin
再来看 foreach 循环 
foreach ($_GET as $key => $value)
$$key = $$value;
foreach ($_POST as $key => $value)
$$key = $value;
$$,变量覆盖
第一个foreach处,能将任意变量的值赋予任意变量
第二个foreach处,能将输入的值赋予任意变量
第三个 IF
if ( $_POST[“flag”] !== $flag )
die($_403);
echo “This is your flag : “. $flag . “\n”;
die($_200);
$_POST[“flag”]如果与$flag不完全相等,即值和类型都比较时,输出$_403
如果完全相等,则输出$flag和$_200
die
die() 函数输出一条消息,并退出当前脚本。
该函数是 exit() 函数的别名。
die()函数用于移除匹配元素上绑定的一个或多个事件的事件处理函数。 die()函数主要用于解除由live()函数绑定的事件处理函数。 该函数属于jQuery对象(实例)。
解法: CTF中的变量覆盖
foreach ($_POST as $key => $value)
$$key = $value;
当只POST一个值为1的变量flag,$$key = $valu=>$flag = 1,使可能原本存在的变量$flag被赋值为1,
即真实的flag被修改为变量flag的值,由于前面的两个if,这是无法被改变的
所以,需要在真实的flag被修改前将其值给其他变量并能输出出来
能输出的只有die($_403);和die($_200);,
所以思路是利用变量覆盖在flag被改前将真实的$flag的值覆盖$_403或$_200并输出
而能利用变量覆盖将一个变量的值覆盖其他变量的地方只有第一个foreach处
$$ 变量覆盖
| 1 |  | 

这样就完成了 变量覆盖  
解法 1 : 将真实的flag覆盖$_200并输出$_200
GET传一个变量_200 的 值 为flag
 POST 方法传 一个变量为flag 值 为 任何数 ,这里传一个flag=1
相当于$_200=$flag,将真flag给了$_200
$flag被修改为1,与$_POST[‘flag’]等值等类型,不满足$_POST[“flag”] !== $flag
输出$_200即输出真flag
| 1 |  | 
解法二 : 将真实的flag 覆盖给 $_403 并构造$_403 能输出
把真实的flag 传给了 403 
然后构造两个flag=2  flag=1  
$flag被修改为1,与$_POST[‘flag’]不等,满足$_POST[“flag”] !== $flag,输出$_403
Eight

| 1 |  | 
一道php  无数字字母webshell 的题 
挺难得 , 看p神的blog  有几种解法 
方法一 是 位运算 进行 异或  
方法二 是 进行取反运算
方法三 
方法是理解了但是实际操作还是不会 。。。。。 哎
参考师傅们的文章:
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
https://www.cnblogs.com/Rain99-/p/12642550.html
https://www.freebuf.com/articles/web/186298.html
https://www.leavesongs.com/SHARE/some-tricks-from-my-secret-group.html
http://arsenetang.com/2021/07/26/RCE%E7%AF%87%E4%B9%8B%E6%97%A0%E5%8F%82%E6%95%B0rce/
https://www.freebuf.com/articles/web/261800.html
https://liduoan.github.io/2020/04/03/%E5%9B%9B%E6%9C%88/%E6%97%A0%E5%8F%82%E6%95%B0RCE/#%E5%89%8D%E8%A8%80
https://blog.csdn.net/Manuffer/article/details/120738755
https://xz.aliyun.com/t/9360
Nine

docker 拉取不了  给了源文件  开始代码审计 
这个题 有全局变量 ip 
shell_exec 函数 稳稳的RCE了  
$substitutions = array(
‘&’ => ‘’,
‘;’ => ‘’,
‘|’ => ‘’,
‘-‘ => ‘’,
‘$’ => ‘’,
‘(‘ => ‘’,
‘)’ => ‘’,
‘`’ => ‘’,
‘||’ => ‘’,
);
存在过滤 
尝试输入一个ip地址  
是可以执行命令的 ,但是由于我这里是window系统 看看能不能存在 windows的过滤方法
找了半天没有存在的绕过windows的方法 ,这里由于是windows搭建的 参加的方法被过滤掉了 
linux可以使用 %0a  去进行 绕过 
完整payload 
http://localhost:3000/challenge9.php?ip=127.0.0.1%0acat$IFS$9flag.php
这里$IFS$9是绕过空格
Ten

**端口  23120 **
| 1 |  | 
主要在于
| 1 |  | 
one =1  nine = 9
不能大于等于1  小于等于 9  
否则就是false 
然后这里 传入的number 还必须等于   3735929054
看见  == 就可以使用php 弱比较 
 把 3735929054 这个转为 16进制看看 
十六进制的3735929054,只包含字母与0,满足条件
Payload  为
answer=0xdeadc0de
