如何用LittleProxy实现云用户数据拦截篡改以突破授权限制?
Absolutely, you can build this man-in-the-middle interceptor with LittleProxy to fake user data and trick your app server. Let's break down how to implement each part of your requirement:
- Intercept all requests targeting
https://localhost:8080/my-app - Spoof the app server into thinking your Google Apps instance has 10,000 users, so it keeps requesting batches until it hits that number
- Tamper with the response data sent to the app server, generating sequentially numbered users (User1 → User100, then User101 → User10000, etc.)
First, let's outline the key logic we need to add to your LittleProxy setup:
1. Filter Only Targeted Requests
We'll first check if the incoming request is for /my-app—all other requests will pass through untouched to avoid interfering with other traffic.
2. Spoof User Count in Requests
When the app server sends a request to fetch user data (e.g., asking for the total number of users or the next batch), we'll modify the request to tell it there are 10,000 total users. This will trigger the server to keep requesting batches until it reaches that number.
3. Generate Fake Sequential Users in Responses
For each response from your actual Google Apps instance (which only returns 100 real users), we'll replace that data with a batch of fake sequentially numbered users. We'll track the current user ID with an atomic counter to ensure continuity across batches.
Here's the complete implementation with all the logic built in. Note that we'll use Jackson for JSON parsing/generation (you'll need to add the Jackson dependencies to your project):
import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.handler.codec.http.*; import org.littleshoot.proxy.HttpFilters; import org.littleshoot.proxy.HttpFiltersAdapter; import org.littleshoot.proxy.HttpFiltersSourceAdapter; import org.littleshoot.proxy.HttpProxyServer; import org.littleshoot.proxy.impl.DefaultHttpProxyServer; import com.fasterxml.jackson.databind.ObjectMapper; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; public class UserDataSpoofProxy { // Atomic counter to track the next user ID to generate (thread-safe for proxy requests) private static final AtomicInteger NEXT_USER_ID = new AtomicInteger(1); private static final int TOTAL_FAKE_USERS = 10000; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); public static void main(String[] args) { HttpProxyServer server = DefaultHttpProxyServer.bootstrap() .withPort(8080) .withFiltersSource(new HttpFiltersSourceAdapter() { @Override public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) { return new HttpFiltersAdapter(originalRequest) { @Override public HttpResponse clientToProxyRequest(HttpObject httpObject) { // Only modify requests targeting /my-app if (httpObject instanceof FullHttpRequest request) { String uri = request.uri(); if (uri.contains("/my-app")) { // Example: Modify query params to set total users to 10,000 // Adjust this to match how your app server requests user data String modifiedUri = uri.replaceFirst("totalUsers=\\d+", "totalUsers=" + TOTAL_FAKE_USERS); request.setUri(modifiedUri); // If your app uses a JSON body instead of query params, modify it here: // ByteBuf content = request.content(); // String originalBody = content.toString(StandardCharsets.UTF_8); // // Parse, modify, and rewrite the JSON body // content.clear(); // content.writeBytes(modifiedBody.getBytes(StandardCharsets.UTF_8)); } } return null; // Return null to let the request proceed } @Override public HttpObject serverToProxyResponse(HttpObject httpObject) { // Only modify responses for /my-app requests if (httpObject instanceof FullHttpResponse response) { String uri = getOriginalRequest().uri(); if (uri.contains("/my-app")) { try { // Parse the original response (real user data) ByteBuf content = response.content(); String originalJson = content.toString(StandardCharsets.UTF_8); List<?> originalUsers = OBJECT_MAPPER.readValue(originalJson, List.class); // Calculate batch size and user ID range for this response int batchSize = originalUsers.size(); int currentId = NEXT_USER_ID.get(); int endId = Math.min(currentId + batchSize - 1, TOTAL_FAKE_USERS); // Generate fake sequential users List<FakeUser> fakeUsers = new ArrayList<>(); for (int i = currentId; i <= endId; i++) { fakeUsers.add(new FakeUser("User" + i, "user" + i + "@example.com")); } // Update counter for next batch NEXT_USER_ID.set(endId + 1); // Replace response content with fake user data String fakeJson = OBJECT_MAPPER.writeValueAsString(fakeUsers); ByteBuf newContent = Unpooled.copiedBuffer(fakeJson, StandardCharsets.UTF_8); response.content().clear(); response.content().writeBytes(newContent); // Update content-length header to match new body size response.headers().set(HttpHeaderNames.CONTENT_LENGTH, newContent.readableBytes()); } catch (Exception e) { e.printStackTrace(); } } } return httpObject; } }; } }) .start(); System.out.println("Proxy server started on port 8080"); } // Simple POJO for fake user data (matches common user object structure) private static class FakeUser { private String username; private String email; public FakeUser(String username, String email) { this.username = username; this.email = email; } // Getters required for Jackson serialization public String getUsername() { return username; } public String getEmail() { return email; } } }
- Request Modification: The example modifies query parameters to set
totalUsers=10000—adjust this logic to match how your app server requests user data (e.g., modify a JSON body if that's what your server uses). - Thread Safety: We use an
AtomicIntegerto track the next user ID, which is safe for concurrent proxy requests since LittleProxy handles traffic across multiple threads. - Jackson Dependency: Add these dependencies to your
pom.xml(Maven) or equivalent for Gradle:<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency> - Termination Handling: Once the counter reaches 10,000, the proxy will stop generating new users. You can extend the logic to return empty batches or trigger a "end of data" signal if your app server expects it.
内容的提问来源于stack exchange,提问作者Swapnil Kotwal

