Commit 94c030ea authored by Mathieu Valois's avatar Mathieu Valois
Browse files

Fix error where GUI calculated different stats than CLI

parent d03fd294
Loading
Loading
Loading
Loading
Loading
+23 −21
Original line number Diff line number Diff line
# docker build . -t gui-statsgen
# docker run -d --name gsg -p 5022:22 gui-statsgen
# ssh -X -p 5022 root@127.0.0.1 /opt/GUI/GUI
# ssh -X -p 5022 root@127.0.0.1 /opt/Statsgen/cstatsgen-gui
FROM ubuntu:bionic

ENV SSH_PASSWORD "rootpass"

RUN apt-get -qq update
RUN apt-get -qq -y install build-essential \
RUN apt-get -qq -y install \
	build-essential \
	qt5-default \
	libqt5charts5-dev \
	supervisor \
	openssh-server \
	>/dev/null

RUN apt-get -qq -y install gdb

# Install SSH access
RUN mkdir /var/run/sshd
RUN echo "root:$SSH_PASSWORD" | chpasswd
RUN sed -i 's/^.*PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN echo "X11UseLocalhost no" >> /etc/ssh/sshd_config
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
RUN mkdir /var/run/sshd && \
	echo "root:$SSH_PASSWORD" | chpasswd && \
	sed -i 's/^.*PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
	echo "X11UseLocalhost no" >> /etc/ssh/sshd_config && \
	sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

# Configure supervisor
RUN mkdir -p /var/log/supervisor
RUN echo "[supervisord]" >> /etc/supervisor/conf.d/supervisord.conf
RUN echo "nodaemon=true" >> /etc/supervisor/conf.d/supervisord.conf
RUN echo "[program:sshd]" >> /etc/supervisor/conf.d/supervisord.conf
RUN echo "command=/usr/sbin/sshd -D" >> /etc/supervisor/conf.d/supervisord.conf
RUN mkdir -p /var/log/supervisor && \
	echo "[supervisord]" >> /etc/supervisor/conf.d/supervisord.conf && \
	echo "nodaemon=true" >> /etc/supervisor/conf.d/supervisord.conf && \
	echo "[program:sshd]" >> /etc/supervisor/conf.d/supervisord.conf && \
	echo "command=/usr/sbin/sshd -D" >> /etc/supervisor/conf.d/supervisord.conf

COPY GUI /opt/GUI
COPY Statsgen /opt/Statsgen

WORKDIR /opt/GUI
RUN qmake
RUN make -s -j$(nproc)
WORKDIR /opt/Statsgen
RUN make -s

CMD [ "/usr/bin/supervisord", "-c",  "/etc/supervisor/conf.d/supervisord.conf" ]

+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ TEMPLATE = app
INCLUDEPATH += include


SOURCES += src/gui/main.cpp\
SOURCES += src/gui/maingui.cpp\
        src/gui/mainwindow.cpp\
        src/core/statsgen.cpp

