Merge remote-tracking branch 'upstream/master'

Conflicts:
	squatm3-api/requirements.txt
This commit is contained in:
2019-01-16 21:35:07 +01:00
46 changed files with 25 additions and 432 deletions

BIN
.DS_Store vendored

Binary file not shown.

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
.DS_Store
*.swp
*.pyc
*.bak
.idea
__pycache__

View File

@@ -6,11 +6,11 @@ Squatm3gator is a complete web solution based on the python tool squatm3, design
- Substitution attacks - Substitution attacks
- Flipping attack - Flipping attack
- Homoglyph attack fast (execute a fast homoglyph attack, mutating only one letter at the time ) - Homoglyph attack fast (execute a fast homoglyph attack, mutating only one letter at the time)
- Homoglyph attack complete (generates all the possible combinations) - Homoglyph attack complete (generates all the possible combinations)
The tool is ment to help penetration testers to identify domains to be used in phishing attack simulations and security analysts to detect and prevent cybersquatting attacks. The tool is meant to help penetration testers to identify domains to be used in phishing attack simulations and security analysts to detect and prevent cybersquatting attacks.
## Architecture ## Architecture
@@ -36,6 +36,7 @@ pip3 install -r requirements.txt
### Spin up a Redis container ### Spin up a Redis container
One way to get it quickly done is to use the bitnami/redis docker:
``` ```
docker run -d -e REDIS_PASSWORD=waddup --name squatme-redis -p 6379:6379 bitnami/redis docker run -d -e REDIS_PASSWORD=waddup --name squatme-redis -p 6379:6379 bitnami/redis

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 154 KiB

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
<component name="PyCharmProfessionalAdvertiser">
<option name="shown" value="true" />
</component>
</project>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/../squatm3-api/.idea/squatm3-api.iml" filepath="$PROJECT_DIR$/../squatm3-api/.idea/squatm3-api.iml" />
</modules>
</component>
</project>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

View File

@@ -1,213 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="f2d4b4ed-a294-4f78-a859-7ceb6e50f732" name="Default Changelist" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FUSProjectUsageTrigger">
<session id="-748862985">
<usages-collector id="statistics.lifecycle.project">
<counts>
<entry key="project.closed" value="1" />
<entry key="project.open.time.0" value="1" />
<entry key="project.opened" value="1" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.open">
<counts>
<entry key="cfg" value="1" />
<entry key="py" value="1" />
<entry key="txt" value="1" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.open">
<counts>
<entry key="PLAIN_TEXT" value="2" />
<entry key="Python" value="1" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.edit">
<counts>
<entry key="cfg" value="1" />
<entry key="py" value="1372" />
<entry key="txt" value="13" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.edit">
<counts>
<entry key="PLAIN_TEXT" value="14" />
<entry key="Python" value="1372" />
</counts>
</usages-collector>
</session>
</component>
<component name="FileEditorManager">
<leaf>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/requirements.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="45">
<caret line="3" column="13" selection-start-line="3" selection-start-column="13" selection-end-line="3" selection-end-column="13" />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/requirements.txt" />
<option value="$PROJECT_DIR$/config.cfg" />
<option value="$PROJECT_DIR$/server.py" />
<option value="$PROJECT_DIR$/config.cfg" />
</list>
</option>
</component>
<component name="ProjectFrameBounds" fullScreen="true">
<option name="width" value="1440" />
<option name="height" value="900" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="squatm3api" type="b2602c69:ProjectViewProjectNode" />
<item name="squatm3api" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scope" />
</panes>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration name="server" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="squatm3-api" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/server.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python.server" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="f2d4b4ed-a294-4f78-a859-7ceb6e50f732" name="Default Changelist" comment="" />
<created>1538500439587</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1538500439587</updated>
</task>
<servers />
</component>
<component name="ToolWindowManager">
<frame x="0" y="0" width="1440" height="900" extended-state="0" />
<layout>
<window_info id="Favorites" order="0" side_tool="true" />
<window_info content_ui="combo" id="Project" order="1" visible="true" weight="0.24947146" />
<window_info id="Structure" order="2" side_tool="true" weight="0.25" />
<window_info anchor="bottom" id="Terminal" order="0" />
<window_info anchor="bottom" id="Event Log" order="1" side_tool="true" />
<window_info anchor="bottom" id="Python Console" order="2" />
<window_info anchor="bottom" id="Message" order="3" />
<window_info anchor="bottom" id="Find" order="4" />
<window_info anchor="bottom" id="Version Control" order="5" show_stripe_button="false" />
<window_info anchor="bottom" id="Run" order="6" weight="0.32891566" />
<window_info anchor="bottom" id="Debug" order="7" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="8" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="9" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="10" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
</layout>
</component>
<component name="UnknownFeatures">
<option featureType="com.intellij.fileTypeFactory" implementationName="*.cfg" />
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/server.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="345">
<caret line="23" column="22" lean-forward="true" selection-start-line="23" selection-start-column="22" selection-end-line="23" selection-end-column="22" />
<folding>
<element signature="e#0#23#0" expanded="true" />
<marker date="1538502903265" expanded="true" signature="410:415" ph="..." />
<marker date="1538502903265" expanded="true" signature="410:459" ph="..." />
<marker date="1538502903265" expanded="true" signature="839:848" ph="..." />
<marker date="1538502903265" expanded="true" signature="839:957" ph="..." />
<marker date="1538502903265" expanded="true" signature="1037:1280" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/config.cfg">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="30">
<caret line="2" column="46" selection-start-line="2" selection-start-column="46" selection-end-line="2" selection-end-column="46" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/requirements.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="45">
<caret line="3" column="13" selection-start-line="3" selection-start-column="13" selection-end-line="3" selection-end-column="13" />
</state>
</provider>
</entry>
</component>
</project>

