forked from p15670423/monkey
Implement detection of monkey on island or locally
Fix UI issue of cleanup Kill all monkeys works Implemented logic for V ticking
This commit is contained in:
parent
8bada60fcd
commit
95d35fc8aa
|
@ -5,6 +5,7 @@ from flask import Flask, send_from_directory, redirect, make_response
|
|||
import flask_restful
|
||||
|
||||
from cc.database import mongo
|
||||
from cc.resources.client_run import ClientRun
|
||||
from cc.resources.monkey import Monkey
|
||||
from cc.resources.local_run import LocalRun
|
||||
from cc.resources.telemetry import Telemetry
|
||||
|
@ -75,6 +76,7 @@ def init_app(mongo_url):
|
|||
api.add_resource(Root, '/api')
|
||||
api.add_resource(Monkey, '/api/monkey', '/api/monkey/', '/api/monkey/<string:guid>')
|
||||
api.add_resource(LocalRun, '/api/local-monkey', '/api/local-monkey/')
|
||||
api.add_resource(ClientRun, '/api/client-monkey', '/api/client-monkey/')
|
||||
api.add_resource(Telemetry, '/api/telemetry', '/api/telemetry/', '/api/telemetry/<string:monkey_guid>')
|
||||
api.add_resource(MonkeyConfiguration, '/api/configuration', '/api/configuration/')
|
||||
api.add_resource(MonkeyDownload, '/api/monkey/download', '/api/monkey/download/',
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
from flask import request, jsonify
|
||||
import flask_restful
|
||||
|
||||
from cc.services.node import NodeService
|
||||
|
||||
__author__ = 'itay.mizeretz'
|
||||
|
||||
|
||||
class ClientRun(flask_restful.Resource):
|
||||
def get(self):
|
||||
client_ip = request.remote_addr
|
||||
if client_ip == "127.0.0.1":
|
||||
monkey = NodeService.get_monkey_island_monkey()
|
||||
else:
|
||||
monkey = NodeService.get_monkey_by_ip(client_ip)
|
||||
NodeService.update_dead_monkeys()
|
||||
if monkey is not None:
|
||||
is_monkey_running = not monkey["dead"]
|
||||
else:
|
||||
is_monkey_running = False
|
||||
|
||||
return jsonify(is_running=is_monkey_running)
|
|
@ -48,7 +48,14 @@ def run_local_monkey():
|
|||
|
||||
class LocalRun(flask_restful.Resource):
|
||||
def get(self):
|
||||
return jsonify(is_running=(NodeService.get_monkey_island_monkey() is not None))
|
||||
NodeService.update_dead_monkeys()
|
||||
island_monkey = NodeService.get_monkey_island_monkey()
|
||||
if island_monkey is not None:
|
||||
is_monkey_running = not island_monkey["dead"]
|
||||
else:
|
||||
is_monkey_running = False
|
||||
|
||||
return jsonify(is_running=is_monkey_running)
|
||||
|
||||
def post(self):
|
||||
body = json.loads(request.data)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
|
||||
import dateutil.parser
|
||||
from flask import request
|
||||
|
@ -14,19 +14,9 @@ __author__ = 'Barak'
|
|||
# TODO: separate logic from interface
|
||||
|
||||
|
||||
def update_dead_monkeys():
|
||||
# Update dead monkeys only if no living monkey transmitted keepalive in the last 10 minutes
|
||||
if mongo.db.monkey.find_one({'dead': {'$ne': True}, 'keepalive': {'$gte': datetime.now() - timedelta(minutes=10)}}):
|
||||
return
|
||||
|
||||
mongo.db.monkey.update(
|
||||
{'keepalive': {'$lte': datetime.now() - timedelta(minutes=10)}, 'dead': {'$ne': True}},
|
||||
{'$set': {'dead': True, 'modifytime': datetime.now()}}, upsert=False, multi=True)
|
||||
|
||||
|
||||
class Monkey(flask_restful.Resource):
|
||||
def get(self, guid=None, **kw):
|
||||
update_dead_monkeys() # refresh monkeys status
|
||||
NodeService.update_dead_monkeys() # refresh monkeys status
|
||||
if not guid:
|
||||
guid = request.args.get('guid')
|
||||
timestamp = request.args.get('timestamp')
|
||||
|
|
|
@ -5,6 +5,7 @@ import flask_restful
|
|||
|
||||
from cc.database import mongo
|
||||
from cc.services.config import ConfigService
|
||||
from cc.services.node import NodeService
|
||||
|
||||
from cc.utils import local_ip_addresses
|
||||
|
||||
|
@ -30,10 +31,11 @@ class Root(flask_restful.Resource):
|
|||
elif action == "killall":
|
||||
mongo.db.monkey.update({}, {'$set': {'config.alive': False, 'modifytime': datetime.now()}}, upsert=False,
|
||||
multi=True)
|
||||
return 200
|
||||
return jsonify(status='OK')
|
||||
else:
|
||||
return make_response(400, {'error': 'unknown action'})
|
||||
|
||||
def get_completed_steps(self):
|
||||
# TODO implement
|
||||
return dict(run_server=True, run_monkey=False, infection_done=False)
|
||||
is_any_exists = NodeService.is_any_monkey_exists()
|
||||
is_any_alive = NodeService.is_any_monkey_alive()
|
||||
return dict(run_server=True, run_monkey=is_any_exists, infection_done=(is_any_exists and not is_any_alive))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from bson import ObjectId
|
||||
|
||||
from cc.database import mongo
|
||||
|
@ -236,3 +236,22 @@ class NodeService:
|
|||
{"_id": node_id},
|
||||
{"$set": {"exploited": True}}
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def update_dead_monkeys():
|
||||
# Update dead monkeys only if no living monkey transmitted keepalive in the last 10 minutes
|
||||
if mongo.db.monkey.find_one(
|
||||
{'dead': {'$ne': True}, 'keepalive': {'$gte': datetime.now() - timedelta(minutes=10)}}):
|
||||
return
|
||||
|
||||
mongo.db.monkey.update(
|
||||
{'keepalive': {'$lte': datetime.now() - timedelta(minutes=10)}, 'dead': {'$ne': True}},
|
||||
{'$set': {'dead': True, 'modifytime': datetime.now()}}, upsert=False, multi=True)
|
||||
|
||||
@staticmethod
|
||||
def is_any_monkey_alive():
|
||||
return mongo.db.monkey.find_one({'dead': False}) is not None
|
||||
|
||||
@staticmethod
|
||||
def is_any_monkey_exists():
|
||||
return mongo.db.monkey.find_one({}) is not None
|
||||
|
|
|
@ -47,7 +47,8 @@ class MapPageComponent extends React.Component {
|
|||
this.state = {
|
||||
graph: {nodes: [], edges: []},
|
||||
selected: null,
|
||||
selectedType: null
|
||||
selectedType: null,
|
||||
killPressed: false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -111,6 +112,12 @@ class MapPageComponent extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
killAllMonkeys = () => {
|
||||
fetch('/api?action=killall')
|
||||
.then(res => res.json())
|
||||
.then(res => this.setState({killPressed: (res.status=="OK")}));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
|
@ -132,6 +139,12 @@ class MapPageComponent extends React.Component {
|
|||
Kill All Monkeys
|
||||
</button>
|
||||
</div>
|
||||
{this.state.killPressed ?
|
||||
<div className="alert alert-info">
|
||||
<i className="glyphicon glyphicon-info-sign" style={{'marginRight': '5px'}}/>
|
||||
Kill command sent to all monkeys
|
||||
</div>
|
||||
: ''}
|
||||
|
||||
<PreviewPane item={this.state.selected} type={this.state.selectedType} />
|
||||
</Col>
|
||||
|
|
|
@ -28,6 +28,13 @@ class RunMonkeyPageComponent extends React.Component {
|
|||
.then(res => this.setState({
|
||||
isRunningOnIsland: res['is_running']
|
||||
}));
|
||||
|
||||
fetch('/api/client-monkey')
|
||||
.then(res => res.json())
|
||||
.then(res => this.setState({
|
||||
isRunningLocally: res['is_running']
|
||||
}));
|
||||
|
||||
this.props.onStatusChange();
|
||||
}
|
||||
|
||||
|
@ -99,16 +106,16 @@ class RunMonkeyPageComponent extends React.Component {
|
|||
className="btn btn-default"
|
||||
disabled={this.state.isRunningOnIsland}>
|
||||
Run on C&C Server
|
||||
{ !this.state.isRunningOnIsland ?
|
||||
{ this.state.isRunningOnIsland ?
|
||||
<Icon name="check" className="text-success" style={{'marginLeft': '5px'}}/>
|
||||
: ''}
|
||||
</button>
|
||||
<a href="/download-monkey"
|
||||
className="btn btn-default"
|
||||
disabled={this.state.isRunningLocally}
|
||||
style={{'margin-left': '1em'}}>
|
||||
style={{'marginLeft': '1em'}}>
|
||||
Download and run locally
|
||||
{ !this.state.isRunningLocally ?
|
||||
{ this.state.isRunningLocally ?
|
||||
<Icon name="check" className="text-success" style={{'marginLeft': '5px'}}/>
|
||||
: ''}
|
||||
</a>
|
||||
|
|
|
@ -41,18 +41,14 @@ class StartOverPageComponent extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
// TODO: fix
|
||||
/*
|
||||
cleanup = () => {
|
||||
this.setState({
|
||||
cleaned: false
|
||||
});
|
||||
*/
|
||||
fetch('/api?action=reset')
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
if (res["status"] == "OK") {
|
||||
// TODO: fix this
|
||||
this.setState({
|
||||
cleaned: true
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue