Merge branch 'master' of https://github.com/guardicore/monkey
This commit is contained in:
commit
4103b30ba0
|
@ -0,0 +1,91 @@
|
||||||
|
How to create a monkey build environment:
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
1. Install python 2.7
|
||||||
|
https://www.python.org/download/releases/2.7
|
||||||
|
2. install pywin32-219.win32-py2.7.exe
|
||||||
|
http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/
|
||||||
|
3. install VCForPython27.msi
|
||||||
|
http://www.microsoft.com/en-us/download/details.aspx?id=44266
|
||||||
|
4. Download & Run get-pip.py
|
||||||
|
https://bootstrap.pypa.io/get-pip.py
|
||||||
|
5. Run:
|
||||||
|
setx path "%path%;C:\Python27\;C:\Python27\Scripts"
|
||||||
|
python -m pip install enum34
|
||||||
|
python -m pip install impacket
|
||||||
|
python -m pip install PyCrypto
|
||||||
|
python -m pip install pyasn1
|
||||||
|
python -m pip install cffi
|
||||||
|
python -m pip install twisted
|
||||||
|
python -m pip install rdpy
|
||||||
|
python -m pip install requests
|
||||||
|
python -m pip install odict
|
||||||
|
python -m pip install paramiko
|
||||||
|
python -m pip install psutil
|
||||||
|
python -m pip install PyInstaller
|
||||||
|
type C:\Python27\Lib\site-packages\zope\__init__.py
|
||||||
|
6. Put source code in C:\Code\monkey\chaos_monkey
|
||||||
|
7. Download and extract UPX binary to C:\Code\monkey\chaos_monkey\bin\upx.exe:
|
||||||
|
http://upx.sourceforge.net/download/upx391w.zip
|
||||||
|
8. Run C:\Code\monkey\chaos_monkey\build_windows.bat to build, output is in dist\monkey.exe
|
||||||
|
|
||||||
|
Linux (Tested on Ubuntu 12.04):
|
||||||
|
1. Run:
|
||||||
|
sudo apt-get update
|
||||||
|
apt-get install python-pip python-dev libffi-dev upx
|
||||||
|
sudo pip install enum34
|
||||||
|
sudo pip install impacket
|
||||||
|
sudo pip install PyCrypto --upgrade
|
||||||
|
sudo pip install pyasn1
|
||||||
|
sudo pip install cffi
|
||||||
|
sudo pip install zope.interface --upgrade
|
||||||
|
sudo pip install twisted
|
||||||
|
sudo pip install rdpy
|
||||||
|
sudo pip install requests --upgrade
|
||||||
|
sudo pip install odict
|
||||||
|
sudo pip install paramiko
|
||||||
|
sudo pip install psutil
|
||||||
|
sudo pip install https://github.com/pyinstaller/pyinstaller/releases/download/3.0.dev2/PyInstaller-3.0.dev2.tar.gz
|
||||||
|
sudo apt-get install winbind
|
||||||
|
2. Put source code in /home/user/Code/monkey/chaos_monkey
|
||||||
|
3. To build, run in terminal:
|
||||||
|
cd /home/user/Code/monkey/chaos_monkey
|
||||||
|
chmod +x build_linux.sh
|
||||||
|
./build_linux.sh
|
||||||
|
output is in dist/monkey
|
||||||
|
|
||||||
|
How to connect build environment to c&c:
|
||||||
|
- will auto compile the source code stored in the c&c and update the c&c binaries accordingly
|
||||||
|
Linux (Tested on Ubuntu 12.04):
|
||||||
|
1. Setup c&c according to readme in monkey_island folder
|
||||||
|
2. Install cifs:
|
||||||
|
sudo apt-get install cifs-utils
|
||||||
|
3. Run:
|
||||||
|
mkdir /home/user/Code
|
||||||
|
sudo mkdir /mnt/sources
|
||||||
|
sudo mkdir /mnt/binaries
|
||||||
|
4. Save username and password for c&c smb:
|
||||||
|
echo username=<username> > /home/user/.smbcreds
|
||||||
|
echo password=<password> >> /home/user/.smbcreds
|
||||||
|
(Change <username> and <password> according to c&c)
|
||||||
|
5. Edit fstab:
|
||||||
|
run: sudo nano /etc/fstab
|
||||||
|
add rows:
|
||||||
|
//monkeycc/sources /mnt/sources cifs iocharset=utf-8,credentials=/home/user/.smbcreds,uid=1000 0 0
|
||||||
|
//monkeycc/binaries /mnt/binaries cifs iocharset=utf-8,credentials=/home/user/.smbcreds,uid=1000 0 0
|
||||||
|
6. Remount:
|
||||||
|
sudo mount -a
|
||||||
|
7. Check if sources exist in /mnt/sources
|
||||||
|
If not, edit hosts file - add a line in /etc/hosts with c&c ip and hostname and remount.
|
||||||
|
8. put build_from_cc.sh in /home/user and run with name of output binary (as appeared on c&c) as parameter,
|
||||||
|
for example: build_from_cc.sh monkey-linux-32
|
||||||
|
use Ctrl+C to manualy check compilation and Ctrl+\ to exit script.
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
1. Setup c&c according to readme in monkey_island folder
|
||||||
|
2. Setup net use to c&c server:
|
||||||
|
net use Z:\ \\monkeycc\sources /persistent:yes
|
||||||
|
net use X:\ \\monkeycc\binaries /persistent:yes
|
||||||
|
3. mkdir C:\Code
|
||||||
|
4. Extract build_from_cc.bat to c:\code and run with name of output binary (as appeared on c&c) as parameter,
|
||||||
|
for example: build_from_cc.bat monkey-windows-64.exe
|
|
@ -0,0 +1,13 @@
|
||||||
|
enum34
|
||||||
|
impacket
|
||||||
|
PyCrypto
|
||||||
|
pyasn1
|
||||||
|
cffi
|
||||||
|
twisted
|
||||||
|
rdpy
|
||||||
|
requests
|
||||||
|
odict
|
||||||
|
paramiko
|
||||||
|
psutil
|
||||||
|
PyInstaller
|
||||||
|
ecdsa
|
|
@ -1,4 +1,4 @@
|
||||||
import socket
|
dimport socket
|
||||||
import random
|
import random
|
||||||
import struct
|
import struct
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
__author__ = 'Administrator'
|
|
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
from abc import ABCMeta, abstractmethod
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
|
||||||
|
|
||||||
class MonitorAction(object):
|
|
||||||
__metaclass__ = ABCMeta
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def do_action(self):
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def undo_action(self):
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
from desktop import ChangeDesktopAction
|
|
|
@ -1,38 +0,0 @@
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import ctypes
|
|
||||||
import shutil
|
|
||||||
import logging
|
|
||||||
from data import resource_path
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
SPI_SETDESKWALLPAPER = 20
|
|
||||||
SPIF_UPDATEINIFILE = 0x01
|
|
||||||
SPIF_SENDCHANGE = 0x02
|
|
||||||
|
|
||||||
class ChangeDesktopAction(object):
|
|
||||||
def __init__(self, desktop_image):
|
|
||||||
self._desktop_image = resource_path(desktop_image)
|
|
||||||
|
|
||||||
assert os.path.exists(self._desktop_image), "desktop image %s is missing" % (self._desktop_image, )
|
|
||||||
|
|
||||||
def do_action(self):
|
|
||||||
ctypes_desktop_img = ctypes.c_char_p(self._desktop_image)
|
|
||||||
|
|
||||||
# set the image
|
|
||||||
if not bool(ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, ctypes_desktop_img, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE)):
|
|
||||||
LOG.warn("Error setting desktop wallpaper image to '%s' (error %d)",
|
|
||||||
ctypes_desktop_img.value, ctypes.windll.kernel32.GetLastError())
|
|
||||||
else:
|
|
||||||
LOG.debug("Desktop wallpaper image is set to %r", ctypes_desktop_img.value)
|
|
||||||
|
|
||||||
def undo_action(self):
|
|
||||||
if not bool(ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, "" , SPIF_SENDCHANGE | SPIF_UPDATEINIFILE)):
|
|
||||||
LOG.warn("Error resetting desktop wallpaper image (error %d)",
|
|
||||||
ctypes.windll.kernel32.GetLastError())
|
|
||||||
else:
|
|
||||||
LOG.debug("Desktop wallpaper image reset")
|
|
|
@ -1,2 +0,0 @@
|
||||||
c:\Python27\python -m PyInstaller.main -F -y --clean monitor.spec
|
|
||||||
move /Y dist\monitor32.exe "%allusersprofile%\desktop\monitor32.exe"
|
|
|
@ -1,13 +0,0 @@
|
||||||
|
|
||||||
from abc import ABCMeta, abstractmethod
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
|
||||||
|
|
||||||
class MonitorCondition(object):
|
|
||||||
__metaclass__ = ABCMeta
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def check_condition(self):
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
from files import FilesExistCondition
|
|
|
@ -1,12 +0,0 @@
|
||||||
|
|
||||||
import os
|
|
||||||
from condition import MonitorCondition
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
|
||||||
|
|
||||||
class FilesExistCondition(MonitorCondition):
|
|
||||||
def __init__(self, file_name):
|
|
||||||
self._file_path = os.path.abspath(file_name)
|
|
||||||
|
|
||||||
def check_condition(self):
|
|
||||||
return os.path.isfile(self._file_path)
|
|
|
@ -1,16 +0,0 @@
|
||||||
|
|
||||||
import sys
|
|
||||||
from condition import FilesExistCondition
|
|
||||||
from action import ChangeDesktopAction
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
|
||||||
|
|
||||||
|
|
||||||
class MonitorConfiguration(object):
|
|
||||||
conditions = [FilesExistCondition(r"C:\windows\monkey.exe"),
|
|
||||||
]
|
|
||||||
|
|
||||||
actions = [ChangeDesktopAction(r"infected.bmp")
|
|
||||||
]
|
|
||||||
|
|
||||||
monitor_interval = 5000 # 5 seconds
|
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
|
||||||
|
|
||||||
def resource_path(relative_path):
|
|
||||||
""" Get absolute path to resource, works for dev and for PyInstaller """
|
|
||||||
try:
|
|
||||||
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
||||||
base_path = sys._MEIPASS
|
|
||||||
except Exception:
|
|
||||||
base_path = os.path.abspath("data")
|
|
||||||
|
|
||||||
return os.path.join(base_path, relative_path)
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 MiB |
|
@ -1,54 +0,0 @@
|
||||||
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
from config import MonitorConfiguration
|
|
||||||
|
|
||||||
__author__ = 'itamar'
|
|
||||||
|
|
||||||
logging.basicConfig(format='%(asctime)s [%(process)d:%(levelname)s] %(module)s.%(funcName)s.%(lineno)d: %(message)s',
|
|
||||||
level=logging.DEBUG)
|
|
||||||
LOG = logging.getLogger()
|
|
||||||
|
|
||||||
def do_infected():
|
|
||||||
LOG.info("Changed state to infected")
|
|
||||||
|
|
||||||
[action.do_action()
|
|
||||||
for action in MonitorConfiguration.actions]
|
|
||||||
|
|
||||||
def do_not_infected():
|
|
||||||
LOG.info("Changed state to not infected")
|
|
||||||
[action.undo_action()
|
|
||||||
for action in MonitorConfiguration.actions]
|
|
||||||
|
|
||||||
def main():
|
|
||||||
infected = False
|
|
||||||
|
|
||||||
LOG.info("Monitor going up...")
|
|
||||||
|
|
||||||
do_not_infected()
|
|
||||||
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
if any([condition.check_condition()
|
|
||||||
for condition in MonitorConfiguration.conditions]):
|
|
||||||
if not infected:
|
|
||||||
do_infected()
|
|
||||||
|
|
||||||
infected = True
|
|
||||||
else:
|
|
||||||
if infected:
|
|
||||||
do_not_infected()
|
|
||||||
|
|
||||||
infected = False
|
|
||||||
|
|
||||||
for _ in range(MonitorConfiguration.monitor_interval / 1000):
|
|
||||||
time.sleep(1.0)
|
|
||||||
finally:
|
|
||||||
if infected:
|
|
||||||
do_not_infected()
|
|
||||||
|
|
||||||
LOG.info("Monitor going down...")
|
|
||||||
|
|
||||||
|
|
||||||
if "__main__" == __name__:
|
|
||||||
main()
|
|
Binary file not shown.
Before Width: | Height: | Size: 348 KiB |
|
@ -0,0 +1,4 @@
|
||||||
|
flask
|
||||||
|
Flask-Pymongo
|
||||||
|
Flask-Restful
|
||||||
|
python-dateutil
|
Loading…
Reference in New Issue