From 696ebc4ae68f4c7c2b803c917de365b98621b3a8 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Mon, 12 Feb 2018 13:55:33 +0100 Subject: Provide a script for upload validation The Python script is using vld (https://derickrethans.nl/projects.html#vld) to check for malicious opcodes.--- scripts/upload_validation.py | 38 +++++++++++++++++++++++++++++ src/tests/config/upload_validation_real.ini | 1 + src/tests/upload_validation_real.phpt | 26 ++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100755 scripts/upload_validation.py create mode 100644 src/tests/config/upload_validation_real.ini create mode 100644 src/tests/upload_validation_real.phpt diff --git a/scripts/upload_validation.py b/scripts/upload_validation.py new file mode 100755 index 0000000..fb1e05f --- /dev/null +++ b/scripts/upload_validation.py @@ -0,0 +1,38 @@ +#!/usr/bin/python + +import sys +import subprocess + +WHITELIST = ('ECHO', 'RETURN', 'PHP', 'NOP') + +def check(filename): + try: + output = subprocess.check_output(["php", + "-d", "vld.active=1", + "-d", "vld.execute=0", + "-d", "extension=vld.so", + "-d", "vld.format=1", + "-d", "vld.col_sep=@", + "-d", "log_errors=0", + filename], + stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + print("Error: %s" % e) + return 2 + + for line in output.splitlines()[8:]: + sp = line.split('@') + if len(sp) < 5: + continue + opcode = sp[4] # ,line, #, EIO, op, fetch, ext, return, operands + if opcode not in WHITELIST: + print("Upload_validation: Found an opcode: %s" % opcode) + return 1 + return 0 + + +if __name__ == '__main__': + if len(sys.argv) != 2: + print('Usage: %0 file_to_test.php', sys.argv[0]) + else: + sys.exit(check(sys.argv[1])) diff --git a/src/tests/config/upload_validation_real.ini b/src/tests/config/upload_validation_real.ini new file mode 100644 index 0000000..6463466 --- /dev/null +++ b/src/tests/config/upload_validation_real.ini @@ -0,0 +1 @@ +sp.upload_validation.script("../scripts/upload_validation.py").enable(); diff --git a/src/tests/upload_validation_real.phpt b/src/tests/upload_validation_real.phpt new file mode 100644 index 0000000..eef7b04 --- /dev/null +++ b/src/tests/upload_validation_real.phpt @@ -0,0 +1,26 @@ +--TEST-- +Upload a file, validation ok, with our real script, using vld +--SKIPIF-- + + +--INI-- +file_uploads=1 +sp.configuration_file={PWD}/config/upload_validation_real.ini +output_buffering=off +--POST_RAW-- +Content-Type: multipart/form-data; boundary=blabla +--blabla +Content-Disposition: form-data; name="test"; filename="test.php" +Content-Type: text/plain + +Some random text that is not PHP + +Some random text again +--blabla-- +--FILE-- + +--EXPECTF-- +Upload_validation: Found an opcode: INIT_FCALL +[snuffleupagus][0.0.0.0][upload_validation][drop] The upload of test.php on ? was rejected. -- cgit v1.3