Skip to content

Commit d6e5d01

Browse files
authored
Merge pull request #36 from hashtopolis/bug/windows-path
Adding test framework, fix for window paths and fix for preprocessors
2 parents 851161f + bd4e4dc commit d6e5d01

32 files changed

Lines changed: 2607 additions & 120 deletions

.devcontainer/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ ENV DEBIAN_FRONTEND=dialog
4343
WORKDIR /app
4444
USER vscode
4545
COPY requirements.txt /app/src/
46+
COPY requirements-tests.txt /app/src/
4647
RUN /usr/bin/pip3 install -r src/requirements.txt
48+
RUN /usr/bin/pip3 install -r src/requirements-tests.txt
4749

4850
# Check for and run optional user-supplied command to enable (advanced) customizations of the dev container
4951
RUN if [ -n "${DEV_CONTAINER_USER_CMD_POST}" ]; then echo "${DEV_CONTAINER_USER_CMD_POST}" | sh ; fi

.devcontainer/windows/Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FROM mcr.microsoft.com/windows-cssc/python3.7.2server:ltsc2022
2+
# Nano image doesn't work because some API are not available
3+
4+
# TODO: Support for USER_CMD_PRE and POST?
5+
# TODO: Create a vscode user?
6+
# TODO: OpenCL/Nvidia?
7+
8+
WORKDIR C:/App/
9+
10+
# Installing python requirements
11+
COPY requirements.txt C:/App/
12+
COPY requirements-tests.txt C:/App/
13+
RUN pip3 install -r requirements.txt -r requirements-tests.txt
14+
15+
# Fix for host.docker.internal not working
16+
COPY .devcontainer/windows/entrypoint.ps1 C:/
17+
COPY .devcontainer/windows/fix-hosts.ps1 C:/
18+
19+
# Setting entrypoint
20+
ENTRYPOINT "C:\entrypoint.ps1"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
version: "3"
2+
services:
3+
hashtopolis-agent-windows:
4+
container_name: hashtopolis_agent_windows
5+
build:
6+
context: ../..
7+
dockerfile: .devcontainer/windows/Dockerfile
8+
volumes:
9+
- ../..:C:\App\
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
powershell C:\fix-hosts.ps1
2+
cmd /c ping -t localhost > $null
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Source https://github.com/docker/for-win/issues/1976
2+
# Credits https://github.com/brunnotelma
3+
$hostsFile = "C:\Windows\System32\drivers\etc\hosts"
4+
5+
try {
6+
$DnsEntries = @("host.docker.internal", "gateway.docker.internal")
7+
# Tries resolving names for Docker
8+
foreach ($Entry in $DnsEntries) {
9+
# If any of the names are not resolved, throws an exception
10+
Resolve-DnsName -Name $Entry -ErrorAction Stop
11+
}
12+
13+
# If it passes, means that DNS is already configured
14+
Write-Host("DNS settings are already configured.")
15+
} catch {
16+
# Gets the gateway IP address, that is the Host's IP address in the Docker network
17+
$ip = (ipconfig | where-object {$_ -match "Default Gateway"} | foreach-object{$_.Split(":")[1]}).Trim()
18+
# Read the current content from Hosts file
19+
$src = [System.IO.File]::ReadAllLines($hostsFile)
20+
# Add the a new line after the content
21+
$lines = $src += ""
22+
23+
# Check the hosts file and write it in if its not there...
24+
if((cat $hostsFile | Select-String -Pattern "host.docker.internal") -And (cat $hostsFile | Select-String -Pattern "gateway.docker.internal")) {
25+
For ($i=0; $i -le $lines.length; $i++) {
26+
if ($lines[$i].Contains("host.docker.internal"))
27+
{
28+
$lines[$i] = ("{0} host.docker.internal" -f $ip)
29+
$lines[$i+1] = ("{0} gateway.docker.internal" -f $ip)
30+
break
31+
}
32+
}
33+
} else {
34+
$lines = $lines += "# Added by Docker for Windows"
35+
$lines = $lines += ("{0} host.docker.internal" -f $ip)
36+
$lines = $lines += ("{0} gateway.docker.internal" -f $ip)
37+
$lines = $lines += "# End of section"
38+
}
39+
# Writes the new content to the Hosts file
40+
[System.IO.File]::WriteAllLines($hostsFile, [string[]]$lines)
41+
42+
Write-Host("New DNS settings written successfully.")
43+
}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
*.iml
22
*.exe
3+
7zr
34
*.log
45
*.json
6+
!/tests/*.json
57
crackers
8+
preprocessors
69
prince
710
files
811
hashlists

.vscode/launch.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"version": "0.2.0",
23
"configurations": [
34
{
45
"name": "Python: Current File",

changelog.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## v0.7.0 -> v0.7.1
2+
3+
### Bugfixes
4+
5+
* Agent working again on Windows, all paths have been converted to Pathlib.Path and using the correct quoting of arguments.
6+
* 7z wordlist not extracting correctly on Windows.
7+
* preprocessor not working correctly on both Windows and Linux.
8+
19
## v0.6.1 -> v0.7.0
210

311
### Enhancements

htpclient/binarydownload.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import os.path
3+
from pathlib import Path
34
import stat
45
import sys
56
from time import sleep
@@ -135,7 +136,7 @@ def check_prince(self):
135136

136137
def check_preprocessor(self, task):
137138
logging.debug("Checking if requested preprocessor is present...")
138-
path = self.config.get_value('preprocessors-path') + "/" + str(task.get_task()['preprocessor']) + "/"
139+
path = Path(self.config.get_value('preprocessors-path'), str(task.get_task()['preprocessor']))
139140
query = copy_and_set_token(dict_downloadBinary, self.config.get_value('token'))
140141
query['type'] = 'preprocessor'
141142
query['preprocessorId'] = task.get_task()['preprocessor']
@@ -160,20 +161,20 @@ def check_preprocessor(self, task):
160161
sleep(5)
161162
return False
162163
if Initialize.get_os() == 1:
163-
os.system("7zr" + Initialize.get_os_extension() + " x -otemp temp.7z")
164+
os.system(f"7zr{Initialize.get_os_extension()} x -otemp temp.7z")
164165
else:
165-
os.system("./7zr" + Initialize.get_os_extension() + " x -otemp temp.7z")
166+
os.system(f"./7zr{Initialize.get_os_extension()} x -otemp temp.7z")
166167
for name in os.listdir("temp"): # this part needs to be done because it is compressed with the main subfolder of prince
167-
if os.path.isdir("temp/" + name):
168-
os.rename("temp/" + name, path)
168+
if os.path.isdir(Path('temp', name)):
169+
os.rename(Path('temp', name), path)
169170
break
170171
os.unlink("temp.7z")
171172
os.rmdir("temp")
172173
logging.debug("Preprocessor downloaded and extracted")
173174
return True
174175

175176
def check_version(self, cracker_id):
176-
path = self.config.get_value('crackers-path') + "/" + str(cracker_id) + "/"
177+
path = Path(self.config.get_value('crackers-path'), str(cracker_id))
177178
query = copy_and_set_token(dict_downloadBinary, self.config.get_value('token'))
178179
query['type'] = 'cracker'
179180
query['binaryVersionId'] = cracker_id
@@ -195,15 +196,28 @@ def check_version(self, cracker_id):
195196
logging.error("Download of cracker binary failed!")
196197
sleep(5)
197198
return False
199+
200+
# we need to extract the 7zip
201+
temp_folder = Path(self.config.get_value('crackers-path'), 'temp')
202+
zip_file = Path(self.config.get_value('crackers-path'), f'{cracker_id}.7z')
203+
198204
if Initialize.get_os() == 1:
199-
os.system("7zr" + Initialize.get_os_extension() + " x -o'" + self.config.get_value('crackers-path') + "/temp' '" + self.config.get_value('crackers-path') + "/" + str(cracker_id) + ".7z'")
205+
# Windows
206+
cmd = f'7zr{Initialize.get_os_extension()} x -o"{temp_folder}" "{zip_file}"'
200207
else:
201-
os.system("./7zr" + Initialize.get_os_extension() + " x -o'" + self.config.get_value('crackers-path') + "/temp' '" + self.config.get_value('crackers-path') + "/" + str(cracker_id) + ".7z'")
202-
os.unlink(self.config.get_value('crackers-path') + "/" + str(cracker_id) + ".7z")
203-
for name in os.listdir(self.config.get_value('crackers-path') + "/temp"):
204-
if os.path.isdir(self.config.get_value('crackers-path') + "/temp/" + name):
205-
os.rename(self.config.get_value('crackers-path') + "/temp/" + name, self.config.get_value('crackers-path') + "/" + str(cracker_id))
208+
# Linux
209+
cmd = f"./7zr{Initialize.get_os_extension()} x -o'{temp_folder}' '{zip_file}'"
210+
os.system(cmd)
211+
212+
# Clean up 7zip
213+
os.unlink(zip_file)
214+
215+
# Workaround for a 7zip containing a folder name or already the contents of a cracker
216+
for name in os.listdir(temp_folder):
217+
to_check_path = Path(temp_folder, name)
218+
if os.path.isdir(to_check_path):
219+
os.rename(to_check_path, path)
206220
else:
207-
os.rename(self.config.get_value('crackers-path') + "/temp", self.config.get_value('crackers-path') + "/" + str(cracker_id))
221+
os.rename(temp_folder, path)
208222
break
209223
return True

htpclient/download.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ class Download:
1414
def download(url, output, no_header=False):
1515
try:
1616
session = Session().s
17-
if Initialize.get_os() == 1:
18-
output = output.replace("/", '\\')
1917

2018
# Check header
2119
if not no_header:

0 commit comments

Comments
 (0)