Skip to content

Commit

Permalink
Fix server issues and building issues (#43)
Browse files Browse the repository at this point in the history
* Update stacoan.spec

* run server if no arguments are given

* Fix modules in build

* travis updater2

* Server optimalisation

* fixes

* update readme
  • Loading branch information
vincentcox authored Mar 4, 2018
1 parent 2d47c3a commit 3750b2f
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 28 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,17 @@ This tool will have trouble with [obfuscated](https://en.wikibooks.org/wiki/Intr
## Getting Started
If you want to get started as soon as possible, head over to the [releases page](https://github.com/vincentcox/StaCoAn/releases) and download the executable or archive which corresponds to your operating system.

If you have downloaded the release zip file, extract this. Copy the .apk or .ipa file to the extracted folder.
If you have downloaded the release zip file, extract this.

On Windows you can just double click the executable. It will open in server mode and you can just drag and drop your mobile applications in the webinterface.

![Windows 1 click](resources/windows-1-click.gif)

On Mac and Linux you can just run it from the terminal without arguments.

```
./stacoan
```

Drag and drop this file onto the executable. The report will now be generated in the `report` folder.

Expand Down
Binary file added resources/windows-1-click.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/helpers/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
from time import localtime, strftime, sleep

import configparser
from colorama import init
from colorama import Fore, Back, Style



from helpers.html_page import Htmlpage
from helpers.constants import PrintColors
Expand All @@ -19,6 +23,15 @@ class Logger:
INFO = 3

class __Logger:
# Fix color output on windows
if 'PYCHARM_HOSTED' in os.environ:
convert = False # in PyCharm, we should disable convert
strip = False
else:
convert = None
strip = None
init(convert=convert, strip=strip)

config = configparser.ConfigParser()

currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/report_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def html_wordlist(self, project):
'href',
hashlib.md5(file.file_path.encode('utf-8')).hexdigest()+'.html?' + "&line=" + str(
match.line)),
("target", "_blank")):
("target", "_self")):
self.text(file.name)

self.doc.stag('br')
Expand Down
59 changes: 54 additions & 5 deletions src/helpers/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ def do_GET(self):

def do_POST(self):
"""Serve a POST request."""
if re.findall(r'KILLSERVERCOMMAND', self.requestline):
ServerWrapper.dragdropserver.q.put("KILLSERVERCOMMAND")
Logger("Server upload killed", Logger.INFO)
self.send_response(200)
exit(0)
return True, "Exit"
r, info = self.deal_post_data()
Logger((str(r) + str(info) + "by: " + str(self.client_address)), Logger.INFO)
f = BytesIO()
Expand All @@ -102,6 +108,10 @@ def do_POST(self):
f.close()

def deal_post_data(self):




content_type = self.headers['content-type']
if not content_type:
return (False, "Content-Type header doesn't contain boundary")
Expand All @@ -113,10 +123,6 @@ def deal_post_data(self):
return (False, "Content NOT begin with boundary")
for line in self.rfile:
remainbytes -= len(line)
if re.findall(r'KILLSERVERCOMMAND', line.decode()):
ServerWrapper.SimpleHTTPRequestHandler.q.put("KILLSERVERCOMMAND")
Logger("Server upload killed", Logger.INFO)
exit(0)
fn = re.findall(r'Content-Disposition.*name="file"; filename="(.*\S.*)"', line.decode())
if fn:
break
Expand Down Expand Up @@ -225,9 +231,9 @@ def list_directory(self, path):
<head>
<meta charset="utf-8">
<title>Drag and Drop File Uploading</title>
<link rel="canonical" href="https://css-tricks.com/examples/DragAndDropFileUploading/">
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,300italic,400" />
<script type="text/javascript" src="report/html/jquery.min.js"></script>
<style>
body
{
Expand Down Expand Up @@ -449,6 +455,34 @@ def list_directory(self, path):
{
background-color: #0f3c4b;
}
.killserverbutton {
-moz-box-shadow:inset 0px 39px 0px -24px #e67a73;
-webkit-box-shadow:inset 0px 39px 0px -24px #e67a73;
box-shadow:inset 0px 39px 0px -24px #e67a73;
background-color:#e4685d;
-moz-border-radius:4px;
-webkit-border-radius:4px;
border-radius:4px;
border:1px solid #ffffff;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:15px;
padding:6px 15px;
text-decoration:none;
text-shadow:0px 1px 0px #b23e35;
}
.killserverbutton:hover {
background-color:#eb675e;
}
.killserverbutton:active {
position:relative;
top:1px;
}
</style>
Expand All @@ -460,6 +494,21 @@ def list_directory(self, path):
<body>
<center>
<form id="killserverform" action="/KILLSERVERCOMMAND" target="" method="POST">
<input type="text" name="KILLSERVERCOMMAND" value="Mickey" hidden>
<input type="submit" value="KILL SERVER" class="killserverbutton">
</form>
<script>
$('#killserverform').submit(function() {
alert("Server will shut down! Bye!");
return true; // return false to cancel form action
});
</script>
</center>
<div class="container" role="main">
Expand Down
2 changes: 1 addition & 1 deletion src/report/start.html
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@
<body>


<a href="lootbox.html" id="test1">Link1</a> <span id="result1"></span>
<a href="lootbox.html" id="test1" hidden>Link1</a> <span id="result1"></span>
<script>

var i = 1; // set your counter to 1
Expand Down
3 changes: 2 additions & 1 deletion src/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
yattag
yattag
colorama
68 changes: 49 additions & 19 deletions src/stacoan.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import configparser
import argparse
import threading
import json
import multiprocessing
from threading import Thread
from multiprocessing import Process
from time import time
Expand Down Expand Up @@ -43,26 +45,29 @@ def parse_args():
# return aur args, usage: args.argname
return parser.parse_args()

def program(args):
# Script cannot be called outside script directory. It contains a lot of os.getcwd().
if not os.path.dirname(os.path.abspath(__file__)) == os.getcwd():
Logger("Script cannot be called outside directory", Logger.ERROR)

# Keep track of execution time
start_time = time()

# Read information from config file
# Todo edit dockerfile with new path for report
# ToDo create a settings class that parses the ini file with set and get functions
# Note that this server(args) function CANNOT be placed in the server.py file. It calls "program()", which cannot be
# called from the server.py file
def server(args):
config = configparser.ConfigParser()
config.read("config.ini")

development = config.getint("Development", 'development')
# Drag and drop server
server_enabled = config.getboolean("ProgramConfig", 'server_enabled')

# This is the servermode, usefull for running on a server or docker.
if server_enabled or args.enable_server or (not len(sys.argv) > 1):

# Windows multithreading is different on Linux and windows (fork <-> new instance without parent context and args)
child=False
if os.name == 'nt':
if os.path.exists(".temp_thread_file"):
with open(".temp_thread_file") as f:
content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content]
args.project = [content[0]]
args.enable_server = content[1]
args.log_warnings = content[2]
args.disable_browser = content[3]
child = True
os.remove(".temp_thread_file")

