import React, { Component } from "react"; import { Modal, Layout, PageHeader, Descriptions, Table, InputNumber, message, Row, Col, Card, Select, Typography, Upload, Button, Space, Input, Form, Radio, Divider, Collapse, Checkbox, Tabs, Steps } from 'antd'; import { ImportOutlined, ExportOutlined, UndoOutlined, PlusOutlined, FileDoneOutlined, AimOutlined, ToolOutlined, ExperimentOutlined } from '@ant-design/icons'; import EventBus from "./eventbus/EventBus"; import { getHashes } from './data/hashes'; import { getAlgorithms } from './data/algorithms'; import { getDictionaries } from './data/dictionaries'; import { getRules } from './data/rules'; import { getMasks } from './data/masks'; import filename from './lib/filename'; const { Content } = Layout; const { Option } = Select; const { Title } = Typography; const { Panel } = Collapse; const { TabPane } = Tabs; const { Step } = Steps; const maxRules = 4; const maskIncrementMin = 1; const maskIncrementMax = 16; function maskLength(mask) { if (typeof(mask) !== "string") return 0; if (mask.length === 0) return 0; var length = 0; var skipNext = false; for (var i = 0; i < mask.length; i++) { if (skipNext === true) { skipNext = false; continue; } let char = mask.charAt(i); if (char === "?") { skipNext = true; } length++; } return length } const initialConfig = { step: 0, advancedOptionsCollapse: [], maskInputType: "text", // text or file attackMode: undefined, algorithm: undefined, dictionaries: undefined, rules: undefined, mask: undefined, maskFile: undefined, leftDictionary: undefined, leftRule: undefined, rightDictionary: undefined, rightRule: undefined, customCharset1: undefined, customCharset2: undefined, customCharset3: undefined, customCharset4: undefined, enableMaskIncrementMode: false, maskIncrementMin: maskIncrementMin, maskIncrementMax: maskIncrementMax, hash: undefined, quiet: true, disablePotFile: true, disableLogFile: true, enableOptimizedKernel: true, enableSlowerCandidateGenerators: false, removeFoundHashes: false, ignoreUsernames: false, disableSelfTest: false, ignoreWarnings: false, devicesIDs: undefined, devicesTypes: undefined, workloadProfile: undefined, disableMonitor: false, tempAbort: undefined, markovDisable: false, markovClassic: false, markovThreshold: 0, extraArguments: [], statusTimer: 20, outputFile: undefined, outputFormat: [1, 2], priority: 0 } class NewTask extends Component { constructor(props) { super(props); this.onChangeStep = this.onChangeStep.bind(this); this.onChangeAdvancedOptionsCollapse = this.onChangeAdvancedOptionsCollapse.bind(this); this.onChangeMaskInputType = this.onChangeMaskInputType.bind(this); this.onChangeAttackMode = this.onChangeAttackMode.bind(this); this.onChangeAlgorithm = this.onChangeAlgorithm.bind(this); this.onChangeDictionaries = this.onChangeDictionaries.bind(this); this.onChangeRules = this.onChangeRules.bind(this); this.onChangeMask = this.onChangeMask.bind(this); this.onChangeMaskFile = this.onChangeMaskFile.bind(this); this.onChangeLeftDictionary = this.onChangeLeftDictionary.bind(this); this.onChangeLeftRule = this.onChangeLeftRule.bind(this); this.onChangeRightDictionary = this.onChangeRightDictionary.bind(this); this.onChangeRightRule = this.onChangeRightRule.bind(this); this.onChangeCustomCharset1 = this.onChangeCustomCharset1.bind(this); this.onChangeCustomCharset2 = this.onChangeCustomCharset2.bind(this); this.onChangeCustomCharset3 = this.onChangeCustomCharset3.bind(this); this.onChangeCustomCharset4 = this.onChangeCustomCharset4.bind(this); this.onChangeEnableMaskIncrementMode = this.onChangeEnableMaskIncrementMode.bind(this); this.onChangeMaskIncrementMin = this.onChangeMaskIncrementMin.bind(this); this.onChangeMaskIncrementMax = this.onChangeMaskIncrementMax.bind(this); this.onChangeHash = this.onChangeHash.bind(this); this.onChangeQuiet = this.onChangeQuiet.bind(this); this.onChangeDisablePotFile = this.onChangeDisablePotFile.bind(this); this.onChangeDisableLogFile = this.onChangeDisableLogFile.bind(this); this.onChangeEnableOptimizedKernel = this.onChangeEnableOptimizedKernel.bind(this); this.onChangeEnableSlowerCandidateGenerators = this.onChangeEnableSlowerCandidateGenerators.bind(this); this.onChangeRemoveFoundHashes = this.onChangeRemoveFoundHashes.bind(this); this.onChangeIgnoreUsernames = this.onChangeIgnoreUsernames.bind(this); this.onChangeDisableSelfTest = this.onChangeDisableSelfTest.bind(this); this.onChangeIgnoreWarnings = this.onChangeIgnoreWarnings.bind(this); this.onChangeDevicesIDs = this.onChangeDevicesIDs.bind(this); this.onChangeDevicesTypes = this.onChangeDevicesTypes.bind(this); this.onChangeWorkloadProfile = this.onChangeWorkloadProfile.bind(this); this.onChangeDisableMonitor = this.onChangeDisableMonitor.bind(this); this.onChangeTempAbort = this.onChangeTempAbort.bind(this); this.onChangeMarkovDisable = this.onChangeMarkovDisable.bind(this); this.onChangeMarkovClassic = this.onChangeMarkovClassic.bind(this); this.onChangeMarkovThreshold = this.onChangeMarkovThreshold.bind(this); this.onChangeExtraArguments = this.onChangeExtraArguments.bind(this); this.onChangeStatusTimer = this.onChangeStatusTimer.bind(this); this.onChangeOutputFile = this.onChangeOutputFile.bind(this); this.onChangeOutputFormat = this.onChangeOutputFormat.bind(this); this.onChangePriority = this.onChangePriority.bind(this); this.onClickCreateTask = this.onClickCreateTask.bind(this); this.onChangePreserveTaskConfig = this.onChangePreserveTaskConfig.bind(this); this.onClickImportConfig = this.onClickImportConfig.bind(this); this.onClickExportConfig = this.onClickExportConfig.bind(this); this.onClickDevicesInfo = this.onClickDevicesInfo.bind(this); this.onClickBenchmark = this.onClickBenchmark.bind(this); this.state = { ...initialConfig, preserveTaskConfig: false, isLoadingImportConfig: false, isLoadingExportConfig: false, isLoadingSetOutputFile: false, isLoadingCreateTask: false, isLoadingDevicesInfo: false, isLoadingBenchmark: false, _dictionaries: getDictionaries(), _rules: getRules(), _masks: getMasks(), _hashes: getHashes(), _algorithms: getAlgorithms() } } onChangeAdvancedOptionsCollapse(e) { this.setState({ advancedOptionsCollapse: e }); } onChangeMaskInputType(e) { this.setState({ maskInputType: e.type }); } onChangeQuiet(e) { this.setState({ quiet: e.target.checked }); } onChangeDisablePotFile(e) { this.setState({ disablePotFile: e.target.checked }); } onChangeDisableLogFile(e) { this.setState({ disableLogFile: e.target.checked }); } onChangeEnableOptimizedKernel(e) { this.setState({ enableOptimizedKernel: e.target.checked }); } onChangeEnableSlowerCandidateGenerators(e) { this.setState({ enableSlowerCandidateGenerators: e.target.checked }); } onChangeRemoveFoundHashes(e) { this.setState({ removeFoundHashes: e.target.checked }); } onChangeIgnoreUsernames(e) { this.setState({ ignoreUsernames: e.target.checked }); } onChangeDisableSelfTest(e) { this.setState({ disableSelfTest: e.target.checked }); } onChangeIgnoreWarnings(e) { this.setState({ ignoreWarnings: e.target.checked }); } onChangeStep(step) { this.setState({ step: step }); } onChangeAttackMode(e) { this.setState({ attackMode: e.target.value }); } onChangeAlgorithm(e) { this.setState({ algorithm: e }); } onChangeDictionaries(e) { this.setState({ dictionaries: e }); } onChangeRules(e) { this.setState({ rules: e.slice(0, maxRules) }); } onChangeMask(e) { this.setState({ mask: e.target.value }); } onChangeMaskFile(e) { this.setState({ maskFile: e }); } onChangeLeftDictionary(e) { this.setState({ leftDictionary: e }); } onChangeLeftRule(e) { this.setState({ leftRule: e.target.value }); } onChangeRightDictionary(e) { this.setState({ rightDictionary: e }); } onChangeRightRule(e) { this.setState({ rightRule: e.target.value }); } onChangeCustomCharset1(e) { this.setState({ customCharset1: e.target.value }); } onChangeCustomCharset2(e) { this.setState({ customCharset2: e.target.value }); } onChangeCustomCharset3(e) { this.setState({ customCharset3: e.target.value }); } onChangeCustomCharset4(e) { this.setState({ customCharset4: e.target.value }); } onChangeEnableMaskIncrementMode(e) { this.setState({ enableMaskIncrementMode: e.target.checked }); } onChangeMaskIncrementMin(e) { this.setState({ maskIncrementMin: e }); } onChangeMaskIncrementMax(e) { this.setState({ maskIncrementMax: e }); } onChangeHash(e) { this.setState({ hash: e }); } onChangeDevicesIDs(e) { this.setState({ devicesIDs: e }); } onChangeDevicesTypes(e) { this.setState({ devicesTypes: e }); } onChangeWorkloadProfile(e) { this.setState({ workloadProfile: e }); } onChangeDisableMonitor(e) { this.setState({ disableMonitor: e.target.checked }); } onChangeTempAbort(e) { this.setState({ tempAbort: e }); } onChangeMarkovDisable(e) { this.setState({ markovDisable: e.target.checked }); } onChangeMarkovClassic(e) { this.setState({ markovClassic: e.target.checked }); } onChangeMarkovThreshold(e) { this.setState({ markovThreshold: e }); } onChangeExtraArguments(e) { this.setState({ extraArguments: e.target.value.split(" ") }); } onChangeStatusTimer(e) { this.setState({ statusTimer: e }); } onChangeOutputFile() { if (typeof window.GOsaveDialog !== "function") { message.error("GOsaveDialog is not a function"); return; } this.setState({isLoadingSetOutputFile: true}, async () => { try { let outputFile = await window.GOsaveDialog(); this.setState({ outputFile: outputFile, isLoadingSetOutputFile: false }); } catch (e) { message.error(e.toString()); this.setState({ isLoadingSetOutputFile: false }); } }); } onChangeOutputFormat(e) { this.setState({ outputFormat: e }); } onChangePriority(priority) { if (typeof(priority) !== "number") return this.setState({ priority: priority }); } onClickCreateTask() { if (typeof window.GOcreateTask !== "function") { message.error("GOcreateTask is not a function"); return; } this.setState({ isLoadingCreateTask: true }, () => { window.GOcreateTask({ attackMode: this.state.attackMode, hashMode: this.state.algorithm, dictionaries: this.state.dictionaries, rules: this.state.rules, mask: this.state.maskInputType === "text" ? this.state.mask : undefined, maskFile: this.state.maskInputType === "file" ? this.state.maskFile : undefined, leftDictionary: this.state.leftDictionary, leftRule: this.state.leftRule, rightDictionary: this.state.rightDictionary, rightRule: this.state.rightRule, customCharset1: this.state.customCharset1, customCharset2: this.state.customCharset2, customCharset3: this.state.customCharset3, customCharset4: this.state.customCharset4, enableMaskIncrementMode: this.state.enableMaskIncrementMode, maskIncrementMin: this.state.maskIncrementMin, maskIncrementMax: this.state.maskIncrementMax, hash: this.state.hash, quiet: this.state.quiet, disablePotFile: this.state.disablePotFile, disableLogFile: this.state.disableLogFile, enableOptimizedKernel: this.state.enableOptimizedKernel, enableSlowerCandidateGenerators: this.state.enableSlowerCandidateGenerators, removeFoundHashes: this.state.removeFoundHashes, ignoreUsernames: this.state.ignoreUsernames, disableSelfTest: this.state.disableSelfTest, ignoreWarnings: this.state.ignoreWarnings, devicesIDs: this.state.devicesIDs, devicesTypes: this.state.devicesTypes, workloadProfile: this.state.workloadProfile, disableMonitor: this.state.disableMonitor, tempAbort: this.state.tempAbort, markovDisable: this.state.markovDisable, markovClassic: this.state.markovClassic, markovThreshold: this.state.markovThreshold, extraArguments: this.state.extraArguments.filter(n => n), statusTimer: this.state.statusTimer, outputFile: this.state.outputFile, outputFormat: this.state.outputFormat, }, this.state.priority).then( response => { message.success("Task has been created successfully!"); this.setState({isLoadingCreateTask: false}); if (!this.state.preserveTaskConfig) this.resetInitialConfig(); }, error => { message.error(error); this.setState({isLoadingCreateTask: false}); } ); }); } onChangePreserveTaskConfig(e) { this.setState({ preserveTaskConfig: e.target.checked }); } resetInitialConfig() { this.setState(initialConfig); } importConfig(config) { const newConfig = {...initialConfig}; Object.keys(newConfig).forEach(key => { if (config.hasOwnProperty(key)) newConfig[key] = config[key]; }); this.setState({ ...newConfig }); } onClickImportConfig(e) { var fileList = e.fileList; if (fileList.length === 0) return; this.setState({ isLoadingImportConfig: true }, () => { var file = fileList[0].originFileObj; var reader = new FileReader(); reader.onload = (e) => { try { const config = JSON.parse(e.target.result); this.importConfig(config); message.success("Imported! (" + filename(file.name) + ")"); } catch (e) { message.error(e.toString()); } this.setState({ isLoadingImportConfig: false }); }; reader.readAsText(file); }); } exportConfig() { const config = {}; Object.keys(initialConfig).forEach(key => { config[key] = this.state[key] } ); return config; } onClickExportConfig() { if (typeof window.GOexportConfig !== "function") { message.error("GOexportConfig is not a function"); return; } this.setState({ isLoadingExportConfig: true }, () => { window.GOexportConfig(this.exportConfig()).then( response => { message.success("Exported! (" + filename(response) + ")"); this.setState({isLoadingExportConfig: false}); }, error => { message.error(error); this.setState({isLoadingExportConfig: false}); } ); }); } onClickDevicesInfo() { if (typeof window.GOhashcatDevices !== "function") { message.error("GOhashcatDevices is not a function"); return; } this.setState({ isLoadingDevicesInfo: true }, () => { window.GOhashcatDevices().then( response => { Modal.info({ title: 'Devices', content: ( <pre style={{ maxHeight: '300px', overflow: 'auto', padding: '.5rem', margin: '0', border: '1px solid #303030' }}> {response} </pre> ), width: 720 }); this.setState({isLoadingDevicesInfo: false}); }, error => { message.error(error); this.setState({isLoadingDevicesInfo: false}); } ); }); } onClickBenchmark() { if (typeof window.GOhashcatBenchmark !== "function") { message.error("GOhashcatBenchmark is not a function"); return; } const algorithm = this.state.algorithm; if (typeof(algorithm) !== "number") { message.error("No algorithm is selected"); return; } this.setState({ isLoadingBenchmark: true }, () => { window.GOhashcatBenchmark(algorithm).then( response => { Modal.info({ title: 'Benchmark', content: ( <pre style={{ maxHeight: '300px', overflow: 'auto', padding: '.5rem', margin: '0', border: '1px solid #303030' }}> {response} </pre> ), width: 720 }); this.setState({isLoadingBenchmark: false}); }, error => { message.error(error); this.setState({isLoadingBenchmark: false}); } ); }); } componentDidMount() { EventBus.on("dataUpdate", "NewTask", () => { this.setState({ _dictionaries: getDictionaries(), _rules: getRules(), _masks: getMasks(), _hashes: getHashes(), _algorithms: getAlgorithms() }); }); } componentWillUnmount() { EventBus.remove("dataUpdate", "NewTask"); } render() { return ( <> <PageHeader title="New Task" extra={[ <Upload key="Import Config" accept=".json" maxCount={1} showUploadList={false} onChange={this.onClickImportConfig} beforeUpload={() => {return false;}} > <Button type="text" icon={<ImportOutlined />} loading={this.state.isLoadingImportConfig} > Import Config </Button> </Upload>, <Button key="Export Config" type="text" icon={<ExportOutlined />} onClick={this.onClickExportConfig} loading={this.state.isLoadingExportConfig} > Export Config </Button> ]} /> <Content style={{ padding: '16px 24px' }}> <Row gutter={[16]}> <Col span={4}> <Steps direction="vertical" current={this.state.step} onChange={this.onChangeStep}> <Step title="Target" icon={<AimOutlined />} description="Select Target" /> <Step title="Attack" icon={<ToolOutlined />} description="Configure Attack" /> <Step title="Advanced" icon={<ExperimentOutlined />} description="Advanced Options" /> <Step title="Output" icon={<ExportOutlined />} description="Set Output" /> <Step title="Finalize" icon={<FileDoneOutlined />} description="Review and Finalize" /> </Steps> </Col> <Col span={20}> <div className="steps-content"> {this.state.step === 0 ? ( <Form layout="vertical"> <Form.Item label="Hash" > <Select showSearch style={{ width: "100%" }} size="large" placeholder="Select Hash" value={this.state.hash} onChange={this.onChangeHash} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._hashes.map(hash => <Option value={hash} key={hash} title={hash}>{filename(hash)}</Option> )} </Select> </Form.Item> <Form.Item label="Algorithm" > <Select showSearch style={{ width: "100%" }} size="large" placeholder="Select Algorithm" value={this.state.algorithm} onChange={this.onChangeAlgorithm} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {Object.keys(this.state._algorithms).map(key => <Option value={Number(key)} key={Number(key)}>{key + " - " + this.state._algorithms[key]}</Option> )} </Select> </Form.Item> </Form> ) : this.state.step === 1 ? ( <Form layout="vertical" requiredMark="optional"> <Form.Item label="Attack Mode" required > <Radio.Group value={this.state.attackMode} onChange={this.onChangeAttackMode}> <Radio value={0}>Dictionary Attack</Radio> <Radio value={1}>Combinator Attack</Radio> <Radio value={3}>Mask Attack</Radio> <Radio value={6}>Hybrid1 (Dictionary + Mask)</Radio> <Radio value={7}>Hybrid2 (Mask + Dictionary)</Radio> </Radio.Group> </Form.Item> {this.state.attackMode === 0 ? ( <> <Form.Item label="Dictionaries" required > <Select mode="multiple" allowClear style={{ width: '100%' }} placeholder="Select Dictionaries" size="large" onChange={this.onChangeDictionaries} value={this.state.dictionaries} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._dictionaries.map(dictionary => <Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option> )} </Select> </Form.Item> <Form.Item label="Rules" > <Select mode="multiple" allowClear style={{ width: '100%' }} placeholder={"Select Rules [max. "+maxRules+"]"} size="large" onChange={this.onChangeRules} value={this.state.rules} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._rules.map(rule => <Option value={rule} key={rule} title={rule}>{filename(rule)}</Option> )} </Select> </Form.Item> </> ) : this.state.attackMode === 1 ? ( <Row gutter={[18, 16]}> <Col span={12}> <Row> <Col span={24}> <Form.Item label="Left Dictionary" required > <Select showSearch allowClear style={{ width: '100%' }} placeholder="Select Left Dictionary" size="large" onChange={this.onChangeLeftDictionary} value={this.state.leftDictionary} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._dictionaries.map(dictionary => <Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option> )} </Select> </Form.Item> </Col> <Col span={24}> <Form.Item label="Left Rule" > <Input allowClear style={{ width: '100%' }} placeholder="Set Left Rule" size="large" onChange={this.onChangeLeftRule} value={this.state.leftRule} /> </Form.Item> </Col> </Row> </Col> <Col span={12}> <Row> <Col span={24}> <Form.Item label="Right Dictionary" required > <Select showSearch allowClear style={{ width: '100%' }} placeholder="Select Right Dictionary" size="large" onChange={this.onChangeRightDictionary} value={this.state.rightDictionary} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._dictionaries.map(dictionary => <Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option> )} </Select> </Form.Item> </Col> <Col span={24}> <Form.Item label="Right Rule" > <Input allowClear style={{ width: '100%' }} placeholder="Set Right Rule" size="large" onChange={this.onChangeRightRule} value={this.state.rightRule} /> </Form.Item> </Col> </Row> </Col> </Row> ) : this.state.attackMode === 3 ? ( <Row gutter={[18, 16]}> <Col span={12}> {this.state.maskInputType === "text" ? ( <Form.Item label="Mask" required > <Input allowClear style={{ width: '100%' }} placeholder="Set Mask" size="large" onChange={this.onChangeMask} value={this.state.mask} suffix={ this.state.mask ? maskLength(this.state.mask) : undefined } /> <Button type="link" style={{ padding: '0' }} onClick={() => this.onChangeMaskInputType({type: "file"})} > Use .hcmask file instead </Button> </Form.Item> ) : this.state.maskInputType === "file" ? ( <Form.Item label="Mask" required > <Select allowClear style={{ width: '100%' }} placeholder="Select Mask" size="large" onChange={this.onChangeMaskFile} value={this.state.maskFile} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._masks.map(mask => <Option value={mask} key={mask} title={mask}>{filename(mask)}</Option> )} </Select> <Button type="link" style={{ padding: '0' }} onClick={() => this.onChangeMaskInputType({type: "text"})} > Use mask text instead </Button> </Form.Item> ) : "unsupported mask input type" } <Form.Item label="Mask increment mode" > <Checkbox checked={this.state.enableMaskIncrementMode} onChange={this.onChangeEnableMaskIncrementMode} > Enable </Checkbox> <InputNumber disabled={!this.state.enableMaskIncrementMode} min={maskIncrementMin} max={maskIncrementMax} value={this.state.maskIncrementMin} onChange={this.onChangeMaskIncrementMin} /> <InputNumber disabled={!this.state.enableMaskIncrementMode} min={maskIncrementMin} max={maskIncrementMax} value={this.state.maskIncrementMax} onChange={this.onChangeMaskIncrementMax} /> </Form.Item> </Col> <Col span={12}> <Form.Item label="Custom charset 1" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 1" size="large" onChange={this.onChangeCustomCharset1} value={this.state.customCharset1} /> </Form.Item> <Form.Item label="Custom charset 2" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 2" size="large" onChange={this.onChangeCustomCharset2} value={this.state.customCharset2} /> </Form.Item> <Form.Item label="Custom charset 3" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 3" size="large" onChange={this.onChangeCustomCharset3} value={this.state.customCharset3} /> </Form.Item> <Form.Item label="Custom charset 4" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 4" size="large" onChange={this.onChangeCustomCharset4} value={this.state.customCharset4} /> </Form.Item> </Col> </Row> ) : this.state.attackMode === 6 ? ( <Row gutter={[18, 16]}> <Col span={24}> <Row gutter={[18, 16]}> <Col span={12}> <Form.Item label="Dictionary" required > <Select showSearch allowClear style={{ width: '100%' }} placeholder="Select Dictionary" size="large" onChange={this.onChangeLeftDictionary} value={this.state.leftDictionary} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._dictionaries.map(dictionary => <Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option> )} </Select> </Form.Item> </Col> <Col span={12}> <Form.Item label="Rule" > <Input allowClear style={{ width: '100%' }} placeholder="Set Rule" size="large" onChange={this.onChangeLeftRule} value={this.state.leftRule} /> </Form.Item> </Col> </Row> </Col> <Col span={12}> {this.state.maskInputType === "text" ? ( <Form.Item label="Mask" required > <Input allowClear style={{ width: '100%' }} placeholder="Set Mask" size="large" onChange={this.onChangeMask} value={this.state.mask} suffix={ this.state.mask ? maskLength(this.state.mask) : undefined } /> <Button type="link" style={{ padding: '0' }} onClick={() => this.onChangeMaskInputType({type: "file"})} > Use .hcmask file instead </Button> </Form.Item> ) : this.state.maskInputType === "file" ? ( <Form.Item label="Mask" required > <Select allowClear style={{ width: '100%' }} placeholder="Select Mask" size="large" onChange={this.onChangeMaskFile} value={this.state.maskFile} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._masks.map(mask => <Option value={mask} key={mask} title={mask}>{filename(mask)}</Option> )} </Select> <Button type="link" style={{ padding: '0' }} onClick={() => this.onChangeMaskInputType({type: "text"})} > Use mask text instead </Button> </Form.Item> ) : "unsupported mask input type" } <Form.Item label="Mask increment mode" > <Checkbox checked={this.state.enableMaskIncrementMode} onChange={this.onChangeEnableMaskIncrementMode} > Enable </Checkbox> <InputNumber disabled={!this.state.enableMaskIncrementMode} min={maskIncrementMin} max={maskIncrementMax} value={this.state.maskIncrementMin} onChange={this.onChangeMaskIncrementMin} /> <InputNumber disabled={!this.state.enableMaskIncrementMode} min={maskIncrementMin} max={maskIncrementMax} value={this.state.maskIncrementMax} onChange={this.onChangeMaskIncrementMax} /> </Form.Item> </Col> <Col span={12}> <Form.Item label="Custom charset 1" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 1" size="large" onChange={this.onChangeCustomCharset1} value={this.state.customCharset1} /> </Form.Item> <Form.Item label="Custom charset 2" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 2" size="large" onChange={this.onChangeCustomCharset2} value={this.state.customCharset2} /> </Form.Item> <Form.Item label="Custom charset 3" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 3" size="large" onChange={this.onChangeCustomCharset3} value={this.state.customCharset3} /> </Form.Item> <Form.Item label="Custom charset 4" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 4" size="large" onChange={this.onChangeCustomCharset4} value={this.state.customCharset4} /> </Form.Item> </Col> </Row> ) : this.state.attackMode === 7 ? ( <Row gutter={[18, 16]}> <Col span={12}> {this.state.maskInputType === "text" ? ( <Form.Item label="Mask" required > <Input allowClear style={{ width: '100%' }} placeholder="Set Mask" size="large" onChange={this.onChangeMask} value={this.state.mask} suffix={ this.state.mask ? maskLength(this.state.mask) : undefined } /> <Button type="link" style={{ padding: '0' }} onClick={() => this.onChangeMaskInputType({type: "file"})} > Use .hcmask file instead </Button> </Form.Item> ) : this.state.maskInputType === "file" ? ( <Form.Item label="Mask" required > <Select allowClear style={{ width: '100%' }} placeholder="Select Mask" size="large" onChange={this.onChangeMaskFile} value={this.state.maskFile} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._masks.map(mask => <Option value={mask} key={mask} title={mask}>{filename(mask)}</Option> )} </Select> <Button type="link" style={{ padding: '0' }} onClick={() => this.onChangeMaskInputType({type: "text"})} > Use mask text instead </Button> </Form.Item> ) : "unsupported mask input type" } <Form.Item label="Mask increment mode" > <Checkbox checked={this.state.enableMaskIncrementMode} onChange={this.onChangeEnableMaskIncrementMode} > Enable </Checkbox> <InputNumber disabled={!this.state.enableMaskIncrementMode} min={maskIncrementMin} max={maskIncrementMax} value={this.state.maskIncrementMin} onChange={this.onChangeMaskIncrementMin} /> <InputNumber disabled={!this.state.enableMaskIncrementMode} min={maskIncrementMin} max={maskIncrementMax} value={this.state.maskIncrementMax} onChange={this.onChangeMaskIncrementMax} /> </Form.Item> </Col> <Col span={12}> <Form.Item label="Custom charset 1" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 1" size="large" onChange={this.onChangeCustomCharset1} value={this.state.customCharset1} /> </Form.Item> <Form.Item label="Custom charset 2" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 2" size="large" onChange={this.onChangeCustomCharset2} value={this.state.customCharset2} /> </Form.Item> <Form.Item label="Custom charset 3" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 3" size="large" onChange={this.onChangeCustomCharset3} value={this.state.customCharset3} /> </Form.Item> <Form.Item label="Custom charset 4" > <Input allowClear style={{ width: '100%' }} placeholder="Set Custom charset 4" size="large" onChange={this.onChangeCustomCharset4} value={this.state.customCharset4} /> </Form.Item> </Col> <Col span={24}> <Row gutter={[18, 16]}> <Col span={12}> <Form.Item label="Dictionary" required > <Select showSearch allowClear style={{ width: '100%' }} placeholder="Select Dictionary" size="large" onChange={this.onChangeRightDictionary} value={this.state.rightDictionary} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {this.state._dictionaries.map(dictionary => <Option value={dictionary} key={dictionary} title={dictionary}>{filename(dictionary)}</Option> )} </Select> </Form.Item> </Col> <Col span={12}> <Form.Item label="Rule" > <Input allowClear style={{ width: '100%' }} placeholder="Set Rule" size="large" onChange={this.onChangeRightRule} value={this.state.rightRule} /> </Form.Item> </Col> </Row> </Col> </Row> ) : ( "Select Attack Mode" )} </Form> ) : this.state.step === 2 ? ( <Form layout="vertical"> <Collapse ghost onChange={this.onChangeAdvancedOptionsCollapse} activeKey={this.state.advancedOptionsCollapse}> <Panel header="General" key="General"> <Row gutter={[18, 16]}> <Col> <Checkbox checked={this.state.quiet} onChange={this.onChangeQuiet} > Quiet </Checkbox> </Col> <Col> <Checkbox checked={this.state.disablePotFile} onChange={this.onChangeDisablePotFile} > Disable Pot File </Checkbox> </Col> <Col> <Checkbox checked={this.state.disableLogFile} onChange={this.onChangeDisableLogFile} > Disable Log File </Checkbox> </Col> <Col> <Checkbox checked={this.state.enableOptimizedKernel} onChange={this.onChangeEnableOptimizedKernel} > Enable optimized kernel </Checkbox> </Col> <Col> <Checkbox checked={this.state.enableSlowerCandidateGenerators} onChange={this.onChangeEnableSlowerCandidateGenerators} > Enable slower candidate generators </Checkbox> </Col> <Col> <Checkbox checked={this.state.removeFoundHashes} onChange={this.onChangeRemoveFoundHashes} > Remove found hashes </Checkbox> </Col> <Col> <Checkbox checked={this.state.ignoreUsernames} onChange={this.onChangeIgnoreUsernames} > Ignore Usernames </Checkbox> </Col> <Col> <Checkbox checked={this.state.disableSelfTest} onChange={this.onChangeDisableSelfTest} > Disable self-test (Not Recommended) </Checkbox> </Col> <Col> <Checkbox checked={this.state.ignoreWarnings} onChange={this.onChangeIgnoreWarnings} > Ignore warnings (Not Recommended) </Checkbox> </Col> </Row> </Panel> <Panel header="Devices" key="Devices"> <Row gutter={[18, 16]}> <Col span={8}> <Form.Item label="Devices IDs" > <Select mode="multiple" allowClear style={{ width: '100%' }} placeholder="Select Devices IDs" size="large" onChange={this.onChangeDevicesIDs} value={this.state.devicesIDs} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > {Array.from(Array(16)).map((x,i) => <Option value={i+1} key={i+1}>{"Device #"+(i+1)}</Option> )} </Select> </Form.Item> </Col> <Col span={8}> <Form.Item label="Devices Types" > <Select mode="multiple" allowClear style={{ width: '100%' }} placeholder="Select Devices Types" size="large" onChange={this.onChangeDevicesTypes} value={this.state.devicesTypes} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > <Option value={1} key={1}>CPU</Option> <Option value={2} key={2}>GPU</Option> <Option value={3} key={3}>FPGA, DSP, Co-Processor</Option> </Select> </Form.Item> </Col> <Col span={8}> <Form.Item label="Workload Profile" tooltip={ <Table columns={[ { title: 'Performance', dataIndex: 'performance', key: 'Performance' }, { title: 'Runtime', dataIndex: 'runtime', key: 'Runtime' }, { title: 'Power Consumption', dataIndex: 'powerConsumption', key: 'Power Consumption' }, { title: 'Desktop Impact', dataIndex: 'desktopImpact', key: 'Desktop Impact' } ]} dataSource={[ { key: '1', performance: 'Low', runtime: '2 ms', powerConsumption: 'Low', desktopImpact: 'Minimal' }, { key: '2', performance: 'Default', runtime: '12 ms', powerConsumption: 'Economic', desktopImpact: 'Noticeable' }, { key: '3', performance: 'High', runtime: '96 ms', powerConsumption: 'High', desktopImpact: 'Unresponsive' }, { key: '4', performance: 'Nightmare', runtime: '480 ms', powerConsumption: 'Insane', desktopImpact: 'Headless' } ]} size="small" pagination={false} style={{ overflow: 'auto' }} /> } > <Select allowClear style={{ width: '100%' }} placeholder="Select Workload Profile" size="large" onChange={this.onChangeWorkloadProfile} value={this.state.workloadProfile} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > <Option value={1} key={1}>Low</Option> <Option value={2} key={2}>Default</Option> <Option value={3} key={3}>High</Option> <Option value={4} key={4}>Nightmare</Option> </Select> </Form.Item> </Col> </Row> <Row gutter={[18, 16]}> <Col> <Button loading={this.state.isLoadingDevicesInfo} onClick={this.onClickDevicesInfo} > Devices Info </Button> </Col> <Col> <Button loading={this.state.isLoadingBenchmark} onClick={this.onClickBenchmark} > Benchmark </Button> </Col> </Row> </Panel> <Panel header="Markov" key="Markov"> <Row gutter={[18, 16]}> <Col> <Checkbox checked={this.state.markovDisable} onChange={this.onChangeMarkovDisable} > Disables markov-chains, emulates classic brute-force </Checkbox> </Col> <Col> <Checkbox checked={this.state.markovClassic} onChange={this.onChangeMarkovClassic} > Enables classic markov-chains, no per-position </Checkbox> </Col> <Col span={24}> <Row gutter={[18, 16]}> <Col span={8}> <Form.Item label="Threshold X when to stop accepting new markov-chains" > <InputNumber value={this.state.markovThreshold} onChange={this.onChangeMarkovThreshold} /> </Form.Item> </Col> </Row> </Col> </Row> </Panel> <Panel header="Monitor" key="Monitor"> <Row gutter={[18, 16]}> <Col> <Checkbox checked={this.state.disableMonitor} onChange={this.onChangeDisableMonitor} > Disable Monitor </Checkbox> </Col> <Col span={24}> <Row gutter={[18, 16]}> <Col span={8}> <Form.Item label="Temp Abort (°C)" > <Select allowClear style={{ width: '100%' }} placeholder="Select Temp Abort (°C)" size="large" onChange={this.onChangeTempAbort} value={this.state.tempAbort} disabled={this.state.disableMonitor} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > <Option value={60} key={60}>60 °C</Option> <Option value={65} key={65}>65 °C</Option> <Option value={70} key={70}>70 °C</Option> <Option value={75} key={75}>75 °C</Option> <Option value={80} key={80}>80 °C</Option> <Option value={85} key={85}>85 °C</Option> <Option value={90} key={90}>90 °C</Option> <Option value={95} key={95}>95 °C</Option> <Option value={100} key={100}>100 °C</Option> </Select> </Form.Item> </Col> </Row> </Col> </Row> </Panel> <Panel header="Extra Arguments" key="Extra Arguments"> <Form.Item label="Extra Arguments" > <Input allowClear style={{ width: '100%' }} placeholder="Set Extra Arguments" size="large" onChange={this.onChangeExtraArguments} value={this.state.extraArguments.join(" ")} /> </Form.Item> </Panel> <Panel header="Misc" key="Misc"> <Form.Item label="Status Timer" > <Select allowClear style={{ width: '100%' }} placeholder="Select Status Timer" size="large" onChange={this.onChangeStatusTimer} value={this.state.statusTimer} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > <Option value={10} key={10}>10 Seconds</Option> <Option value={20} key={20}>20 Seconds</Option> <Option value={30} key={30}>30 Seconds</Option> <Option value={45} key={45}>45 Seconds</Option> <Option value={60} key={60}>60 Seconds</Option> <Option value={90} key={90}>90 Seconds</Option> <Option value={120} key={120}>120 Seconds</Option> <Option value={300} key={300}>300 Seconds</Option> </Select> </Form.Item> </Panel> </Collapse> </Form> ) : this.state.step === 3 ? ( <Form layout="vertical"> <Form.Item label="Output File" extra={this.state.outputFile ? this.state.outputFile : null} > <Button type="primary" onClick={this.onChangeOutputFile} loading={this.state.isLoadingSetOutputFile} > Set Output File </Button> </Form.Item> <Form.Item label="Output Format" > <Select mode="multiple" allowClear style={{ width: '100%' }} placeholder="Select Output Format" size="large" onChange={this.onChangeOutputFormat} value={this.state.outputFormat} filterOption={(input, option) => String(option.value).toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.children).toLowerCase().indexOf(input.toLowerCase()) >= 0 } > <Option value={1} key={1}>hash[:salt]</Option> <Option value={2} key={2}>plain</Option> <Option value={3} key={3}>hex_plain</Option> <Option value={4} key={4}>crack_pos</Option> <Option value={5} key={5}>timestamp absolute</Option> <Option value={6} key={6}>timestamp relative</Option> </Select> </Form.Item> </Form> ) : this.state.step === 4 ? ( <Space direction="vertical"> <Form layout="vertical"> <Form.Item label="Priority" tooltip={ <Typography> Tasks are started automatically in a descending order of priority. <br /> Set to -1 to disable auto-start. </Typography> } > <InputNumber min={-1} max={999} value={this.state.priority} onChange={this.onChangePriority} bordered={true} /> </Form.Item> </Form> <Space size="large" direction="horizontal"> <Button type="primary" icon={<PlusOutlined />} onClick={this.onClickCreateTask} loading={this.state.isLoadingCreateTask} > Create Task </Button> <Checkbox checked={this.state.preserveTaskConfig} onChange={this.onChangePreserveTaskConfig} > Preserve task config </Checkbox> </Space> </Space> ) : null } </div> </Col> </Row> </Content> </> ) } } export default NewTask;