Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New attack mode: Association attack #95

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ RUN mkdir /srv/db_init
EXPOSE 80
EXPOSE 5000

HEALTHCHECK --interval=5s --timeout=20s CMD ps -ef | grep apache2 | grep -v grep || exit 1

# Entrypoint
RUN ["chmod", "+x", "/srv/fitcrack/entrypoint-fitcrack.sh"]
ENTRYPOINT ["/srv/fitcrack/entrypoint-fitcrack.sh"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need these changes?


HEALTHCHECK --interval=5s --timeout=20s CMD ps -ef | grep apache2 | grep -v grep || exit 1
3 changes: 3 additions & 0 deletions boinc_connect_local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(boinccmd --project 127.0.0.1/fitcrack/ detach || true) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed for our repo.

KEY=$(boinccmd --create_account 127.0.0.1/fitcrack/ [email protected] fitcrack dukek | grep -oP 'account key: \K\w+') &&
boinccmd --project_attach 127.0.0.1/fitcrack/ $KEY
4 changes: 2 additions & 2 deletions docker-compose-custom-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ services:
image: fitcrack_server

hostname: fitcrack

cap_add:
- SYS_NICE
# Configuration of the build context
build:
context: .
dockerfile: Dockerfile
args:
- COMPILER_THREADS=1 # Higher values may cause linker race conditions

command: ./entrypoint-fitcrack.sh
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly bad merge of dev branch?

restart: always
ports:
- ${BACKEND_PORT}:${BACKEND_PORT} # Mapping of WebAdmin backend
Expand Down
6 changes: 5 additions & 1 deletion installer/fitcrack_changes_in_boinc.patch
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ diff -ruN boinc_org/sched/Makefile.am boinc/sched/Makefile.am

schedcgi_PROGRAMS= \
cgi \
@@ -307,6 +311,82 @@
@@ -307,6 +311,86 @@
sched_driver_SOURCES = sched_driver.cpp
sched_driver_LDADD = $(SERVERLIBS)

Expand All @@ -112,6 +112,8 @@ diff -ruN boinc_org/sched/Makefile.am boinc/sched/Makefile.am
+ AttackPcfg.h \
+ AttackPcfgClient.h \
+ AttackPcfgRules.h \
+ AttackAssoc.h \
+ AttackAssocNoRule.h \
+ Base64.h \
+ BenchmarkClasses.h \
+ Config.h \
Expand All @@ -138,6 +140,8 @@ diff -ruN boinc_org/sched/Makefile.am boinc/sched/Makefile.am
+ AttackPcfg.cpp \
+ AttackPcfgClient.cpp \
+ AttackPcfgRules.cpp \
+ AttackAssoc.cpp \
+ AttackAssocNoRule.cpp \
+ BenchmarkClasses.cpp \
+ Config.cpp \
+ Dictionary.cpp \
Expand Down
4 changes: 4 additions & 0 deletions rebuild_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
./remove_docker_installation.sh &&
yes | docker system prune -a --volumes &&
docker-compose -f docker-compose-custom-build.yml build &&
docker-compose -f docker-compose-custom-build.yml up
1 change: 1 addition & 0 deletions runner/include/Attack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum AttackType {
AT_Benchmark,
AT_HybridDictMask,
AT_HybridMaskDict,
AT_Association,
AT_Unknown
};

Expand Down
31 changes: 31 additions & 0 deletions runner/include/AttackAssociation.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Author : see AUTHORS
* Licence: MIT, see LICENSE
*/

#ifndef ATTACKASSOCIATION_HPP
#define ATTACKASSOCIATION_HPP

#include "AttackCrackingBase.hpp"

/** Class representing hashcat's association attack */
class AttackAssociation: public AttackCrackingBase {

protected:

/**
* @brief Adds all attack specific arguments
*/
void addSpecificArguments();

public:

/**
* @brief Basic constructor
* @param config [in] Representation of config file
* @param directory [in] Working directory
*/
AttackAssociation(const ConfigTask& config, Directory& directory);

};
#endif // ATTACKASSOCIATION_HPP
41 changes: 21 additions & 20 deletions runner/src/Attack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,28 @@
#include "AttackMask.hpp"
#include "AttackPCFG.hpp"
#include "AttackPrince.hpp"
#include "AttackAssociation.hpp"

AttackType AttackModeToType(char attack_mode)
AttackType AttackModeToType(std::string attack_mode)
{
switch (attack_mode) {
case '0':
// opted for readablility but tree would be faster
if(attack_mode == "0")
return AT_Dictionary;
break;
case '1':
if(attack_mode == "1")
return AT_Combinator;
break;
case '3':
if(attack_mode == "3")
return AT_Mask;
break;
case '6':
if(attack_mode == "6")
return AT_HybridDictMask;
break;
case '7':
if(attack_mode == "7")
return AT_HybridMaskDict;
break;
case '8':
if(attack_mode == "8")
return AT_Prince;
case '9':
if(attack_mode == "9")
return AT_PCFG;
break;
default:
return AT_Unknown;
}
if(attack_mode == "10")
return AT_Association;
return AT_Unknown;
}

AttackBase *Attack::create(const ConfigTask &task_config, Directory &directory) {
Expand Down Expand Up @@ -69,11 +64,14 @@ AttackBase *Attack::create(const ConfigTask &task_config, Directory &directory)
case AT_PCFG:
attack = new AttackPCFG(task_config, directory);
break;
case AT_Association:
attack = new AttackAssociation(task_config, directory);
break;
case AT_Benchmark:
{
std::string attack_mode;
task_config.find("attack_mode", attack_mode);
switch(AttackModeToType(attack_mode[0]))
switch(AttackModeToType(attack_mode))
{
case AT_Dictionary:
attack = new AttackBenchmark<AttackDictionary>(task_config, directory);
Expand All @@ -96,6 +94,9 @@ AttackBase *Attack::create(const ConfigTask &task_config, Directory &directory)
case AT_PCFG:
attack = new AttackBenchmark<AttackPCFG>(task_config, directory);
break;
case AT_Association:
attack = new AttackBenchmark<AttackAssociation>(task_config, directory);
break;
default:
RunnerUtils::runtimeException("invalid attack mode for benchmark");
return nullptr;
Expand All @@ -116,7 +117,7 @@ enum AttackType Attack::detectAttackType(const ConfigTask &task_config) {
task_config.find("mode", mode);
task_config.find("attack_mode", attack_mode);
if (mode == "n") {
return AttackModeToType(attack_mode[0]);
return AttackModeToType(attack_mode);
} else if (mode == "a" || mode == "b") {
return AT_Benchmark;
}
Expand Down
56 changes: 56 additions & 0 deletions runner/src/AttackAssociation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Author : see AUTHORS
* Licence: MIT, see LICENSE
*/

#include "AttackAssociation.hpp"
#include "Dictstat.hpp"


AttackAssociation::AttackAssociation(const ConfigTask& config, Directory& directory)
: AttackCrackingBase(config, directory, "9") { // change attack mode for hashcat
std::string mode;

config.find("mode", mode);

// This is abusing an undefined behavior in hascat (multiple definitions of attack mode argument)
// The last defined one will be considered the correct
if (mode == "b" || mode == "a"){
// Association mode doen't like 0 keyspace so testing is done on dictionary
addArgument("-a");
addArgument("0");
}
}

void AttackAssociation::addSpecificArguments() {
AttackCrackingBase::addSpecificArguments();

if (attack_submode_ == "0") {

// Do nothing just at the end add dictionaries

} else if (attack_submode_ == "1") {

addArgument("--rules-file");
addRequiredFile("rules");

} else {
RunnerUtils::runtimeException("Unsupported attack_submode = " + attack_submode_ + " attack_mode = " + attack_mode_ + " has no such attack_submode");
}

std::string relativePath = addRequiredFile("dict1");

std::string dict1Keyspace;
if (config_.find(ConfigTask::DICT1_KEYSPACE, dict1Keyspace)) {
// Build hashcat.dictstat2 so hashcat does not have to recompute
// number of passwords in this dictionary - could be a bottleneck for huge
// dictionaries.
DictStatBuilder dsBuilder;
bool dict1StatAdded =
dsBuilder.addStatForDict(relativePath.c_str(), stoull(dict1Keyspace));
if (dict1StatAdded) {
Logging::debugPrint(Logging::Detail::GeneralInfo,
"dictstat2 created for " + relativePath);
}
}
}
59 changes: 59 additions & 0 deletions server/src/headers/AttackModes/AttackAssoc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @file AttackDict.h
* @brief Header file for creation of Dictionary Attack
* @authors Lukas Zobal (zobal.lukas(at)gmail.com)
* @date 12. 12. 2018
* @license MIT, see LICENSE
*/

#ifndef WORKGENERATOR_ATTACKASSOC_H
#define WORKGENERATOR_ATTACKASSOC_H

#include <AttackMode.h>


class CAttackAssoc : public AttackMode {
public:
/**
* @brief Constructor for Association Attack
* @param job [in] Instance of CJob which is parent of this attack instance
* @param host [in] Instance of CHost which this attack belongs to
* @param seconds [in] Number of seconds this instance of attack should take
*/
CAttackAssoc(PtrJob job, PtrHost &host, uint64_t seconds, CSqlLoader *sqlLoader);

/**
* @brief Default destructor
*/
~CAttackAssoc() override = default;

/**
* @brief Creates BOINC workunit, adds entry to fc_workunit
* @return True if a workunit was planned, False otherwise
*/
bool makeWorkunit() override ;

virtual bool requiresDicts() const override {return true;}

virtual bool hasStickyLeftDict() const override {
return m_job->getDistributionMode() == 1 || m_job->getDistributionMode() == 2;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to put these constants to enum

}

/**
* @brief enum for distribution mode options readability
*/
enum DistributionMode {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have them here, so move this declaration somewhere else, into some more general header, so we can use these named constants everywhere.

FragmentOnServer = 0,
FragmentOnHosts = 1,
FragmentByRules = 2
};

private:
/**
* @brief Function to generate new CWorkunit for certain host for given time
* @return True if workunit was generated successfully, False otherwise
*/
bool generateWorkunit() override ;
};

#endif //WORKGENERATOR_ATTACKASSOC_H
59 changes: 59 additions & 0 deletions server/src/headers/AttackModes/AttackAssocNoRule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @file AttackDict.h
* @brief Header file for creation of Dictionary Attack
* @authors Lukas Zobal (zobal.lukas(at)gmail.com)
* @date 12. 12. 2018
* @license MIT, see LICENSE
*/

#ifndef WORKGENERATOR_ATTACKASSOC_NO_RULE_H
#define WORKGENERATOR_ATTACKASSOC_NO_RULE_H

#include <AttackMode.h>


class CAttackAssocNoRule : public AttackMode {
public:
/**
* @brief Constructor for Association Attack
* @param job [in] Instance of CJob which is parent of this attack instance
* @param host [in] Instance of CHost which this attack belongs to
* @param seconds [in] Number of seconds this instance of attack should take
*/
CAttackAssocNoRule(PtrJob job, PtrHost &host, uint64_t seconds, CSqlLoader *sqlLoader);

/**
* @brief Default destructor
*/
~CAttackAssocNoRule() override = default;

/**
* @brief Creates BOINC workunit, adds entry to fc_workunit
* @return True if a workunit was planned, False otherwise
*/
bool makeWorkunit() override ;

virtual bool requiresDicts() const override {return true;}

virtual bool hasStickyLeftDict() const override {
return m_job->getDistributionMode() == 1 || m_job->getDistributionMode() == 2;
}

/**
* @brief enum for distribution mode options readability
*/
enum DistributionMode {
FragmentOnServer = 0,
FragmentOnHosts = 1,
FragmentByRules = 2
};

private:
/**
* @brief Function to generate new CWorkunit for certain host for given time
* @return True if workunit was generated successfully, False otherwise
*/
bool generateWorkunit() override ;
};

#endif //WORKGENERATOR_ATTACKASSOC_NO_RULE_H
Loading