Skip to content

Commit 91aa12d

Browse files
committed
Add supertask runtime estimation
Show estimated total runtime of a supertask, allowing the user to interactively size a supertask by adding or removing subtasks * Allow adding and removing subtasks to supertask * Parse hashcat command to compute runtime per subtask. Gratefully uses the code submitted by shivanraptor in hashtopolis#672 * Save line count of dictionary files and rule files in database * Compute runtime per subtask of supertask, depending on benchmark values entered by the user * Works for -a0 and -a3 hashcat attacks. Adds 'Unknown' to runtime estimate when not every subtask runtime could be estimated * Feature includes custom charsets for masks in -a3 attacks
1 parent 7af83ea commit 91aa12d

18 files changed

+1342
-42
lines changed

src/dba/models/File.class.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ class File extends AbstractModel {
99
private $isSecret;
1010
private $fileType;
1111
private $accessGroupId;
12+
private $lineCount;
1213

13-
function __construct($fileId, $filename, $size, $isSecret, $fileType, $accessGroupId) {
14+
function __construct($fileId, $filename, $size, $isSecret, $fileType, $accessGroupId, $lineCount) {
1415
$this->fileId = $fileId;
1516
$this->filename = $filename;
1617
$this->size = $size;
1718
$this->isSecret = $isSecret;
1819
$this->fileType = $fileType;
1920
$this->accessGroupId = $accessGroupId;
21+
$this->lineCount = $lineCount;
2022
}
2123

2224
function getKeyValueDict() {
@@ -27,6 +29,7 @@ function getKeyValueDict() {
2729
$dict['isSecret'] = $this->isSecret;
2830
$dict['fileType'] = $this->fileType;
2931
$dict['accessGroupId'] = $this->accessGroupId;
32+
$dict['lineCount'] = $this->lineCount;
3033

3134
return $dict;
3235
}
@@ -94,11 +97,21 @@ function getAccessGroupId() {
9497
function setAccessGroupId($accessGroupId) {
9598
$this->accessGroupId = $accessGroupId;
9699
}
100+
101+
function getLineCount() {
102+
return $this->lineCount;
103+
}
104+
105+
function setLineCount($lineCount) {
106+
$this->lineCount = $lineCount;
107+
}
108+
97109

98110
const FILE_ID = "fileId";
99111
const FILENAME = "filename";
100112
const SIZE = "size";
101113
const IS_SECRET = "isSecret";
102114
const FILE_TYPE = "fileType";
103115
const ACCESS_GROUP_ID = "accessGroupId";
116+
const LINE_COUNT = "lineCount";
104117
}

src/dba/models/FileFactory.class.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function getCacheValidTime() {
2323
* @return File
2424
*/
2525
function getNullObject() {
26-
$o = new File(-1, null, null, null, null, null);
26+
$o = new File(-1, null, null, null, null, null, null);
2727
return $o;
2828
}
2929

@@ -33,7 +33,7 @@ function getNullObject() {
3333
* @return File
3434
*/
3535
function createObjectFromDict($pk, $dict) {
36-
$o = new File($dict['fileId'], $dict['filename'], $dict['size'], $dict['isSecret'], $dict['fileType'], $dict['accessGroupId']);
36+
$o = new File($dict['fileId'], $dict['filename'], $dict['size'], $dict['isSecret'], $dict['fileType'], $dict['accessGroupId'], $dict['lineCount']);
3737
return $o;
3838
}
3939

src/inc/Util.class.php

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,12 @@ public static function insertFile($path, $name, $type, $accessGroupId) {
359359
// check if there is an old deletion request for the same filename
360360
$qF = new QueryFilter(FileDelete::FILENAME, $name, "=");
361361
Factory::getFileDeleteFactory()->massDeletion([Factory::FILTER => $qF]);
362-
363-
$file = new File(null, $name, Util::filesize($path), 1, $fileType, $accessGroupId);
362+
if ($fileType == 1) {
363+
$file = new File(null, $name, Util::filesize($path), 1, $fileType, $accessGroupId, Util::rulefileLineCount($path));
364+
}
365+
else {
366+
$file = new File(null, $name, Util::filesize($path), 1, $fileType, $accessGroupId, Util::fileLineCount($path));
367+
}
364368
$file = Factory::getFileFactory()->save($file);
365369
if ($file == null) {
366370
return false;
@@ -647,7 +651,48 @@ public static function filesize($file) {
647651

648652
return $pos;
649653
}
654+
655+
/**
656+
* This counts the number of lines in a given file
657+
* @param $file string Filepath you want to get the size from
658+
* @return int -1 if the file doesn't exist, else filesize
659+
*/
660+
public static function fileLineCount($file) {
661+
if (!file_exists($file)) {
662+
return -1;
663+
}
664+
// TODO: find out what a prettier solution for this would be, as opposed to setting the max execution time to an arbitrary two hours
665+
ini_set('max_execution_time', '7200');
666+
$file = new \SplFileObject($file, 'r');
667+
$file->seek(PHP_INT_MAX);
668+
669+
return $file->key();
670+
}
650671

672+
/**
673+
* This counts the number of lines in a rule file, excluding lines starting with # and empty lines
674+
* @param $file string Filepath you want to get the size from
675+
* @return int -1 if the file doesn't exist, else filesize
676+
*/
677+
public static function rulefileLineCount($file) {
678+
if (!file_exists($file)) {
679+
return -1;
680+
}
681+
// TODO: find out what a prettier solution for this would be, as opposed to setting the max execution time to an arbitrary two hours
682+
ini_set('max_execution_time', '7200');
683+
$lineCount = 0;
684+
$handle = fopen($file, "r");
685+
while(!feof($handle)){
686+
$line = fgets($handle);
687+
if (!(Util::startsWith($line, '#') or trim($line) == "")) {
688+
$lineCount = $lineCount + 1;
689+
}
690+
}
691+
692+
fclose($handle);
693+
return $lineCount;
694+
}
695+
651696
/**
652697
* Refreshes the page with the current url, also includes the query string.
653698
*/
@@ -1348,7 +1393,9 @@ public static function arrayOfIds($array) {
13481393
}
13491394
return $arr;
13501395
}
1351-
1396+
1397+
// new function added: fileLineCount(). This function is independent of OS.
1398+
// TODO check whether we can remove one of these functions
13521399
public static function countLines($tmpfile) {
13531400
if (stripos(PHP_OS, "WIN") === 0) {
13541401
// windows line count

src/inc/defines/files.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ class DFileAction {
1919

2020
const EDIT_FILE = "editFile";
2121
const EDIT_FILE_PERM = DAccessControl::MANAGE_FILE_ACCESS;
22+
23+
const COUNT_FILE_LINES = "countFileLines";
24+
const COUNT_FILE_LINES_PERM = DAccessControl::MANAGE_FILE_ACCESS;
2225
}

src/inc/defines/tasks.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ class DSupertaskAction {
5555

5656
const BULK_SUPERTASK = "bulkSupertaskCreation";
5757
const BULK_SUPERTASK_PERM = DAccessControl::CREATE_SUPERTASK_ACCESS;
58+
59+
const REMOVE_PRETASK_FROM_SUPERTASK = "removePretaskFromSupertask";
60+
const REMOVE_PRETASK_FROM_SUPERTASK_PERM = DAccessControl::CREATE_SUPERTASK_ACCESS;
61+
62+
const ADD_PRETASK_TO_SUPERTASK = "addPretaskToSupertask";
63+
const ADD_PRETASK_TO_SUPERTASK_PERM = DAccessControl::CREATE_SUPERTASK_ACCESS;
5864
}
5965

6066
class DTaskAction {

src/inc/handlers/FileHandler.class.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public function handle($action) {
2727
FileUtils::saveChanges($_POST['fileId'], $_POST['filename'], $_POST['accessGroupId'], AccessControl::getInstance()->getUser());
2828
FileUtils::setFileType($_POST['fileId'], $_POST['filetype'], AccessControl::getInstance()->getUser());
2929
break;
30+
case DFileAction::COUNT_FILE_LINES:
31+
AccessControl::getInstance()->checkPermission(DFileAction::COUNT_FILE_LINES_PERM);
32+
FileUtils::fileCountLines($_POST['file']);
33+
UI::addMessage(UI::SUCCESS, "Line count has been successfully calculated!");
34+
break;
3035
default:
3136
UI::addMessage(UI::ERROR, "Invalid action!");
3237
break;

src/inc/handlers/SupertaskHandler.class.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ public function handle($action) {
2929
AccessControl::getInstance()->checkPermission(DSupertaskAction::BULK_SUPERTASK_PERM);
3030
SupertaskUtils::bulkSupertask($_POST['name'], $_POST['command'], $_POST['isCpu'], $_POST['isSmall'], $_POST['crackerBinaryTypeId'], $_POST['benchtype'], @$_POST['basefile'], @$_POST['iterfile'], Login::getInstance()->getUser());
3131
break;
32+
case DSupertaskAction::REMOVE_PRETASK_FROM_SUPERTASK:
33+
AccessControl::getInstance()->checkPermission(DSupertaskAction::REMOVE_PRETASK_FROM_SUPERTASK_PERM);
34+
SupertaskUtils::removePretaskFromSupertask($_POST['supertaskId'], $_POST['pretaskId']);
35+
break;
36+
case DSupertaskAction::ADD_PRETASK_TO_SUPERTASK:
37+
AccessControl::getInstance()->checkPermission(DSupertaskAction::ADD_PRETASK_TO_SUPERTASK_PERM);
38+
SupertaskUtils::addPretaskToSupertask($_POST['supertaskId'], $_POST['pretaskId']);
39+
break;
3240
default:
3341
UI::addMessage(UI::ERROR, "Invalid action!");
3442
break;

src/inc/utils/FileUtils.class.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,4 +338,30 @@ public static function getFile($fileId, $user) {
338338
}
339339
return $file;
340340
}
341+
342+
/**
343+
* @param $fileId
344+
* @throws HTException
345+
*/
346+
public static function fileCountLines($fileId) {
347+
$file = Factory::getFileFactory()->get($fileId);
348+
$fileName = $file->getFilename();
349+
$filePath = dirname(__FILE__) . "/../../files/" . $fileName;
350+
if (!file_exists($filePath)) {
351+
throw new HTException("File not found!");
352+
}
353+
if ($file->getFileType() == 1) {
354+
$count = Util::rulefileLineCount($filePath);
355+
}
356+
else {
357+
$count = Util::fileLineCount($filePath);
358+
}
359+
360+
if ($count == -1) {
361+
throw new HTException("Could not determine line count.");
362+
}
363+
else {
364+
Factory::getFileFactory()->set($file, File::LINE_COUNT, $count);
365+
}
366+
}
341367
}

src/inc/utils/HashlistUtils.class.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public static function createWordlists($hashlistId, $user) {
208208
fclose($wordlistFile);
209209

210210
//add file to files list
211-
$file = new File(null, $wordlistName, Util::filesize($wordlistFilename), $hashlist->getIsSecret(), 0, $hashlist->getAccessGroupId());
211+
$file = new File(null, $wordlistName, Util::filesize($wordlistFilename), $hashlist->getIsSecret(), 0, $hashlist->getAccessGroupId(), null);
212212
Factory::getFileFactory()->save($file);
213213
return [$wordCount, $wordlistName, $file];
214214
}
@@ -674,7 +674,7 @@ public static function export($hashlistId, $user) {
674674
fclose($file);
675675
usleep(1000000);
676676

677-
$file = new File(null, $tmpname, Util::filesize($tmpfile), $hashlist->getIsSecret(), 0, $hashlist->getAccessGroupId());
677+
$file = new File(null, $tmpname, Util::filesize($tmpfile), $hashlist->getIsSecret(), 0, $hashlist->getAccessGroupId(), null);
678678
$file = Factory::getFileFactory()->save($file);
679679
return $file;
680680
}
@@ -759,6 +759,7 @@ public static function createHashlist($name, $isSalted, $isSecret, $isHexSalted,
759759
Factory::getAgentFactory()->getDB()->rollback();
760760
throw new HTException("Required file does not exist!");
761761
}
762+
// TODO: replace countLines with fileLineCount? Seems like a better option, not OS-dependent
762763
else if (Util::countLines($tmpfile) > SConfig::getInstance()->getVal(DConfig::MAX_HASHLIST_SIZE)) {
763764
Factory::getAgentFactory()->getDB()->rollback();
764765
throw new HTException("Hashlist has too many lines!");
@@ -1047,7 +1048,7 @@ public static function leftlist($hashlistId, $user) {
10471048
fclose($file);
10481049
usleep(1000000);
10491050

1050-
$file = new File(null, $tmpname, Util::filesize($tmpfile), $hashlist->getIsSecret(), 0, $hashlist->getAccessGroupId());
1051+
$file = new File(null, $tmpname, Util::filesize($tmpfile), $hashlist->getIsSecret(), 0, $hashlist->getAccessGroupId(), null);
10511052
return Factory::getFileFactory()->save($file);
10521053
}
10531054

src/inc/utils/SupertaskUtils.class.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,4 +463,38 @@ private static function prepareImportMasks(&$masks) {
463463
$masks[$i] = $mask;
464464
}
465465
}
466+
467+
/**
468+
* @param $supertaskId
469+
* @param $pretaskId
470+
* @throws HTException
471+
*/
472+
public static function removePretaskFromSupertask($supertaskId, $pretaskId) {
473+
if ($supertaskId == null) {
474+
throw new HTException("Invalid supertask ID!");
475+
}
476+
if ($pretaskId == null) {
477+
throw new HTException("Invalid pretask ID!");
478+
}
479+
$qF1 = new QueryFilter(SupertaskPretask::SUPERTASK_ID, $supertaskId, "=");
480+
$qF2 = new QueryFilter(SupertaskPretask::PRETASK_ID, $pretaskId, "=");
481+
$supertaskPretask = Factory::getSupertaskPretaskFactory()->filter([Factory::FILTER => [$qF1, $qF2]], true);
482+
Factory::getSupertaskPretaskFactory()->delete($supertaskPretask);
483+
}
484+
485+
/**
486+
* @param $supertaskId
487+
* @param $pretaskId
488+
* @throws HTException
489+
*/
490+
public static function addPretaskToSupertask($supertaskId, $pretaskId) {
491+
if ($supertaskId == null) {
492+
throw new HTException("Invalid supertask ID!");
493+
}
494+
if ($pretaskId == null) {
495+
throw new HTException("Invalid pretask ID!");
496+
}
497+
$supertaskPretask = new SupertaskPretask(null, $supertaskId, $pretaskId);
498+
Factory::getSupertaskPretaskFactory()->save($supertaskPretask);
499+
}
466500
}

0 commit comments

Comments
 (0)