+16 −16
Original line number Diff line number Diff line
@@ -41,9 +41,9 @@ struct Policy{
 */
struct Container {
	int pass_length = 0;
	std::wstring characterset = L"";
	std::wstring advancedmask_string = L"";
	std::wstring simplemask_string = L"";
	std::string characterset = "";
	std::string advancedmask_string = "";
	std::string simplemask_string = "";
	Policy pol;
};

@@ -89,14 +89,14 @@ struct thread_data {
	uint64_t total_filter = 0;

	std::unordered_map<int, uint64_t> length;
	std::unordered_map<std::wstring, uint64_t> simplemasks;
	std::unordered_map<std::wstring, uint64_t> advancedmasks;
	std::unordered_map<std::wstring, uint64_t> charactersets;
	std::queue<std::wstring> password_queue;
	std::unordered_map<std::string, uint64_t> simplemasks;
	std::unordered_map<std::string, uint64_t> advancedmasks;
	std::unordered_map<std::string, uint64_t> charactersets;
	std::queue<std::string> password_queue;

	minMax minMaxValue;

	std::wregex current_regex;
	std::regex current_regex;
	bool use_regex = false;
	bool withcount = false;

@@ -219,7 +219,7 @@ public:
	uint64_t getTotalFilter();
	uint64_t getNbSecurePasswords();
	std::unordered_map<int, uint64_t> getStatsLength();
	std::unordered_map<std::wstring, uint64_t> getStatsCharsets();
	std::unordered_map<std::string, uint64_t> getStatsCharsets();



@@ -232,7 +232,7 @@ private:

	int hiderare = 0; 				// Hide low statistics
	int top = 10;					// Show only a top of statistics
	std::wregex current_regex;		// Regex for the interesting passwords
	std::regex current_regex;		// Regex for the interesting passwords
	bool use_regex = false;			// Know if we use a regex or not
	bool withcount = false;			// Know if the database is at the format withcount or not
	int limitSimplemask = 12;		// Limit the size of Simple Mask
@@ -246,9 +246,9 @@ private:
	// Dictionary

	std::unordered_map<int, uint64_t> stats_length;					// Passwords' length linked to their occurrence
	std::unordered_map<std::wstring, uint64_t> stats_simplemasks;	// Passwords' simple mask linked to their occurrence
	std::unordered_map<std::wstring, uint64_t> stats_advancedmasks;	// Passwords' advanced mask linked to their occurrence
	std::unordered_map<std::wstring, uint64_t> stats_charactersets;	// Passwords' characterset linked to their occurrence
	std::unordered_map<std::string, uint64_t> stats_simplemasks;	// Passwords' simple mask linked to their occurrence
	std::unordered_map<std::string, uint64_t> stats_advancedmasks;	// Passwords' advanced mask linked to their occurrence
	std::unordered_map<std::string, uint64_t> stats_charactersets;	// Passwords' characterset linked to their occurrence


	// Counters
@@ -281,14 +281,14 @@ private:
 * @param sizeAdvancedMask: size of the current advanced mask
 * @param sizeSimpleMask: size of the current simple mask
 */
void analyse_letter(const char & letter, char & last_simplemask, std::wstring & simplemask_string, std::wstring & advancedmask_string, Policy & policy, int & sizeAdvancedMask, int & sizeSimpleMask);
void analyse_letter(const char & letter, char & last_simplemask, std::string & simplemask_string, std::string & advancedmask_string, Policy & policy, int & sizeAdvancedMask, int & sizeSimpleMask);

/**
 * @brief Analyse the characterset of the current password
 * @param charset: characterset of the current password
 * @param policy: current number of digit, lower, upper and special for the current password
 */
void analyse_charset(std::wstring & charset, const Policy & policy);
void analyse_charset(std::string & charset, const Policy & policy);

/**
 * @brief Analyse a password
@@ -298,7 +298,7 @@ void analyse_charset(std::wstring & charset, const Policy & policy);
 * @param limitAdvancedmask: define the limit for the size of advanced masks
 * @param limitSimplemask: define the limit for the size of simple masks
 */
void analyze_password(const std::wstring & password, Container & c, SecurityRules & sr, const int & limitAdvancedmask, const int & limitSimplemask);
void analyze_password(const std::string & password, Container & c, SecurityRules & sr, const int & limitAdvancedmask, const int & limitSimplemask);

/**
 * @brief Update minima and maxima of all general data from analysed passwords
+4 −2
Original line number Diff line number Diff line
@@ -61,13 +61,15 @@ multimap<uint64_t, A> flip_map(const std::unordered_map<A, uint64_t> & src) {
template<typename Type>
void readResult(uint64_t res, Type carac, int & count, const uint64_t & total_counter, const int & hiderare) {
	float percentage;
	std::ostringstream ss;
	percentage = (float) (100*res) / total_counter;

	if (percentage >= hiderare) {
		wstring value = to_wstring(percentage);
		ss << percentage;
		std::string value(ss.str());
		value = value.substr(0,5);

		wcout << setw(40) << right << carac << ":  "
		cout << setw(40) << right << carac << ":  "
			<< setw(5) << right << value << "%"
			<< setw(5) << right << "(" << res << ")" << endl;

+48 −47
Original line number Diff line number Diff line
@@ -47,10 +47,10 @@ void Statsgen::setTop(int val) {


void Statsgen::setRegex(string expr) {
	wstring tmp(expr.length(),L' ');
	string tmp(expr.length(),' ');
	copy(expr.begin(), expr.end(), tmp.begin());

	wregex tmp_reg(tmp);
	regex tmp_reg(tmp);
	current_regex = tmp_reg;

	use_regex = true;
@@ -175,9 +175,9 @@ int Statsgen::generate_stats() {

	// split stdin into nbThread files on disk
	if (is_stdin){
		wstring line;
		string line;
		nbline = 0;
		while(getline(wcin, line)){
		while(getline(cin, line)){
			td[nbline%nbThread].password_queue.push(line);
			nbline++;
		}
@@ -286,6 +286,7 @@ int Statsgen::generate_stats() {
		return 0;
	}

	cout << "total counter " << total_counter << endl;

	return 1;
}
@@ -334,7 +335,7 @@ void Statsgen::print_stats() {

	if (limitSimplemask > 0) {
		wcout << endl;
		readResult(stats_simplemasks[L"othermasks"], L"othermasks", count, total_counter, hiderare);
		readResult(stats_simplemasks["othermasks"], "othermasks", count, total_counter, hiderare);
	}


@@ -343,11 +344,11 @@ void Statsgen::print_stats() {

	if (outfile_name != ""){
		locale::global(locale("C"));
		wofstream outfile_stream(outfile_name);
		multimap<uint64_t, wstring> reverse = flip_map<wstring>(stats_advancedmasks);
		ofstream outfile_stream(outfile_name);
		multimap<uint64_t, string> reverse = flip_map<string>(stats_advancedmasks);
		for(auto it=reverse.end();it!=reverse.begin();it--){
			if (it == reverse.end()) continue;
			if(it->second == L"othermasks") continue;
			if(it->second == "othermasks") continue;
			outfile_stream << it->second << "," << it->first << endl;
		}
		outfile_stream.close();
@@ -355,7 +356,7 @@ void Statsgen::print_stats() {

	if (limitAdvancedmask > 0) {
		wcout << endl;
		readResult(stats_advancedmasks[L"othermasks"], L"othermasks", count, total_counter, hiderare);
		readResult(stats_advancedmasks["othermasks"], "othermasks", count, total_counter, hiderare);
	}
}

@@ -364,101 +365,101 @@ void Statsgen::print_stats() {



void analyse_letter(const char & letter, char & last_simplemask, wstring & simplemask_string, wstring & advancedmask_string, Policy & policy, int & sizeAdvancedMask, int & sizeSimpleMask) {
void analyse_letter(const char & letter, char & last_simplemask, string & simplemask_string, string & advancedmask_string, Policy & policy, int & sizeAdvancedMask, int & sizeSimpleMask) {
	sizeAdvancedMask++;

	if (letter >= L'0' && letter <= L'9') {
	if (letter >= '0' && letter <= '9') {
		policy.digit++;
		advancedmask_string += L"?d";
		advancedmask_string += "?d";
		if (last_simplemask != 'd') {
			sizeSimpleMask++;
			simplemask_string += L"digit";
			simplemask_string += "digit";
			last_simplemask = 'd';
		}
	}
	else if(letter >= L'a' && letter <= L'z') {
	else if(letter >= 'a' && letter <= 'z') {
		policy.lower++;
		advancedmask_string += L"?l";
		advancedmask_string += "?l";
		if (last_simplemask != 'l') {
			sizeSimpleMask++;
			simplemask_string += L"lower";
			simplemask_string += "lower";
			last_simplemask = 'l';
		}
	}
	else if(letter >= L'A' && letter <= L'Z') {
	else if(letter >= 'A' && letter <= 'Z') {
		policy.upper++;
		advancedmask_string += L"?u";
		advancedmask_string += "?u";
		if (last_simplemask != 'u') {
			sizeSimpleMask++;
			simplemask_string += L"upper";
			simplemask_string += "upper";
			last_simplemask = 'u';
		}
	}
	else {
		policy.special++;
		advancedmask_string += L"?s";
		advancedmask_string += "?s";

		if (last_simplemask != 's') {
			sizeSimpleMask++;
			simplemask_string += L"special";
			simplemask_string += "special";
			last_simplemask = 's';
		}
	}
}


void analyse_charset(wstring & charset, const Policy & policy) {
void analyse_charset(string & charset, const Policy & policy) {
	if (policy.digit && !policy.lower && !policy.upper && !policy.special) {
		charset = L"numeric";
		charset = "numeric";
	}
	else if (!policy.digit && policy.lower && !policy.upper && !policy.special) {
		charset = L"loweralpha";
		charset = "loweralpha";
	}
	else if (!policy.digit && !policy.lower && policy.upper && !policy.special) {
		charset = L"upperalpha";
		charset = "upperalpha";
	}
	else if (!policy.digit && !policy.lower && !policy.upper && policy.special) {
		charset = L"special";
		charset = "special";
	}
	else if (!policy.digit && policy.lower && policy.upper && !policy.special) {
		charset = L"mixedalpha";
		charset = "mixedalpha";
	}
	else if (policy.digit && policy.lower && !policy.upper && !policy.special) {
		charset = L"loweralphanum";
		charset = "loweralphanum";
	}
	else if (policy.digit && !policy.lower && policy.upper && !policy.special) {
		charset = L"upperalphanum";
		charset = "upperalphanum";
	}
	else if (!policy.digit && policy.lower && !policy.upper && policy.special) {
		charset = L"loweralphaspecial";
		charset = "loweralphaspecial";
	}
	else if (!policy.digit && !policy.lower && policy.upper && policy.special) {
		charset = L"upperalphaspecial";
		charset = "upperalphaspecial";
	}
	else if (policy.digit && !policy.lower && !policy.upper && policy.special) {
		charset = L"specialnum";
		charset = "specialnum";
	}

	else if (!policy.digit && policy.lower && policy.upper && policy.special) {
		charset = L"mixedalphaspecial";
		charset = "mixedalphaspecial";
	}
	else if (policy.digit && !policy.lower && policy.upper && policy.special) {
		charset = L"upperalphaspecialnum";
		charset = "upperalphaspecialnum";
	}
	else if (policy.digit && policy.lower && !policy.upper && policy.special) {
		charset = L"loweralphaspecialnum";
		charset = "loweralphaspecialnum";
	}
	else if (policy.digit && policy.lower && policy.upper && !policy.special) {
		charset = L"mixedalphanum";
		charset = "mixedalphanum";
	}

	else {
		charset = L"all";
		charset = "all";
	}
}


void analyze_password(const wstring & password, Container & c, SecurityRules & sr, const int & limitAdvancedmask, const int & limitSimplemask) {
void analyze_password(const string & password, Container & c, SecurityRules & sr, const int & limitAdvancedmask, const int & limitSimplemask) {
	c.pass_length = password.size();

	char last_simplemask = 'a';
@@ -482,11 +483,11 @@ void analyze_password(const wstring & password, Container & c, SecurityRules & s
	}

	if (sizeAdvancedMask > limitAdvancedmask) {
		c.advancedmask_string = L"othermasks";
		c.advancedmask_string = "othermasks";
	}

	if (sizeSimpleMask > limitSimplemask) {
		c.simplemask_string = L"othermasks";
		c.simplemask_string = "othermasks";
	}
}

@@ -527,7 +528,7 @@ void * generate_stats_thread_queue(void * threadarg) {
	struct thread_data *my_data;
	my_data = (struct thread_data *) threadarg;

	wstring line;
	string line;
	uint64_t nbline = 0;
	while(!my_data->password_queue.empty()) {
		++nbline;
@@ -562,8 +563,8 @@ void * generate_stats_thread(void * threadarg) {
	struct thread_data *my_data;
	my_data = (struct thread_data *) threadarg;

	wifstream readfile(my_data->filename);
	wstring line;
	ifstream readfile(my_data->filename);
	string line;
	uint64_t nbline = 0;

	while(readfile.good()) {
@@ -594,7 +595,7 @@ void * generate_stats_thread(void * threadarg) {
					break;
				}
			}
			wstring password = line.substr(i+1,line.length());
			string password = line.substr(i+1,line.length());
			uint64_t nbPasswords = stoi(line.substr(0,i));

			my_data->total_counter += nbPasswords;
@@ -646,14 +647,14 @@ std::unordered_map<int, uint64_t> Statsgen::getStatsLength(){
	return stats_length;
}

std::unordered_map<std::wstring, uint64_t> Statsgen::getStatsCharsets(){
std::unordered_map<std::string, uint64_t> Statsgen::getStatsCharsets(){
	return stats_charactersets;
}


uint64_t nbline_file(const string & filename) {
	wifstream readfile(filename);
	wstring line;
	ifstream readfile(filename);
	string line;
	uint64_t nb = 0;

	while(readfile.good()) {
Loading