View File

@@ -1,103 +0,0 @@
<title>Web Socket</title>
<style>
#chat { width: 97%; }
.them { font-weight: bold; }
.them:before { content: 'them '; color: #bbb; font-size: 14px; }
.you { font-style: italic; }
.you:before { content: 'you '; color: #bbb; font-size: 14px; font-weight: bold; }
#log {
overflow: auto;
max-height: 300px;
list-style: none;
padding: 0;
/* margin: 0;*/
}
#log li {
border-top: 1px solid #ccc;
margin: 0;
padding: 10px 0;
}
</style>
<article>
<form>
<input type="text" id="chat" placeholder="type and press enter to chat" />
</form>
<p id="status">Not connected</p>
<p>Users connected: <span id="connected">0</span></p>
<p>To test, open two windows with Web Socket support, type a message above and press return.</p>
<p>The server side code is available here: <a href="http://github.com/remy/html5demos/tree/master/server/">node-web-socket & server</a> (note that it runs on <a href="http://nodejs.org/" title="node.js">nodejs</a>)</p>
<ul id="log"></ul>
</article>
<script>
// let's invite Firefox to the party.
if (window.MozWebSocket) {
window.WebSocket = window.MozWebSocket;
}
function openConnection() {
// uses global 'conn' object
if (conn.readyState === undefined || conn.readyState > 1) {
conn = new WebSocket('wss://remy-ws.glitch.me/');
conn.onopen = function () {
state.className = 'success';
state.innerHTML = 'Socket open';
};
conn.onmessage = function (event) {
// console.log(event.data);
var message = event.data; //JSON.parse(event.data);
if (!(/^\d+$/).test(message)) {
log.innerHTML = '<li class="them">' + message.replace(/[<>&]/g, function (m) { return entities[m]; }) + '</li>' + log.innerHTML;
} else {
connected.innerHTML = message;
}
};
conn.onclose = function (event) {
state.className = 'fail';
state.innerHTML = 'Socket closed';
};
}
}
var connected = document.getElementById('connected'),
log = document.getElementById('log'),
chat = document.getElementById('chat'),
form = chat.form,
conn = {},
state = document.getElementById('status'),
entities = {
'<' : '<',
'>' : '>',
'&' : '&'
};
if (window.WebSocket === undefined) {
state.innerHTML = 'Sockets not supported';
state.className = 'fail';
} else {
state.onclick = function () {
if (conn.readyState !== 1) {
conn.close();
setTimeout(function () {
openConnection();
}, 250);
}
};
addEvent(form, 'submit', function (event) {
event.preventDefault();
// if we're connected
if (conn.readyState === 1) {
conn.send(JSON.stringify(chat.value));
log.innerHTML = '<li class="you">' + chat.value.replace(/[<>&]/g, function (m) { return entities[m]; }) + '</li>' + log.innerHTML;
chat.value = '';
}
});
openConnection();
}
</script>

