Web


Nmap discovered a Web server on the target port 80 The running service is Apache httpd 2.4.18

Webroot It appears to be a WordPress blog for the private Minecraft server hosted over the port 25565 There is a mention of the website being under development for;

  • A wiki system for the server
  • A core plugin tracking player stats and stuff

Wappalyzer identified technologies involved WordPress 4.8 PHP

wpscan


┌──(kali㉿kali)-[~/archive/htb/labs/blocky]
└─$ wpscan --url http://blocky.htb/ -e u
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|
 
         WordPress Security Scanner by the WPScan Team
                         Version 3.8.24
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________
 
[+] URL: http://blocky.htb/ [10.10.10.37]
[+] Started: Tue Sep 19 13:34:13 2023
 
Interesting Finding(s):
 
[+] Headers
 | Interesting Entry: Server: Apache/2.4.18 (Ubuntu)
 | Found By: Headers (Passive Detection)
 | Confidence: 100%
 
[+] XML-RPC seems to be enabled: http://blocky.htb/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/
 
[+] WordPress readme found: http://blocky.htb/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 
[+] Upload directory has listing enabled: http://blocky.htb/wp-content/uploads/
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 
[+] The external WP-Cron seems to be enabled: http://blocky.htb/wp-cron.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 60%
 | References:
 |  - https://www.iplocation.net/defend-wordpress-from-ddos
 |  - https://github.com/wpscanteam/wpscan/issues/1299
 
[+] WordPress version 4.8 identified (Insecure, released on 2017-06-08).
 | Found By: Rss Generator (Passive Detection)
 |  - http://blocky.htb/index.php/feed/, <generator>https://wordpress.org/?v=4.8</generator>
 |  - http://blocky.htb/index.php/comments/feed/, <generator>https://wordpress.org/?v=4.8</generator>
 
[+] WordPress theme in use: twentyseventeen
 | Location: http://blocky.htb/wp-content/themes/twentyseventeen/
 | Last Updated: 2023-03-29T00:00:00.000Z
 | Readme: http://blocky.htb/wp-content/themes/twentyseventeen/README.txt
 | [!] The version is out of date, the latest version is 3.2
 | Style URL: http://blocky.htb/wp-content/themes/twentyseventeen/style.css?ver=4.8
 | Style Name: Twenty Seventeen
 | Style URI: https://wordpress.org/themes/twentyseventeen/
 | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Css Style In Homepage (Passive Detection)
 |
 | Version: 1.3 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://blocky.htb/wp-content/themes/twentyseventeen/style.css?ver=4.8, Match: 'Version: 1.3'
 
[+] Enumerating Users (via Passive and Aggressive Methods)
 Brute Forcing Author IDs - Time: 00:00:00 <=====================================> (10 / 10) 100.00% Time: 00:00:00
 
[i] User(s) Identified:
 
[+] notch
 | Found By: Author Posts - Author Pattern (Passive Detection)
 | Confirmed By:
 |  Wp Json Api (Aggressive Detection)
 |   - http://blocky.htb/index.php/wp-json/wp/v2/users/?per_page=100&page=1
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 |  Login Error Messages (Aggressive Detection)
 
[+] Notch
 | Found By: Rss Generator (Passive Detection)
 | Confirmed By: Login Error Messages (Aggressive Detection)
 
[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register
 
[+] Finished: Tue Sep 19 13:34:15 2023
[+] Requests Done: 25
[+] Cached Requests: 38
[+] Data Sent: 6.607 KB
[+] Data Received: 123.244 KB
[+] Memory used: 178.406 MB
[+] Elapsed time: 00:00:02

wpsscan has confirmed the version information; WordPress 3.8 It has also discovered the theme in use; twentyseventeen 1.3 with 80% of confidence Lastly, a user has been found; notch

Vulnerability


┌──(kali㉿kali)-[~/archive/htb/labs/blocky]
└─$ searchsploit WordPress Core 4.8
----------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                         |  Path
----------------------------------------------------------------------- ---------------------------------
WordPress Core < 4.9.6 - (Authenticated) Arbitrary File Deletion       | php/webapps/44949.txt
WordPress Core < 5.2.3 - Viewing Unauthenticated/Password/Private Post | multiple/webapps/47690.md
WordPress Core < 5.3.x - 'xmlrpc.php' Denial of Service                | php/dos/47800.py
----------------------------------------------------------------------- ---------------------------------
shellcodes: No Results
papers: No Results

The target web application built with WordPress 4.8 appears to suffer from a series of vulnerabilities

One of the listed vulnerabilities allows unauthenticated users to view private post or password According to the documentation, it can be achieved by appending ?static=1, followed by additional parameters including order or orderby

I have played around with it for awhile and came to a conclusion that the website does not have any private post

Bruteforce Attack


┌──(kali㉿kali)-[~/archive/htb/labs/blocky]
└─$ wpscan --url http://blocky.htb/ -U notch -P /usr/share/wordlists/rockyou.txt
_______________________________________________________________
[+] URL: http://blocky.htb/ [10.10.10.37]
[+] Started: Tue Sep 19 13:39:26 2023
 
[...REDACTED...]
 
[+] Performing password attack on Xmlrpc against 1 user/s
^Cying notch / 280204 Time: 00:36:50 <                                   > (94270 / 14344393)  0.65%  ETA: 92:48:15
[i] No Valid Passwords Found.
 
[!] No WPScan API Token given, as a result vulnerability data has not been output./ 14344393)  0.65%  ETA: 92:48:11
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register
 
[+] Finished: Tue Sep 19 14:16:23 2023
[+] Requests Done: 94421
[+] Cached Requests: 37
[+] Data Sent: 47.342 MB
[+] Data Received: 55.5 MB
[+] Memory used: 306.094 MB
[+] Elapsed time: 00:36:57
 
Scan Aborted: Canceled by User

Bruteforcing doesn’t seem to be the way in

Fuzzing


┌──(kali㉿kali)-[~/archive/htb/labs/blocky]
└─$ ffuf -c -w /usr/share/wordlists/seclists/discovery/web-content/directory-list-lowercase-2.3-medium.txt -u http://blocky.htb/FUZZ -ic -e .txt,.php
________________________________________________
 
 :: Method           : GET
 :: URL              : http://blocky.htb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt
 :: Extensions       : .txt .php 
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
 
[status: 301, Size: 307, Words: 20, Lines: 10, Duration: 23ms]
    * fuzz: wiki
 
[status: 301, Size: 313, Words: 20, Lines: 10, Duration: 23ms]
    * fuzz: wp-content
 
[status: 301, Size: 0, Words: 1, Lines: 1, Duration: 1594ms]
    * fuzz: index.php
 
[status: 200, Size: 2397, Words: 147, Lines: 70, Duration: 54ms]
    * fuzz: wp-login.php
 
[status: 301, Size: 310, Words: 20, Lines: 10, Duration: 27ms]
    * fuzz: plugins
 
[status: 200, Size: 19935, Words: 3334, Lines: 386, Duration: 29ms]
    * fuzz: license.txt
 
[status: 301, Size: 314, Words: 20, Lines: 10, Duration: 23ms]
    * fuzz: wp-includes
 
[status: 301, Size: 313, Words: 20, Lines: 10, Duration: 28ms]
    * fuzz: javascript
 
[status: 200, Size: 135, Words: 11, Lines: 5, Duration: 119ms]
    * fuzz: wp-trackback.php
 
[status: 301, Size: 311, Words: 20, Lines: 10, Duration: 26ms]
    * fuzz: wp-admin
 
[status: 301, Size: 313, Words: 20, Lines: 10, Duration: 27ms]
    * fuzz: phpmyadmin
 
[status: 405, Size: 42, Words: 6, Lines: 1, Duration: 35ms]
    * fuzz: xmlrpc.php
 
[status: 302, Size: 0, Words: 1, Lines: 1, Duration: 125ms]
    * fuzz: wp-signup.php
 
[status: 403, Size: 298, Words: 22, Lines: 12, Duration: 26ms]
    * fuzz: server-status
 
:: Progress: [622890/622890] :: Job [1/1] :: 1315 req/sec :: Duration: [0:06:47] :: Errors: 0 ::

Aside from all the regular endpoints generated by WordPress, I see there are the /wiki and /plugins directories Those directories appear to be relevant to the development article earlier

/wiki/


The /wiki/ directory indeed is under development as mentioned earlier.

/plugins/


The /plugins/ directory, on the other hand, contains 2 Java files;

  • BlockyCore.jar
  • griefprevention-1.11.2-3.1.1.298.jar

A .jar file, which stands for “Java Archive,” is a file format used in Java programming to package multiple Java classes, resources, and metadata into a single compressed file. These files are commonly used for distributing and sharing Java libraries or applications, making it easier to manage dependencies and ensure portability across different Java environments. They are executed using the Java Virtual Machine (JVM) and can be run on various platforms without modification.

