INFORMATION GAHTERING

PORT SCANNING

NMAP - TCP PORTS

  • 개방된 TCP 포트 : 22, 80
└─# nmap -p- -sC -sV -Pn -n --min-rate 10000 10.129.67.51 -oN 10.129.67.51_TCP
Starting Nmap 7.95 ( https://nmap.org ) at 2025-09-08 05:53 EDT
Warning: 10.129.67.51 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.129.67.51
Host is up (0.26s latency).
Not shown: 64769 closed tcp ports (reset), 764 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://strutted.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 31.38 seconds

NMAP - TCP PORTS

  • 개방된 UDP 포트는 존재하지 않았다.
└─# nmap -sU -sV -Pn -n --top-ports 100 --min-rate 10000 10.129.67.51 -oN 10.129.67.51_UDP
Starting Nmap 7.95 ( https://nmap.org ) at 2025-09-08 05:53 EDT
Nmap scan report for 10.129.67.51
Host is up (0.26s latency).
Not shown: 95 open|filtered udp ports (no-response)
PORT     STATE  SERVICE VERSION
49/udp   closed tacacs
427/udp  closed svrloc
520/udp  closed route
2049/udp closed nfs
5060/udp closed sip
 
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 427.37 seconds

PORT 80

  • 80번 포트로 접근 시 http://strutted.htb 경로로 리다이렉트 되며 접속이 불가하다.
  • 해당 포트로 접근하기 위해 /etc/hosts 파일에 대상 호스트의 IP 주소와 도메인 주소를 맵핑한다.
└─# cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       kali
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
10.129.67.51    strutted.htb

  • Upload 기능을 통해 임의의 파일 업로드 시도 시 지정된 확장자 파일만 서버에 업로드 가능한 것을 확인했다.

  • 추가로, 우측 상단의 Download 클릭하여 strutted.zip 압축파일 다운로드 후 정보를 수집했다.

  • [1] tomcat-users.xml : 톰캣 관리자 계정정보 확인
    • (내부에서 실행중인 관리자 페이지(EX; 아파치 톰캣) 혹은 SSH 접속 시 활용해볼 수 있다.)
└─# cat tomcat-users.xml                      
<?xml version='1.0' encoding='utf-8'?>
 
<tomcat-users>
    <role rolename="manager-gui"/>
    <role rolename="admin-gui"/>
    <user username="admin" password="skqKY6360z!Y" roles="manager-gui,admin-gui"/>
</tomcat-users>

  • [2] pom.xml : 웹 애플리케이션 개발에 사용된 프레임워크(apache struts2)에 대한 정보를 획득했다.
    • <struts2.version>6.3.0.1</struts2.version>
  • [3] 해당 버전은 CVE-2024-53677에 취약한 버전이었다.
  • [4] 위 CVE를 활용하기 위해 strutted.zip 압축파일의 소스코드를 분석하여 파일 업로 우회 포인트를 확인한다.


VULNERABILITY ASSESSMENT

Bypass - File Upload

  • [1] /strutted/src/main/webapp/WEB-INF/upload.jsp 소스를 살펴보면, 파일 업로드 시 upload 라는 이름의 액션이 실행된다. 이는 Apache Struts2 프레임워크에서 제공하는 태그(<s:form>, <s:file>, <s:submit>)를 사용한 파일 업로드 폼이므로 struts.xml 설정파일을 통해 사전에 정의된 호출 로직을 확인해야 한다.

  • [2] /strutted/src/main/resources/struts.xml 파일의 소스로부터 upload 요청이 들어오면 org.strutted.htb.Upload 파일이 호출되는 구조를 확인했다.

  • [3] /strutted/src/main/java/org/strutted/htb/Upload.java 파일을 살펴보면 upload.jsp에서 upload 액션이 호출되었을 때, 해당 파일의 Upload 클래스 객체가 생성되고 execute 메서드가 실행된다.
  • [4] uploadFileName 파라미터로 받은 값을 . 문자로 구분하여 확장자를 추출한 후 extension 변수에 할당한다.
  • [5] 추가로, 컨텐츠 타입 검증과 업로드 파일의 매직바이트 검증 메서드도 확인되었다.

  • isAllowedContentType - 컨텐츠 타입이 “image/jpeg, image/png, image/gif” 중 하나인지 검증

  • isImageByMagicBytes - 각 이미지 파일의 헤더(매직바이트)를 검사하여 실제로 이미지 파일인지 검증


  • 서버에 파일을 업로드하기 위해서는 파일의 컨텐트 타입과 헤더 값을 허용된 값으로 설정해줘야 한다.

  • 이 규칙을 지킨 상태에서 파일을 업로드하면 악의적인 페이로드(EX; 웹쉘)가 담긴 파일이더라도 업로드에 성공하는 것을 확인할 수 있다.


EXPLOIT

  • 이제 파일을 실행시키기 위해서는 해당 파일이 JSP 파일로서 동작하도록 해야한다.
  • 아래 내용을 참고하여 CVE-2024-53677 익스플로잇을 진행하였으며 웹쉘 업로드에 성공했다.


  • 웹쉘 업로드 경로로 접근하여 정보 수집을 진행한다.
  • [1] /etc/hosts - 네트워크 관리자(Network Administrator) 계정(james) 확인
  • [2] ./conf/tomcat-users.xml - admin 계정의 패스워드 정보를 획득
    • 해당 정보를 이용하여 james 계정으로 SSH 접속을 시도해본다.


LATERAL MOVEMENT

  • 이전 과정에서 확인한 관리자 계정정보를 이용하여 james 계정으로 SSH 접속에 성공했다.
    • (기존에 웹 서버 운영계정(tomcat)에서 james로 횡적이동에 성공했다.)
└─# ssh james@10.129.231.200
james@10.129.231.200's password:
 
[ . . . ]
 
Last login: Tue Jan 21 13:46:18 2025 from 10.10.14.64
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
 
james@strutted:~$


PRIVILEGE ESCALATION

  • sudo -l 명령어를 이용하여 james 계정에서 루트 권한으로 실행가능한 명령어를 확인한다.
  • tcpdump 바이너리에 대해 루트 실행권한이 있음을 확인했다.
james@strutted:~$ sudo -l
Matching Defaults entries for james on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty
 
User james may run the following commands on localhost:
    (ALL) NOPASSWD: /usr/sbin/tcpdump

  • GTFOBINS 사이트의 SUDO tcpdump 부분을 참고하여 권한상승을 시도한다.
    • [1] COMMAND 변수는 루트 권한으로 실행될 명령어를 의미한다.
    • [2] /bin/bash -p 명령어에서 -p 옵션은 특권모드를 의미한다. SUID/SGID가 설정된 상태에서 해당 프로그램의 EUID를 그대로 유지하고 실행시키기 때문에 여기서는 루트 권한으로 실행된다.


  • 권한상승에 성공하여 루트 계정 탈취에 성공하였다.

Reference

  1. https://struts.apache.org/maven/struts2-core/apidocs/org/apache/struts2/interceptor/FileUploadInterceptor.html
  2. https://www.skshieldus.com/kor/eqstinsight/cve2501.html
  3. https://www.skshieldus.com/download/files/download.do?o_fname=EQST%20insight_Research%20Technique_202402.pdf&r_fname=20240220143226638.pdf