View File

@@ -1,8 +1,16 @@
tld==0.9.1 Flask==1.0.2
Flask_And_Redis>=0.7
Flask_RESTful>=0.3.6
Flask_Session>=0.3.1
Flask_SocketIO>=3.0.2
attr==0.3.1
attrs==18.2.0 attrs==18.2.0
eventlet==0.24.1
homoglyphs==1.3.1
redis==2.10.6 redis==2.10.6
requests>=2.20.0 requests>=2.20.1
simplejson==3.16.0 simplejson==3.16.0
<<<<<<< HEAD
Flask_RESTful==0.3.6 Flask_RESTful==0.3.6
Flask==1.0.2 Flask==1.0.2
Flask_Session==0.3.1 Flask_Session==0.3.1
@@ -13,3 +21,7 @@ attr==0.3.1
Flask_And_Redis==0.7 Flask_And_Redis==0.7
eventlet eventlet
Flask-Redis==0.3.0 Flask-Redis==0.3.0
=======
tld==0.9.1
validators==0.12.2
>>>>>>> upstream/master

View File

@@ -15,8 +15,6 @@ import validators
import eventlet import eventlet
eventlet.monkey_patch(socket=True) eventlet.monkey_patch(socket=True)
# initiate the app, Api and redis settings reading from config file # initiate the app, Api and redis settings reading from config file
template_dir = os.path.abspath('../squatm3-ui') template_dir = os.path.abspath('../squatm3-ui')
app = Flask(__name__, template_folder=template_dir) app = Flask(__name__, template_folder=template_dir)
@@ -31,17 +29,15 @@ app.static_url_path="../squatm3-ui/static"
# set the absolute path to the static folder # set the absolute path to the static folder
app.static_folder=app.static_url_path app.static_folder=app.static_url_path
#print(app.static_url_path)
#print(app.static_folder)
#app.config.from_pyfile('config.cfg')
# Setup Session
app.config['SESSION_TYPE'] = 'redis' app.config['SESSION_TYPE'] = 'redis'
app.config['SECRET_KEY'] = 'mysecretrediskey' app.config['SECRET_KEY'] = 'mysecretrediskey'
app.config['SESSION_REDIS'] = redis.Redis(host='localhost', port=6379, password='waddup') app.config['SESSION_REDIS'] = redis.Redis(host='localhost', port=6379, password='waddup')
sess = Session() sess = Session()
sess.init_app(app) sess.init_app(app)
# Setup SocketIO
socketio = SocketIO(app) socketio = SocketIO(app)
socketio.init_app(app, async_mode=async_mode, message_queue='redis://:waddup@localhost:6379/') socketio.init_app(app, async_mode=async_mode, message_queue='redis://:waddup@localhost:6379/')
@@ -64,8 +60,6 @@ def start_reporting(sess_key=None, sid=None):
We do this by comparing the job_id and the session key. When we start an attack we create a UUID used as session We do this by comparing the job_id and the session key. When we start an attack we create a UUID used as session
key and as job_id key and as job_id
''' '''
#sess_key = "123"
print(sess_key + "##" + sid)
print("Entering start_reporting") print("Entering start_reporting")
c = comm.Communication() c = comm.Communication()
with app.app_context(): with app.app_context():
@@ -75,29 +69,21 @@ def start_reporting(sess_key=None, sid=None):
if job and sess_key: if job and sess_key:
w_id,job_id,msg = job.decode().split("#") w_id,job_id,msg = job.decode().split("#")
if job_id == sess_key: if job_id == sess_key:
print("###########")
print(msg)
print("###########")
socketio.emit('results', msg, room=sid) socketio.emit('results', msg, room=sid)
else: else:
print("NOT FOR THIS SESSION")
print(msg)
#message not for this client, return it back in the queue #message not for this client, return it back in the queue
c.redis.rpush(c.channel_reporting, job) c.redis.rpush(c.channel_reporting, job)
@socketio.on('client_connected') @socketio.on('client_connected')
def handle_client_connect_event(): def handle_client_connect_event():
print("connected client socketio")
worker_reporter = threading.Thread(target=start_reporting, kwargs=dict(sess_key=check_session(), sid=request.sid)) worker_reporter = threading.Thread(target=start_reporting, kwargs=dict(sess_key=check_session(), sid=request.sid))
worker_reporter.setDaemon(True) worker_reporter.setDaemon(True)
worker_reporter.start() worker_reporter.start()
#threadreport = socketio.start_background_task(target=start_reporting(check_session()))
@app.route('/') @app.route('/')
def index(): def index():
create_session() create_session()
print('Session has been created')
return render_template('index.html', async_mode=socketio.async_mode) return render_template('index.html', async_mode=socketio.async_mode)
@app.errorhandler(404) @app.errorhandler(404)
@@ -146,14 +132,10 @@ class get_list_domains_generated(Resource):
commands = ["Hf","Hc","-add","F","R"] commands = ["Hf","Hc","-add","F","R"]
for attack in attacks: for attack in attacks:
print(attack)
if attack in commands: if attack in commands:
options = options + "-" + attack + " " options = options + "-" + attack + " "
if godaddy == 1: if godaddy == 1:
options = options + "--godaddy " options = options + "--godaddy "
@@ -164,11 +146,8 @@ class get_list_domains_generated(Resource):
except Exception as e: except Exception as e:
print(e) print(e)
return "Something went wrong while parsing the query string" return "Something went wrong while parsing the query string"
""" """
Retrieves all the domains generated by the ALL attacks Retrieves all the domains generated by the ALL attacks
We use the redis producer to push a Job object to the queue. We use the redis producer to push a Job object to the queue.
@@ -196,8 +175,6 @@ class get_list_domains_generated(Resource):
api.add_resource(get_list_domains_generated, '/api/<domain>') api.add_resource(get_list_domains_generated, '/api/<domain>')
#Utils Funcs #Utils Funcs
def create_session(): def create_session():
key = str(uuid.uuid4()) key = str(uuid.uuid4())
@@ -210,5 +187,4 @@ def check_session():
#main #main
if __name__== '__main__': if __name__== '__main__':
#app.run()
socketio.run(app, async_mode=async_mode) socketio.run(app, async_mode=async_mode)