┌──(kali㉿kali)-[~/…/htb/labs/blocky/plugins]
└─$ wget -q http://blocky.htb/plugins/files/BlockyCore.jar ; wget -q http://blocky.htb/plugins/files/griefprevention-1.11.2-3.1.1.298.jar

I will download those 2 Java files for review

griefprevention-1.11.2-3.1.1.298.jar


┌──(kali㉿kali)-[~/…/labs/blocky/plugins/griefprevention-1.11.2-3.1.1.298]
└─$ 7z x griefprevention-1.11.2-3.1.1.298.jar
 
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,32 CPUs 11th Gen Intel(R) Core(TM) i9-11900H @ 2.50GHz (806D1),ASM,AES-NI)
 
Scanning the drive for archives:
1 file, 532928 bytes (521 KiB)
 
Extracting archive: griefprevention-1.11.2-3.1.1.298.jar
--
Path = griefprevention-1.11.2-3.1.1.298.jar
Type = zip
Physical Size = 532928
 
Everything is Ok
 
Folders: 23
Files: 190
Size:       1221658
Compressed: 532928

I will start by extracting content of the file

┌──(kali㉿kali)-[~/…/labs/blocky/plugins/griefprevention-1.11.2-3.1.1.298]
└─$ tree -a .                        
.
├── griefprevention-1.11.2-3.1.1.298.jar
├── mcmod.info
├── me
│   └── ryanhamshire
│       └── griefprevention
│           ├── api
│           │   ├── claim
│           │   │   ├── Claim$Builder.class
│           │   │   ├── Claim.class
│           │   │   ├── ClaimManager.class
│           │   │   ├── ClaimResult.class
│           │   │   ├── ClaimResultType.class
│           │   │   ├── ClaimType.class
│           │   │   └── TrustType.class
│           │   ├── data
│           │   │   ├── ClaimData.class
│           │   │   └── PlayerData.class
│           │   ├── event
│           │   │   ├── AttackPlayerEvent.class
│           │   │   ├── BorderClaimEvent.class
│           │   │   ├── ClaimEvent.class
│           │   │   ├── CreateClaimEvent.class
│           │   │   ├── DeleteClaimEvent$Abandon.class
│           │   │   ├── DeleteClaimEvent.class
│           │   │   ├── GPNamedCause.class
│           │   │   ├── ResizeClaimEvent.class
│           │   │   ├── TransferClaimEvent.class
│           │   │   ├── TrustClaimEvent$Add.class
│           │   │   ├── TrustClaimEvent$Remove.class
│           │   │   └── TrustClaimEvent.class
│           │   └── GriefPreventionApi.class
│           ├── BlockPosCache.class
│           ├── claim
│           │   ├── ClaimContextCalculator.class
│           │   ├── ClaimsMode.class
│           │   ├── GPClaim$ClaimBuilder.class
│           │   ├── GPClaim.class
│           │   ├── GPClaimManager.class
│           │   └── GPClaimResult.class
│           ├── command
│           │   ├── BaseCommand.class
│           │   ├── CommandAccessTrust.class
│           │   ├── CommandAdjustBonusClaimBlocks.class
│           │   ├── CommandClaimAbandonAll.class
│           │   ├── CommandClaimAbandon.class
│           │   ├── CommandClaimAdmin.class
│           │   ├── CommandClaimAdminList.class
│           │   ├── CommandClaimBanItem.class
│           │   ├── CommandClaimBasic.class
│           │   ├── CommandClaimBook.class
│           │   ├── CommandClaimBuy.class
│           │   ├── CommandClaimClear.class
│           │   ├── CommandClaimCuboid.class
│           │   ├── CommandClaimDeleteAllAdmin.class
│           │   ├── CommandClaimDeleteAll.class
│           │   ├── CommandClaimDelete.class
│           │   ├── CommandClaimFarewell.class
│           │   ├── CommandClaimFlag$FlagType.class
│           │   ├── CommandClaimFlag.class
│           │   ├── CommandClaimFlagDebug.class
│           │   ├── CommandClaimFlagGroup.class
│           │   ├── CommandClaimFlagPlayer.class
│           │   ├── CommandClaimFlagReset.class
│           │   ├── CommandClaimGreeting.class
│           │   ├── CommandClaimIgnore.class
│           │   ├── CommandClaimInfo.class
│           │   ├── CommandClaimInherit.class
│           │   ├── CommandClaimList.class
│           │   ├── CommandClaimName.class
│           │   ├── CommandClaimOptionGroup.class
│           │   ├── CommandClaimOptionPlayer.class
│           │   ├── CommandClaimPermissionGroup.class
│           │   ├── CommandClaimPermissionPlayer.class
│           │   ├── CommandClaimSell.class
│           │   ├── CommandClaimSetSpawn.class
│           │   ├── CommandClaimSpawn.class
│           │   ├── CommandClaimSubdivide.class
│           │   ├── CommandClaimTransfer.class
│           │   ├── CommandClaimUnbanItem.class
│           │   ├── CommandContainerTrust.class
│           │   ├── CommandDebug.class
│           │   ├── CommandGivePet.class
│           │   ├── CommandGpReload.class
│           │   ├── CommandHelper.class
│           │   ├── CommandIgnoredPlayerList.class
│           │   ├── CommandIgnorePlayer.class
│           │   ├── CommandPermissionTrust.class
│           │   ├── CommandPlayerInfo.class
│           │   ├── CommandRestoreNatureAggressive.class
│           │   ├── CommandRestoreNature.class
│           │   ├── CommandRestoreNatureFill.class
│           │   ├── CommandSeparate.class
│           │   ├── CommandSetAccruedClaimBlocks.class
│           │   ├── CommandSiege.class
│           │   ├── CommandSoftMute.class
│           │   ├── CommandTrustAll.class
│           │   ├── CommandTrust.class
│           │   ├── CommandTrustList.class
│           │   ├── CommandUnignorePlayer.class
│           │   ├── CommandUnlockDrops.class
│           │   ├── CommandUnseparate.class
│           │   ├── CommandUntrustAll.class
│           │   └── CommandUntrust.class
│           ├── configuration
│           │   ├── category
│           │   │   ├── ClaimCategory.class
│           │   │   ├── ConfigCategory.class
│           │   │   ├── DatabaseCategory.class
│           │   │   ├── EconomyCategory.class
│           │   │   ├── FlagCategory.class
│           │   │   ├── GeneralCategory.class
│           │   │   ├── LoggingCategory.class
│           │   │   ├── MigratorCategory.class
│           │   │   ├── PlayerDataCategory.class
│           │   │   ├── PvpCategory.class
│           │   │   ├── SiegeCategory.class
│           │   │   └── SpamCategory.class
│           │   ├── ClaimDataConfig.class
│           │   ├── ClaimStorageData.class
│           │   ├── ClaimTemplateConfig.class
│           │   ├── ClaimTemplateStorage.class
│           │   ├── GriefPreventionConfig$Type.class
│           │   ├── GriefPreventionConfig.class
│           │   ├── IClaimData.class
│           │   ├── PlayerDataConfig.class
│           │   ├── PlayerStorageData.class
│           │   ├── SubDivisionDataConfig.class
│           │   └── type
│           │       ├── ConfigBase.class
│           │       ├── DimensionConfig.class
│           │       ├── GlobalConfig.class
│           │       └── WorldConfig.class
│           ├── DatabaseDataStore.class
│           ├── DataStore.class
│           ├── event
│           │   ├── GPAttackPlayerEvent.class
│           │   ├── GPBorderClaimEvent.class
│           │   ├── GPClaimEvent.class
│           │   ├── GPCreateClaimEvent.class
│           │   ├── GPDeleteClaimEvent$Abandon.class
│           │   ├── GPDeleteClaimEvent.class
│           │   ├── GPResizeClaimEvent.class
│           │   ├── GPTransferClaimEvent.class
│           │   ├── GPTrustClaimEvent$Add.class
│           │   ├── GPTrustClaimEvent$Remove.class
│           │   └── GPTrustClaimEvent.class
│           ├── exception
│           │   └── NoTransferException.class
│           ├── FlatFileDataStore.class
│           ├── GPApiProvider.class
│           ├── GPFlags.class
│           ├── GPPlayerData.class
│           ├── GPTimings.class
│           ├── GriefPrevention.class
│           ├── GriefPreventionPlugin$IgnoreMode.class
│           ├── GriefPreventionPlugin.class
│           ├── IpBanInfo.class
│           ├── ItemInfo.class
│           ├── listener
│           │   ├── BlockEventHandler.class
│           │   ├── EntityEventHandler$1.class
│           │   ├── EntityEventHandler$2.class
│           │   ├── EntityEventHandler.class
│           │   ├── EntityRemovalListener.class
│           │   ├── NucleusEventHandler.class
│           │   ├── PlayerEventHandler.class
│           │   └── WorldEventHandler.class
│           ├── logging
│           │   ├── CustomLogEntryTypes.class
│           │   ├── CustomLogger$1.class
│           │   ├── CustomLogger$EntryWriter.class
│           │   ├── CustomLogger$ExpiredLogRemover.class
│           │   └── CustomLogger.class
│           ├── MCClansApiProvider.class
│           ├── message
│           │   ├── CustomizableMessage.class
│           │   ├── Messages.class
│           │   └── TextMode.class
│           ├── migrator
│           │   ├── PolisMigrator.class
│           │   └── RedProtectMigrator.class
│           ├── permission
│           │   ├── GPOptions.class
│           │   ├── GPPermissionHandler.class
│           │   └── GPPermissions.class
│           ├── ShovelMode.class
│           ├── SiegeData.class
│           ├── task
│           │   ├── AutoExtendClaimTask$ExecuteExtendClaimTask.class
│           │   ├── AutoExtendClaimTask.class
│           │   ├── CheckForPortalTrapTask.class
│           │   ├── CleanupUnusedClaimsTask.class
│           │   ├── DeliverClaimBlocksTask.class
│           │   ├── IgnoreLoaderThread.class
│           │   ├── PlayerKickBanTask.class
│           │   ├── PvPImmunityValidationTask.class
│           │   ├── RestoreNatureExecutionTask.class
│           │   ├── RestoreNatureProcessingTask.class
│           │   ├── SecureClaimTask.class
│           │   ├── SendPlayerMessageTask.class
│           │   ├── SiegeCheckupTask.class
│           │   ├── VisualizationApplicationTask.class
│           │   ├── VisualizationReversionTask.class
│           │   └── WelcomeTask.class
│           ├── util
│           │   ├── BlockUtils.class
│           │   ├── NbtDataHelper.class
│           │   ├── PlayerUtils.class
│           │   └── WordFinder.class
│           └── visual
│               ├── Visualization.class
│               └── VisualizationType.class
└── META-INF
    └── MANIFEST.MF
 
