Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NGINX 反代无法访问页面 #44

Closed
ReaJason opened this issue Feb 22, 2025 · 0 comments
Closed

NGINX 反代无法访问页面 #44

ReaJason opened this issue Feb 22, 2025 · 0 comments
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@ReaJason
Copy link
Owner

ReaJason commented Feb 22, 2025

在已有的武器化利用平台集成内存马生成界面时出现无法访问的问题。

复现步骤

常规情况下启动 memshell-party 容器开放 8080 端口。并使用 Nginx 进行反代配置如下:

location /memshell-generator {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-By $server_addr:$server_port;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_http_version 1.1;
    proxy_connect_timeout 3s;
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;
    proxy_buffer_size 16k;
    proxy_buffers 8 64k;
    proxy_busy_buffers_size 128k;
}

访问响应如图所示:

Image

且可以看到容器有访问日志

org.springframework.web.servlet.resource.NoResourceFoundException: No static resource memshell-generator.
	at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585) ~[spring-webmvc-6.2.0.jar:6.2.0]
	at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52) ~[spring-webmvc-6.2.0.jar:6.2.0]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088) ~[spring-webmvc-6.2.0.jar:6.2.0]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978) ~[spring-webmvc-6.2.0.jar:6.2.0]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.0.jar:6.2.0]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.2.0.jar:6.2.0]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.0.jar:6.2.0]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.0.jar:6.2.0]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.0.jar:6.2.0]
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.0.jar:6.2.0]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.0.jar:6.2.0]
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.0.jar:6.2.0]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.0.jar:6.2.0]
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101) ~[undertow-servlet-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:395) ~[undertow-core-2.3.18.Final.jar:2.3.18.Final]
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:861) ~[undertow-core-2.3.18.Final.jar:2.3.18.Final]
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
	at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282) ~[xnio-api-3.8.16.Final.jar:3.8.16.Final]
	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]

此时其实已经能通过 Nginx 成功访问到生成服务了,不过容器默认提供的是 / 访问,/memshell-generator 是没有提供服务的,不过可以使用 Nginx 的 rewrite 功能,去掉原地址的 /memshell-generator,直接 rewrite 到目标服务的 / 即可,尝试修改如下:

location /memshell-generator {
    rewrite ^/memshell-generator/?(.*)$ /$1 break;
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-By $server_addr:$server_port;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_http_version 1.1;
    proxy_connect_timeout 3s;
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;
    proxy_buffer_size 16k;
    proxy_buffers 8 64k;
    proxy_busy_buffers_size 128k;
}

继续尝试访问页面,此时页面空白,f12 查看页面请求,HTML 已经能拿到了,不过可以看到静态资源并未能成功获取到。

Image

原因分析

静态资源访问的是 /asserts 下没有自动带上 /memshell-generator,是因为 HTML 使用的是 react 项目打包而来,并没有通过服务端渲染所以并不知道 context path,所以并不能成功响应预期的路径。

调试

首先我在尝试了给 Spring Boot 添加 --server.servlet.context-path=/memshell-generator 启动参数,并在 HTML 写上服务端渲染路径让界面和静态资源都能成功被访问到(去掉 Nginx 的重写功能)。访问如下:

Image

还是歇逼了,原因是前端打包的时候会指定后端地址,我指定的是 /,所以打包的时候就必须对上,并且可以看到下面那个 Not Found,前端路由也需要给对上,不然也歇逼。

修复方案

提供一个 Dockerfile 能通过传入指定访问前缀编译可用镜像,例如 /memshell-generator 让整个服务也正常工作。

  1. 修改 boot Dockerfile 支持传入 Spring Boot 参数 --server.servlet.context-path=/memshell-generator 来修改 path
  2. 前端打包时支持传入后端地址和路由参数,使其编译出合适路径的 HTML 静态资源,并替换 HTML 语法支持感知服务端 context path 能力从而返回正确的路径文件。
@ReaJason ReaJason added bug Something isn't working enhancement New feature or request labels Feb 22, 2025
@ReaJason ReaJason self-assigned this Feb 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant