Abacus-Group-RTO / legion

Legion is an open source, easy-to-use, super-extensible and semi-automated network penetration testing tool that aids in discovery, reconnaissance and exploitation of information systems.
GNU General Public License v3.0
1.03k stars 170 forks source link

Kali package development and discussion on some patches #244

Closed daniruiz closed 1 year ago

daniruiz commented 1 year ago

Hello! I'm a kali package maintainer and recently I've been working on the update of Kali's legion package (https://gitlab.com/kalilinux/packages/legion). Right now I'm uploading the update for version 4.1 and I would like to know your view on the changes that I've made to make it work in our system. If you could test our package in Kali and confirm that everything is working as expected that would be great too.

One major issue that I've found with the new update is that the tool is trying to write to wrong folders or to the folder where legion is installed. In one case it was just due to a missing expanduser function, but the others where caused by the function unixPath2Win, which is used in multiple places over controller.py. This function is returning paths with the backslash character which linux doesn't understand, so it creates local files with a super long filename with the route of the windows path (including backslashes). This later makes legion unable to find where it has stored these output files. Just removing these functions fixed the issue.

Fix missing expanduser in auxiliary.py

--- a/app/auxiliary.py
+++ b/app/auxiliary.py
@@ -74,9 +74,9 @@
             os.makedirs(tempPath)
         log.info("WSL is detected. The AppData Temp directory path is {0} ({1})".format(tempPath, tempPathWin))
     else:
-        tempPath = "~/.local/share/legion/tmp"
-        if not os.path.isdir(os.path.expanduser(tempPath)):
-            os.makedirs(os.path.expanduser(tempPath))
+        tempPath = os.path.expanduser("~/.local/share/legion/tmp")
+        if not os.path.isdir(tempPath):
+            os.makedirs(tempPath)
         log.info("Non-WSL The AppData Temp directory path is {0}".format(tempPath))
     return tempPath

Remove unixPath2Win calls in controller.py:

--- a/controller/controller.py
+++ b/controller/controller.py
@@ -247,20 +247,17 @@
                 self.runStagedNmap(targetHosts, runHostDiscovery)
             elif runHostDiscovery:
                 outputfile = getNmapRunningFolder(runningFolder) + "/" + getTimestamp() + '-host-discover'
-                outputfile = unixPath2Win(outputfile)
                 command = f"nmap -n -sV -O --version-light -T{str(nmapSpeed)} {targetHosts} -oA {outputfile}"
                 self.runCommand('nmap', 'nmap (discovery)', targetHosts, '', '', command, getTimestamp(True),
                                 outputfile, self.view.createNewTabForHost(str(targetHosts), 'nmap (discovery)', True))
             else:
                 outputfile = getNmapRunningFolder(runningFolder) + "/" + getTimestamp() + '-nmap-list'
-                outputfile = unixPath2Win(outputfile)
                 command = "nmap -n -sL -T" + str(nmapSpeed) + " " + targetHosts + " -oA " + outputfile
                 self.runCommand('nmap', 'nmap (list)', targetHosts, '', '', command, getTimestamp(True),
                                 outputfile,
                                 self.view.createNewTabForHost(str(targetHosts), 'nmap (list)', True))
         elif scanMode == 'Hard':
             outputfile = getNmapRunningFolder(runningFolder) + "/" + getTimestamp() + '-nmap-custom'
-            outputfile = unixPath2Win(outputfile)
             nmapOptionsString = ' '.join(nmapOptions)
             if 'randomize' not in nmapOptionsString:
                 nmapOptionsString = nmapOptionsString + " -T" + str(nmapSpeed)
@@ -363,7 +360,7 @@
                 command = str(self.settings.hostActions[i][2])
                 command = command.replace('[IP]', ip).replace('[OUTPUT]', outputfile)
                 if 'nmap' in command:
-                    command = "{0} -oA {1}".format(command, unixPath2Win(outputfile))
+                    command = "{0} -oA {1}".format(command, outputfile)

                 # check if same type of nmap scan has already been made and purge results before scanning
                 if 'nmap' in command:
@@ -434,7 +431,7 @@
                     command = str(self.settings.portActions[srvc_num][2])
                     command = command.replace('[IP]', ip[0]).replace('[PORT]', ip[1]).replace('[OUTPUT]', outputfile)
                     if 'nmap' in command:
-                        command = "{0} -oA {1}".format(command, unixPath2Win(outputfile))
+                        command = "{0} -oA {1}".format(command, outputfile)

                     if 'nmap' in command and ip[2] == 'udp':
                         command = command.replace("-sV", "-sVU")
@@ -761,7 +758,6 @@
         if not stop:
             textbox = self.view.createNewTabForHost(str(targetHosts), 'nmap (stage ' + str(stage) + ')', True)
             outputfile = getNmapRunningFolder(runningFolder) + "/" + getTimestamp() + '-nmapstage' + str(stage)
-            outputfile = unixPath2Win(outputfile)

             if stage == 1:
                 stageData = self.settings.tools_nmap_stage1_ports

Other changes that I added to kali's package:

These are not as important but I wanted to share the other modifications that I made to Kali's legion package. Maybe some of them can be merge to upstream code.

sscottgvit commented 1 year ago

@daniruiz Good recommendations. All in 4.2. Added a check isWsl() before running unixPath2Win. I test in WSL mostly, that's where that oversight came from. Second on monospaced. Added a isKali() check for eyewitness vs PhantomJS. Once Eyewitness is more broadly available I can scrap the countercase.

daniruiz commented 1 year ago

Perfect thank you! ;) I've updated the package and the latest 4.3 version is now in kali: https://pkg.kali.org/pkg/legion I've found other issues that I'll try to debug later, but I'm listing them here just in case you find a solution first:

With more time I'll open a MR or an issue with more information, but just to let you know for now.