View File

@@ -1,22 +0,0 @@
socket = io.connect('http://' + document.domain + ':' + location.port);
socket.on('connect', function() {
socket.emit('client_connected', {data: 'New client!'});
});
socket.on('results', function (data) {
console.log(data);
});
socket.on('alert', function (data) {
alert('Alert Message!! ' + data);
});
function json_button() {
socket.send('{"message": "test"}');
alert(1)
}
function alert_button() {
socket.emit('alert_button', 'Message from client!')
}

View File

@@ -1,10 +0,0 @@
<!doctype html>
<title>Websockets tutorial</title>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='app.js') }}"></script>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
<h1>Hello World!</h1>
<button type="button" onclick="json_button()">Json Message</button>
<button type="button" onclick="alert_button()">Alert Message</button>
</div>

View File

@@ -1,21 +0,0 @@
from server import socketio
from flask_socketio import send, emit
@socketio.on('client_connected')
def handle_client_connect_event(json):
print('received json: {0}'.format(str(json)))
@socketio.on('message')
def handle_json_button(json):
# it will forward the json to all clients.
send(json, json=True)
@socketio.on('results')
def handle_alert_event(json):
# it will forward the json to all clients.
print('Message from client was {0}'.format(json))
emit('results', 'Message from backend')

View File

@@ -1,6 +0,0 @@
import redis
from wrapper.classes import job
from wrapper.consumer import consumer
c = consumer
c.listen_for_commands()

View File

@@ -6,7 +6,6 @@ c_jobs = comm.Communication()
job_process = None job_process = None
def report(connection, channel, message): def report(connection, channel, message):
print("CH: "+channel)
#connection.redis.lpush(connection.channel_reporting, message) #connection.redis.lpush(connection.channel_reporting, message)
if channel == connection.channel_reporting: if channel == connection.channel_reporting:
connection.redis.lpush(connection.channel_reporting, message) connection.redis.lpush(connection.channel_reporting, message)