AVAgent/rcs_client.py
import urllib2
from urllib2 import HTTPError
import cookielib
import json
import traceback
from time import sleep
from StringIO import StringIO
import gzip
import os
import sys
import inspect
#pp = pprint.PrettyPrinter(indent=4)
if ".." not in sys.path:
sys.path.insert(0, "..")
from AVCommon.logger import logging
class Rcs_client:
myid = "0"
def __init__(self, host, user="avtest", passwd="avtest"):
self.host = host
self.user = user
self.passwd = passwd
if 'logging' not in globals():
from AVCommon.logger import logging
globals()['logging']=logging
#self.cookie = self.do_login
def _get_response(self, link, cookies=None):
""" Basic HTTP Request/Response with Cookie
@param link
@param cookie
@returns response page
"""
try:
#print "calling link: %s" % link
req = urllib2.Request(link)
req.add_header('Accept-encoding', 'gzip')
if cookies:
opener = urllib2.build_opener(
urllib2.HTTPCookieProcessor(cookies))
response = opener.open(req)
if response.info().get('Content-Encoding') == 'gzip':
buf = StringIO( response.read())
f = gzip.GzipFile(fileobj=buf)
data = f.read()
else:
data = response.read()
sleep(1)
return data
except HTTPError as e:
logging.error("ERROR: processing %s: %s, %s" % (link, e, e.read()))
raise e
def _post_response(self, link, cj, data=None):
""" Basic POST Request / Response
@param link
@param data
@param cookie
@returns response page
"""
try:
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj),
urllib2.HTTPHandler())
req = urllib2.Request(link, data)
resp = opener.open(req).read()
sleep(1)
return resp
except HTTPError as e:
logging.error("ERROR: processing %s: %s, %s" % (link, e, e.read()))
raise e
def _call_post(self, api_name, data={}, binary=False, argjson=True):
link = 'https://%s/%s' % (self.host, api_name)
logging.debug("_call: %s" % link)
#logging.debug("binary %s, argjson %s" % (binary, argjson))
arg = data
if argjson:
arg = json.dumps(data)
resp = self._post_response(link, self.cookie, arg)
if binary:
return resp
try:
result = json.loads(resp)
return result
except Exception, e:
logging.error("ERROR: %s" % e)
logging.debug("DBG trace %s" % traceback.format_exc())
logging.debug("call error: %s" % resp)
raise e
def _call_get(self, api_name):
link = 'https://%s/%s' % (self.host, api_name)
#logging.debug("_call_get: %s" % link)
resp = self._get_response(link, self.cookie)
result = json.loads(resp)
return result
def login(self):
""" Do Login request to catch cookie
@param link: url to login page
@param data: post data
@returns cookie
"""
login = {'user': self.user,
'pass': self.passwd,
'version': 2013031101}
link = "https://%s/auth/login" % self.host
data = json.dumps(login)
cj = cookielib.CookieJar()
resp = self._post_response(link, cj, data)
result = json.loads(resp)
# logging.debug(result)
self.myid = result['user']['_id']
# logging.debug("my id = %s" % self.myid)
self.cookie = cj
return cj
def logged_in(self):
return self.cookie is not None
def logout(self):
""" Logout for session
@param session cookie
@return True/False
"""
self._call_post('auth/logout')
return True
def server_status(self):
status = self._call_get('status/counters')
return status
def disable_analysis(self):
ret = self._call_post('agent/disable_analysis')
return ret
def operation(self, operation):
""" gets the operation id of an operation """
operations = self._call_get('operation')
#logging.debug("DBG operation: %s" % operations)
ret = [(op['_id'], op['group_ids'][0])
for op in operations if op['name'] == operation]
return ret[0] if ret else (None, None)
def targets(self, operation_id, target=None):
""" gets the targets id of an operation, matching the target name """
targets = self._call_get('target')
#logging.debug("targets: %s" % targets)
#pp = pprint.PrettyPrinter(indent=4)
# pp.pprint(targets)
if target:
ret = [op['_id']
for op in targets if op['name'] == target and op['path'][0] == operation_id]
else:
ret = [op['_id']
for op in targets if op['path'][0] == operation_id]
return ret
def all_factories(self):
""" gets the factories """
factories = self._call_get('factory')
# pp.pprint(factories)
ret = [(op['_id'], op['ident'], op['path'])
for op in factories]
return ret
def factories(self, target_id, all_factories=None):
""" gets the factories of an operation, matching the target id """
if not all_factories:
all_factories = self.all_factories()
# pp.pprint(factories)
ret = [(op[0], op[1])
for op in all_factories if target_id in op[2]]
return ret
def instances(self, ident):
""" gets the instances id of an operation, matching the ident """
agents = self._call_get('agent')
# instances: [{u'status': u'open', u'scout': False, u'good': True, u'name': u'avtagent_desktop_windows_elite_silent (1)', u'platform': u'windows', u'demo': False, u'_kind': u'agent', u'stat': {u'grid_size': 183088, u'last_sync': 1386874247, u'source': u'172.20.20.151', u'user': u'avtest', u'device': u'AVTAGENT', u'last_sync_status': 0, u'size': 34599}, u'upgradable': False, u'instance': u'7f198461c7ce800381480345cc5d8617b3015c89', u'ident': u'RCS_0000057058', u'version': 2013103102, u'path': [u'51224a314e091305b800005d', u'52a895cc4e0913f2e600b406'], u'_id': u'52aa04d14e0913a56300c604', u'type': u'desktop', u'desc': u'made by vmavtestat at Thu Dec 12 19:46:32 2013'}]
# pp.pprint(agents)
ret = [op['_id'] for op in agents if ident in op['ident'] and op['_kind'] == 'agent']
return ret
def instances_by_target_id(self, target_id):
""" gets the instances id of an operation, matching the ident """
logging.debug("lookin for instances with target: %s" % target_id)
agents = self._call_get('agent')
#logging.debug("agents: %s" % agents)
#pp.pprint(agents)
ret = [op for op in agents if target_id in op['path'] and op['_kind'] == 'agent']
return ret
def instances_by_name(self, name):
""" gets the instances id of an operation, matching the ident """
logging.debug("looking for instances with target: %s" % name)
agents = self._call_get('agent')
#logging.debug("agents: %s" % agents)
#pp.pprint(agents)
ret = [op for op in agents if name in op['name'] and op['_kind'] == 'agent']
return ret
def instances_by_deviceid(self, deviceid, target_id):
""" gets the instances id of an operation, matching the ident """
logging.debug("lookin for instances with deviceid: %s" % deviceid)
agents = self._call_get('agent')
ret = [op for op in agents
if 'stat' in op and 'device' in op['stat'] and deviceid in op['stat']['device']
and op['_kind'] == 'agent' and target_id in op['path']]
return ret
def agents(self, target_id):
""" gets the agents (agents and factories) of an operation, matching the target id """
agents = self._call_get('agent')
# pp.pprint(agents)
ret = [(op['_id'], op['ident'], op['name'])
for op in agents if target_id in op['path']]
return ret
# user list : verifica presenza utente
# add group to user
def user_create(self, name, password, privs, group_id):
""" Create a user """
logging.debug("user_create: %s, %s, %s" % (name, password, group_id))
try:
data = {'name': name, 'pass': password, 'group_ids':
[group_id], 'privs': privs, 'enabled': True}
user = self._call_post('user/create', data)
return user['_id']
# return True
except HTTPError as e:
if e.code == 409:
return True
logging.error(e)
return False
def target_delete(self, target_id):
""" Delete a given target """
return self._call_post('target/destroy', {'_id': target_id})
def target_create(self, operation_id, name, desc):
""" Create a given target """
data = {'name': name, 'desc': desc, 'operation': operation_id}
target = self._call_post('target/create', data)
return target['_id']
def factory_create(self, operation_id, target_id, ftype, name, desc):
""" Create a factory """
data = {'name': name, 'desc': desc, 'operation':
operation_id, 'target': target_id, 'type': ftype}
factory = self._call_post('agent/create', data)
return factory['_id'], factory['ident']
def factory_add_config(self, factory_id, config):
""" adds a config to a factory """
data = {'_id': factory_id, 'config': config}
return self._call_post('agent/add_config', data)
def update_conf(self, conf_file, factory):
""" Update sync configuration
@param configuration file
@param factory id
@return True/False
"""
try:
base = 'https://%s' % self.host
faclink = '%s/factory' % base
resp = self._get_response(faclink, self.cookie)
facts = json.loads(resp)
for fact in facts:
if fact["ident"] == factory:
fct = fact
break
if not fct:
return False
# logging.debug(fct)
addlink = '%s/agent/add_config' % base
f = open(conf_file, 'r')
cnf = f.read()
data = {'_id': fct["_id"], 'config': cnf}
# logging.debug(data)
resp = self._post_response(addlink, self.cookie, json.dumps(data))
return True
except Exception as e:
logging.debug("DBG trace %s" % traceback.format_exc())
logging.error(e)
return False
def instance_upgrade(self, instance_id, force_soldier = False):
params = {'_id': instance_id}
if force_soldier:
params["force"] = "soldier"
logging.debug("upgrade: %s" % params)
try:
self._call_post('agent/upgrade', params)
return True
except:
return False
def instance_can_upgrade(self, instance_id):
try:
value = self._call_get('agent/can_upgrade/%s' % instance_id)
return value
except HTTPError, ex:
logging.error("cannot get can_upgrade")
return "Error%s" % ex.code
except Exception, ex:
logging.exception("cannot get can_upgrade")
return "error"
def instance_level(self, instance_id):
params = {'_id': instance_id}
try:
info = self.instance_info(instance_id)
logging.debug("info: %s" %(info))
return info["level"]
except:
return False
def instance_info(self, instance_id):
agents = self._call_get('agent')
# pp.pprint(agents)
ret = [op for op in agents if op['_id'] == instance_id]
return ret[0] if ret else None
def instance_close(self, instance_id):
params = {'_id': instance_id, 'status': 'closed'}
self._call_post('agent/update', params)
def instance_rename(self, instance_id, name):
params = {'_id': instance_id, 'name': name}
self._call_post('agent/update', params)
def instance_delete(self, instance_id):
""" Delete a given instance
@param instance
"""
data = {'_id': instance_id, 'permanent': True}
return self._call_post('agent/destroy', data)
# logging.debug(resp)
def blacklist(self):
return self._call_post('agent/blacklist')
def evidences_by_instance(self, instance_id, filter_type=None, filter_value=None):
logging.debug("evidences_by_instance: %s,%s,%s" %( instance_id, filter_type, filter_value))
if filter_type and filter_value:
f = {filter_type: filter_value, "agent": instance_id, 'date':'dr'}
else:
f = { "agent": instance_id, 'date':'dr'}
filter = urllib2.quote(json.dumps(f))
link = 'https://%s/evidence?filter=%s' % (self.host, filter)
resp = self._get_response(link, self.cookie)
result = json.loads(resp)
logging.debug("results: " % result)
return result
def evidences(self, target_id, instance_id, filter_type=None, filter_value=None):
""" Get evidences of given agent and target
@param target
@param agent
@param type (if None all types should be returned)
date: '24h' 'week' 'month' 'now'
dr e da sono per il :date
gli altri sono per il :from :to
dr -> date received, da -> date acquired
"""
logging.debug("evidences: %s,%s,%s,%s" %(target_id, instance_id, filter_type, filter_value))
if filter_type and filter_value:
f = {filter_type: filter_value, "target": target_id, "agent": instance_id, 'date':'dr'}
else:
f = {"target": target_id, "agent": instance_id, 'date':'dr'}
filter = urllib2.quote(json.dumps(f))
link = 'https://%s/evidence?filter=%s' % (self.host, filter)
resp = self._get_response(link, self.cookie)
result = json.loads(resp)
logging.debug("results: " % result)
return result
def infos(self, target_id, instance_id, filter_type=None, filter_value=None):
""" Get info of given agent and target
@param target
@param agent
@param type (if None all types should be returned)
date: '24h' 'week' 'month' 'now'
dr e da sono per il :date
gli altri sono per il :from :to
dr -> date received, da -> date acquired
"""
logging.debug("info: %s,%s,%s,%s" %(target_id, instance_id, filter_type, filter_value))
if filter_type and filter_value:
f = {filter_type: filter_value, "target": target_id, "agent": instance_id, 'date':'dr'}
else:
f = {"target": target_id, "agent": instance_id, 'date':'dr'}
filter = urllib2.quote(json.dumps(f))
link = 'https://%s/evidence/info?filter=%s' % (self.host, filter)
resp = self._get_response(link, self.cookie)
result = json.loads(resp)
logging.debug("results: " % result)
return result
def build(self, factory, params, out_file):
""" Build Silent Exe
@param param_file
@param factory
@param out_file
"""
params['factory'] = {"_id": "%s" % factory}
# logging.debug("+ Build params: \n%s" % params)
resp = self._call_post('build', params, binary=True)
out = open(out_file, 'wb')
out.write(resp)
# logging.debug("+ %s bytes saved to %s" % (len(out), out_file))
def build_melt(self, factory, params, melt_file, out_file):
""" Build Melted Exe
@param param_file
@param factory
@param out_file
"""
params['factory'] = {"_id": "%s" % factory}
f = open(melt_file, "rb")
payload = f.read()
logging.debug("DBG payload size: %s file: %s" % ( len(payload), melt_file))
melt_id = self._call_post('upload', payload, binary=True, argjson=False)
logging.debug("DBG uploaded: %s" % melt_id)
params['melt']['input'] = melt_id
#: Build: melting: {"admin"=>false, "bit64"=>true, "codec"=>true, "scout"=>true, "input"=>"4f60909baef1de0e4800000a-1361192221.897401094"}
logging.debug("DBG Build melt params: \n%s" % params)
#link = 'https://%s/build' % self.host
#resp = self.post_response(link, json.dumps(params))
resp = self._call_post('build', params, binary=True)
out = open(out_file, 'wb')
out.write(resp)
if __name__ == "__main__":
host = "rcs-minotauro"
user = "avmonitor"
passwd = "avmonitorp123"
operation = 'AVMonitor'
rcs=[]
conn = Rcs_client(host, user, passwd)
conn.login()
try:
#instance_id = "52efa51d4e0913760f000138"
ret = conn.blacklist()
print ret.encode('utf-8')
logging.debug("ret: %s" % ret)
finally:
conn.logout()