diff --git a/ci/files/db_0.13.0.sql b/ci/files/db_0.13.0.sql new file mode 100644 index 000000000..7246637ad --- /dev/null +++ b/ci/files/db_0.13.0.sql @@ -0,0 +1,1444 @@ +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT = @@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS = @@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION = @@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- Create tables and insert default entries +CREATE TABLE `AccessGroup` ( + `accessGroupId` INT(11) NOT NULL, + `groupName` VARCHAR(50) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `AccessGroupAgent` ( + `accessGroupAgentId` INT(11) NOT NULL, + `accessGroupId` INT(11) NOT NULL, + `agentId` INT(11) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `AccessGroupUser` ( + `accessGroupUserId` INT(11) NOT NULL, + `accessGroupId` INT(11) NOT NULL, + `userId` INT(11) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `Agent` ( + `agentId` INT(11) NOT NULL, + `agentName` VARCHAR(100) NOT NULL, + `uid` VARCHAR(100) NOT NULL, + `os` INT(11) NOT NULL, + `hardwareGroupId` INT(11) DEFAULT NULL, + `cmdPars` VARCHAR(256) NOT NULL, + `ignoreErrors` TINYINT(4) NOT NULL, + `isActive` TINYINT(4) NOT NULL, + `isTrusted` TINYINT(4) NOT NULL, + `token` VARCHAR(30) NOT NULL, + `lastAct` VARCHAR(50) NOT NULL, + `lastTime` BIGINT NOT NULL, + `lastIp` VARCHAR(50) NOT NULL, + `userId` INT(11) DEFAULT NULL, + `cpuOnly` TINYINT(4) NOT NULL, + `clientSignature` VARCHAR(50) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `AgentBinary` ( + `agentBinaryId` INT(11) NOT NULL, + `type` VARCHAR(20) NOT NULL, + `version` VARCHAR(20) NOT NULL, + `operatingSystems` VARCHAR(50) NOT NULL, + `filename` VARCHAR(50) NOT NULL, + `updateTrack` VARCHAR(20) NOT NULL, + `updateAvailable` VARCHAR(20) NOT NULL +) ENGINE = InnoDB; + +INSERT INTO `AgentBinary` (`agentBinaryId`, `type`, `version`, `operatingSystems`, `filename`, `updateTrack`, `updateAvailable`) VALUES + (1, 'python', '0.7.1', 'Windows, Linux, OS X', 'hashtopolis.zip', 'stable', ''); + +CREATE TABLE `AgentError` ( + `agentErrorId` INT(11) NOT NULL, + `agentId` INT(11) NOT NULL, + `taskId` INT(11) DEFAULT NULL, + `time` BIGINT NOT NULL, + `error` TEXT NOT NULL, + `chunkId` INT(11) NULL +) ENGINE = InnoDB; + +CREATE TABLE `AgentStat` ( + `agentStatId` INT(11) NOT NULL, + `agentId` INT(11) NOT NULL, + `statType` INT(11) NOT NULL, + `time` BIGINT NOT NULL, + `value` VARCHAR(128) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `AgentZap` ( + `agentZapId` INT(11) NOT NULL, + `agentId` INT(11) NOT NULL, + `lastZapId` INT(11) NULL +) ENGINE = InnoDB; + +CREATE TABLE `Assignment` ( + `assignmentId` INT(11) NOT NULL, + `taskId` INT(11) NOT NULL, + `agentId` INT(11) NOT NULL, + `benchmark` VARCHAR(50) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `Chunk` ( + `chunkId` INT(11) NOT NULL, + `taskId` INT(11) NOT NULL, + `skip` BIGINT(20) UNSIGNED NOT NULL, + `length` BIGINT(20) UNSIGNED NOT NULL, + `agentId` INT(11) NULL, + `dispatchTime` BIGINT NOT NULL, + `solveTime` BIGINT NOT NULL, + `checkpoint` BIGINT(20) UNSIGNED NOT NULL, + `progress` INT(11) NULL, + `state` INT(11) NOT NULL, + `cracked` INT(11) NOT NULL, + `speed` BIGINT(20) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `Config` ( + `configId` INT(11) NOT NULL, + `configSectionId` INT(11) NOT NULL, + `item` VARCHAR(80) NOT NULL, + `value` TEXT NOT NULL +) ENGINE = InnoDB; + +INSERT INTO `Config` (`configId`, `configSectionId`, `item`, `value`) VALUES + (1, 1, 'agenttimeout', '30'), + (2, 1, 'benchtime', '30'), + (3, 1, 'chunktime', '600'), + (4, 1, 'chunktimeout', '30'), + (9, 1, 'fieldseparator', ':'), + (10, 1, 'hashlistAlias', '#HL#'), + (11, 1, 'statustimer', '5'), + (12, 4, 'timefmt', 'd.m.Y, H:i:s'), + (13, 1, 'blacklistChars', '&|`\"\'{}()[]$<>;'), + (14, 3, 'numLogEntries', '5000'), + (15, 1, 'disptolerance', '20'), + (16, 3, 'batchSize', '50000'), + (18, 2, 'yubikey_id', ''), + (19, 2, 'yubikey_key', ''), + (20, 2, 'yubikey_url', 'https://api.yubico.com/wsapi/2.0/verify'), + (22, 3, 'pagingSize', '5000'), + (23, 3, 'plainTextMaxLength', '200'), + (24, 3, 'hashMaxLength', '1024'), + (25, 5, 'emailSender', 'hashtopolis@example.org'), + (26, 5, 'emailSenderName', 'Hashtopolis'), + (27, 5, 'baseHost', ''), + (28, 3, 'maxHashlistSize', '5000000'), + (29, 4, 'hideImportMasks', '1'), + (30, 7, 'telegramBotToken', ''), + (31, 5, 'contactEmail', ''), + (32, 5, 'voucherDeletion', '0'), + (33, 4, 'hashesPerPage', '1000'), + (34, 4, 'hideIpInfo', '0'), + (35, 1, 'defaultBenchmark', '1'), + (36, 4, 'showTaskPerformance', '0'), + (37, 1, 'ruleSplitSmallTasks', '0'), + (38, 1, 'ruleSplitAlways', '0'), + (39, 1, 'ruleSplitDisable', '1'), + (41, 4, 'agentStatLimit', '100'), + (42, 1, 'agentDataLifetime', '3600'), + (43, 4, 'agentStatTension', '0'), + (44, 6, 'multicastEnable', '0'), + (45, 6, 'multicastDevice', 'eth0'), + (46, 6, 'multicastTransferRateEnable', '0'), + (47, 6, 'multicastTranserRate', '500000'), + (48, 1, 'disableTrimming', '0'), + (49, 5, 'serverLogLevel', '20'), + (50, 7, 'notificationsProxyEnable', '0'), + (60, 7, 'notificationsProxyServer', ''), + (61, 7, 'notificationsProxyPort', '8080'), + (62, 7, 'notificationsProxyType', 'HTTP'), + (63, 1, 'priority0Start', '0'), + (64, 5, 'baseUrl', ''), + (65, 4, 'maxSessionLength', '48'), + (66, 1, 'hashcatBrainEnable', '0'), + (67, 1, 'hashcatBrainHost', ''), + (68, 1, 'hashcatBrainPort', '0'), + (69, 1, 'hashcatBrainPass', ''), + (70, 1, 'hashlistImportCheck', '0'), + (71, 5, 'allowDeregister', '0'), + (72, 4, 'agentTempThreshold1', '70'), + (73, 4, 'agentTempThreshold2', '80'), + (74, 4, 'agentUtilThreshold1', '90'), + (75, 4, 'agentUtilThreshold2', '75'), + (76, 3, 'uApiSendTaskIsComplete', '0'), + (77, 1, 'hcErrorIgnore', 'DeviceGetFanSpeed'); + +CREATE TABLE `ConfigSection` ( + `configSectionId` INT(11) NOT NULL, + `sectionName` VARCHAR(100) NOT NULL +) ENGINE = InnoDB; + +INSERT INTO `ConfigSection` (`configSectionId`, `sectionName`) VALUES + (1, 'Cracking/Tasks'), + (2, 'Yubikey'), + (3, 'Finetuning'), + (4, 'UI'), + (5, 'Server'), + (6, 'Multicast'), + (7, 'Notifications'); + +CREATE TABLE `CrackerBinary` ( + `crackerBinaryId` INT(11) NOT NULL, + `crackerBinaryTypeId` INT(11) NOT NULL, + `version` VARCHAR(20) NOT NULL, + `downloadUrl` VARCHAR(150) NOT NULL, + `binaryName` VARCHAR(50) NOT NULL +) ENGINE = InnoDB; + +INSERT INTO `CrackerBinary` (`crackerBinaryId`, `crackerBinaryTypeId`, `version`, `downloadUrl`, `binaryName`) VALUES + (1, 1, '6.2.6', 'https://hashcat.net/files/hashcat-6.2.6.7z', 'hashcat'); + +CREATE TABLE `CrackerBinaryType` ( + `crackerBinaryTypeId` INT(11) NOT NULL, + `typeName` VARCHAR(30) NOT NULL, + `isChunkingAvailable` TINYINT(4) NOT NULL +) ENGINE = InnoDB; + +INSERT INTO `CrackerBinaryType` (`crackerBinaryTypeId`, `typeName`, `isChunkingAvailable`) VALUES + (1, 'hashcat', 1); + +CREATE TABLE `File` ( + `fileId` INT(11) NOT NULL, + `filename` VARCHAR(100) NOT NULL, + `size` BIGINT(20) NOT NULL, + `isSecret` TINYINT(4) NOT NULL, + `fileType` INT(11) NOT NULL, + `accessGroupId` INT(11) NOT NULL, + `lineCount` BIGINT(20) DEFAULT NULL +) ENGINE = InnoDB; + +CREATE TABLE `FilePretask` ( + `filePretaskId` INT(11) NOT NULL, + `fileId` INT(11) NOT NULL, + `pretaskId` INT(11) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `FileTask` ( + `fileTaskId` INT(11) NOT NULL, + `fileId` INT(11) NOT NULL, + `taskId` INT(11) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `FileDelete` ( + `fileDeleteId` INT(11) NOT NULL, + `filename` VARCHAR(256) NOT NULL, + `time` BIGINT NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE `Hash` ( + `hashId` INT(11) NOT NULL, + `hashlistId` INT(11) NOT NULL, + `hash` MEDIUMTEXT NOT NULL, + `salt` VARCHAR(256) DEFAULT NULL, + `plaintext` VARCHAR(256) DEFAULT NULL, + `timeCracked` BIGINT DEFAULT NULL, + `chunkId` INT(11) DEFAULT NULL, + `isCracked` TINYINT(4) NOT NULL, + `crackPos` BIGINT NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `HashBinary` ( + `hashBinaryId` INT(11) NOT NULL, + `hashlistId` INT(11) NOT NULL, + `essid` VARCHAR(100) NOT NULL, + `hash` LONGTEXT NOT NULL, + `plaintext` VARCHAR(1024) DEFAULT NULL, + `timeCracked` BIGINT DEFAULT NULL, + `chunkId` INT(11) DEFAULT NULL, + `isCracked` TINYINT(4) NOT NULL, + `crackPos` BIGINT NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `Hashlist` ( + `hashlistId` INT(11) NOT NULL, + `hashlistName` VARCHAR(100) NOT NULL, + `format` INT(11) NOT NULL, + `hashTypeId` INT(11) NOT NULL, + `hashCount` INT(11) NOT NULL, + `saltSeparator` VARCHAR(10) DEFAULT NULL, + `cracked` INT(11) NOT NULL, + `isSecret` TINYINT(4) NOT NULL, + `hexSalt` TINYINT(4) NOT NULL, + `isSalted` TINYINT(4) NOT NULL, + `accessGroupId` INT(11) NOT NULL, + `notes` TEXT NOT NULL, + `brainId` INT(11) NOT NULL, + `brainFeatures` TINYINT(4) NOT NULL, + `isArchived` TINYINT(4) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `HashlistHashlist` ( + `hashlistHashlistId` INT(11) NOT NULL, + `parentHashlistId` INT(11) NOT NULL, + `hashlistId` INT(11) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `HashType` ( + `hashTypeId` INT(11) NOT NULL, + `description` VARCHAR(256) NOT NULL, + `isSalted` TINYINT(4) NOT NULL, + `isSlowHash` TINYINT(4) NOT NULL +) ENGINE = InnoDB; + +INSERT INTO `HashType` (`hashTypeId`, `description`, `isSalted`, `isSlowHash`) VALUES + (0, 'MD5', 0, 0), + (10, 'md5($pass.$salt)', 1, 0), + (11, 'Joomla < 2.5.18', 1, 0), + (12, 'PostgreSQL', 1, 0), + (20, 'md5($salt.$pass)', 1, 0), + (21, 'osCommerce, xt:Commerce', 1, 0), + (22, 'Juniper Netscreen/SSG (ScreenOS)', 1, 0), + (23, 'Skype', 1, 0), + (24, 'SolarWinds Serv-U', 0, 0), + (30, 'md5(utf16le($pass).$salt)', 1, 0), + (40, 'md5($salt.utf16le($pass))', 1, 0), + (50, 'HMAC-MD5 (key = $pass)', 1, 0), + (60, 'HMAC-MD5 (key = $salt)', 1, 0), + (70, 'md5(utf16le($pass))', 0, 0), + (100, 'SHA1', 0, 0), + (101, 'nsldap, SHA-1(Base64), Netscape LDAP SHA', 0, 0), + (110, 'sha1($pass.$salt)', 1, 0), + (111, 'nsldaps, SSHA-1(Base64), Netscape LDAP SSHA', 0, 0), + (112, 'Oracle S: Type (Oracle 11+)', 1, 0), + (120, 'sha1($salt.$pass)', 1, 0), + (121, 'SMF >= v1.1', 1, 0), + (122, 'OS X v10.4, v10.5, v10.6', 0, 0), + (124, 'Django (SHA-1)', 0, 0), + (125, 'ArubaOS', 0, 0), + (130, 'sha1(utf16le($pass).$salt)', 1, 0), + (131, 'MSSQL(2000)', 0, 0), + (132, 'MSSQL(2005)', 0, 0), + (133, 'PeopleSoft', 0, 0), + (140, 'sha1($salt.utf16le($pass))', 1, 0), + (141, 'EPiServer 6.x < v4', 0, 0), + (150, 'HMAC-SHA1 (key = $pass)', 1, 0), + (160, 'HMAC-SHA1 (key = $salt)', 1, 0), + (170, 'sha1(utf16le($pass))', 0, 0), + (200, 'MySQL323', 0, 0), + (300, 'MySQL4.1/MySQL5+', 0, 0), + (400, 'phpass, MD5(Wordpress), MD5(Joomla), MD5(phpBB3)', 0, 0), + (500, 'md5crypt, MD5(Unix), FreeBSD MD5, Cisco-IOS MD5 2', 0, 0), + (501, 'Juniper IVE', 0, 0), + (600, 'BLAKE2b-512', 0, 0), + (610, 'BLAKE2b-512($pass.$salt)', 1, 0), + (620, 'BLAKE2b-512($salt.$pass)', 1, 0), + (900, 'MD4', 0, 0), + (1000, 'NTLM', 0, 0), + (1100, 'Domain Cached Credentials (DCC), MS Cache', 1, 0), + (1300, 'SHA-224', 0, 0), + (1400, 'SHA256', 0, 0), + (1410, 'sha256($pass.$salt)', 1, 0), + (1411, 'SSHA-256(Base64), LDAP {SSHA256}', 0, 0), + (1420, 'sha256($salt.$pass)', 1, 0), + (1421, 'hMailServer', 0, 0), + (1430, 'sha256(utf16le($pass).$salt)', 1, 0), + (1440, 'sha256($salt.utf16le($pass))', 1, 0), + (1441, 'EPiServer 6.x >= v4', 0, 0), + (1450, 'HMAC-SHA256 (key = $pass)', 1, 0), + (1460, 'HMAC-SHA256 (key = $salt)', 1, 0), + (1470, 'sha256(utf16le($pass))', 0, 0), + (1500, 'descrypt, DES(Unix), Traditional DES', 0, 0), + (1600, 'md5apr1, MD5(APR), Apache MD5', 0, 0), + (1700, 'SHA512', 0, 0), + (1710, 'sha512($pass.$salt)', 1, 0), + (1711, 'SSHA-512(Base64), LDAP {SSHA512}', 0, 0), + (1720, 'sha512($salt.$pass)', 1, 0), + (1722, 'OS X v10.7', 0, 0), + (1730, 'sha512(utf16le($pass).$salt)', 1, 0), + (1731, 'MSSQL(2012), MSSQL(2014)', 0, 0), + (1740, 'sha512($salt.utf16le($pass))', 1, 0), + (1750, 'HMAC-SHA512 (key = $pass)', 1, 0), + (1760, 'HMAC-SHA512 (key = $salt)', 1, 0), + (1770, 'sha512(utf16le($pass))', 0, 0), + (1800, 'sha512crypt, SHA512(Unix)', 0, 0), + (2000, 'STDOUT', 0, 0), + (2100, 'Domain Cached Credentials 2 (DCC2), MS Cache', 0, 1), + (2400, 'Cisco-PIX MD5', 0, 0), + (2410, 'Cisco-ASA MD5', 1, 0), + (2500, 'WPA/WPA2', 0, 1), + (2501, 'WPA-EAPOL-PMK', 0, 1), + (2600, 'md5(md5($pass))', 0, 0), + (2611, 'vBulletin < v3.8.5', 1, 0), + (2612, 'PHPS', 0, 0), + (2711, 'vBulletin >= v3.8.5', 1, 0), + (2811, 'IPB2+, MyBB1.2+', 1, 0), + (3000, 'LM', 0, 0), + (3100, 'Oracle H: Type (Oracle 7+), DES(Oracle)', 1, 0), + (3200, 'bcrypt, Blowfish(OpenBSD)', 0, 0), + (3500, 'md5(md5(md5($pass)))', 0, 0), + (3710, 'md5($salt.md5($pass))', 1, 0), + (3711, 'Mediawiki B type', 0, 0), + (3800, 'md5($salt.$pass.$salt)', 1, 0), + (3910, 'md5(md5($pass).md5($salt))', 1, 0), + (4010, 'md5($salt.md5($salt.$pass))', 1, 0), + (4110, 'md5($salt.md5($pass.$salt))', 1, 0), + (4300, 'md5(strtoupper(md5($pass)))', 0, 0), + (4400, 'md5(sha1($pass))', 0, 0), + (4410, 'md5(sha1($pass).$salt)', 1, 0), + (4500, 'sha1(sha1($pass))', 0, 0), + (4510, 'sha1(sha1($pass).$salt)', 1, 0), + (4520, 'sha1($salt.sha1($pass))', 1, 0), + (4521, 'Redmine Project Management Web App', 0, 0), + (4522, 'PunBB', 0, 0), + (4700, 'sha1(md5($pass))', 0, 0), + (4710, 'sha1(md5($pass).$salt)', 1, 0), + (4711, 'Huawei sha1(md5($pass).$salt)', 1, 0), + (4800, 'MD5(Chap), iSCSI CHAP authentication', 1, 0), + (4900, 'sha1($salt.$pass.$salt)', 1, 0), + (5000, 'SHA-3(Keccak)', 0, 0), + (5100, 'Half MD5', 0, 0), + (5200, 'Password Safe v3', 0, 1), + (5300, 'IKE-PSK MD5', 0, 0), + (5400, 'IKE-PSK SHA1', 0, 0), + (5500, 'NetNTLMv1-VANILLA / NetNTLMv1+ESS', 0, 0), + (5600, 'NetNTLMv2', 0, 0), + (5700, 'Cisco-IOS SHA256', 0, 0), + (5800, 'Samsung Android Password/PIN', 1, 0), + (6000, 'RipeMD160', 0, 0), + (6100, 'Whirlpool', 0, 0), + (6211, 'TrueCrypt 5.0+ PBKDF2-HMAC-RipeMD160 + AES/Serpent/Twofish', 0, 1), + (6212, 'TrueCrypt 5.0+ PBKDF2-HMAC-RipeMD160 + AES-Twofish/Serpent-AES/Twofish-Serpent', 0, 1), + (6213, 'TrueCrypt 5.0+ PBKDF2-HMAC-RipeMD160 + AES-Twofish-Serpent/Serpent-Twofish-AES', 0, 1), + (6221, 'TrueCrypt 5.0+ SHA512 + AES/Serpent/Twofish', 0, 1), + (6222, 'TrueCrypt 5.0+ SHA512 + AES-Twofish/Serpent-AES/Twofish-Serpent', 0, 1), + (6223, 'TrueCrypt 5.0+ SHA512 + AES-Twofish-Serpent/Serpent-Twofish-AES', 0, 1), + (6231, 'TrueCrypt 5.0+ Whirlpool + AES/Serpent/Twofish', 0, 1), + (6232, 'TrueCrypt 5.0+ Whirlpool + AES-Twofish/Serpent-AES/Twofish-Serpent', 0, 1), + (6233, 'TrueCrypt 5.0+ Whirlpool + AES-Twofish-Serpent/Serpent-Twofish-AES', 0, 1), + (6241, 'TrueCrypt 5.0+ PBKDF2-HMAC-RipeMD160 + AES/Serpent/Twofish + boot', 0, 1), + (6242, 'TrueCrypt 5.0+ PBKDF2-HMAC-RipeMD160 + AES-Twofish/Serpent-AES/Twofish-Serpent + boot', 0, 1), + (6243, 'TrueCrypt 5.0+ PBKDF2-HMAC-RipeMD160 + AES-Twofish-Serpent/Serpent-Twofish-AES + boot', 0, 1), + (6300, 'AIX {smd5}', 0, 0), + (6400, 'AIX {ssha256}', 0, 1), + (6500, 'AIX {ssha512}', 0, 1), + (6600, '1Password, Agile Keychain', 0, 1), + (6700, 'AIX {ssha1}', 0, 1), + (6800, 'Lastpass', 1, 1), + (6900, 'GOST R 34.11-94', 0, 0), + (7000, 'Fortigate (FortiOS)', 0, 0), + (7100, 'OS X v10.8 / v10.9', 0, 1), + (7200, 'GRUB 2', 0, 1), + (7300, 'IPMI2 RAKP HMAC-SHA1', 1, 0), + (7400, 'sha256crypt, SHA256(Unix)', 0, 0), + (7401, 'MySQL $A$ (sha256crypt)', 0, 0), + (7500, 'Kerberos 5 AS-REQ Pre-Auth', 0, 0), + (7700, 'SAP CODVN B (BCODE)', 0, 0), + (7701, 'SAP CODVN B (BCODE) from RFC_READ_TABLE', 0, 0), + (7800, 'SAP CODVN F/G (PASSCODE)', 0, 0), + (7801, 'SAP CODVN F/G (PASSCODE) from RFC_READ_TABLE', 0, 0), + (7900, 'Drupal7', 0, 0), + (8000, 'Sybase ASE', 0, 0), + (8100, 'Citrix Netscaler', 0, 0), + (8200, '1Password, Cloud Keychain', 0, 1), + (8300, 'DNSSEC (NSEC3)', 1, 0), + (8400, 'WBB3, Woltlab Burning Board 3', 1, 0), + (8500, 'RACF', 0, 0), + (8600, 'Lotus Notes/Domino 5', 0, 0), + (8700, 'Lotus Notes/Domino 6', 0, 0), + (8800, 'Android FDE <= 4.3', 0, 1), + (8900, 'scrypt', 1, 0), + (9000, 'Password Safe v2', 0, 0), + (9100, 'Lotus Notes/Domino', 0, 1), + (9200, 'Cisco $8$', 0, 1), + (9300, 'Cisco $9$', 0, 0), + (9400, 'Office 2007', 0, 1), + (9500, 'Office 2010', 0, 1), + (9600, 'Office 2013', 0, 1), + (9700, 'MS Office ⇐ 2003 MD5 + RC4, oldoffice$0, oldoffice$1', 0, 0), + (9710, 'MS Office <= 2003 $0/$1, MD5 + RC4, collider #1', 0, 0), + (9720, 'MS Office <= 2003 $0/$1, MD5 + RC4, collider #2', 0, 0), + (9800, 'MS Office ⇐ 2003 SHA1 + RC4, oldoffice$3, oldoffice$4', 0, 0), + (9810, 'MS Office <= 2003 $3, SHA1 + RC4, collider #1', 0, 0), + (9820, 'MS Office <= 2003 $3, SHA1 + RC4, collider #2', 0, 0), + (9900, 'Radmin2', 0, 0), + (10000, 'Django (PBKDF2-SHA256)', 0, 1), + (10100, 'SipHash', 1, 0), + (10200, 'Cram MD5', 0, 0), + (10300, 'SAP CODVN H (PWDSALTEDHASH) iSSHA-1', 0, 0), + (10400, 'PDF 1.1 - 1.3 (Acrobat 2 - 4)', 0, 0), + (10410, 'PDF 1.1 - 1.3 (Acrobat 2 - 4), collider #1', 0, 0), + (10420, 'PDF 1.1 - 1.3 (Acrobat 2 - 4), collider #2', 0, 0), + (10500, 'PDF 1.4 - 1.6 (Acrobat 5 - 8)', 0, 0), + (10600, 'PDF 1.7 Level 3 (Acrobat 9)', 0, 0), + (10700, 'PDF 1.7 Level 8 (Acrobat 10 - 11)', 0, 0), + (10800, 'SHA384', 0, 0), + (10810, 'sha384($pass.$salt)', 1, 0), + (10820, 'sha384($salt.$pass)', 1, 0), + (10830, 'sha384(utf16le($pass).$salt)', 1, 0), + (10840, 'sha384($salt.utf16le($pass))', 1, 0), + (10870, 'sha384(utf16le($pass))', 0, 0), + (10900, 'PBKDF2-HMAC-SHA256', 0, 1), + (10901, 'RedHat 389-DS LDAP (PBKDF2-HMAC-SHA256)', 0, 1), + (11000, 'PrestaShop', 1, 0), + (11100, 'PostgreSQL Challenge-Response Authentication (MD5)', 0, 0), + (11200, 'MySQL Challenge-Response Authentication (SHA1)', 0, 0), + (11300, 'Bitcoin/Litecoin wallet.dat', 0, 1), + (11400, 'SIP digest authentication (MD5)', 0, 0), + (11500, 'CRC32', 1, 0), + (11600, '7-Zip', 0, 0), + (11700, 'GOST R 34.11-2012 (Streebog) 256-bit', 0, 0), + (11750, 'HMAC-Streebog-256 (key = $pass), big-endian', 0, 0), + (11760, 'HMAC-Streebog-256 (key = $salt), big-endian', 0, 0), + (11800, 'GOST R 34.11-2012 (Streebog) 512-bit', 0, 0), + (11850, 'HMAC-Streebog-512 (key = $pass), big-endian', 0, 0), + (11860, 'HMAC-Streebog-512 (key = $salt), big-endian', 0, 0), + (11900, 'PBKDF2-HMAC-MD5', 0, 1), + (12000, 'PBKDF2-HMAC-SHA1', 0, 1), + (12001, 'Atlassian (PBKDF2-HMAC-SHA1)', 0, 1), + (12100, 'PBKDF2-HMAC-SHA512', 0, 1), + (12200, 'eCryptfs', 0, 1), + (12300, 'Oracle T: Type (Oracle 12+)', 0, 1), + (12400, 'BSDiCrypt, Extended DES', 0, 0), + (12500, 'RAR3-hp', 0, 0), + (12600, 'ColdFusion 10+', 1, 0), + (12700, 'Blockchain, My Wallet', 0, 1), + (12800, 'MS-AzureSync PBKDF2-HMAC-SHA256', 0, 1), + (12900, 'Android FDE (Samsung DEK)', 0, 1), + (13000, 'RAR5', 0, 1), + (13100, 'Kerberos 5 TGS-REP etype 23', 0, 0), + (13200, 'AxCrypt', 0, 0), + (13300, 'AxCrypt in memory SHA1', 0, 0), + (13400, 'Keepass 1/2 AES/Twofish with/without keyfile', 0, 0), + (13500, 'PeopleSoft PS_TOKEN', 1, 0), + (13600, 'WinZip', 0, 1), + (13711, 'VeraCrypt PBKDF2-HMAC-RIPEMD160 + AES, Serpent, Twofish', 0, 1), + (13712, 'VeraCrypt PBKDF2-HMAC-RIPEMD160 + AES-Twofish, Serpent-AES, Twofish-Serpent', 0, 1), + (13713, 'VeraCrypt PBKDF2-HMAC-RIPEMD160 + Serpent-Twofish-AES', 0, 1), + (13721, 'VeraCrypt PBKDF2-HMAC-SHA512 + AES, Serpent, Twofish', 0, 1), + (13722, 'VeraCrypt PBKDF2-HMAC-SHA512 + AES-Twofish, Serpent-AES, Twofish-Serpent', 0, 1), + (13723, 'VeraCrypt PBKDF2-HMAC-SHA512 + Serpent-Twofish-AES', 0, 1), + (13731, 'VeraCrypt PBKDF2-HMAC-Whirlpool + AES, Serpent, Twofish', 0, 1), + (13732, 'VeraCrypt PBKDF2-HMAC-Whirlpool + AES-Twofish, Serpent-AES, Twofish-Serpent', 0, 1), + (13733, 'VeraCrypt PBKDF2-HMAC-Whirlpool + Serpent-Twofish-AES', 0, 1), + (13741, 'VeraCrypt PBKDF2-HMAC-RIPEMD160 + boot-mode + AES', 0, 1), + (13742, 'VeraCrypt PBKDF2-HMAC-RIPEMD160 + boot-mode + AES-Twofish', 0, 1), + (13743, 'VeraCrypt PBKDF2-HMAC-RIPEMD160 + boot-mode + AES-Twofish-Serpent', 0, 1), + (13751, 'VeraCrypt PBKDF2-HMAC-SHA256 + AES, Serpent, Twofish', 0, 1), + (13752, 'VeraCrypt PBKDF2-HMAC-SHA256 + AES-Twofish, Serpent-AES, Twofish-Serpent', 0, 1), + (13753, 'VeraCrypt PBKDF2-HMAC-SHA256 + Serpent-Twofish-AES', 0, 1), + (13761, 'VeraCrypt PBKDF2-HMAC-SHA256 + boot-mode (PIM + AES | Twofish)', 0, 1), + (13762, 'VeraCrypt PBKDF2-HMAC-SHA256 + boot-mode + Serpent-AES', 0, 1), + (13763, 'VeraCrypt PBKDF2-HMAC-SHA256 + boot-mode + Serpent-Twofish-AES', 0, 1), + (13771, 'VeraCrypt Streebog-512 + XTS 512 bit', 0, 1), + (13772, 'VeraCrypt Streebog-512 + XTS 1024 bit', 0, 1), + (13773, 'VeraCrypt Streebog-512 + XTS 1536 bit', 0, 1), + (13781, 'VeraCrypt Streebog-512 + XTS 512 bit + boot-mode (legacy)', 0, 1), + (13782, 'VeraCrypt Streebog-512 + XTS 1024 bit + boot-mode (legacy)', 0, 1), + (13783, 'VeraCrypt Streebog-512 + XTS 1536 bit + boot-mode (legacy)', 0, 1), + (13800, 'Windows 8+ phone PIN/Password', 1, 0), + (13900, 'OpenCart', 1, 0), + (14000, 'DES (PT = $salt, key = $pass)', 1, 0), + (14100, '3DES (PT = $salt, key = $pass)', 1, 0), + (14400, 'sha1(CX)', 1, 0), + (14500, 'Linux Kernel Crypto API (2.4)', 0, 0), + (14600, 'LUKS 10', 0, 1), + (14700, 'iTunes Backup < 10.0 11', 0, 1), + (14800, 'iTunes Backup >= 10.0 11', 0, 1), + (14900, 'Skip32 12', 1, 0), + (15000, 'FileZilla Server >= 0.9.55', 1, 0), + (15100, 'Juniper/NetBSD sha1crypt', 0, 1), + (15200, 'Blockchain, My Wallet, V2', 0, 0), + (15300, 'DPAPI masterkey file v1 and v2', 0, 1), + (15310, 'DPAPI masterkey file v1 (context 3)', 0, 1), + (15400, 'ChaCha20', 0, 0), + (15500, 'JKS Java Key Store Private Keys (SHA1)', 0, 0), + (15600, 'Ethereum Wallet, PBKDF2-HMAC-SHA256', 0, 1), + (15700, 'Ethereum Wallet, SCRYPT', 0, 0), + (15900, 'DPAPI master key file version 2 + Active Directory domain context', 0, 1), + (15910, 'DPAPI masterkey file v2 (context 3)', 0, 1), + (16000, 'Tripcode', 0, 0), + (16100, 'TACACS+', 0, 0), + (16200, 'Apple Secure Notes', 0, 1), + (16300, 'Ethereum Pre-Sale Wallet, PBKDF2-HMAC-SHA256', 0, 1), + (16400, 'CRAM-MD5 Dovecot', 0, 0), + (16500, 'JWT (JSON Web Token)', 0, 0), + (16600, 'Electrum Wallet (Salt-Type 1-3)', 0, 0), + (16700, 'FileVault 2', 0, 1), + (16800, 'WPA-PMKID-PBKDF2', 0, 1), + (16801, 'WPA-PMKID-PMK', 0, 1), + (16900, 'Ansible Vault', 0, 1), + (17010, 'GPG (AES-128/AES-256 (SHA-1($pass)))', 0, 1), + (17200, 'PKZIP (Compressed)', 0, 0), + (17210, 'PKZIP (Uncompressed)', 0, 0), + (17220, 'PKZIP (Compressed Multi-File)', 0, 0), + (17225, 'PKZIP (Mixed Multi-File)', 0, 0), + (17230, 'PKZIP (Compressed Multi-File Checksum-Only)', 0, 0), + (17300, 'SHA3-224', 0, 0), + (17400, 'SHA3-256', 0, 0), + (17500, 'SHA3-384', 0, 0), + (17600, 'SHA3-512', 0, 0), + (17700, 'Keccak-224', 0, 0), + (17800, 'Keccak-256', 0, 0), + (17900, 'Keccak-384', 0, 0), + (18000, 'Keccak-512', 0, 0), + (18100, 'TOTP (HMAC-SHA1)', 1, 0), + (18200, 'Kerberos 5 AS-REP etype 23', 0, 1), + (18300, 'Apple File System (APFS)', 0, 1), + (18400, 'Open Document Format (ODF) 1.2 (SHA-256, AES)', 0, 1), + (18500, 'sha1(md5(md5($pass)))', 0, 0), + (18600, 'Open Document Format (ODF) 1.1 (SHA-1, Blowfish)', 0, 1), + (18700, 'Java Object hashCode()', 0, 1), + (18800, 'Blockchain, My Wallet, Second Password (SHA256)', 0, 1), + (18900, 'Android Backup', 0, 1), + (19000, 'QNX /etc/shadow (MD5)', 0, 1), + (19100, 'QNX /etc/shadow (SHA256)', 0, 1), + (19200, 'QNX /etc/shadow (SHA512)', 0, 1), + (19300, 'sha1($salt1.$pass.$salt2)', 0, 0), + (19500, 'Ruby on Rails Restful-Authentication', 0, 0), + (19600, 'Kerberos 5 TGS-REP etype 17 (AES128-CTS-HMAC-SHA1-96)', 0, 1), + (19700, 'Kerberos 5 TGS-REP etype 18 (AES256-CTS-HMAC-SHA1-96)', 0, 1), + (19800, 'Kerberos 5, etype 17, Pre-Auth', 0, 1), + (19900, 'Kerberos 5, etype 18, Pre-Auth', 0, 1), + (20011, 'DiskCryptor SHA512 + XTS 512 bit (AES) / DiskCryptor SHA512 + XTS 512 bit (Twofish) / DiskCryptor SHA512 + XTS 512 bit (Serpent)', 0, 1), + (20012, 'DiskCryptor SHA512 + XTS 1024 bit (AES-Twofish) / DiskCryptor SHA512 + XTS 1024 bit (Twofish-Serpent) / DiskCryptor SHA512 + XTS 1024 bit (Serpent-AES)', 0, 1), + (20013, 'DiskCryptor SHA512 + XTS 1536 bit (AES-Twofish-Serpent)', 0, 1), + (20200, 'Python passlib pbkdf2-sha512', 0, 1), + (20300, 'Python passlib pbkdf2-sha256', 0, 1), + (20400, 'Python passlib pbkdf2-sha1', 0, 0), + (20500, 'PKZIP Master Key', 0, 0), + (20510, 'PKZIP Master Key (6 byte optimization)', 0, 0), + (20600, 'Oracle Transportation Management (SHA256)', 0, 0), + (20710, 'sha256(sha256($pass).$salt)', 1, 0), + (20711, 'AuthMe sha256', 0, 0), + (20720, 'sha256($salt.sha256($pass))', 1, 0), + (20800, 'sha256(md5($pass))', 0, 0), + (20900, 'md5(sha1($pass).md5($pass).sha1($pass))', 0, 0), + (21000, 'BitShares v0.x - sha512(sha512_bin(pass))', 0, 0), + (21100, 'sha1(md5($pass.$salt))', 1, 0), + (21200, 'md5(sha1($salt).md5($pass))', 1, 0), + (21300, 'md5($salt.sha1($salt.$pass))', 1, 0), + (21400, 'sha256(sha256_bin(pass))', 0, 0), + (21420, 'sha256($salt.sha256_bin($pass))', 1, 0), + (21500, 'SolarWinds Orion', 0, 0), + (21501, 'SolarWinds Orion v2', 0, 0), + (21600, 'Web2py pbkdf2-sha512', 0, 0), + (21700, 'Electrum Wallet (Salt-Type 4)', 0, 0), + (21800, 'Electrum Wallet (Salt-Type 5)', 0, 0), + (22000, 'WPA-PBKDF2-PMKID+EAPOL', 0, 0), + (22001, 'WPA-PMK-PMKID+EAPOL', 0, 0), + (22100, 'BitLocker', 0, 0), + (22200, 'Citrix NetScaler (SHA512)', 0, 0), + (22300, 'sha256($salt.$pass.$salt)', 1, 0), + (22301, 'Telegram client app passcode (SHA256)', 0, 0), + (22400, 'AES Crypt (SHA256)', 0, 0), + (22500, 'MultiBit Classic .key (MD5)', 0, 0), + (22600, 'Telegram Desktop App Passcode (PBKDF2-HMAC-SHA1)', 0, 0), + (22700, 'MultiBit HD (scrypt)', 0, 1), + (22911, 'RSA/DSA/EC/OPENSSH Private Keys ($0$)', 0, 0), + (22921, 'RSA/DSA/EC/OPENSSH Private Keys ($6$)', 0, 0), + (22931, 'RSA/DSA/EC/OPENSSH Private Keys ($1, $3$)', 0, 0), + (22941, 'RSA/DSA/EC/OPENSSH Private Keys ($4$)', 0, 0), + (22951, 'RSA/DSA/EC/OPENSSH Private Keys ($5$)', 0, 0), + (23001, 'SecureZIP AES-128', 0, 0), + (23002, 'SecureZIP AES-192', 0, 0), + (23003, 'SecureZIP AES-256', 0, 0), + (23100, 'Apple Keychain', 0, 1), + (23200, 'XMPP SCRAM PBKDF2-SHA1', 0, 0), + (23300, 'Apple iWork', 0, 0), + (23400, 'Bitwarden', 0, 0), + (23500, 'AxCrypt 2 AES-128', 0, 0), + (23600, 'AxCrypt 2 AES-256', 0, 0), + (23700, 'RAR3-p (Uncompressed)', 0, 0), + (23800, 'RAR3-p (Compressed)', 0, 0), + (23900, 'BestCrypt v3 Volume Encryption', 0, 0), + (24100, 'MongoDB ServerKey SCRAM-SHA-1', 0, 0), + (24200, 'MongoDB ServerKey SCRAM-SHA-256', 0, 0), + (24300, 'sha1($salt.sha1($pass.$salt))', 1, 0), + (24410, 'PKCS#8 Private Keys (PBKDF2-HMAC-SHA1 + 3DES/AES)', 0, 0), + (24420, 'PKCS#8 Private Keys (PBKDF2-HMAC-SHA256 + 3DES/AES)', 0, 0), + (24500, 'Telegram Desktop >= v2.1.14 (PBKDF2-HMAC-SHA512)', 0, 0), + (24600, 'SQLCipher', 0, 0), + (24700, 'Stuffit5', 0, 0), + (24800, 'Umbraco HMAC-SHA1', 0, 0), + (24900, 'Dahua Authentication MD5', 0, 0), + (25000, 'SNMPv3 HMAC-MD5-96/HMAC-SHA1-96', 0, 1), + (25100, 'SNMPv3 HMAC-MD5-96', 0, 1), + (25200, 'SNMPv3 HMAC-SHA1-96', 0, 1), + (25300, 'MS Office 2016 - SheetProtection', 0, 0), + (25400, 'PDF 1.4 - 1.6 (Acrobat 5 - 8) - edit password', 0, 0), + (25500, 'Stargazer Stellar Wallet XLM', 0, 0), + (25600, 'bcrypt(md5($pass)) / bcryptmd5', 0, 1), + (25700, 'MurmurHash', 1, 0), + (25800, 'bcrypt(sha1($pass)) / bcryptsha1', 0, 1), + (25900, 'KNX IP Secure - Device Authentication Code', 0, 0), + (26000, 'Mozilla key3.db', 0, 0), + (26100, 'Mozilla key4.db', 0, 0), + (26200, 'OpenEdge Progress Encode', 0, 0), + (26300, 'FortiGate256 (FortiOS256)', 0, 0), + (26401, 'AES-128-ECB NOKDF (PT = $salt, key = $pass)', 0, 0), + (26402, 'AES-192-ECB NOKDF (PT = $salt, key = $pass)', 0, 0), + (26403, 'AES-256-ECB NOKDF (PT = $salt, key = $pass)', 0, 0), + (26500, 'iPhone passcode (UID key + System Keybag)', 0, 0), + (26600, 'MetaMask Wallet', 0, 1), + (26700, 'SNMPv3 HMAC-SHA224-128', 0, 0), + (26800, 'SNMPv3 HMAC-SHA256-192', 0, 0), + (26900, 'SNMPv3 HMAC-SHA384-256', 0, 0), + (27000, 'NetNTLMv1 / NetNTLMv1+ESS (NT)', 0, 0), + (27100, 'NetNTLMv2 (NT)', 0, 0), + (27200, 'Ruby on Rails Restful Auth (one round, no sitekey)', 1, 0), + (27300, 'SNMPv3 HMAC-SHA512-384', 0, 0), + (27400, 'VMware VMX (PBKDF2-HMAC-SHA1 + AES-256-CBC)', 0, 0), + (27500, 'VirtualBox (PBKDF2-HMAC-SHA256 & AES-128-XTS)', 0, 1), + (27600, 'VirtualBox (PBKDF2-HMAC-SHA256 & AES-256-XTS)', 0, 1), + (27700, 'MultiBit Classic .wallet (scrypt)', 0, 0), + (27800, 'MurmurHash3', 1, 0), + (27900, 'CRC32C', 1, 0), + (28000, 'CRC64Jones', 1, 0), + (28100, 'Windows Hello PIN/Password', 0, 1), + (28200, 'Exodus Desktop Wallet (scrypt)', 0, 0), + (28300, 'Teamspeak 3 (channel hash)', 0, 0), + (28400, 'bcrypt(sha512($pass)) / bcryptsha512', 0, 0), + (28501, 'Bitcoin WIF private key (P2PKH), compressed', 0, 0), + (28502, 'Bitcoin WIF private key (P2PKH), uncompressed', 0, 0), + (28503, 'Bitcoin WIF private key (P2WPKH, Bech32), compressed', 0, 0), + (28504, 'Bitcoin WIF private key (P2WPKH, Bech32), uncompressed', 0, 0), + (28505, 'Bitcoin WIF private key (P2SH(P2WPKH)), compressed', 0, 0), + (28506, 'Bitcoin WIF private key (P2SH(P2WPKH)), uncompressed', 0, 0), + (28600, 'PostgreSQL SCRAM-SHA-256', 0, 1), + (28700, 'Amazon AWS4-HMAC-SHA256', 0, 0), + (28800, 'Kerberos 5, etype 17, DB', 0, 1), + (28900, 'Kerberos 5, etype 18, DB', 0, 1), + (29000, 'sha1($salt.sha1(utf16le($username).'':''.utf16le($pass)))', 0, 0), + (29100, 'Flask Session Cookie ($salt.$salt.$pass)', 0, 0), + (29200, 'Radmin3', 0, 0), + (29311, 'TrueCrypt RIPEMD160 + XTS 512 bit', 0, 0), + (29312, 'TrueCrypt RIPEMD160 + XTS 1024 bit', 0, 0), + (29313, 'TrueCrypt RIPEMD160 + XTS 1536 bit', 0, 0), + (29321, 'TrueCrypt SHA512 + XTS 512 bit', 0, 0), + (29322, 'TrueCrypt SHA512 + XTS 1024 bit', 0, 0), + (29323, 'TrueCrypt SHA512 + XTS 1536 bit', 0, 0), + (29331, 'TrueCrypt Whirlpool + XTS 512 bit', 0, 0), + (29332, 'TrueCrypt Whirlpool + XTS 1024 bit', 0, 0), + (29333, 'TrueCrypt Whirlpool + XTS 1536 bit', 0, 0), + (29341, 'TrueCrypt RIPEMD160 + XTS 512 bit + boot-mode', 0, 0), + (29342, 'TrueCrypt RIPEMD160 + XTS 1024 bit + boot-mode', 0, 0), + (29343, 'TrueCrypt RIPEMD160 + XTS 1536 bit + boot-mode', 0, 0), + (29411, 'VeraCrypt RIPEMD160 + XTS 512 bit', 0, 0), + (29412, 'VeraCrypt RIPEMD160 + XTS 1024 bit', 0, 0), + (29413, 'VeraCrypt RIPEMD160 + XTS 1536 bit', 0, 0), + (29421, 'VeraCrypt SHA512 + XTS 512 bit', 0, 0), + (29422, 'VeraCrypt SHA512 + XTS 1024 bit', 0, 0), + (29423, 'VeraCrypt SHA512 + XTS 1536 bit', 0, 0), + (29431, 'VeraCrypt Whirlpool + XTS 512 bit', 0, 0), + (29432, 'VeraCrypt Whirlpool + XTS 1024 bit', 0, 0), + (29433, 'VeraCrypt Whirlpool + XTS 1536 bit', 0, 0), + (29441, 'VeraCrypt RIPEMD160 + XTS 512 bit + boot-mode', 0, 0), + (29442, 'VeraCrypt RIPEMD160 + XTS 1024 bit + boot-mode', 0, 0), + (29443, 'VeraCrypt RIPEMD160 + XTS 1536 bit + boot-mode', 0, 0), + (29451, 'VeraCrypt SHA256 + XTS 512 bit', 0, 0), + (29452, 'VeraCrypt SHA256 + XTS 1024 bit', 0, 0), + (29453, 'VeraCrypt SHA256 + XTS 1536 bit', 0, 0), + (29461, 'VeraCrypt SHA256 + XTS 512 bit + boot-mode', 0, 0), + (29462, 'VeraCrypt SHA256 + XTS 1024 bit + boot-mode', 0, 0), + (29463, 'VeraCrypt SHA256 + XTS 1536 bit + boot-mode', 0, 0), + (29471, 'VeraCrypt Streebog-512 + XTS 512 bit', 0, 0), + (29472, 'VeraCrypt Streebog-512 + XTS 1024 bit', 0, 0), + (29473, 'VeraCrypt Streebog-512 + XTS 1536 bit', 0, 0), + (29481, 'VeraCrypt Streebog-512 + XTS 512 bit + boot-mode', 0, 0), + (29482, 'VeraCrypt Streebog-512 + XTS 1024 bit + boot-mode', 0, 0), + (29483, 'VeraCrypt Streebog-512 + XTS 1536 bit + boot-mode', 0, 0), + (29511, 'LUKS v1 SHA-1 + AES', 0, 1), + (29512, 'LUKS v1 SHA-1 + Serpent', 0, 1), + (29513, 'LUKS v1 SHA-1 + Twofish', 0, 1), + (29521, 'LUKS v1 SHA-256 + AES', 0, 1), + (29522, 'LUKS v1 SHA-256 + Serpent', 0, 1), + (29523, 'LUKS v1 SHA-256 + Twofish', 0, 1), + (29531, 'LUKS v1 SHA-512 + AES', 0, 1), + (29532, 'LUKS v1 SHA-512 + Serpent', 0, 1), + (29533, 'LUKS v1 SHA-512 + Twofish', 0, 1), + (29541, 'LUKS v1 RIPEMD-160 + AES', 0, 1), + (29542, 'LUKS v1 RIPEMD-160 + Serpent', 0, 1), + (29543, 'LUKS v1 RIPEMD-160 + Twofish', 0, 1), + (29600, 'Terra Station Wallet (AES256-CBC(PBKDF2($pass)))', 0, 1), + (29700, 'KeePass 1 (AES/Twofish) and KeePass 2 (AES) - keyfile only mode', 0, 1), + (30000, 'Python Werkzeug MD5 (HMAC-MD5 (key = $salt))', 0, 0), + (30120, 'Python Werkzeug SHA256 (HMAC-SHA256 (key = $salt))', 0, 0), + (99999, 'Plaintext', 0, 0); + +CREATE TABLE `LogEntry` ( + `logEntryId` INT(11) NOT NULL, + `issuer` VARCHAR(50) NOT NULL, + `issuerId` VARCHAR(50) NOT NULL, + `level` VARCHAR(50) NOT NULL, + `message` TEXT NOT NULL, + `time` BIGINT NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `NotificationSetting` ( + `notificationSettingId` INT(11) NOT NULL, + `action` VARCHAR(50) NOT NULL, + `objectId` INT(11) NULL, + `notification` VARCHAR(50) NOT NULL, + `userId` INT(11) NOT NULL, + `receiver` VARCHAR(256) NOT NULL, + `isActive` TINYINT(4) NOT NULL +)ENGINE = InnoDB; + +CREATE TABLE `Pretask` ( + `pretaskId` INT(11) NOT NULL, + `taskName` VARCHAR(100) NOT NULL, + `attackCmd` VARCHAR(256) NOT NULL, + `chunkTime` INT(11) NOT NULL, + `statusTimer` INT(11) NOT NULL, + `color` VARCHAR(20) NULL, + `isSmall` TINYINT(4) NOT NULL, + `isCpuTask` TINYINT(4) NOT NULL, + `useNewBench` TINYINT(4) NOT NULL, + `priority` INT(11) NOT NULL, + `maxAgents` INT(11) NOT NULL, + `isMaskImport` TINYINT(4) NOT NULL, + `crackerBinaryTypeId` INT(11) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `RegVoucher` ( + `regVoucherId` INT(11) NOT NULL, + `voucher` VARCHAR(100) NOT NULL, + `time` BIGINT NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `RightGroup` ( + `rightGroupId` INT(11) NOT NULL, + `groupName` VARCHAR(50) NOT NULL, + `permissions` TEXT NOT NULL +) ENGINE = InnoDB; + +INSERT INTO `RightGroup` (`rightGroupId`, `groupName`, `permissions`) VALUES + (1, 'Administrator', 'ALL'); + +CREATE TABLE `Session` ( + `sessionId` INT(11) NOT NULL, + `userId` INT(11) NOT NULL, + `sessionStartDate` BIGINT NOT NULL, + `lastActionDate` BIGINT NOT NULL, + `isOpen` TINYINT(4) NOT NULL, + `sessionLifetime` INT(11) NOT NULL, + `sessionKey` VARCHAR(256) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `Speed` ( + `speedId` INT(11) NOT NULL, + `agentId` INT(11) NOT NULL, + `taskId` INT(11) NOT NULL, + `speed` BIGINT(20) NOT NULL, + `time` BIGINT(20) NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE `StoredValue` ( + `storedValueId` VARCHAR(50) NOT NULL, + `val` VARCHAR(256) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `Supertask` ( + `supertaskId` INT(11) NOT NULL, + `supertaskName` VARCHAR(50) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `SupertaskPretask` ( + `supertaskPretaskId` INT(11) NOT NULL, + `supertaskId` INT(11) NOT NULL, + `pretaskId` INT(11) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `Task` ( + `taskId` INT(11) NOT NULL, + `taskName` VARCHAR(256) NOT NULL, + `attackCmd` VARCHAR(256) NOT NULL, + `chunkTime` INT(11) NOT NULL, + `statusTimer` INT(11) NOT NULL, + `keyspace` BIGINT(20) NOT NULL, + `keyspaceProgress` BIGINT(20) NOT NULL, + `priority` INT(11) NOT NULL, + `maxAgents` INT(11) NOT NULL, + `color` VARCHAR(20) NULL, + `isSmall` TINYINT(4) NOT NULL, + `isCpuTask` TINYINT(4) NOT NULL, + `useNewBench` TINYINT(4) NOT NULL, + `skipKeyspace` BIGINT(20) NOT NULL, + `crackerBinaryId` INT(11) DEFAULT NULL, + `crackerBinaryTypeId` INT(11) NULL, + `taskWrapperId` INT(11) NOT NULL, + `isArchived` TINYINT(4) NOT NULL, + `notes` TEXT NOT NULL, + `staticChunks` INT(11) NOT NULL, + `chunkSize` BIGINT(20) NOT NULL, + `forcePipe` TINYINT(4) NOT NULL, + `usePreprocessor` TINYINT(4) NOT NULL, + `preprocessorCommand` VARCHAR(256) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `TaskDebugOutput` ( + `taskDebugOutputId` INT(11) NOT NULL, + `taskId` INT(11) NOT NULL, + `output` VARCHAR(256) NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE `TaskWrapper` ( + `taskWrapperId` INT(11) NOT NULL, + `priority` INT(11) NOT NULL, + `taskType` INT(11) NOT NULL, + `hashlistId` INT(11) NOT NULL, + `accessGroupId` INT(11) DEFAULT NULL, + `taskWrapperName` VARCHAR(100) NOT NULL, + `isArchived` TINYINT(4) NOT NULL, + `cracked` INT(11) NOT NULL +)ENGINE = InnoDB; + +CREATE TABLE `User` ( + `userId` INT(11) NOT NULL, + `username` VARCHAR(100) NOT NULL, + `email` VARCHAR(150) NOT NULL, + `passwordHash` VARCHAR(256) NOT NULL, + `passwordSalt` VARCHAR(256) NOT NULL, + `isValid` TINYINT(4) NOT NULL, + `isComputedPassword` TINYINT(4) NOT NULL, + `lastLoginDate` BIGINT NOT NULL, + `registeredSince` BIGINT NOT NULL, + `sessionLifetime` INT(11) NOT NULL, + `rightGroupId` INT(11) NOT NULL, + `yubikey` VARCHAR(256) DEFAULT NULL, + `otp1` VARCHAR(256) DEFAULT NULL, + `otp2` VARCHAR(256) DEFAULT NULL, + `otp3` VARCHAR(256) DEFAULT NULL, + `otp4` VARCHAR(256) DEFAULT NULL +) ENGINE = InnoDB; + +CREATE TABLE `Benchmark` ( + `benchmarkId` INT(11) NOT NULL, + `benchmarkValue` VARCHAR(256) NOT NULL, + `hardwareGroupId` INT(11) NOT NULL, + `crackerBinaryId` INT(11) NOT NULL, + `attackParameters` VARCHAR(512) NOT NULL, + `ttl` int(11) NOT NULL, + `hashMode` int(11) NOT NULL, + `benchmarkType` varchar(10) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `HardwareGroup` ( + `hardwareGroupId` INT(11) NOT NULL, + `devices` VARCHAR(65000) NULL +) ENGINE = InnoDB; + +CREATE TABLE `Zap` ( + `zapId` INT(11) NOT NULL, + `hash` MEDIUMTEXT NOT NULL, + `solveTime` BIGINT NOT NULL, + `agentId` INT(11) NULL, + `hashlistId` INT(11) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `ApiKey` ( + `apiKeyId` INT(11) NOT NULL, + `startValid` BIGINT(20) NOT NULL, + `endValid` BIGINT(20) NOT NULL, + `accessKey` VARCHAR(256) NOT NULL, + `accessCount` INT(11) NOT NULL, + `userId` INT(11) NOT NULL, + `apiGroupId` INT(11) NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE `ApiGroup` ( + `apiGroupId` INT(11) NOT NULL, + `name` VARCHAR(100) NOT NULL, + `permissions` TEXT NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE `FileDownload` ( + `fileDownloadId` INT(11) NOT NULL, + `time` BIGINT NOT NULL, + `fileId` INT(11) NOT NULL, + `status` INT(11) NOT NULL +) ENGINE=InnoDB; + +INSERT INTO `ApiGroup` ( `apiGroupId`, `name`, `permissions`) VALUES + (1, 'Administrators', 'ALL'); + +CREATE TABLE `HealthCheck` ( + `healthCheckId` INT(11) NOT NULL, + `time` BIGINT(20) NOT NULL, + `status` INT(11) NOT NULL, + `checkType` INT(11) NOT NULL, + `hashtypeId` INT(11) NOT NULL, + `crackerBinaryId` INT(11) NOT NULL, + `expectedCracks` INT(11) NOT NULL, + `attackCmd` VARCHAR(256) NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE `HealthCheckAgent` ( + `healthCheckAgentId` INT(11) NOT NULL, + `healthCheckId` INT(11) NOT NULL, + `agentId` INT(11) NOT NULL, + `status` INT(11) NOT NULL, + `cracked` INT(11) NOT NULL, + `numGpus` INT(11) NOT NULL, + `start` BIGINT(20) NOT NULL, + `end` BIGINT(20) NOT NULL, + `errors` TEXT NOT NULL +) ENGINE=InnoDB; + +CREATE TABLE `Preprocessor` ( + `preprocessorId` INT(11) NOT NULL, + `name` VARCHAR(256) NOT NULL, + `url` VARCHAR(512) NOT NULL, + `binaryName` VARCHAR(256) NOT NULL, + `keyspaceCommand` VARCHAR(256) NULL, + `skipCommand` VARCHAR(256) NULL, + `limitCommand` VARCHAR(256) NULL +) ENGINE=InnoDB; + +INSERT INTO `Preprocessor` ( `preprocessorId`, `name`, `url`, `binaryName`, `keyspaceCommand`, `skipCommand`, `limitCommand`) VALUES + (1, 'Prince', 'https://github.com/hashcat/princeprocessor/releases/download/v0.22/princeprocessor-0.22.7z', 'pp', '--keyspace', '--skip', '--limit'); + +-- Add Indexes +ALTER TABLE `AccessGroup` + ADD PRIMARY KEY (`accessGroupId`); + +ALTER TABLE `AccessGroupAgent` + ADD PRIMARY KEY (`accessGroupAgentId`), + ADD KEY `accessGroupId` (`accessGroupId`), + ADD KEY `agentId` (`agentId`); + +ALTER TABLE `AccessGroupUser` + ADD PRIMARY KEY (`accessGroupUserId`), + ADD KEY `accessGroupId` (`accessGroupId`), + ADD KEY `userId` (`userId`); + +ALTER TABLE `HardwareGroup` + ADD PRIMARY KEY (`hardwareGroupId`); + +ALTER TABLE `Agent` + ADD PRIMARY KEY (`agentId`), + ADD KEY `userId` (`userId`); + -- ADD KEY `hardwareGroupId` (`hardwareGroupId`); + +ALTER TABLE `AgentBinary` + ADD PRIMARY KEY (`agentBinaryId`); + +ALTER TABLE `AgentError` + ADD PRIMARY KEY (`agentErrorId`), + ADD KEY `agentId` (`agentId`), + ADD KEY `taskId` (`taskId`); + +ALTER TABLE `AgentStat` + ADD PRIMARY KEY (`agentStatId`), + ADD KEY `agentId` (`agentId`); + +ALTER TABLE `AgentZap` + ADD PRIMARY KEY (`agentZapId`), + ADD KEY `agentId` (`agentId`), + ADD KEY `lastZapId` (`lastZapId`); + +ALTER TABLE `ApiKey` + ADD PRIMARY KEY (`apiKeyId`); + +ALTER TABLE `ApiGroup` + ADD PRIMARY KEY (`apiGroupId`); + +ALTER TABLE `Assignment` + ADD PRIMARY KEY (`assignmentId`), + ADD KEY `taskId` (`taskId`), + ADD KEY `agentId` (`agentId`); + +ALTER TABLE `Chunk` + ADD PRIMARY KEY (`chunkId`), + ADD KEY `taskId` (`taskId`), + ADD KEY `agentId` (`agentId`); + +ALTER TABLE `Config` + ADD PRIMARY KEY (`configId`), + ADD KEY `configSectionId` (`configSectionId`); + +ALTER TABLE `ConfigSection` + ADD PRIMARY KEY (`configSectionId`); + +ALTER TABLE `CrackerBinary` + ADD PRIMARY KEY (`crackerBinaryId`), + ADD KEY `crackerBinaryTypeId` (`crackerBinaryTypeId`); + +ALTER TABLE `CrackerBinaryType` + ADD PRIMARY KEY (`crackerBinaryTypeId`); + +ALTER TABLE `File` + ADD PRIMARY KEY (`fileId`); + +ALTER TABLE `FileDownload` + ADD PRIMARY KEY (`fileDownloadId`); + +ALTER TABLE `FileDelete` + ADD PRIMARY KEY (`fileDeleteId`); + +ALTER TABLE `FilePretask` + ADD PRIMARY KEY (`filePretaskId`), + ADD KEY `fileId` (`fileId`), + ADD KEY `pretaskId` (`pretaskId`); + +ALTER TABLE `FileTask` + ADD PRIMARY KEY (`fileTaskId`), + ADD KEY `fileId` (`fileId`), + ADD KEY `taskId` (`taskId`); + +ALTER TABLE `Hash` + ADD PRIMARY KEY (`hashId`), + ADD KEY `hashlistId` (`hashlistId`), + ADD KEY `chunkId` (`chunkId`), + ADD KEY `isCracked` (`isCracked`), + ADD KEY `hash` (`hash`(500)); + +ALTER TABLE `HashBinary` + ADD PRIMARY KEY (`hashBinaryId`), + ADD KEY `hashlistId` (`hashlistId`), + ADD KEY `chunkId` (`chunkId`); + +ALTER TABLE `Hashlist` + ADD PRIMARY KEY (`hashlistId`), + ADD KEY `hashTypeId` (`hashTypeId`); + +ALTER TABLE `HashlistHashlist` + ADD PRIMARY KEY (`hashlistHashlistId`), + ADD KEY `parentHashlistId` (`parentHashlistId`), + ADD KEY `hashlistId` (`hashlistId`); + +ALTER TABLE `HashType` + ADD PRIMARY KEY (`hashTypeId`); + +ALTER TABLE `HealthCheck` + ADD PRIMARY KEY (`healthCheckId`); + +ALTER TABLE `HealthCheckAgent` + ADD PRIMARY KEY (`healthCheckAgentId`); + +ALTER TABLE `LogEntry` + ADD PRIMARY KEY (`logEntryId`); + +ALTER TABLE `NotificationSetting` + ADD PRIMARY KEY (`notificationSettingId`), + ADD KEY `userId` (`userId`); + +ALTER TABLE `Pretask` + ADD PRIMARY KEY (`pretaskId`); + +ALTER TABLE `RegVoucher` + ADD PRIMARY KEY (`regVoucherId`); + +ALTER TABLE `RightGroup` + ADD PRIMARY KEY (`rightGroupId`); + +ALTER TABLE `Session` + ADD PRIMARY KEY (`sessionId`), + ADD KEY `userId` (`userId`); + +ALTER TABLE `Speed` + ADD PRIMARY KEY (`speedId`), + ADD KEY `agentId` (`agentId`), + ADD KEY `taskId` (`taskId`); + +ALTER TABLE `StoredValue` + ADD PRIMARY KEY (`storedValueId`); + +ALTER TABLE `Supertask` + ADD PRIMARY KEY (`supertaskId`); + +ALTER TABLE `SupertaskPretask` + ADD PRIMARY KEY (`supertaskPretaskId`), + ADD KEY `supertaskId` (`supertaskId`), + ADD KEY `pretaskId` (`pretaskId`); + +ALTER TABLE `Task` + ADD PRIMARY KEY (`taskId`), + ADD KEY `crackerBinaryId` (`crackerBinaryId`); + +ALTER TABLE `TaskDebugOutput` + ADD PRIMARY KEY (`taskDebugOutputId`); + +ALTER TABLE `TaskWrapper` + ADD PRIMARY KEY (`taskWrapperId`), + ADD KEY `hashlistId` (`hashlistId`), + ADD KEY `accessGroupId` (`accessGroupId`); + +ALTER TABLE `User` + ADD PRIMARY KEY (`userId`), + ADD UNIQUE KEY `username` (`username`), + ADD KEY `rightGroupId` (`rightGroupId`); + +ALTER TABLE `Zap` + ADD PRIMARY KEY (`zapId`), + ADD KEY `agentId` (`agentId`), + ADD KEY `hashlistId` (`hashlistId`); + +ALTER TABLE `Preprocessor` + ADD PRIMARY KEY (`preprocessorId`); + +ALTER TABLE `Benchmark` + ADD PRIMARY KEY (`benchmarkId`), + ADD KEY `crackerBinaryId` (`crackerBinaryId`), + ADD KEY `hardwareGroupId` (`hardwareGroupId`); + +-- Add AUTO_INCREMENT for tables +ALTER TABLE `AccessGroup` + MODIFY `accessGroupId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `AccessGroupAgent` + MODIFY `accessGroupAgentId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `AccessGroupUser` + MODIFY `accessGroupUserId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Agent` + MODIFY `agentId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `AgentBinary` + MODIFY `agentBinaryId` INT(11) NOT NULL AUTO_INCREMENT, + AUTO_INCREMENT = 2; + +ALTER TABLE `AgentError` + MODIFY `agentErrorId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `AgentStat` + MODIFY `agentStatId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `AgentZap` + MODIFY `agentZapId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `ApiKey` + MODIFY `apiKeyId` int(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `ApiGroup` + MODIFY `apiGroupId` int(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Assignment` + MODIFY `assignmentId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Chunk` + MODIFY `chunkId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Config` + MODIFY `configId` INT(11) NOT NULL AUTO_INCREMENT, + AUTO_INCREMENT = 72; + +ALTER TABLE `ConfigSection` + MODIFY `configSectionId` INT(11) NOT NULL AUTO_INCREMENT, + AUTO_INCREMENT = 8; + +ALTER TABLE `CrackerBinary` + MODIFY `crackerBinaryId` INT(11) NOT NULL AUTO_INCREMENT, + AUTO_INCREMENT = 2; + +ALTER TABLE `CrackerBinaryType` + MODIFY `crackerBinaryTypeId` INT(11) NOT NULL AUTO_INCREMENT, + AUTO_INCREMENT = 2; + +ALTER TABLE `File` + MODIFY `fileId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `FileDownload` + MODIFY `fileDownloadId` int(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `FileDelete` + MODIFY `fileDeleteId` int(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `FilePretask` + MODIFY `filePretaskId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `FileTask` + MODIFY `fileTaskId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Hash` + MODIFY `hashId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `HashBinary` + MODIFY `hashBinaryId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Hashlist` + MODIFY `hashlistId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `HashlistHashlist` + MODIFY `hashlistHashlistId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `HealthCheck` + MODIFY `healthCheckId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `HealthCheckAgent` + MODIFY `healthCheckAgentId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `LogEntry` + MODIFY `logEntryId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `NotificationSetting` + MODIFY `notificationSettingId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Pretask` + MODIFY `pretaskId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `RegVoucher` + MODIFY `regVoucherId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `RightGroup` + MODIFY `rightGroupId` INT(11) NOT NULL AUTO_INCREMENT, + AUTO_INCREMENT = 2; + +ALTER TABLE `Session` + MODIFY `sessionId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Speed` + MODIFY `speedId` int(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Supertask` + MODIFY `supertaskId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `SupertaskPretask` + MODIFY `supertaskPretaskId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Task` + MODIFY `taskId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `TaskDebugOutput` + MODIFY `taskDebugOutputId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `TaskWrapper` + MODIFY `taskWrapperId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `User` + MODIFY `userId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Zap` + MODIFY `zapId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Preprocessor` + MODIFY `preprocessorId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `Benchmark` + MODIFY `benchmarkId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `HardwareGroup` + MODIFY `hardwareGroupId` INT(11) NOT NULL AUTO_INCREMENT; + +-- Add Constraints +ALTER TABLE `AccessGroupAgent` + ADD CONSTRAINT `AccessGroupAgent_ibfk_1` FOREIGN KEY (`accessGroupId`) REFERENCES `AccessGroup` (`accessGroupId`), + ADD CONSTRAINT `AccessGroupAgent_ibfk_2` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`); + +ALTER TABLE `AccessGroupUser` + ADD CONSTRAINT `AccessGroupUser_ibfk_1` FOREIGN KEY (`accessGroupId`) REFERENCES `AccessGroup` (`accessGroupId`), + ADD CONSTRAINT `AccessGroupUser_ibfk_2` FOREIGN KEY (`userId`) REFERENCES `User` (`userId`); + +ALTER TABLE `Agent` + ADD CONSTRAINT `Agent_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `User` (`userId`); + -- ADD CONSTRAINT `Agent_ibfk_2` FOREIGN KEY (`hardwareGroupId`) REFERENCES `HardwareGroup` (`hardwareGroupId`); + +ALTER TABLE `AgentError` + ADD CONSTRAINT `AgentError_ibfk_1` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`), + ADD CONSTRAINT `AgentError_ibfk_2` FOREIGN KEY (`taskId`) REFERENCES `Task` (`taskId`); + +ALTER TABLE `AgentStat` + ADD CONSTRAINT `AgentStat_ibfk_1` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`); + +ALTER TABLE `AgentZap` + ADD CONSTRAINT `AgentZap_ibfk_1` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`), + ADD CONSTRAINT `AgentZap_ibfk_2` FOREIGN KEY (`lastZapId`) REFERENCES `Zap` (`zapId`); + +ALTER TABLE `ApiKey` + ADD CONSTRAINT `ApiKey_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `User` (`userId`), + ADD CONSTRAINT `ApiKey_ibfk_2` FOREIGN KEY (`apiGroupId`) REFERENCES `ApiGroup` (`apiGroupId`); + +ALTER TABLE `Assignment` + ADD CONSTRAINT `Assignment_ibfk_1` FOREIGN KEY (`taskId`) REFERENCES `Task` (`taskId`), + ADD CONSTRAINT `Assignment_ibfk_2` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`); + +ALTER TABLE `Chunk` + ADD CONSTRAINT `Chunk_ibfk_1` FOREIGN KEY (`taskId`) REFERENCES `Task` (`taskId`), + ADD CONSTRAINT `Chunk_ibfk_2` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`); + +ALTER TABLE `Config` + ADD CONSTRAINT `Config_ibfk_1` FOREIGN KEY (`configSectionId`) REFERENCES `ConfigSection` (`configSectionId`); + +ALTER TABLE `CrackerBinary` + ADD CONSTRAINT `CrackerBinary_ibfk_1` FOREIGN KEY (`crackerBinaryTypeId`) REFERENCES `CrackerBinaryType` (`crackerBinaryTypeId`); + +ALTER TABLE `File` + ADD CONSTRAINT `File_ibfk_1` FOREIGN KEY (`accessGroupId`) REFERENCES `AccessGroup` (`accessGroupId`); + +ALTER TABLE `FileDownload` + ADD CONSTRAINT `FileDownload_ibkf_1` FOREIGN KEY (`fileId`) REFERENCES `File`(`fileId`); + +ALTER TABLE `FilePretask` + ADD CONSTRAINT `FilePretask_ibfk_1` FOREIGN KEY (`fileId`) REFERENCES `File` (`fileId`), + ADD CONSTRAINT `FilePretask_ibfk_2` FOREIGN KEY (`pretaskId`) REFERENCES `Pretask` (`pretaskId`); + +ALTER TABLE `FileTask` + ADD CONSTRAINT `FileTask_ibfk_1` FOREIGN KEY (`fileId`) REFERENCES `File` (`fileId`), + ADD CONSTRAINT `FileTask_ibfk_2` FOREIGN KEY (`taskId`) REFERENCES `Task` (`taskId`); + +ALTER TABLE `Hash` + ADD CONSTRAINT `Hash_ibfk_1` FOREIGN KEY (`hashlistId`) REFERENCES `Hashlist` (`hashlistId`), + ADD CONSTRAINT `Hash_ibfk_2` FOREIGN KEY (`chunkId`) REFERENCES `Chunk` (`chunkId`); + +ALTER TABLE `HashBinary` + ADD CONSTRAINT `HashBinary_ibfk_1` FOREIGN KEY (`hashlistId`) REFERENCES `Hashlist` (`hashlistId`), + ADD CONSTRAINT `HashBinary_ibfk_2` FOREIGN KEY (`chunkId`) REFERENCES `Chunk` (`chunkId`); + +ALTER TABLE `Hashlist` + ADD CONSTRAINT `Hashlist_ibfk_1` FOREIGN KEY (`hashTypeId`) REFERENCES `HashType` (`hashTypeId`), + ADD CONSTRAINT `Hashlist_ibfk_2` FOREIGN KEY (`accessGroupId`) REFERENCES `AccessGroup` (`accessGroupId`); + +ALTER TABLE `HashlistHashlist` + ADD CONSTRAINT `HashlistHashlist_ibfk_1` FOREIGN KEY (`parentHashlistId`) REFERENCES `Hashlist` (`hashlistId`), + ADD CONSTRAINT `HashlistHashlist_ibfk_2` FOREIGN KEY (`hashlistId`) REFERENCES `Hashlist` (`hashlistId`); + +ALTER TABLE `HealthCheck` + ADD CONSTRAINT `HealthCheck_ibfk_1` FOREIGN KEY (`crackerBinaryId`) REFERENCES `CrackerBinary` (`crackerBinaryId`); + +ALTER TABLE `HealthCheckAgent` + ADD CONSTRAINT `HealthCheckAgent_ibfk_1` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`), + ADD CONSTRAINT `HealthCheckAgent_ibfk_2` FOREIGN KEY (`healthCheckId`) REFERENCES `HealthCheck` (`healthCheckId`); + +ALTER TABLE `NotificationSetting` + ADD CONSTRAINT `NotificationSetting_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `User` (`userId`); + +ALTER TABLE `Pretask` + ADD CONSTRAINT `Pretask_ibfk_1` FOREIGN KEY (`crackerBinaryTypeId`) REFERENCES `CrackerBinaryType` (`crackerBinaryTypeId`); + +ALTER TABLE `Session` + ADD CONSTRAINT `Session_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `User` (`userId`); + +ALTER TABLE `Speed` + ADD CONSTRAINT `Speed_ibfk_1` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`), + ADD CONSTRAINT `Speed_ibfk_2` FOREIGN KEY (`taskId`) REFERENCES `Task` (`taskId`); + +ALTER TABLE `SupertaskPretask` + ADD CONSTRAINT `SupertaskPretask_ibfk_1` FOREIGN KEY (`supertaskId`) REFERENCES `Supertask` (`supertaskId`), + ADD CONSTRAINT `SupertaskPretask_ibfk_2` FOREIGN KEY (`pretaskId`) REFERENCES `Pretask` (`pretaskId`); + +ALTER TABLE `Task` + ADD CONSTRAINT `Task_ibfk_1` FOREIGN KEY (`crackerBinaryId`) REFERENCES `CrackerBinary` (`crackerBinaryId`), + ADD CONSTRAINT `Task_ibfk_2` FOREIGN KEY (`crackerBinaryTypeId`) REFERENCES `CrackerBinaryType` (`crackerBinaryTypeId`), + ADD CONSTRAINT `Task_ibfk_3` FOREIGN KEY (`taskWrapperId`) REFERENCES `TaskWrapper` (`taskWrapperId`); + +ALTER TABLE `TaskDebugOutput` + ADD CONSTRAINT `TaskDebugOutput_ibfk_1` FOREIGN KEY (`taskId`) REFERENCES `Task` (`taskId`); + +ALTER TABLE `TaskWrapper` + ADD CONSTRAINT `TaskWrapper_ibfk_1` FOREIGN KEY (`hashlistId`) REFERENCES `Hashlist` (`hashlistId`), + ADD CONSTRAINT `TaskWrapper_ibfk_2` FOREIGN KEY (`accessGroupId`) REFERENCES `AccessGroup` (`accessGroupId`); + +ALTER TABLE `User` + ADD CONSTRAINT `User_ibfk_1` FOREIGN KEY (`rightGroupId`) REFERENCES `RightGroup` (`rightGroupId`); + +ALTER TABLE `Benchmark` + ADD CONSTRAINT `Benchmark_ibfk_1` FOREIGN KEY (`hardwareGroupId`) REFERENCES `HardwareGroup` (`hardwareGroupId`), + ADD CONSTRAINT `Benchmark_ibfk_2` FOREIGN KEY (`crackerBinaryId`) REFERENCES `CrackerBinary` (`crackerBinaryId`); + +ALTER TABLE `Zap` + ADD CONSTRAINT `Zap_ibfk_1` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`), + ADD CONSTRAINT `Zap_ibfk_2` FOREIGN KEY (`hashlistId`) REFERENCES `Hashlist` (`hashlistId`); + +/*!40101 SET CHARACTER_SET_CLIENT = @OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS = @OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION = @OLD_COLLATION_CONNECTION */; diff --git a/ci/run.php b/ci/run.php index 747d4bb12..9e3299440 100644 --- a/ci/run.php +++ b/ci/run.php @@ -11,8 +11,14 @@ require_once(dirname(__FILE__) . "/../src/inc/Util.class.php"); require_once(dirname(__FILE__) . "/../src/inc/Encryption.class.php"); require_once(dirname(__FILE__) . "/../src/inc/utils/AccessUtils.class.php"); +require_once(dirname(__FILE__) . "/../src/inc/utils/BenchmarkUtils.class.php"); +require_once(dirname(__FILE__) . "/../src/inc/utils/HardwareGroupUtils.class.php"); +require_once(dirname(__FILE__) . "/../src/inc/SConfig.class.php"); +require_once(dirname(__FILE__) . "/../src/inc/Dataset.class.php"); + require_once(dirname(__FILE__) . "/HashtopolisTest.class.php"); require_once(dirname(__FILE__) . "/HashtopolisTestFramework.class.php"); +require_once(dirname(__FILE__) . "/../src/inc/HTException.class.php"); $dir = scandir(dirname(__FILE__) . "/tests/"); foreach ($dir as $entry) { diff --git a/ci/tests/BenchmarkTest.class.php b/ci/tests/BenchmarkTest.class.php new file mode 100644 index 000000000..a54ecebb6 --- /dev/null +++ b/ci/tests/BenchmarkTest.class.php @@ -0,0 +1,120 @@ +getTestName() . "..."); + parent::init($version); + } + + public function run() { + HashtopolisTestFramework::log(HashtopolisTestFramework::LOG_INFO, "Running " . $this->getTestName() . "..."); + $this->createAgentWithHardwareGroup(); + $this->testAddToCache(); + $this->testGetFromCache(); + $this->testDeleteCache(); + $this->testTtl(); + HashtopolisTestFramework::log(HashtopolisTestFramework::LOG_INFO, $this->getTestName() . " completed"); + } + + public function getTestName() { + return "Benchmark Test"; + } + + private function createAgentWithHardwareGroup() { + $agent = new Agent(100, "testAgent", "ebfc57ec-2d6f-4a60-932d-60f127dbb2a8",0, null, "", 0, 1, 0, "TeStToKeN0", "sendProgress", + 1683904809, "127.0.0.1", 1, 0, "s3-python-0.7.1"); + $agentSameHardware = new Agent(101, "testAgent2", "ebfc57ec-2d6f-4a60-932d-60f127dbb2a9",0, null, "", 0, 1, 0, "TeStToKeN1", "sendProgress", + 1683904809, "127.0.0.2", 1, 0, "s3-python-0.7.1"); + $agentDifferentHardware = new Agent(102, "testAgent3", "ebfc57ec-2d6f-4a60-932d-60f127dbb2b8",0, null, "", 0, 1, 0, "TeStToKeN2", "sendProgress", + 1683904809, "127.0.0.3", 1, 0, "s3-python-0.7.1"); + + Factory::getAgentFactory()->save($agent); + Factory::getAgentFactory()->save($agentSameHardware); + Factory::getAgentFactory()->save($agentDifferentHardware); + + $agent = HardwareGroupUtils::updateHardwareOfAgent("11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz", $agent); + $agentSameHardware = HardwareGroupUtils::updateHardwareOfAgent("11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz", $agentSameHardware); + $agentDifferentHardware = HardwareGroupUtils::updateHardwareOfAgent("10th Gen Intel(R) Core(TM) i6-1165G7 @ 2.80GHz", $agentDifferentHardware); + + if ($agent->getHardwareGroupId() != $agentSameHardware->getHardwareGroupId()) { + $this->testFailed("BenchmarkTest:createAgentWithHardwareGroup", "Agents with the same hardware are not added to the same hardwareGroup! + Agent1 hardwaregroup id: " . $agent->getHardwareGroupId() . "Agent2 hardwareGroupId: " . $agentSameHardware->getHardwareGroupId()); + } + if ($agent->getHardwareGroupId() == $agentDifferentHardware->getHardwareGroupId()) { + $this->testFailed("BenchmarkTest:createAgentWithHardwareGroup", "Agents with different hardware are added to the same hardwareGroup! + Agent1 hardwaregroup id: " . $agent->getHardwareGroupId() . "Agent2 hardwareGroupId: " . $agentDifferentHardware->getHardwareGroupId()); + } + + $this->agent = $agent; //save agent for future tests + $this->testSuccess("BenchmarkTest:createAgentWithHardwareGroup"); + } + + private function testAddToCache(){ + $crackerBinary = new CrackerBinary(3036, 1, "6.2.6", "https://hashcat.net/files/hashcat-6.2.6.7z", "hashcat"); + Factory::getCrackerBinaryFactory()->save($crackerBinary); + $benchmark = BenchmarkUtils::saveBenchmarkInCache("#HL# -a 3 ?l?l?l?l -d 1 --force", $this->agent->getHardwareGroupId(), "676:1.78", 1000, "speed", $crackerBinary->getId()); + + if(!isset($benchmark)) { + $this->testFailed("BenchmarkTest:testAddToCache", "Cannot add benchmark to cache"); + } else { + $this->testSuccess("BenchmarkTest:testAddToCache"); + } + + $this->crackerBinary = $crackerBinary; //save crackerbinary for future tests + } + + private function testGetFromCache(){ + $benchmark = BenchmarkUtils::getBenchmarkByValue("#HL# -a 3 ?l?l?l?l -d 1 --force", $this->agent->getHardwareGroupId(), 1000, 1, $this->crackerBinary->getId()); + + if(!isset($benchmark)) { + $this->testFailed("BenchmarkTest:testGetFromCache", "Cannot get benchmark from cache in normal situation"); + } else { + $this->testSuccess("BenchmarkTest:testGetFromCache"); + } + + $benchmark2 = BenchmarkUtils::getBenchmarkByValue("#HL# -a3 ?l?l?l?l -d 1 --force", $this->agent->getHardwareGroupId(),1000, 1, $this->crackerBinary->getId()); + $benchmark3 = BenchmarkUtils::getBenchmarkByValue("#HL# -d 1 --attack-mode 3 ?l?l?l?l --force", $this->agent->getHardwareGroupId(),1000, 1, $this->crackerBinary->getId()); + $benchmark4 = BenchmarkUtils::getBenchmarkByValue("#HL# --force -a3 ?l?l?l?l -d 1", $this->agent->getHardwareGroupId(), 1000, 1, $this->crackerBinary->getId()); + + if(!isset($benchmark2) || !isset($benchmark3) || !isset($benchmark4)) { + $this->testFailed("BenchmarkTest:testGetFromCache", "Cannot get benchmark from cache with parsing commandline in different formats"); + } else { + $this->testSuccess("BenchmarkTest:testGetFromCache"); + } + } + + private function testDeleteCache() { + BenchmarkUtils::deleteCache(); + $benchmark = BenchmarkUtils::getBenchmarkByValue("#HL# -a 3 ?l?l?l?l -d 1 --force", $this->agent->getHardwareGroupId(), 1000, "1", $this->crackerBinary->getId()); + if(isset($benchmark)) { + $this->testFailed("BenchmarkTest:testDeleteCache", "There is still a value in the cache!"); + } else { + $this->testSuccess("BenchmarkTest:testDeleteCache"); + } + } + + private function testTtl() { + $benchmark = new Benchmark(3, "speed", "1234:88","#HL# -a 3 ?u?u?u", 200, $this->agent->getHardwareGroupId(), time() - 10, $this->crackerBinary->getId()); //ttl in the past to test invalid ttl + Factory::getBenchmarkFactory()->save($benchmark); + $found = BenchmarkUtils::getBenchmarkByValue("#HL# -a 3 ?u?u?u", $this->agent->getHardwareGroupId(), 200, 1, $this->crackerBinary->getId()); + if($found != null) { + $this->testFailed("BenchmarkTest:testTtl", "benchmark with ttl in the past should not be valid!"); + } else { + $this->testSuccess("BenchmarkTest:testTtl"); + } + } +} + +HashtopolisTestFramework::register(new BenchmarkTest()); diff --git a/doc/changelog.md b/doc/changelog.md index c5ae3b5de..890631094 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -3,6 +3,14 @@ ## Bugfixes - Clicking pretask in Supertask create screen now directs correctly to the pretask and not a task with the same id (#945) +## Benchmark cache system +A cache for the benchmarks so that benchmarks can be reused and the benchmark process can be skipped when the benchmark has already been cached. +Key components: + +- Added a benchmark model. The benchmark model got a field for all the dependencies of the benchmark output. These are the benchmark type (speed or runtime), the cracker binary, the hardware that is used, the attack parameters and the hashmode. +- Agents are split up into hardware groups, so that benchmark can be linked to a hardwaregroup and not a single agent. +- Benchmarks get invalidated by a time to live. +- frontend for the benchmarks in /benchmark.php to show what has been cached and to manually remove values. # v0.13.1 -> v0.14.0 diff --git a/src/agents.php b/src/agents.php index c501b4605..7aee6d6d6 100755 --- a/src/agents.php +++ b/src/agents.php @@ -56,6 +56,7 @@ //show agent detail Template::loadInstance("agents/detail"); $agent = Factory::getAgentFactory()->get($_GET['id']); + $hardwareGroup = Factory::getHardwareGroupFactory()->get($agent->getHardwareGroupId()); if (!$agent) { UI::printError("ERROR", "Agent not found!"); } @@ -64,12 +65,12 @@ } else { // uniq devices lines and prepend with count - $tmp_devices_tuple = array_count_values(explode("\n", $agent->getDevices())); + $tmp_devices_tuple = array_count_values(explode("\n", $hardwareGroup->getDevices())); $devices_tuple = array(); foreach ($tmp_devices_tuple as $key => $value) { $devices_tuple[] = str_replace("*", "  ", sprintf("%'*2d× ", $value) . $key); } - $agent->setDevices(implode("\n", $devices_tuple)); + $agent->setHardwareGroupId(implode("\n", $devices_tuple)); UI::add('agent', $agent); UI::add('users', Factory::getUserFactory()->filter([])); @@ -158,12 +159,14 @@ $joined = Factory::getAccessGroupFactory()->filter([Factory::FILTER => $qF, Factory::JOIN => $jF]); $accessGroupAgents->addValue($agent->getId(), $joined[Factory::getAccessGroupFactory()->getModelName()]); // uniq devices lines and prepend with count - $tmp_devices_tuple = array_count_values(explode("\n", $agent->getDevices())); + $hardwareGroup = Factory::getHardwareGroupFactory()->get($agent->getHardwareGroupId()); + + $tmp_devices_tuple = array_count_values(explode("\n", $hardwareGroup->getDevices())); $devices_tuple = array(); foreach ($tmp_devices_tuple as $key => $value) { $devices_tuple[] = str_replace("*", "  ", sprintf("%'*2d× ", $value) . $key); } - $agent->setDevices(implode("\n", $devices_tuple)); + $agent->setHardwareGroupId(implode("\n", $devices_tuple)); } UI::add('accessGroupAgents', $accessGroupAgents); diff --git a/src/api/v2/index.php b/src/api/v2/index.php index 4c83b737a..823f554ee 100644 --- a/src/api/v2/index.php +++ b/src/api/v2/index.php @@ -247,6 +247,8 @@ public function process(Request $request, RequestHandler $handler): Response { require __DIR__ . "/../../inc/apiv2/users.routes.php"; require __DIR__ . "/../../inc/apiv2/vouchers.routes.php"; require __DIR__ . "/../../inc/apiv2/taskwrappers.routes.php"; +require __DIR__ . "/../../inc/apiv2/benchmark.routes.php"; +require __DIR__ . "/../../inc/apiv2/hardwaregroup.routes.php"; $errorMiddleware = $app->addErrorMiddleware(true, true, true); diff --git a/src/benchmark.php b/src/benchmark.php new file mode 100644 index 000000000..27aaaa3d9 --- /dev/null +++ b/src/benchmark.php @@ -0,0 +1,58 @@ +isLoggedin()) { + header("Location: index.php?err=4" . time() . "&fw=" . urlencode($_SERVER['PHP_SELF'] . "?" . $_SERVER['QUERY_STRING'])); + die(); +} + +Template::loadInstance("benchmarks/index"); + +AccessControl::getInstance()->checkPermission(DViewControl::AGENTS_VIEW_PERM); + +Menu::get()->setActive("benchmark_cache"); + +if (isset($_POST['action']) && CSRF::check($_POST['csrf'])) { + $benchmarkHandler = new BenchmarkHandler(); + $benchmarkHandler->handle($_POST['action']); + if (UI::getNumMessages() == 0) { + Util::refresh(); + } +} + +$benchmarks = Factory::getBenchmarkFactory()->filter([]); + +$oF = new OrderFilter(CrackerBinary::CRACKER_BINARY_ID, "DESC"); +$versions = Factory::getCrackerBinaryFactory()->filter([Factory::ORDER => $oF]); +usort($versions, ["Util", "versionComparisonBinary"]); + + foreach ($benchmarks as $benchmark) { + //format the devices pretty + $devices = HardwareGroupUtils::getDevicesFromBenchmark($benchmark); + + $tmp_devices_tuple = array_count_values(explode("\n", $devices)); + $devices_tuple = array(); + foreach ($tmp_devices_tuple as $key => $value) { + $devices_tuple[] = str_replace("*", "  ", sprintf("%'*2d× ", $value) . $key); + } + $benchmark->setHardwareGroupId(implode("\n", $devices_tuple)); + + //get the correct cracker binary for the benchmarks + foreach ($versions as $version) { + if ($benchmark->getCrackerBinaryId() == $version->getId()) { + + $benchmark->setCrackerBinaryId($version->getBinaryName() . " " . $version->getVersion()); + break; + } + } +} + +UI::add('benchmarks', $benchmarks); +UI::add('numBenchmarks', sizeof($benchmarks)); + +echo Template::getInstance()->render(UI::getObjects()); diff --git a/src/dba/Factory.class.php b/src/dba/Factory.class.php index aaa44afc7..d586dde00 100644 --- a/src/dba/Factory.class.php +++ b/src/dba/Factory.class.php @@ -18,6 +18,8 @@ class Factory { private static $fileFactory = null; private static $hashFactory = null; private static $hashBinaryFactory = null; + private static $benchmarkFactory = null; + private static $hardwareGroupFactory = null; private static $hashlistFactory = null; private static $hashTypeFactory = null; private static $logEntryFactory = null; @@ -137,6 +139,27 @@ public static function getConfigFactory() { return self::$configFactory; } } + + public static function getBenchmarkFactory() { + if (self::$benchmarkFactory == null) { + $f = new BenchmarkFactory(); + self::$benchmarkFactory = $f; + return $f; + } else { + return self::$benchmarkFactory; + } + } + + public static function getHardwareGroupFactory() { + if (self::$hardwareGroupFactory == null) { + $f = new HardwareGroupFactory(); + self::$hardwareGroupFactory = $f; + return $f; + } else { + return self::$hardwareGroupFactory; + } + } + public static function getConfigSectionFactory() { if (self::$configSectionFactory == null) { diff --git a/src/dba/models/Agent.class.php b/src/dba/models/Agent.class.php index 9b4771c60..c21dae26b 100644 --- a/src/dba/models/Agent.class.php +++ b/src/dba/models/Agent.class.php @@ -7,7 +7,7 @@ class Agent extends AbstractModel { private $agentName; private $uid; private $os; - private $devices; + private $hardwareGroupId; private $cmdPars; private $ignoreErrors; private $isActive; @@ -20,12 +20,12 @@ class Agent extends AbstractModel { private $cpuOnly; private $clientSignature; - function __construct($agentId, $agentName, $uid, $os, $devices, $cmdPars, $ignoreErrors, $isActive, $isTrusted, $token, $lastAct, $lastTime, $lastIp, $userId, $cpuOnly, $clientSignature) { + function __construct($agentId, $agentName, $uid, $os, $hardwareGroupId, $cmdPars, $ignoreErrors, $isActive, $isTrusted, $token, $lastAct, $lastTime, $lastIp, $userId, $cpuOnly, $clientSignature) { $this->agentId = $agentId; $this->agentName = $agentName; $this->uid = $uid; $this->os = $os; - $this->devices = $devices; + $this->hardwareGroupId = $hardwareGroupId; $this->cmdPars = $cmdPars; $this->ignoreErrors = $ignoreErrors; $this->isActive = $isActive; @@ -45,7 +45,7 @@ function getKeyValueDict() { $dict['agentName'] = $this->agentName; $dict['uid'] = $this->uid; $dict['os'] = $this->os; - $dict['devices'] = $this->devices; + $dict['hardwareGroupId'] = $this->hardwareGroupId; $dict['cmdPars'] = $this->cmdPars; $dict['ignoreErrors'] = $this->ignoreErrors; $dict['isActive'] = $this->isActive; @@ -67,7 +67,7 @@ static function getFeatures() { $dict['agentName'] = ['read_only' => False, "type" => "str(100)", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "agentName"]; $dict['uid'] = ['read_only' => False, "type" => "str(100)", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "uid"]; $dict['os'] = ['read_only' => False, "type" => "int", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "os"]; - $dict['devices'] = ['read_only' => False, "type" => "str(65535)", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "devices"]; + $dict['hardwareGroupId'] = ['read_only' => False, "type" => "int", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "hardwareGroupId"]; $dict['cmdPars'] = ['read_only' => False, "type" => "str(256)", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "cmdPars"]; $dict['ignoreErrors'] = ['read_only' => False, "type" => "bool", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "ignoreErrors"]; $dict['isActive'] = ['read_only' => False, "type" => "bool", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "isActive"]; @@ -131,12 +131,12 @@ function setOs($os) { $this->os = $os; } - function getDevices() { - return $this->devices; + function getHardwareGroupId() { + return $this->hardwareGroupId; } - function setDevices($devices) { - $this->devices = $devices; + function setHardwareGroupId($hardwareGroupId) { + $this->hardwareGroupId = $hardwareGroupId; } function getCmdPars() { @@ -231,7 +231,7 @@ function setClientSignature($clientSignature) { const AGENT_NAME = "agentName"; const UID = "uid"; const OS = "os"; - const DEVICES = "devices"; + const HARDWARE_GROUP_ID = "hardwareGroupId"; const CMD_PARS = "cmdPars"; const IGNORE_ERRORS = "ignoreErrors"; const IS_ACTIVE = "isActive"; diff --git a/src/dba/models/AgentFactory.class.php b/src/dba/models/AgentFactory.class.php index 3363c2a6a..6a66bd420 100644 --- a/src/dba/models/AgentFactory.class.php +++ b/src/dba/models/AgentFactory.class.php @@ -33,7 +33,7 @@ function getNullObject() { * @return Agent */ function createObjectFromDict($pk, $dict) { - $o = new Agent($dict['agentId'], $dict['agentName'], $dict['uid'], $dict['os'], $dict['devices'], $dict['cmdPars'], $dict['ignoreErrors'], $dict['isActive'], $dict['isTrusted'], $dict['token'], $dict['lastAct'], $dict['lastTime'], $dict['lastIp'], $dict['userId'], $dict['cpuOnly'], $dict['clientSignature']); + $o = new Agent($dict['agentId'], $dict['agentName'], $dict['uid'], $dict['os'], $dict['hardwareGroupId'], $dict['cmdPars'], $dict['ignoreErrors'], $dict['isActive'], $dict['isTrusted'], $dict['token'], $dict['lastAct'], $dict['lastTime'], $dict['lastIp'], $dict['userId'], $dict['cpuOnly'], $dict['clientSignature']); return $o; } diff --git a/src/dba/models/Benchmark.class.php b/src/dba/models/Benchmark.class.php new file mode 100644 index 000000000..66581073a --- /dev/null +++ b/src/dba/models/Benchmark.class.php @@ -0,0 +1,142 @@ +benchmarkId = $benchmarkId; + $this->benchmarkType = $benchmarkType; + $this->benchmarkValue = $benchmarkValue; + $this->attackParameters = $attackParameters; + $this->hashMode = $hashMode; + $this->hardwareGroupId = $hardwareGroupId; + $this->ttl = $ttl; + $this->crackerBinaryId = $crackerBinaryId; + } + + function getKeyValueDict() { + $dict = array(); + $dict['benchmarkId'] = $this->benchmarkId; + $dict['benchmarkType'] = $this->benchmarkType; + $dict['benchmarkValue'] = $this->benchmarkValue; + $dict['attackParameters'] = $this->attackParameters; + $dict['hashMode'] = $this->hashMode; + $dict['hardwareGroupId'] = $this->hardwareGroupId; + $dict['ttl'] = $this->ttl; + $dict['crackerBinaryId'] = $this->crackerBinaryId; + + return $dict; + } + + static function getFeatures() { + $dict = array(); + $dict['benchmarkId'] = ['read_only' => True, "type" => "int", "subtype" => "unset", "null" => False, "pk" => True, "protected" => True, "private" => False, "alias" => "benchmarkId"]; + $dict['benchmarkType'] = ['read_only' => True, "type" => "str(10)", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "benchmarkType"]; + $dict['benchmarkValue'] = ['read_only' => True, "type" => "str(256)", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "benchmarkValue"]; + $dict['attackParameters'] = ['read_only' => True, "type" => "str(512)", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "attackParameters"]; + $dict['hashMode'] = ['read_only' => True, "type" => "int", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "hashMode"]; + $dict['hardwareGroupId'] = ['read_only' => True, "type" => "int", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "hardwareGroupId"]; + $dict['ttl'] = ['read_only' => True, "type" => "int", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "ttl"]; + $dict['crackerBinaryId'] = ['read_only' => True, "type" => "int", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "crackerBinaryId"]; + + return $dict; + } + + function getPrimaryKey() { + return "benchmarkId"; + } + + function getPrimaryKeyValue() { + return $this->benchmarkId; + } + + function getId() { + return $this->benchmarkId; + } + + function setId($id) { + $this->benchmarkId = $id; + } + + /** + * Used to serialize the data contained in the model + * @return array + */ + public function expose() { + return get_object_vars($this); + } + + function getBenchmarkType() { + return $this->benchmarkType; + } + + function setBenchmarkType($benchmarkType) { + $this->benchmarkType = $benchmarkType; + } + + function getBenchmarkValue() { + return $this->benchmarkValue; + } + + function setBenchmarkValue($benchmarkValue) { + $this->benchmarkValue = $benchmarkValue; + } + + function getAttackParameters() { + return $this->attackParameters; + } + + function setAttackParameters($attackParameters) { + $this->attackParameters = $attackParameters; + } + + function getHashMode() { + return $this->hashMode; + } + + function setHashMode($hashMode) { + $this->hashMode = $hashMode; + } + + function getHardwareGroupId() { + return $this->hardwareGroupId; + } + + function setHardwareGroupId($hardwareGroupId) { + $this->hardwareGroupId = $hardwareGroupId; + } + + function getTtl() { + return $this->ttl; + } + + function setTtl($ttl) { + $this->ttl = $ttl; + } + + function getCrackerBinaryId() { + return $this->crackerBinaryId; + } + + function setCrackerBinaryId($crackerBinaryId) { + $this->crackerBinaryId = $crackerBinaryId; + } + + const BENCHMARK_ID = "benchmarkId"; + const BENCHMARK_TYPE = "benchmarkType"; + const BENCHMARK_VALUE = "benchmarkValue"; + const ATTACK_PARAMETERS = "attackParameters"; + const HASH_MODE = "hashMode"; + const HARDWARE_GROUP_ID = "hardwareGroupId"; + const TTL = "ttl"; + const CRACKER_BINARY_ID = "crackerBinaryId"; +} diff --git a/src/dba/models/BenchmarkFactory.class.php b/src/dba/models/BenchmarkFactory.class.php new file mode 100644 index 000000000..1bcb5ff52 --- /dev/null +++ b/src/dba/models/BenchmarkFactory.class.php @@ -0,0 +1,82 @@ +hardwareGroupId = $hardwareGroupId; + $this->devices = $devices; + } + + function getKeyValueDict() { + $dict = array(); + $dict['hardwareGroupId'] = $this->hardwareGroupId; + $dict['devices'] = $this->devices; + + return $dict; + } + + static function getFeatures() { + $dict = array(); + $dict['hardwareGroupId'] = ['read_only' => True, "type" => "int", "subtype" => "unset", "null" => False, "pk" => True, "protected" => True, "private" => False, "alias" => "benchmarkId"]; + $dict['devices'] = ['read_only' => True, "type" => "str(65000)", "subtype" => "unset", "null" => False, "pk" => False, "protected" => False, "private" => False, "alias" => "devices"]; + + return $dict; + } + + function getPrimaryKey() { + return "hardwareGroupId"; + } + + function getPrimaryKeyValue() { + return $this->hardwareGroupId; + } + + function getId() { + return $this->hardwareGroupId; + } + + function setId($id) { + $this->hardwareGroupId = $id; + } + + /** + * Used to serialize the data contained in the model + * @return array + */ + public function expose() { + return get_object_vars($this); + } + + function getDevices() { + return $this->devices; + } + + function setDevices($devices) { + $this->devices = $devices; + } + + const HARDWARE_GROUP_ID = "hardwareGroupId"; + const DEVICES = "devices"; +} diff --git a/src/dba/models/HardwareGroupFactory.class.php b/src/dba/models/HardwareGroupFactory.class.php new file mode 100644 index 000000000..b879a91ba --- /dev/null +++ b/src/dba/models/HardwareGroupFactory.class.php @@ -0,0 +1,82 @@ + 'os', 'read_only' => False, 'type' => 'int'], ['name' => 'devices', 'read_only' => False, 'type' => 'str(65535)'], ['name' => 'cmdPars', 'read_only' => False, 'type' => 'str(256)'], + ['name' => 'hardwareGroupId', 'read_only' => True, 'type' => 'int'], ['name' => 'ignoreErrors', 'read_only' => False, 'type' => 'bool'], ['name' => 'isActive', 'read_only' => False, 'type' => 'bool'], ['name' => 'isTrusted', 'read_only' => False, 'type' => 'bool'], @@ -81,6 +82,16 @@ ['name' => 'benchmark', 'read_only' => False, 'type' => 'str(50)'], ]; // FIXME: Add correct read_only mapping to relevant fields +$CONF['Benchmark'] = [ + ['name' => 'benchmarkId', 'read_only' => True, 'type' => 'int', 'protected' => True], + ['name' => 'benchmarkValue', 'read_only' => False, 'type' => 'str(256)'], + ['name' => 'hardwareGroupId', 'read_only' => False, 'type' => 'int'], + ['name' => 'crackerBinaryId', 'read_only' => False, 'type' => 'int'], + ['name' => 'ttl', 'read_only' => False, 'type' => 'int'], + ['name' => 'hashmode', 'read_only' => False, 'type' => 'int'], + ['name' => 'benchmarkType', 'read_only' => False, 'type' => 'str(10)'], +]; +// FIXME: Add correct read_only mapping to relevant fields $CONF['Chunk'] = [ ['name' => 'chunkId', 'read_only' => True, 'type' => 'int', 'protected' => True], ['name' => 'taskId', 'read_only' => False, 'type' => 'int'], @@ -179,6 +190,10 @@ ['name' => 'isSalted', 'read_only' => False, 'type' => 'bool'], ['name' => 'isSlowHash', 'read_only' => False, 'type' => 'bool'] ]; +$CONF['HardwareGroup'] = [ + ['name' => 'hardwareGroupId', 'read_only' => True, 'type' => 'int', 'protected' => True], + ['name' => 'devices', 'read_only' => False, 'type' => 'str(65000)'], +]; // FIXME: Add correct read_only mapping to relevant fields $CONF['LogEntry'] = [ ['name' => 'logEntryId', 'read_only' => True, 'type' => 'int', 'protected' => True], diff --git a/src/inc/api/APIGetChunk.class.php b/src/inc/api/APIGetChunk.class.php index 79af89730..c383a8ade 100644 --- a/src/inc/api/APIGetChunk.class.php +++ b/src/inc/api/APIGetChunk.class.php @@ -40,6 +40,7 @@ public function execute($QUERY = array()) { $qF1 = new QueryFilter(Assignment::AGENT_ID, $this->agent->getId(), "="); $qF2 = new QueryFilter(Assignment::TASK_ID, $task->getId(), "="); $assignment = Factory::getAssignmentFactory()->filter([Factory::FILTER => [$qF1, $qF2]], true); + if ($assignment == null) { DServerLog::log(DServerLog::WARNING, "Requested chunk on task it is not assigned to!", [$this->agent]); $this->sendErrorResponse(PActions::GET_CHUNK, "You are not assigned to this task!"); @@ -54,13 +55,27 @@ public function execute($QUERY = array()) { ); } else if ($assignment->getBenchmark() == 0 && $task->getIsSmall() == 0 && $task->getStaticChunks() == DTaskStaticChunking::NORMAL) { // benchmark only required on non-small tasks and on non-special chunk tasks - DServerLog::log(DServerLog::TRACE, "Need to run a benchmark!", [$this->agent, $task]); + $taskWrapper = Factory::getTaskWrapperFactory()->get($task->getTaskWrapperId()); + $hashlist = Factory::getHashlistFactory()->get($taskWrapper->getHashlistId()); + + $ttl = SConfig::getInstance()->getVal(DConfig::BENCHMARKCACHE_TTL); + $attackParameters = $task->getAttackCmd() . " " . $this->agent->getCmdPars(); + + $benchmark = BenchmarkUtils::getBenchmarkByValue($attackParameters, $this->agent->getHardwareGroupId(), $hashlist->getHashTypeId(), $task->getUseNewBench(), $task->getCrackerBinaryId()); + + if ($benchmark === NULL || $ttl == 0) { + DServerLog::log(DServerLog::INFO, "Need to run a benchmark!", [$this->agent, $task]); $this->sendResponse(array( PResponseGetChunk::ACTION => PActions::GET_CHUNK, PResponseGetChunk::RESPONSE => PValues::SUCCESS, PResponseGetChunk::CHUNK_STATUS => PValuesChunkType::BENCHMARK_REQUIRED ) ); + } else { + DServerLog::log(DServerLog::INFO, "Found benchmark in cache", [$this->agent, $task]); + $assignment->setBenchmark($benchmark->getBenchmarkValue()); + Factory::getAssignmentFactory()->update($assignment); + } } else if ($this->agent->getIsActive() == 0) { DServerLog::log(DServerLog::TRACE, "Agent is inactive!", [$this->agent]); diff --git a/src/inc/api/APIRegisterAgent.class.php b/src/inc/api/APIRegisterAgent.class.php index bd2a1098a..084a66ca9 100644 --- a/src/inc/api/APIRegisterAgent.class.php +++ b/src/inc/api/APIRegisterAgent.class.php @@ -28,7 +28,7 @@ public function execute($QUERY = array()) { //create access token & save agent details $token = Util::randomString(10); - $agent = new Agent(null, $name, "", -1, "", "", 0, 1, 0, $token, PActions::REGISTER, time(), Util::getIP(), null, $cpuOnly, ""); + $agent = new Agent(null, $name, "", -1, 0, "", 0, 1, 0, $token, PActions::REGISTER, time(), Util::getIP(), null, $cpuOnly, ""); if (SConfig::getInstance()->getVal(DConfig::VOUCHER_DELETION) == 0) { Factory::getRegVoucherFactory()->delete($voucher); diff --git a/src/inc/api/APISendBenchmark.class.php b/src/inc/api/APISendBenchmark.class.php index cacccb807..82dec608f 100644 --- a/src/inc/api/APISendBenchmark.class.php +++ b/src/inc/api/APISendBenchmark.class.php @@ -4,7 +4,6 @@ use DBA\Assignment; use DBA\QueryFilter; use DBA\Factory; -use DBA\File; class APISendBenchmark extends APIBasic { public function execute($QUERY = array()) { @@ -75,10 +74,20 @@ public function execute($QUERY = array()) { Factory::getAgentFactory()->set($this->agent, Agent::IS_ACTIVE, 0); $this->sendErrorResponse(PActions::SEND_BENCHMARK, "Invalid benchmark type!"); } - + $assignment->setBenchmark($benchmark); Factory::getAssignmentFactory()->update($assignment); - DServerLog::log(DServerLog::DEBUG, "Saved agent benchmark", [$this->agent, $task, $assignment]); + + // save benchmark in cache if cache ttl is higher than 0 + $ttl = SConfig::getInstance()->getVal(DConfig::BENCHMARKCACHE_TTL); + + if ($ttl != 0) { + $hashlist = Factory::getHashlistFactory()->get($taskWrapper->getHashlistId()); + $attackParameters = $task->getAttackCmd(). " " . $this->agent->getCmdPars(); + BenchmarkUtils::saveBenchmarkInCache($attackParameters, $this->agent->getHardwareGroupId(), $benchmark, $hashlist->getHashTypeId(), $type, $task->getCrackerBinaryId()); + DServerLog::log(DServerLog::DEBUG, "Saved agent benchmark", [$this->agent, $task, $assignment]); + } + $this->sendResponse(array( PResponseSendBenchmark::ACTION => PActions::SEND_BENCHMARK, PResponseSendBenchmark::RESPONSE => PValues::SUCCESS, diff --git a/src/inc/api/APIUpdateClientInformation.class.php b/src/inc/api/APIUpdateClientInformation.class.php index ab1309622..8946cd672 100644 --- a/src/inc/api/APIUpdateClientInformation.class.php +++ b/src/inc/api/APIUpdateClientInformation.class.php @@ -29,13 +29,14 @@ public function execute($QUERY = array()) { // we only update this variable on the first time, otherwise we would overwrite manual changes Factory::getAgentFactory()->set($this->agent, Agent::CPU_ONLY, $cpuOnly); } + Factory::getAgentFactory()->mset($this->agent, [ - Agent::DEVICES => htmlentities(implode("\n", $devices), ENT_QUOTES, "UTF-8"), Agent::UID => $uid, Agent::OS => $os ] ); - + HardwareGroupUtils::updateHardwareOfAgent(htmlentities(implode("\n", $devices), ENT_QUOTES, "UTF-8"), $this->agent); + $this->updateAgent(PActions::UPDATE_CLIENT_INFORMATION); DServerLog::log(DServerLog::DEBUG, "Agent sent updated client information", [$this->agent]); diff --git a/src/inc/apiv2/agents.routes.php b/src/inc/apiv2/agents.routes.php index e9cb61396..d1d17b510 100644 --- a/src/inc/apiv2/agents.routes.php +++ b/src/inc/apiv2/agents.routes.php @@ -33,7 +33,7 @@ protected function getFactory(): object { } public function getExpandables(): array { - return ['agentstats']; + return ['agentstats', "hardwareGroup"]; } protected function getFilterACL(): array { diff --git a/src/inc/apiv2/benchmark.routes.php b/src/inc/apiv2/benchmark.routes.php new file mode 100644 index 000000000..b9868d6e1 --- /dev/null +++ b/src/inc/apiv2/benchmark.routes.php @@ -0,0 +1,67 @@ +getId()); + } +} + +BenchmarkAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/hardwaregroup.routes.php b/src/inc/apiv2/hardwaregroup.routes.php new file mode 100644 index 000000000..9d7fa9fcd --- /dev/null +++ b/src/inc/apiv2/hardwaregroup.routes.php @@ -0,0 +1,68 @@ +get($item['accessGroupId']); $item[$NAME] = $this->obj2Array($obj); break; + case 'hardwareGroup': + $obj = Factory::getHardwareGroupFactory()->get($item['hardwareGroupId']); + $item[$NAME] = $this->obj2Array($obj); + break; case 'chunk': if ($item['chunkId'] === null) { /* Chunk expansions are optional, hence the chunk object could be null */ diff --git a/src/inc/defines/accessControl.php b/src/inc/defines/accessControl.php index f910e7a6a..5c70a0038 100644 --- a/src/inc/defines/accessControl.php +++ b/src/inc/defines/accessControl.php @@ -26,6 +26,8 @@ class DAccessControl { const SERVER_CONFIG_ACCESS = "serverConfigAccess"; const USER_CONFIG_ACCESS = "userConfigAccess"; const MANAGE_ACCESS_GROUP_ACCESS = "manageAccessGroupAccess"; + const VIEW_BENCHMARK_ACCESS = "ViewBenchmarkAccess"; + const DELETE_BENCHMARK_ACCESS = "DeleteBenchmarkAccess"; // special access definitions for public access pages and pages which are viewable if logged in const PUBLIC_ACCESS = "publicAccess"; @@ -102,6 +104,11 @@ public static function getDescription($access) { return "Can manage preconfigured supertasks."; case DAccessControl::MANAGE_ACCESS_GROUP_ACCESS: return "Can manage access groups."; + case DAccessControl::VIEW_BENCHMARK_ACCESS: + return "Can view the cached benchmarks"; + case DAccessControl::DELETE_BENCHMARK_ACCESS: + return "Can delete the cached benchmarks"; + } return "__" . $access . "__"; } diff --git a/src/inc/defines/benchmarks.php b/src/inc/defines/benchmarks.php new file mode 100644 index 000000000..ff95953dd --- /dev/null +++ b/src/inc/defines/benchmarks.php @@ -0,0 +1,8 @@ +checkPermission(DBenchmarkAction::DELETE_BENCHMARK); + BenchmarkUtils::delete($_POST['benchmarkId']); + break; + default: + UI::addMessage(UI::ERROR, "Invalid action!"); + break; + } + } + catch (HTException $e) { + UI::addMessage(UI::ERROR, $e->getMessage()); + } + } +} \ No newline at end of file diff --git a/src/inc/user-api/UserAPIAgent.class.php b/src/inc/user-api/UserAPIAgent.class.php index 17394ab31..4f29e5629 100644 --- a/src/inc/user-api/UserAPIAgent.class.php +++ b/src/inc/user-api/UserAPIAgent.class.php @@ -79,12 +79,13 @@ private function deleteAgent($QUERY) { */ private function getAgent($QUERY) { $agent = AgentUtils::getAgent($QUERY[UQueryAgent::AGENT_ID], $this->user); + $devices = HardwareGroupUtils::getDevicesForAgent($agent); $response = [ UResponseAgent::SECTION => $QUERY[UQueryAgent::SECTION], UResponseAgent::REQUEST => $QUERY[UQueryAgent::REQUEST], UResponseAgent::RESPONSE => UValues::OK, UResponseAgent::AGENT_NAME => $agent->getAgentName(), - UResponseAgent::AGENT_DEVICES => explode("\n", $agent->getDevices()), + UResponseAgent::AGENT_DEVICES => explode("\n", $devices), UResponseAgent::AGENT_OWNER => [ UResponseAgent::AGENT_OWNER_ID => (int)$agent->getUserId(), UResponseAgent::AGENT_OWNER_NAME => Util::getUsernameById($agent->getUserId()) @@ -203,10 +204,12 @@ private function listAgents() { $agents = Factory::getAgentFactory()->filter([Factory::FILTER => $qF, Factory::ORDER => $oF]); $arr = []; foreach ($agents as $agent) { + $devices = HardwareGroupUtils::getDevicesForAgent($agent); + $arr[] = array( UResponseAgent::AGENTS_ID => $agent->getId(), UResponseAgent::AGENTS_NAME => $agent->getAgentName(), - UResponseAgent::AGENTS_DEVICES => explode("\n", $agent->getDevices()) + UResponseAgent::AGENTS_DEVICES => explode("\n", $devices) ); } $this->sendResponse(array( diff --git a/src/inc/utils/BenchmarkUtils.class.php b/src/inc/utils/BenchmarkUtils.class.php new file mode 100644 index 000000000..31ab6f7bc --- /dev/null +++ b/src/inc/utils/BenchmarkUtils.class.php @@ -0,0 +1,216 @@ +get($benchmarkId); + if ($benchmark == null) { + throw new HTException("Invalid benchmark ID!"); + } + return $benchmark; + } + + /** + * @param int $benchmarkId + * @throws HTException + */ + public static function delete($benchmarkId) { + $benchmark = BenchmarkUtils::getBenchmark($benchmarkId); + if ($benchmark == null) { + throw new HTException("Invalid benchmark ID!"); + } + Factory::getBenchmarkFactory()->delete($benchmark); + } + + /** + * @param string $attackCmd + * @throws HTException + */ + static function cleanupAttackParameters($attackCmd) { + $attackCmd = trim($attackCmd); + + if (strlen($attackCmd) == 0) { + throw new HTException("Attack command cannot be empty!"); + } else if (strlen($attackCmd) > 256) { + throw new HTException("Attack command is too long (max 256 characters)!"); + } + + $parameterParseMap = array(); + $parameterParseMap["-m"] = "--hash-type"; + $parameterParseMap["-a"] = "--attack-mode"; + $parameterParseMap["-S"] = "--slow-candidates"; + $parameterParseMap["-i"] = "--increment"; + + $parts_cmd = preg_split('/\s+/', $attackCmd); + + //arguments will be added in a associative array so that the value of the arguments can be easily extracted + //and the array can be sorted on the keys to get 1 format + $arguments = array(); + + $hashlist = SConfig::getInstance()->getVal(DConfig::HASHLIST_ALIAS); + $attackValue = ""; //this is the dictionary or attack mask + + $i = 0; + $size = sizeof($parts_cmd); + + for ($i = 0; $i < count($parts_cmd); $i++) { + $arg = $parts_cmd[$i]; + if ($arg == $hashlist) { //the hashlist is always #HL# so it doesnt have to be parsed + continue; + } + + if (!str_starts_with($arg, "-")) { //if the argument doesnt start with '-', its the attackvalue which is gonna be appended on the end + $attackValue = $arg; + continue; + } + + $number = null; + if (!str_contains($arg, "=")) { //if the argument is in format "-a3" the number needs to be split to properly parse + $number = preg_replace('/[^0-9]/', '', $arg); + $arg = preg_replace('/[^a-zA-Z\-]/', '', $arg); + } + + if (array_key_exists($arg, $parameterParseMap)) { //parse to long format + $arg = $parameterParseMap[$arg]; + } + + if (!empty($number)) { //when an argument is in format -a3 use the number as value and continue to next itteration + $arguments[$arg] = $number; + continue; + } + //parse longparameter in style: --remove-timer=30 + if (str_contains($arg, '=')) { + $longParameterSplit = explode('=', $arg); + $arguments[$longParameterSplit[0]] = $longParameterSplit[1]; + continue; + } else if ($i <= ($size - 2)) { //if the next character doesnt start with '-' it means that its the value of the parameter + if (!str_starts_with($parts_cmd[$i + 1], "-")) { + $arguments[$arg] = $parts_cmd[$i + 1]; + $i++; + continue; + } + } + $arguments[$arg] = null; + } + + // if (!array_key_exists("--hash-type", $arguments)) { //if --hash-type not in arguments that means hashtype 0 is in use + // $arguments["--hash-type"] = "0"; + // } + if (!array_key_exists("--attack-mode", $arguments)) { //if --hash-type not in arguments that means attackMode 0 is in use + $arguments["--attack-mode"] = "0"; + } + + ksort($arguments); //sort the arguments by key + + $cleanAttackCmd = ""; + + foreach ($arguments as $key => $value) { + $cleanAttackCmd = $cleanAttackCmd . " " . $key; + if ($value != null) { + $cleanAttackCmd = $cleanAttackCmd . " " . $value; + } + } + + $cleanAttackCmd = $hashlist . $cleanAttackCmd . " " . $attackValue; + + return $cleanAttackCmd; + } + + /** + * @param string $attackParameters + * @param int $hardwareGroupId + * @param int $hashmode + * @param string $useNewBenchmark + * @param int $crackerBinaryId + */ + public static function getBenchmarkByValue($attackParameters, $hardwareGroupId, $hashmode, $useNewBenchmark, $crackerBinaryId) { + $hardwareGroup = Factory::getHardwareGroupFactory()->get($hardwareGroupId); + $crackerBinary = Factory::getCrackerBinaryFactory()->get($crackerBinaryId); + + if ($hardwareGroup == null) { + throw new HTException("Invalid hardwareGroupId!"); + } + if ($crackerBinary == null) { + throw new HTException("Invalid crackerBinaryId!"); + } + + $cleanAttackParameter = self::cleanupAttackParameters($attackParameters); + + $qF1 = new QueryFilter(Benchmark::ATTACK_PARAMETERS, $cleanAttackParameter, "="); + $qF2 = new QueryFilter(Benchmark::HARDWARE_GROUP_ID, $hardwareGroup->getId(), "="); + $qF3 = new QueryFilter(Benchmark::HASH_MODE, $hashmode, "="); + + $benchmarkType = $useNewBenchmark == 1 ? "speed" : "runtime"; + + $qF4 = new QueryFilter(Benchmark::BENCHMARK_TYPE, $benchmarkType, "="); + $qF5 = new QueryFilter(Benchmark::CRACKER_BINARY_ID, $crackerBinary->getId(), "="); + + $res = Factory::getBenchmarkFactory()->filter([Factory::FILTER => [$qF1, $qF2, $qF3, $qF4, $qF5]], true); + + if (isset($res)) { + if ($res->getTtl() < time()) { // if ttl has been exceeded, remove value and return null + + Factory::getBenchmarkFactory()->delete($res); + return null; + } + } + + return $res; + } + + /** + * @param string $attackParamters + * @param int $hardwareGroupId + * @param string $benchmarkValue + * @param int $hashmode + * @param string $benchmarkType + * @param int $crackerBinaryId + * @throws HTException + */ + public static function saveBenchmarkInCache($attackParameters, $hardwareGroupId, $benchmarkValue, $hashmode, $benchmarkType, $crackerBinaryId) { + $hardwareGroup = Factory::getHardwareGroupFactory()->get($hardwareGroupId); + + if (!isset($hardwareGroup)) { + return null; + } + + $cleanAttackParameters = self::cleanupAttackParameters($attackParameters); + $ttl = SConfig::getInstance()->getVal(DConfig::BENCHMARKCACHE_TTL); + + $qF1 = new QueryFilter(Benchmark::ATTACK_PARAMETERS, $cleanAttackParameters, "="); + $qF2 = new QueryFilter(Benchmark::HARDWARE_GROUP_ID, $hardwareGroupId, "="); + + $foundBenchmark = Factory::getBenchmarkFactory()->filter([Factory::FILTER => [$qF1, $qF2]], true); + + if (isset($foundBenchmark)) { //if benchmark already in cache, update the value + + $foundBenchmark->setTtl(time() + $ttl); + $foundBenchmark->setBenchmarkValue($benchmarkValue); + $benchmark = Factory::getBenchmarkFactory()->update($foundBenchmark); + } else { + $newBenchmark = new Benchmark(null, $benchmarkType, $benchmarkValue, $cleanAttackParameters, $hashmode, $hardwareGroupId, time() + $ttl, $crackerBinaryId); + $benchmark = Factory::getBenchmarkFactory()->save($newBenchmark); + } + + return $benchmark; + } + + //removes all values where the time to live has been exceeded + public static function refreshCache() { + $qF = new QueryFilter(Benchmark::TTL, time(), "<"); + Factory::getBenchmarkFactory()->massDeletion([Factory::FILTER => $qF]); + } + + //removes all values in cache + public static function deleteCache() { + Factory::getBenchmarkFactory()->massDeletion([]); + } +} diff --git a/src/inc/utils/HardwareGroupUtils.class.php b/src/inc/utils/HardwareGroupUtils.class.php new file mode 100644 index 000000000..ce0f8489d --- /dev/null +++ b/src/inc/utils/HardwareGroupUtils.class.php @@ -0,0 +1,44 @@ +filter([Factory::FILTER => [$qF]], true); + + if(isset($res)) { + Factory::getAgentFactory()->set($agent, Agent::HARDWARE_GROUP_ID, $res->getId()); + } else { + //make new hardwareGroup and add the id to the agent + $newHardwareGroup = new HardwareGroup(null, $devices); + $savedHardwareGroup = Factory::getHardwareGroupFactory()->save($newHardwareGroup); + + Factory::getAgentFactory()->set($agent, Agent::HARDWARE_GROUP_ID, $savedHardwareGroup->getId()); + } + return $agent; +} + +public static function getDevicesForAgent($agent) { + $qF = new QueryFilter(HardwareGroup::HARDWARE_GROUP_ID, $agent->getHardwareGroupId(), "="); + $res = Factory::getHardwareGroupFactory()->filter([Factory::FILTER => [$qF]], true); + return $res->getDevices(); +} + +public static function getDevicesFromBenchmark($benchmark) { + $qF = new QueryFilter(HardwareGroup::HARDWARE_GROUP_ID, $benchmark->getHardwareGroupId(), "="); + $res = Factory::getHardwareGroupFactory()->filter([Factory::FILTER => [$qF]], true); + return $res->getDevices(); +} + +public static function getHardwareGroupByDevices($devices) { + $qF = new QueryFilter(HardwareGroup::DEVICES, $devices, "="); + $res = Factory::getHardwareGroupFactory()->filter([Factory::FILTER => [$qF]], true); + + return $res; +} +} \ No newline at end of file diff --git a/src/install/hashtopolis.sql b/src/install/hashtopolis.sql index a2d1dacdb..3cbeb1e07 100644 --- a/src/install/hashtopolis.sql +++ b/src/install/hashtopolis.sql @@ -30,7 +30,7 @@ CREATE TABLE `Agent` ( `agentName` VARCHAR(100) NOT NULL, `uid` VARCHAR(100) NOT NULL, `os` INT(11) NOT NULL, - `devices` TEXT NOT NULL, + `hardwareGroupId` INT(11) DEFAULT NULL, `cmdPars` VARCHAR(256) NOT NULL, `ignoreErrors` TINYINT(4) NOT NULL, `isActive` TINYINT(4) NOT NULL, @@ -170,7 +170,8 @@ INSERT INTO `Config` (`configId`, `configSectionId`, `item`, `value`) VALUES (74, 4, 'agentUtilThreshold1', '90'), (75, 4, 'agentUtilThreshold2', '75'), (76, 3, 'uApiSendTaskIsComplete', '0'), - (77, 1, 'hcErrorIgnore', 'DeviceGetFanSpeed'); + (77, 1, 'hcErrorIgnore', 'DeviceGetFanSpeed'), + (78, 1, 'benchmarkcacheTtl', '216000'); CREATE TABLE `ConfigSection` ( `configSectionId` INT(11) NOT NULL, @@ -911,6 +912,25 @@ CREATE TABLE `User` ( `otp4` VARCHAR(256) DEFAULT NULL ) ENGINE = InnoDB; +CREATE TABLE `Benchmark` ( + `benchmarkId` INT(11) NOT NULL, + `benchmarkValue` VARCHAR(256) NOT NULL, + `hardwareGroupId` INT(11) NOT NULL, + `crackerBinaryId` INT(11) NOT NULL, + `attackParameters` VARCHAR(512) NOT NULL, + `ttl` int(11) NOT NULL, + `hashMode` int(11) NOT NULL, + `benchmarkType` varchar(10) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE `HardwareGroup` ( + `hardwareGroupId` INT(11) NOT NULL, + `devices` VARCHAR(65000) NULL +) ENGINE = InnoDB; + +INSERT INTO `HardwareGroup` (`hardwareGroupId`, `devices`) VALUES + (0, 'Default'); + CREATE TABLE `Zap` ( `zapId` INT(11) NOT NULL, `hash` MEDIUMTEXT NOT NULL, @@ -995,10 +1015,13 @@ ALTER TABLE `AccessGroupUser` ADD KEY `accessGroupId` (`accessGroupId`), ADD KEY `userId` (`userId`); +ALTER TABLE `HardwareGroup` + ADD PRIMARY KEY (`hardwareGroupId`); + ALTER TABLE `Agent` ADD PRIMARY KEY (`agentId`), ADD KEY `userId` (`userId`); - + ALTER TABLE `AgentBinary` ADD PRIMARY KEY (`agentBinaryId`); @@ -1156,6 +1179,11 @@ ALTER TABLE `Zap` ALTER TABLE `Preprocessor` ADD PRIMARY KEY (`preprocessorId`); +ALTER TABLE `Benchmark` + ADD PRIMARY KEY (`benchmarkId`), + ADD KEY `crackerBinaryId` (`crackerBinaryId`), + ADD KEY `hardwareGroupId` (`hardwareGroupId`); + -- Add AUTO_INCREMENT for tables ALTER TABLE `AccessGroup` MODIFY `accessGroupId` INT(11) NOT NULL AUTO_INCREMENT; @@ -1289,6 +1317,12 @@ ALTER TABLE `Zap` ALTER TABLE `Preprocessor` MODIFY `preprocessorId` INT(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE `Benchmark` + MODIFY `benchmarkId` INT(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `HardwareGroup` + MODIFY `hardwareGroupId` INT(11) NOT NULL AUTO_INCREMENT; + -- Add Constraints ALTER TABLE `AccessGroupAgent` ADD CONSTRAINT `AccessGroupAgent_ibfk_1` FOREIGN KEY (`accessGroupId`) REFERENCES `AccessGroup` (`accessGroupId`), @@ -1299,7 +1333,8 @@ ALTER TABLE `AccessGroupUser` ADD CONSTRAINT `AccessGroupUser_ibfk_2` FOREIGN KEY (`userId`) REFERENCES `User` (`userId`); ALTER TABLE `Agent` - ADD CONSTRAINT `Agent_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `User` (`userId`); + ADD CONSTRAINT `Agent_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `User` (`userId`), + ADD CONSTRAINT `Agent_ibfk_2` FOREIGN KEY (`hardwareGroupId`) REFERENCES `HardwareGroup` (`hardwareGroupId`); ALTER TABLE `AgentError` ADD CONSTRAINT `AgentError_ibfk_1` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`), @@ -1399,6 +1434,10 @@ ALTER TABLE `TaskWrapper` ALTER TABLE `User` ADD CONSTRAINT `User_ibfk_1` FOREIGN KEY (`rightGroupId`) REFERENCES `RightGroup` (`rightGroupId`); +ALTER TABLE `Benchmark` + ADD CONSTRAINT `Benchmark_ibfk_1` FOREIGN KEY (`hardwareGroupId`) REFERENCES `HardwareGroup` (`hardwareGroupId`), + ADD CONSTRAINT `Benchmark_ibfk_2` FOREIGN KEY (`crackerBinaryId`) REFERENCES `CrackerBinary` (`crackerBinaryId`); + ALTER TABLE `Zap` ADD CONSTRAINT `Zap_ibfk_1` FOREIGN KEY (`agentId`) REFERENCES `Agent` (`agentId`), ADD CONSTRAINT `Zap_ibfk_2` FOREIGN KEY (`hashlistId`) REFERENCES `Hashlist` (`hashlistId`); diff --git a/src/install/updates/update_v0.14.x_v0.x.x.php b/src/install/updates/update_v0.14.x_v0.x.x.php new file mode 100644 index 000000000..e88334086 --- /dev/null +++ b/src/install/updates/update_v0.14.x_v0.x.x.php @@ -0,0 +1,58 @@ +getDB()->query("CREATE TABLE `HardwareGroup` ( + `hardwareGroupId` INT(11) NOT NULL, + `devices` VARCHAR(65000) NOT NULL + ) ENGINE=InnoDB;" + ); + + Factory::getAgentFactory()->getDB()->query("ALTER TABLE `HardwareGroup` + ADD PRIMARY KEY (`hardwareGroupId`); + "); + + Factory::getAgentFactory()->getDB()->query("ALTER TABLE `HardwareGroup` MODIFY `hardwareGroupId` int(11) NOT NULL AUTO_INCREMENT;"); + + //change Agent table + Factory::getAgentFactory()->getDB()->query("ALTER TABLE `Agent` + DROP COLUMN devices; + "); + + Factory::getAgentFactory()->getDB()->query("ALTER TABLE `Agent` + ADD COLUMN hardwareGroupId INT(11) DEFAULT NULL; + "); + Factory::getAgentFactory()->getDB()->query("ALTER TABLE `Agent` ADD CONSTRAINT FOREIGN KEY (`hardwareGroupId`) REFERENCES `HardwareGroup` (`hardwareGroupId`);"); + + Factory::getAgentFactory()->getDB()->query("CREATE TABLE `Benchmark` ( + `benchmarkId` INT(11) NOT NULL, + `benchmarkValue` VARCHAR(256) NOT NULL, + `hardwareGroupId` INT(11) NOT NULL, + `crackerBinaryId` INT(11) NOT NULL, + `attackParameters` VARCHAR(512) NOT NULL, + `ttl` INT(11) NULL, + `hashMode` INT(11) NULL, + `benchmarkType` VARCHAR(10) NULL + ) ENGINE=InnoDB;" + ); + + Factory::getAgentFactory()->getDB()->query("ALTER TABLE `Benchmark` + ADD PRIMARY KEY (`benchmarkId`), + ADD KEY `crackerBinaryId` (`crackerBinaryId`), + ADD KEY `hardwareGroupId` (`hardwareGroupId`);"); + + Factory::getAgentFactory()->getDB()->query("ALTER TABLE `Benchmark` MODIFY `benchmarkId` int(11) NOT NULL AUTO_INCREMENT;"); + + Factory::getAgentFactory()->getDB()->query("ALTER TABLE `Benchmark` + ADD CONSTRAINT `Benchmark_ibfk_1` FOREIGN KEY (`hardwareGroupId`) REFERENCES `HardwareGroup` (`hardwareGroupId`);"); + + Factory::getAgentFactory()->getDB()->query("INSERT INTO `Config` (`configId`, `configSectionId`, `item`, `value`) VALUES + (78, 1, 'benchmarkcacheTtl', '216000');"); + + Factory::getAgentFactory()->getDB()->query("INSERT INTO `HardwareGroup` (`hardwareGroupId`, `devices`) VALUES + (0, 'Default');"); + + $EXECUTED["v0.14.x_benchmark_cache"] = true; + } +} \ No newline at end of file diff --git a/src/templates/agents/detail.template.html b/src/templates/agents/detail.template.html index c37c39728..b40a7a580 100644 --- a/src/templates/agents/detail.template.html +++ b/src/templates/agents/detail.template.html @@ -126,7 +126,7 @@
| ID | +CMD | +Hashmode | +Cracker Binary | +CPU/GPU | +Benchmark value | +TTL | +Action | +|
|---|---|---|---|---|---|---|---|---|
| [[benchmark.getId()]] | +[[benchmark.getAttackParameters()]] | +[[benchmark.getHashMode()]] | +[[benchmark.getCrackerBinaryId()]] | +[[str_replace("\n"," ",[[benchmark.getHardwareGroupId()]])]] |
+ [[benchmark.getBenchmarkValue()]] | +[[date([[config.getVal(DConfig::TIME_FORMAT)]], [[benchmark.getTtl()]])]] | + {{IF [[accessControl.hasPermission([[$DAccessControl::DELETE_BENCHMARK_ACCESS]])]]}} ++ + | + {{ELSE}} ++ {{ENDIF}} + |