Samba


Nmap discovered a Samba server on the target port 36455 The running service is Samba smbd 4

┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem]
└─$ nmap --script smb-enum-shares -sV -p36445 $IP
Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-10 15:05 CET
Nmap scan report for 192.168.113.105
Host is up (0.024s latency).
 
PORT      STATE SERVICE     VERSION
36445/tcp open  netbios-ssn Samba smbd 4
 
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 54.36 seconds

Share mapping failed

┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem]
└─$ nxc smb $IP --port 36445 -u '' -p '' --shares --interfaces        
SMB         192.168.113.105 36445  NUKEM            [*] Unix - Samba (name:NUKEM) (domain:) (signing:False) (SMBv1:False)
SMB         192.168.113.105 36445  NUKEM            [+] \: 
SMB         192.168.113.105 36445  NUKEM            [*] Enumerated shares
SMB         192.168.113.105 36445  NUKEM            Share           Permissions     Remark
SMB         192.168.113.105 36445  NUKEM            -----           -----------     ------
SMB         192.168.113.105 36445  NUKEM            Commander       READ,WRITE      Commander Files
SMB         192.168.113.105 36445  NUKEM            IPC$                            IPC Service (Samba 4.12.6)

The target Samba server allows anonymous access to the Commander share. Both read and write access are granted

Null Session


┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem]
└─$ smbclient //$IP/Commander -p 36445   
Password for [WORKGROUP\kali]:
Anonymous login successful
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Mon Mar 10 15:08:04 2025
  ..                                  D        0  Thu Jan 30 08:49:11 2025
  .gitignore                          H       15  Fri Sep 18 19:19:19 2020
  README.md                           N      417  Fri Sep 18 19:19:19 2020
  server.py                           N     2552  Fri Sep 18 19:19:19 2020
  requirements.txt                    N      287  Fri Sep 18 19:19:19 2020
  chinook.db                          N   884736  Fri Sep 18 19:19:19 2020
 
		9738528 blocks of size 1024. 4444868 blocks available
smb: \> 

The Commander share contains the source code of some kind of a server

smb: \> put test
putting file test as \test (0.0 kb/s) (average 0.0 kb/s)

Write access is granted

┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem/smb]
└─$ smbget smb://$IP:36445/Commander -U '' -N -e --recursive
Using guest user
Encryption required and setup failed with error NT_STATUS_INVALID_PARAMETER_MIX.
Using guest user
smb://192.168.113.105:36445/Commander/.gitignore                                          
Using guest user
smb://192.168.113.105:36445/Commander/README.md                                           
Using guest user
smb://192.168.113.105:36445/Commander/server.py                                           
Using guest user
smb://192.168.113.105:36445/Commander/requirements.txt                                    
Using guest user
smb://192.168.113.105:36445/Commander/chinook.db                                          
Downloaded 867.19kB in 2 seconds

Exfiltrating everything from the Commander share

README.md


┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem/smb]
└─$ cat README.md
# Flask Rest API
 
This code is a self explanatory code, I got from [impythonist](https://impythonist.wordpress.com/2015/07/12/build-an-api-under-30-lines-of-code-with-python-and-flask/) blog. The current repository,
helps in getting started with the basic REST API Development of Flask. PRs are welcome for the other REQUESTS. The sole existence of
this repo is to spread the information and no profit is made on it.

N/A

.gitignore


┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem/smb]
└─$ cat .gitignore
venv/
.DS_Store

The project was made from an OSX system and had a Python virtual environment

requirements.txt


┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem/smb]
└─$ cat requirements.txt
aniso8601==1.2.0
appdirs==1.4.0
click==6.7
Flask==1.0
Flask-Jsonpify==1.5.0
Flask-RESTful==0.3.5
Flask-SQLAlchemy==2.1
itsdangerous==0.24
Jinja2==2.9.5
MarkupSafe==0.23
packaging==16.8
pyparsing==2.1.10
python-dateutil==2.6.0
pytz==2016.10
six==1.10.0
SQLAlchemy==1.1.5
Werkzeug==0.15.3

N/A Some of those modules might be outdated and vulnerable

server.py


┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem/smb]
└─$ cat server.py
#!/usr/bin/python3
from flask import Flask, request, jsonify
from flask_restful import Resource, Api
from sqlalchemy import create_engine
from json import dumps
 
db_connect = create_engine('sqlite:///chinook.db')
app = Flask(__name__)
api = Api(app)
 
 
class Employees(Resource):
    def get(self):
        conn = db_connect.connect() # connect to database
        query = conn.execute("select * from employees") # This line performs query and returns json result
        return {'employees': [i[0] for i in query.cursor.fetchall()]} # Fetches first column that is Employee ID
 
    def post(self):
        conn = db_connect.connect()
        print(request.json)
        LastName = request.json['LastName']
        FirstName = request.json['FirstName']
        Title = request.json['Title']
        ReportsTo = request.json['ReportsTo']
        BirthDate = request.json['BirthDate']
        HireDate = request.json['HireDate']
        Address = request.json['Address']
        City = request.json['City']
        State = request.json['State']
        Country = request.json['Country']
        PostalCode = request.json['PostalCode']
        Phone = request.json['Phone']
        Fax = request.json['Fax']
        Email = request.json['Email']
        query = conn.execute("insert into employees values(null,'{0}','{1}','{2}','{3}', \
                             '{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}', \
                             '{13}')".format(LastName,FirstName,Title,
                             ReportsTo, BirthDate, HireDate, Address,
                             City, State, Country, PostalCode, Phone, Fax,
                             Email))
        return {'status':'success'}
 
 
class Tracks(Resource):
    def get(self):
        conn = db_connect.connect()
        query = conn.execute("select trackid, name, composer, unitprice from tracks;")
        result = {'data': [dict(zip(tuple (query.keys()) ,i)) for i in query.cursor]}
        return jsonify(result)
 
 
class Employees_Name(Resource):
    def get(self, employee_id):
        conn = db_connect.connect()
        query = conn.execute("select * from employees where EmployeeId =%d "  %int(employee_id))
        result = {'data': [dict(zip(tuple (query.keys()) ,i)) for i in query.cursor]}
        return jsonify(result)
 
 
api.add_resource(Employees, '/employees') # Route_1
api.add_resource(Tracks, '/tracks') # Route_2
api.add_resource(Employees_Name, '/employees/<employee_id>') # Route_3
 
 
if __name__ == '__main__':
     app.run(host='0.0.0.0')

The server.py file is a Flask application that uses a SQLite3 database, chinook.db, as a backend DB It would appears that there are essentially 3 features that uses 2 API endpoints;

  • Employees Class
    • using the /employees API endpoint to fetch and list all the employees
  • Employees_Name Class
    • using the /employees/<employee_id> API endpoint to fetch the USER-SUPPLIED <employee_id>
      • The SQL query appears to be vulnerable to SQL injection
  • Tracks Class
    • using the /tracks API endpoint to list about information about available tracks

This might have to do with the web server running on the target port 5000 as it is a Python web application

chinook.db


┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/nukem/smb]
└─$ open chinook.db  

There are 13 tables, including the employees table

employees Table

The email column contains email addresses that may be used as username