capa scanner start

This commit is contained in:
Johannes Bülow 2025-06-13 13:03:52 +02:00
parent 7a3bc3bd75
commit d3407351af
Signed by: jmb
GPG key ID: B56971CF7B8F83A6
9 changed files with 102 additions and 0 deletions

24
scanners/capa/Dockerfile Normal file
View file

@ -0,0 +1,24 @@
FROM python:3-alpine
# Set environment variables (these can be overridden in `docker-compose.yml` or `docker run`)
ENV FILE_DIRECTORY="/mnt/storage/files/"
ENV HOST="127.0.0.1"
ENV PORT="5001"
ENV DEBUG="True"
ENV WORKERS="4"
# Expose the port Flask will run on
EXPOSE 5000
WORKDIR /opt/capa
COPY . .
RUN apk --no-cache add wget unzip
RUN pip install --no-cache --upgrade pip
RUN pip install --no-cache -r requirements.txt
RUN wget https://github.com/mandiant/capa-rules/archive/refs/tags/v4.0.0.zip
RUN unzip v4.0.0.zip
# Start the Flask app
#CMD ["python", "app.py"]
CMD ["sh", "-c", "gunicorn -w $WORKERS -b $HOST:$PORT app:app"]

16
scanners/capa/app.py Normal file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env python3
from flask import Flask
from routes.capa import capa_bp
from config import Config
app = Flask(__name__)
# Apply config settings
app.config.from_object(Config)
# Register Blueprints (Modules)
app.register_blueprint(oleid_bp, url_prefix='/oleid')
if __name__ == '__main__':
app.run(host=Config.HOST, port=Config.PORT, debug=Config.DEBUG)

12
scanners/capa/config.py Normal file
View file

@ -0,0 +1,12 @@
import os
class Config:
# Read values from environment variables or use defaults
FILE_DIRECTORY = os.environ.get("FILE_DIRECTORY", "/mnt/storage/files")
HOST = os.environ.get("HOST", "127.0.0.1")
PORT = int(os.environ.get("PORT", 5000))
DEBUG = os.environ.get("DEBUG", "False").lower() in ("true", "1")
# Ensure upload directory exists
if not os.path.exists(Config.FILE_DIRECTORY):
os.makedirs(Config.FILE_DIRECTORY)

View file

@ -0,0 +1,3 @@
gunicorn
flask
flare-capa

View file

View file

@ -0,0 +1,31 @@
from logging import log
import logging
from flask import Blueprint, request, jsonify, abort
from os import path
import config
capa_bp = Blueprint('capa', __name__)
@capa_bp.route('/analyze', methods=['GET'])
def analyze_mraptor():
file = request.args.get('file', '')
if file == '':
abort(400)
filepath = path.join(config.Config.FILE_DIRECTORY, file)
# Analyze with olevba
vbaparser = olevba.VBA_Parser(filepath)
if vbaparser.detect_vba_macros():
vba_code = ''
try:
vba_code = vbaparser.get_vba_code_all_modules()
except Exception as e:
logging.error(e)
abort(500)
raptor = mraptor.MacroRaptor(vba_code)
raptor.scan()
if raptor.suspicious:
return jsonify({'filename': file, 'result': mraptor.Result_Suspicious, 'flags': raptor.get_flags(), 'matches': raptor.matches})
else:
return jsonify({'filename': file, 'result': mraptor.Result_MacroOK, 'flags': raptor.get_flags(), 'matches': raptor.matches})
else:
return jsonify({'filename': file, 'result': mraptor.Result_NoMacro})

View file

View file

@ -0,0 +1,14 @@
import os
from flask import current_app
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'doc', 'xls', 'ppt', 'pps', 'bin'}
def save_file(file):
filepath = os.path.join(current_app.config['UPLOAD_FOLDER'], file.filename)
file.save(filepath)
return filepath
def delete_file(filepath):
os.remove(filepath)

View file

@ -3,6 +3,7 @@
from flask import Flask from flask import Flask
from routes.oleid import oleid_bp from routes.oleid import oleid_bp
from routes.olevba import olevba_bp from routes.olevba import olevba_bp
from routes.mraptor import mraptor_bp
from config import Config from config import Config
app = Flask(__name__) app = Flask(__name__)
@ -13,6 +14,7 @@ app.config.from_object(Config)
app.register_blueprint(oleid_bp, url_prefix='/oleid') app.register_blueprint(oleid_bp, url_prefix='/oleid')
app.register_blueprint(olevba_bp, url_prefix='/olevba') app.register_blueprint(olevba_bp, url_prefix='/olevba')
app.register_blueprint(mraptor_bp, url_prefix='/mraptor')
if __name__ == '__main__': if __name__ == '__main__':
app.run(host=Config.HOST, port=Config.PORT, debug=Config.DEBUG) app.run(host=Config.HOST, port=Config.PORT, debug=Config.DEBUG)