24 directories, 191 files

There is a lot going on with this Java file This might be an existing Minecraft “mod”

Existing “mod”

griefprevention is indeed a Minecraft server plugin while it is possible that this particular version of griefprevention may contain security vulnerabilities despite the software being “released” after hours of auditing, I will move on to the next Java file since it appears to be more “custom” from the user-end

BlockyCore.jar


┌──(kali㉿kali)-[~/…/labs/blocky/plugins/BlockyCore]
└─$ 7z x BlockyCore.jar 
 
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,32 CPUs 11th Gen Intel(R) Core(TM) i9-11900H @ 2.50GHz (806D1),ASM,AES-NI)
 
Scanning the drive for archives:
1 file, 883 bytes (1 KiB)
 
Extracting archive: BlockyCore.jar
--
Path = BlockyCore.jar
Type = zip
Physical Size = 883
 
Everything is Ok
 
Files: 2
Size:       964
Compressed: 883

Extracting content

┌──(kali㉿kali)-[~/…/labs/blocky/plugins/BlockyCore]
└─$ tree -a .  
.
├── BlockyCore.jar
├── com
│   └── myfirstplugin
│       └── BlockyCore.class
└── META-INF
    └── MANIFEST.MF
 
4 directories, 3 files

The com directory typically contains the compiled Java class files and packages of the Java application or library stored within the .jar archive. These classes make up the functional code of the software. The META-INF directory holds metadata and configuration files used by the Java runtime and other tools. It may contain files like MANIFEST.MF, which provides information about the JAR file, such as its version and entry points, and other resources required for proper execution, like digital signatures.

CLEARTEXT Credential

┌──(kali㉿kali)-[~/…/labs/blocky/plugins/BlockyCore]
└─$ cat com/myfirstplugin/BlockyCore.class                                 
����4-com/myfirstplugin/BlockyCorejava/lang/ObjectsqlHostLjava/lang/String;sqlUsersqlPass<init>()VCode
 
	
	localhost	
                       root	
                               8YsqfCTnvxAUeduzjNSXe22	
                                                       LineNumberTableLocalVariableTablethisLcom/myfirstponServerStartore;
             onServerStop
                         onPlayerJoi"TODO get usernam$!Welcome to the BlockyCraft!!!!!!!
&
 '(
   sendMessage'(Ljava/lang/String;Ljava/lang/String;)usernamemessage
SourceFileBlockyCore.java!
 
Q*�
   *�*�*���
 
 
 

 
 
 

 
 
	*!#�%��
 
	
        ��

While the Java class file is in the binary format, some of the data are still in CLEARTEXT string and there appears to be a hard-coded cleartext credential; root:8YsqfCTnvxAUeduzjNSXe22

While this credential does not work against the WordPress login page to the administrative panel, I should also test it against the target system