summaryrefslogtreecommitdiff
path: root/replme/app
diff options
context:
space:
mode:
Diffstat (limited to 'replme/app')
-rw-r--r--replme/app/flag.txt1
-rw-r--r--replme/app/replme.py207
-rw-r--r--replme/app/requirements.txt10
3 files changed, 218 insertions, 0 deletions
diff --git a/replme/app/flag.txt b/replme/app/flag.txt
new file mode 100644
index 0000000..61fd8d5
--- /dev/null
+++ b/replme/app/flag.txt
@@ -0,0 +1 @@
+UMASS{h0n3y_c4ll_p357_c0n7r0l_w3_607_4_bu6_pr0bl3m}
diff --git a/replme/app/replme.py b/replme/app/replme.py
new file mode 100644
index 0000000..fda3bcf
--- /dev/null
+++ b/replme/app/replme.py
@@ -0,0 +1,207 @@
+import os
+import subprocess
+import shlex
+from flask import Flask, flash, request, redirect, make_response, url_for
+from werkzeug.utils import secure_filename
+
+import subprocess
+import resource
+
+# Maximal virtual memory for subprocesses (in bytes).
+MAX_VIRTUAL_MEMORY = 20 * 1024 * 1024 # 2 MB
+
+def limit_virtual_memory():
+ # The tuple below is of the form (soft limit, hard limit). Limit only
+ # the soft part so that the limit can be increased later (setting also
+ # the hard limit would prevent that).
+ # When the limit cannot be changed, setrlimit() raises ValueError.
+ resource.setrlimit(resource.RLIMIT_AS, (MAX_VIRTUAL_MEMORY, resource.RLIM_INFINITY))
+
+app = Flask(__name__)
+
+PRELUDE = b"""
+(defn all-bindings [&] (error "Function all-bindings not allowed"))
+(defn all-dynamics [&] (error "Function all-dynamics not allowed"))
+(defn bad-compile [&] (error "Function bad-compile not allowed"))
+(defn bad-parse [&] (error "Function bad-parse not allowed"))
+(defn cli-main [&] (error "Function cli-main not allowed"))
+(defn compile [&] (error "Function compile not allowed"))
+(defn curenv [&] (error "Function curenv not allowed"))
+(defn debug [&] (error "Function debug not allowed"))
+(defn debug/arg-stack [&] (error "Function debug/arg-stack not allowed"))
+(defn debug/break [&] (error "Function debug/break not allowed"))
+(defn debug/fbreak [&] (error "Function debug/fbreak not allowed"))
+(defn debug/lineage [&] (error "Function debug/lineage not allowed"))
+(defn debug/stack [&] (error "Function debug/stack not allowed"))
+(defn debug/stacktrace [&] (error "Function debug/stacktrace not allowed"))
+(defn debug/step [&] (error "Function debug/step not allowed"))
+(defn debug/unbreak [&] (error "Function debug/unbreak not allowed"))
+(defn debug/unfbreak [&] (error "Function debug/unfbreak not allowed"))
+(defn debugger-env [&] (error "Function debugger-env not allowed"))
+(defn dofile [&] (error "Function dofile not allowed"))
+(defn env-lookup [&] (error "Function env-lookup not allowed"))
+(defn eval [&] (error "Function eval not allowed"))
+(defn eval-string [&] (error "Function eval-string not allowed"))
+(defn fiber/getenv [&] (error "Function fiber/getenv not allowed"))
+(defn fiber/setenv [&] (error "Function fiber/setenv not allowed"))
+(defn file/close [&] (error "Function file/close not allowed"))
+(defn file/flush [&] (error "Function file/flush not allowed"))
+(defn file/open [&] (error "Function file/open not allowed"))
+(defn file/popen [&] (error "Function file/popen not allowed"))
+(defn file/read [&] (error "Function file/read not allowed"))
+(defn file/seek [&] (error "Function file/seek not allowed"))
+(defn file/temp [&] (error "Function file/temp not allowed"))
+(defn file/write [&] (error "Function file/write not allowed"))
+(defn import [&] (error "Function import not allowed"))
+(defn import* [&] (error "Function import* not allowed"))
+(defn load-image [&] (error "Function load-image not allowed"))
+(defn load-image-dict [&] (error "Function load-image-dict not allowed"))
+(defn make-env [&] (error "Function make-env not allowed"))
+(defn make-image [&] (error "Function make-image not allowed"))
+(defn make-image-dict [&] (error "Function make-image-dict not allowed"))
+(defn marshal [&] (error "Function marshal not allowed"))
+(defn module/add-paths [&] (error "Function module/add-paths not allowed"))
+(defn module/cache [&] (error "Function module/cache not allowed"))
+(defn module/expand-path [&] (error "Function module/expand-path not allowed"))
+(defn module/find [&] (error "Function module/find not allowed"))
+(defn module/loaders [&] (error "Function module/loaders not allowed"))
+(defn module/loading [&] (error "Function module/loading not allowed"))
+(defn module/paths [&] (error "Function module/paths not allowed"))
+(defn net/accept [&] (error "Function net/accept not allowed"))
+(defn net/accept-loop [&] (error "Function net/accept-loop not allowed"))
+(defn net/address [&] (error "Function net/address not allowed"))
+(defn net/chunk [&] (error "Function net/chunk not allowed"))
+(defn net/close [&] (error "Function net/close not allowed"))
+(defn net/connect [&] (error "Function net/connect not allowed"))
+(defn net/flush [&] (error "Function net/flush not allowed"))
+(defn net/listen [&] (error "Function net/listen not allowed"))
+(defn net/read [&] (error "Function net/read not allowed"))
+(defn net/recv-from [&] (error "Function net/recv-from not allowed"))
+(defn net/send-to [&] (error "Function net/send-to not allowed"))
+(defn net/server [&] (error "Function net/server not allowed"))
+(defn net/write [&] (error "Function net/write not allowed"))
+(defn os/cd [&] (error "Function os/cd not allowed"))
+(defn os/chmod [&] (error "Function os/chmod not allowed"))
+(defn os/clock [&] (error "Function os/clock not allowed"))
+(defn os/cryptorand [&] (error "Function os/cryptorand not allowed"))
+(defn os/cwd [&] (error "Function os/cwd not allowed"))
+(defn os/date [&] (error "Function os/date not allowed"))
+(defn os/dir [&] (error "Function os/dir not allowed"))
+(defn os/environ [&] (error "Function os/environ not allowed"))
+(defn os/execute [&] (error "Function os/execute not allowed"))
+(defn os/exit [&] (error "Function os/exit not allowed"))
+(defn os/getenv [&] (error "Function os/getenv not allowed"))
+(defn os/link [&] (error "Function os/link not allowed"))
+(defn os/lstat [&] (error "Function os/lstat not allowed"))
+(defn os/mkdir [&] (error "Function os/mkdir not allowed"))
+(defn os/sleep [&] (error "Function os/sleep not allowed"))
+(defn os/mktime [&] (error "Function os/mktime not allowed"))
+(defn os/open [&] (error "Function os/open not allowed"))
+(defn os/perm-int [&] (error "Function os/perm-int not allowed"))
+(defn os/perm-string [&] (error "Function os/perm-string not allowed"))
+(defn os/pipe [&] (error "Function os/pipe not allowed"))
+(defn os/proc-close [&] (error "Function os/proc-close not allowed"))
+(defn os/proc-kill [&] (error "Function os/proc-kill not allowed"))
+(defn os/proc-wait [&] (error "Function os/proc-wait not allowed"))
+(defn os/readlink [&] (error "Function os/readlink not allowed"))
+(defn os/realpath [&] (error "Function os/realpath not allowed"))
+(defn os/rename [&] (error "Function os/rename not allowed"))
+(defn os/rm [&] (error "Function os/rm not allowed"))
+(defn os/rmdir [&] (error "Function os/rmdir not allowed"))
+(defn os/setenv [&] (error "Function os/setenv not allowed"))
+(defn os/shell [&] (error "Function os/shell not allowed"))
+(defn os/spawn [&] (error "Function os/spawn not allowed"))
+(defn os/stat [&] (error "Function os/stat not allowed"))
+(defn os/symlink [&] (error "Function os/symlink not allowed"))
+(defn os/time [&] (error "Function os/time not allowed"))
+(defn os/touch [&] (error "Function os/touch not allowed"))
+(defn os/umask [&] (error "Function os/umask not allowed"))
+(defn os/which [&] (error "Function os/which not allowed"))
+(defn repl [&] (error "Function repl not allowed"))
+(defn require [&] (error "Function require not allowed"))
+(defn root-env [&] (error "Function root-env not allowed"))
+(defn run-context [&] (error "Function run-context not allowed"))
+(defn signal [&] (error "Function signal not allowed"))
+(defn symbol [&] (error "Function symbol not allowed"))
+(defn symbol/slice [&] (error "Function symbol/slice not allowed"))
+(defn thread/close [&] (error "Function thread/close not allowed"))
+(defn thread/current [&] (error "Function thread/current not allowed"))
+(defn thread/exit [&] (error "Function thread/exit not allowed"))
+(defn thread/new [&] (error "Function thread/new not allowed"))
+(defn thread/receive [&] (error "Function thread/receive not allowed"))
+(defn thread/send [&] (error "Function thread/send not allowed"))
+(defn trace [&] (error "Function trace not allowed"))
+(defn tracev [&] (error "Function tracev not allowed"))
+(defn unmarshal [&] (error "Function unmarshal not allowed"))
+(defn use [&] (error "Function use not allowed"))
+"""
+
+PROC = {}
+
+@app.route('/', methods=['GET', 'POST'])
+def upload_file():
+ if request.method == 'POST':
+ # Limit one process per IP.
+ if request.remote_addr in PROC:
+ PROC[request.remote_addr].kill()
+ del PROC[request.remote_addr]
+ source_code = request.get_data()
+ proc = subprocess.Popen(
+ ['build/janet', '/dev/stdin'],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ preexec_fn=limit_virtual_memory
+ )
+ PROC[request.remote_addr] = proc
+ result = "Something went wrong..."
+ try:
+ result = proc.communicate(input=PRELUDE + source_code, timeout=10*60)
+ result = result[0]
+ except Exception:
+ pass
+ response = make_response(result, 200)
+ response.mimetype = "text/plain"
+ return response
+ return '''
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Janet REPL</title>
+ </head>
+ <body>
+ <p>Janet Script:</p>
+ <textarea cols="80" id="code" name="" rows="10"></textarea>
+ <br>
+ <button id="send">Run me!</button>
+ <p>Program output:</p>
+ <textarea cols="80" id="response" name="" rows="10" readonly>
+Janet 1.1.0-dev-6887dd05 Copyright (C) 2017-2019 Calvin Rose
+janet:0:>
+ </textarea>
+ <script>
+let code = document.getElementById("code");
+let response = document.getElementById("response");
+let button = document.getElementById("send");
+
+button.addEventListener("click", () => {
+ let http = new XMLHttpRequest();
+ let url = '/';
+ let params = code.value;
+ http.open('POST', url, true);
+
+ // Send the proper header information along with the request
+ http.setRequestHeader('Content-type', 'text/plain');
+
+ http.onreadystatechange = () => {
+ if (http.readyState == 4 && http.status == 200) {
+ response.value = http.responseText;
+ }
+ }
+
+ http.send(params);
+});
+</script>
+ </body>
+</html>
+ '''
diff --git a/replme/app/requirements.txt b/replme/app/requirements.txt
new file mode 100644
index 0000000..d9b53c5
--- /dev/null
+++ b/replme/app/requirements.txt
@@ -0,0 +1,10 @@
+click==7.1.2
+Flask==1.1.2
+Flask-JWT-Extended==4.1.0
+gunicorn==20.0.4
+itsdangerous==1.1.0
+Jinja2==2.11.3
+MarkupSafe==1.1.1
+PyJWT==2.0.1
+Werkzeug==1.0.1
+requests==2.25.1