diff --git a/.gitignore b/.gitignore
index 1e788cb1852089d59aae33e59d76809676604c59..ffd7e372182e1205917b047c9d84b42201bab7be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
 **.swp
 wiser-wcs-reports/.idea/*
 wiser-wcs-reports/env/*
-wiser-wcs-reports/example_nmap_output/*
 wiser-wcs-reports/__pycache__/*
+wiser-wcs-reports/example_output/*
 
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index fc4459fbe61fb96282ef61d3048a7df4303fdf34..695f9519a793b785785addfa5b9fbf152b35ec0d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,15 +18,18 @@ test:
     script:
     - docker network create test-genscan
     - docker run --rm -d --network=test-genscan --name dvwa vulnerables/web-dvwa
-    - cp "${CI_PROJECT_DIR}/config-example.json" /tmp
-    - docker run --rm --network=test-genscan -e TARGET="http://dvwa/" -v /tmp/:/root/out registry-gitlab.xlab.si/cyberwiser/$SERVICE:$VERSION
-    - cat /tmp/cscan-log.txt
-    - grep -q "W3af" /tmp/genscan-out.json
-    - grep -q "OWASP ZAP" /tmp/genscan-out.json
+    - cp "${CI_PROJECT_DIR}/config-example.json" /tmp/
+    - mkdir /tmp/out
+    - docker run --rm --network=test-genscan -v /tmp/config-example.json:/root/config.json -v /tmp/out:/root/out registry-gitlab.xlab.si/cyberwiser/$SERVICE:$VERSION
+    - cat /tmp/out/cscan-log.txt
+    - grep -q "W3af" /tmp/out/genscan-out.json
+    - grep -q "OWASP ZAP" /tmp/out/genscan-out.json
+    - grep -q "nmap" /tmp/out/genscan-out.json
     after_script:
     - docker kill dvwa || docker network rm test-genscan
     - docker network rm test-genscan
-    - rm /tmp/genscan-out.json
+    - rm /tmp/genscan-out.json || true
+    - rm -rf /tmp/out
 
 push:
     stage: push
diff --git a/Dockerfile b/Dockerfile
index 080376663d83e571b3d3f57a00e1b233b5480ffe..fd0dd04ab99e435e8ffbc1d2de3fb7432d401c05 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -18,6 +18,8 @@ COPY wiser-wcs-reports /service/wiser-wcs-reports/
 COPY install/wiser-wcs.sh /tmp/install/
 RUN chmod +x /tmp/install/wiser-wcs.sh && /tmp/install/wiser-wcs.sh
 
+RUN apt install -y nmap
+
 COPY install/cleanup.sh /tmp/install/
 RUN chmod +x /tmp/install/cleanup.sh && /tmp/install/cleanup.sh
 
diff --git a/MANIFEST b/MANIFEST
index cd8acda39449e1dd0a4b9a1469ee978986311fa6..f5fd3aad31471eba9c53d0472377ec6e8c4fdc2d 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,3 +1,3 @@
-VERSION=v1.3.4
+VERSION=v1.4.0
 SERVICE=vat-genscan
 
diff --git a/Makefile b/Makefile
index d170f2f3b32a1f06dc7ba370a6f1070a0e5164f4..c221fc92a4870766e3934ab05a28ba73ced5bd73 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,7 @@ test:
 	docker network rm test-genscan
 	grep -q "W3af" $(TEST_DIR)genscan-out.json
 	grep -q "OWASP ZAP" $(TEST_DIR)genscan-out.json
+	grep -q "nmap" $(TEST_DIR)genscan-out.json
 
 start:
 ifdef OUTPUT_DIR
diff --git a/README.md b/README.md
index 0e3b424cc8bb3a98571441e6f1ae0a2f2aaba8e0..4cbaf2ac78164cbf30c6138618fcb646ed05f2c7 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,8 @@ Supported scanners and their profiles:
 	* `fast_scan`: no parameters
 * `zap`
 	* `basic`: no parameters
+* `nmap`
+	* `basic_discovery`: no parameters
 
 Example JSON config file:
 
@@ -35,6 +37,9 @@ Example JSON config file:
         },
         "zap": {
             "profile": "basic"
+        },
+        "nmap": {
+            "profile": "basic_discovery"
         }
     }
 }
@@ -42,8 +47,6 @@ Example JSON config file:
 
 ### TODOs and FIXMEs:
 
-* use latest w3af and zap (now fetching static, old commits)
-* use cscan from Faraday repo (newer?)
 * include some configuration options (at least authenticated scans for w3af)
 
 
diff --git a/config-example.json b/config-example.json
index fed87a25babb48bb8698576dfd73fc876048c969..9f61d529fc69cc8a872189bcded19a615fb65382 100644
--- a/config-example.json
+++ b/config-example.json
@@ -1,6 +1,7 @@
 {
     "target": {
-        "url": "http://dvwa/"
+        "url": "http://dvwa/",
+        "ip": "dvwa"
     },
     "config": {
         "w3af": {
@@ -8,6 +9,9 @@
         },
         "zap": {
             "profile": "basic"
+        },
+        "nmap": {
+            "profile": "basic_discovery"
         }
     }
 }
diff --git a/configure.py b/configure.py
index 800fb44b4d1d92575388702ff872c86605d5fc8b..6e27c9875b1bc5c45041526789709789d28ebe17 100644
--- a/configure.py
+++ b/configure.py
@@ -6,6 +6,7 @@ import configparser
 Supported scanners:
     - w3af
     - zap
+    - nmap
 '''
 
 
@@ -49,6 +50,13 @@ def configure():
             if profile != "basic":
                 raise UnsupportedProfileException()
             cs_scripts.append("zap.sh")
+        elif scanner == "nmap":
+            cscan_config["NMAP"] = {"CS_NMAP": "nmap"}
+            if profile == "basic_discovery":
+                cscan_config["NMAP"]["CS_NMAP_ARGS"] = "-sV"
+            else:
+                raise UnsupportedProfileException()
+            cs_scripts.append("nmap.sh")
         else:
             raise UnsupportedScannerException()
     
diff --git a/wiser-wcs-reports/main.py b/wiser-wcs-reports/main.py
index e446e39dec42a63455de78fe0715c6426d6920ab..60e3d00f9463eb67778bd2cc69a0bce35ed6e7ad 100644
--- a/wiser-wcs-reports/main.py
+++ b/wiser-wcs-reports/main.py
@@ -6,6 +6,7 @@ import configparser
 import json
 import w3af
 import zap
+import nmap
 
 
 class Options(object):
@@ -55,6 +56,8 @@ def list_vulnerabilities(reports):
 			vulnerabilities.extend(zap.WiserZapReport(report_dict['OWASPZAPReport']).get_report())
 		if "w3af-run" in report_dict:
 			vulnerabilities.extend(w3af.WiserW3afReport(report_dict['w3af-run']).get_report())
+		if "nmaprun" in report_dict:
+			vulnerabilities.extend(nmap.WiserNmapReport(report_dict['nmaprun']).get_report())
 	return vulnerabilities
 
 if __name__ == "__main__":
diff --git a/wiser-wcs-reports/nmap.py b/wiser-wcs-reports/nmap.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..690c3bbf8ac7865a6ff0cdda0334ce9fcb4d6a3b 100644
--- a/wiser-wcs-reports/nmap.py
+++ b/wiser-wcs-reports/nmap.py
@@ -0,0 +1,75 @@
+from wiser import WiserReport, WiserVulnerability
+from collections import OrderedDict
+import re
+
+
+def _safe_get(ordered_dict, key):
+	try:
+		return ordered_dict[key]
+	except KeyError:
+		return ""
+
+
+class WiserNmapVulnerability(WiserVulnerability):
+
+	def __init__(self):
+		super().__init__()
+		self.risk_level = "Information"
+		self.source_pentest = "nmap"
+		self.w_risk_level = 1
+
+	@staticmethod
+	def from_port_report(report_port, address):
+		vuln = WiserNmapVulnerability()
+		vuln.short_desc = "Port %d on host %s is %s." % (report_port['@portid'],
+		                                                address,
+		                                                report_port['state']['@state'])
+		vuln.desc = ''
+		if 'service' in report_port:
+			vuln.desc = "Host %s is likely running the following service on port %d %s: " \
+			            "%s %s %s (%s) (%s) " \
+			            % (address, report_port['@portid'], report_port['@protocol'],
+			               _safe_get(report_port['service'], '@name'), _safe_get(report_port['service'], '@product'),
+			               _safe_get(report_port['service'], '@version'), _safe_get(report_port['service'], '@extrainfo'),
+			               _safe_get(report_port['service'], '@ostype'))
+		vuln.desc = re.sub('\\(\\)', '', vuln.desc).strip()
+		return vuln
+
+	@staticmethod
+	def from_host(address, state):
+		vuln = WiserNmapVulnerability()
+		vuln.short_desc = "Host %s appears to be %s." % (address, state)
+		return vuln
+
+
+class WiserNmapReport(WiserReport):
+
+	def __init__(self, report):
+		super().__init__()
+		self.parse_report(report)
+
+	def parse_report(self, report_dict):
+		if isinstance(report_dict['host'], OrderedDict):
+			self.parse_host(report_dict['host'])
+		else:
+			for i in report_dict['host']:
+				self.parse_host(i)
+
+	def parse_host(self, report_host):
+		address = ''
+		if isinstance(report_host['address'], OrderedDict):
+			address = report_host['address']['@addr']
+		else:
+			for i in report_host['address']:
+				if i['@addrtype'] == 'ipv4':
+					address = i['@addr']
+					break
+
+		if 'port' in report_host['ports']:
+			if isinstance(report_host['ports']['port'], OrderedDict):
+				self.report.append(WiserNmapVulnerability.from_port_report(report_host['ports']['port'], address))
+			else:
+				for i in report_host['ports']['port']:
+					self.report.append(WiserNmapVulnerability.from_port_report(i, address))
+		else:
+			self.report.append(WiserNmapVulnerability.from_host(address, report_host['status']['@state']))
diff --git a/wiser-wcs-reports/wiser.py b/wiser-wcs-reports/wiser.py
index 597ef1978fb8302ec2498b13897cc650c3a0587f..02ae0249b8f9238df1de656c04895cf196a78028 100644
--- a/wiser-wcs-reports/wiser.py
+++ b/wiser-wcs-reports/wiser.py
@@ -32,12 +32,6 @@ class WiserVulnerability(IterMixin):
 	def __init__(self):
 		pass
 
-	def parse_from_alert(self, alert_dict, type):
-		pass
-
-	def parse_report(self, report_dict):
-		pass
-
 	"""
 	Sets WISER risk level to the Vulnerability.
 	"""