Search code examples
pythondockerflasknmap

Python3 os.popen is not working with Nmap when I dckerize it


I have a HTTP Flask API for nmap tool, the code:

from flask import Flask, request, render_template, redirect, url_for
import os

rejected_characters = ';|\\&'

app = Flask(__name__)

@app.route('/', methods=['POST'])
def index():
    if request.method == 'POST':
        args = request.get_json()["nmap_args"]
        for i in rejected_characters:
            if i in args:
                return render_template('scan.html', response="Invalid request")
        nmap_output = os.popen("nmap {}".format(args)).read()
        return render_template('scan.html', response=nmap_output)       
    else:
        respose = "Send a POST request to '/' with json content containing 'nmap_args' key\n"
        respose += "nmap_args will be the arguments passed to nmap command `nmap [nmap_args]`"
        return render_template('scan.html', respose=respose)

if __name__ == "__main__":
    app.run(host='0.0.0.0')

When I turn on the server by running python3 app.py everything working fine, and when I send a request like this:

curl -X POST http://localhost:5000 --data '{"nmap_args": "-sC -sV localhost -p22"}' -H "Content-Type: application/json"

The response will back when nmap is finished with it's scan. Response will be something like this:

Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-30 15:12 EEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00023s latency).
Other addresses for localhost (not scanned): ::1

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9 (protocol 2.0)
| ssh-hostkey:
|   2048 87:75:d4:af:97:e6:bb:7b:e8:14:36:65:a1:ee:58:c1 (RSA)
|   256 a0:b6:03:50:84:45:6a:f2:d1:d6:66:ce:36:06:ce:75 (ECDSA)
|_  256 22:c4:e0:c2:d7:c1:7e:b6:0c:03:7e:e8:ef:eb:8f:c4 (ED25519)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1.13 seconds

The problem is when I dockerized the application, I was receiving the responses immediately without the full results of nmap. I just receives Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-30 15:12 EEST.

What is the problem with the docker image and how to fix it?

Note: I ran the docker image using command: docker run -p 5000:5000 nmap-api


Solution

  • The problem was because of os.popen(..), I don't know exactly why it was not working in the docker image.

    However, I replaced this line nmap_output = os.popen("nmap {}".format(args)).read() by this piece of code (used subprocess instead of os):

    cmd = ["nmap"] + args.split(' ')
    result = subprocess.check_output(cmd)
    nmap_output = result.decode('utf-8')