if (server_enabled or args.enable_server or ((not len(sys.argv) > 1))) and (not child):
# This is a "bridge" between the stacoan program and the server. It communicates via this pipe (queue)
def serverlistener(in_q):
while True:
Expand All @@ -77,6 +82,13 @@ def serverlistener(in_q):

# Process the data
args = argparse.Namespace(project=[data], enable_server=False, log_warnings=False, log_errors=False, disable_browser=True)
# On windows: write arguments to file, spawn process, read arguments from file, delete.
if os.name == 'nt':
with open('.temp_thread_file', 'a') as the_file:
the_file.write(data+"\n")
the_file.write("False\n") # enable_server
the_file.write("False\n") # log_warnings
the_file.write("True\n")
p = Process(target=program, args=(args,))
p.start()

Expand All @@ -97,7 +109,6 @@ def serverlistener(in_q):

if not args.disable_browser:
Logger("Now automatically opening the HTML report.")
import json
DRAG_DROP_SERVER_PORT = json.loads(config.get("Server", 'drag_drop_server_port'))
# Open the webbrowser to the generated start page.
report_folder_start = "http:///127.0.0.1:" + str(DRAG_DROP_SERVER_PORT)
Expand All @@ -108,6 +119,21 @@ def serverlistener(in_q):
drag_drop_server_thread.join()
return() # Not needed because it will be killed eventually.

def program(args):
# Script cannot be called outside script directory. It contains a lot of os.getcwd().
if not os.path.dirname(os.path.abspath(__file__)) == os.getcwd():
Logger("Script cannot be called outside directory", Logger.ERROR)


# Keep track of execution time
start_time = time()

# Read information from config file
# Todo edit dockerfile with new path for report
# ToDo create a settings class that parses the ini file with set and get functions

config = configparser.ConfigParser()
config.read("config.ini")

# Update log level
if not (args.log_warnings or args.log_errors):
Expand All @@ -121,6 +147,9 @@ def serverlistener(in_q):
# Import the searchwords lists
Searchwords.searchwords_import(Searchwords())

# Server(args) checks if the server should be run and handles the spawning of the server and control of it
server(args)

# For each project (read .ipa or .apk file), run the scripts.
all_project_paths = args.project
for project_path in all_project_paths:
Expand All @@ -137,7 +166,7 @@ def serverlistener(in_q):
Logger("Searching done.")
Logger("start generating report")

# To Do: Generate the tree-view + Source code view for each SOURCE file
# ToDo: Generate the tree-view + Source code view for each SOURCE file
all_files = dict()
all_files.update(Project.projects[project_path].db_files)
all_files.update(Project.projects[project_path].src_files)
Expand Down Expand Up @@ -220,6 +249,7 @@ def serverlistener(in_q):
sys.exit()

if __name__ == "__main__":
multiprocessing.freeze_support()
if os.environ.get('DEBUG') is not None:
program(parse_args())
exit(0)
Expand Down

0 comments on commit 3750b2f

Please sign in to comment.