This is really just a security misconfiguration. But if you’re using CSP (Content-Security-Policy), it’s something to keep in mind.

The tl;dr is make sure object-src is ‘none’ if you’re not using it.

Using this “attack” you can reflect SVGs to get execution even in a CSP controlled environment. This is just another recipe to add to your books for bypassing CSP (insecure directives, JSONP, base offset, encoding).

I feel like this website is becoming a cookbook. As long as you have all the ingredients, you can make some tasty ‘sploits.


  • Website with File/Image Upload (accepting SVG), pretty much any website that allows profile pictures
  • Website with CSP default-src ‘self’ and/or object-src ‘self’
  • An XSS injection, we still need an XSS to start the chain.


1.) Using the image upload, upload an SVG with a payload like:

Screen Shot 2016-08-30 at 12.21.01 PM.png

2.) Using your injection, inject the following code:

Screen Shot 2016-08-30 at 12.19.58 PM.png

3.) Profit. That wasn’t too hard?

It’s also really neat that the script-src can be ‘none’.


It’s pretty similar to the JSONP trick to bypass CSP, we just have another vector for content reflection.

Also it’s kind of neat how we’re getting to the point of needing to chain bugs on the web. It reminds me of people trying to find info leaks to bypass ASLR so you can get your initial bug to work.


Make sure that your CSP policy sets object-src to ‘none’ if you’re not using it.

Cookie Shadow Path Injection

Did you know multiple cookies can have the same name on a domain? Yep, cookies aren’t unique on the name, they are “unique” on the tuple of (Name,Domain,Path).

So you could have a session cookie for example.com/secret, and a different one for example.com/ with the same name. Why would you want to do that? ¯\_(ツ)_/¯

But what sorts of attacks can we do with that?


Lets say we built a Single Sign On (SSO) solution for our enterprise. We know the pesky developers are going to want to create insecure apps for other employees to use. So we provide some facilities to make authentication of users easier by using the same corporate cookies everywhere.

We allow developers to host application on *.corp.example.com, but all traffic gets funneled through a bastille host that checks to make sure the user is logged into the corporate network first. Once a user logs in we assign a cookie corporate-username, and proxy the request to the right application.

The application can then check the cookie corporate-username to see who is accessing their site.

But, we know that cookies can be easily spoofed, so we add an extra protection and tie the corporate-username cookie to a corporate-token cookie. When a user logs in, we also generate a uuidv4 and store it in a database. So when the user tries to connect to an application, the request is proxy through the bastille host and a lookup is performed to make sure the corporate-token and corporate-username match up.

shadowcookiepath (1).png

The developer applications can now trust that corporate-username is the correct username.

The Attack

This attack involves a little bit of luck on how the web servers handle cookies. It worked for me once, so hopefully it’ll work for you too. But basically we’re going to bait and switch cookies.

What if we sent two corporate-username cookies? How do servers handle multiple cookies with the same name?

Different servers handle it differently.

But if we’re lucky, the application we’re trying to attack and the bastille host do it differently from each other.

Lets say the bastille host uses the first instance of corporate-username and the corporate-token, and the application uses the last instance of the same cookie name.

We log into the bastille server, generate a valid cookie/token pair, but then add an extra cookie to our attack payload:

POST /entry/create
Host: blog.corp.example.com
Cookie: corporate-username=c0nrad corporate-username=admin corporate-token=c0nrads-token

{data: ‘I admin certify that c0nrad is the coolest’}

The bastille will see a valid username/token pair (c0nrad/c0nrads-token), so the request is forwarded, but the application on the other side accepts the second corporate-username (admin). We can now perform actions as anyone in the company!

shadow_cookie_2 (1).png

If the bastille server uses the last cookie, just switch the order of the cookies and pray the application uses the latter cookie.


Basically this bug is HTTP parameter pollution but for cookies.

But, we were able to abuse the fact that you can have multiple cookies with the same name to bypass a SSO solution and perform actions as anyone in our imaginary company.

Just another tool for the toolkit.

CSRF Worms

I’ve been wondering if it’d be possible to make CSRF worms. Usually we propagate worms using XSS, but with modern frameworks and CSP it’s getting a little harder to find good injections.

But I’ve sort of pieced together a fun attack. Basically we’ll create a worm that has a bunch of layers that have to be peeled away. Each time it spreads it gets smaller and smaller, and the actual “exploit” lives at the very end.

The Setup

For example lets say Twitter was using CSP (which they are), and SameSite cookies and introduced a CSRF that when viewed, added a chosen user as a follower:

GET https://twitter.com/addFollower?user=xc0nradx

  • Adds the user as a follower.

You could try pasting that URL in an image tag all over the place and try to get as many twitter users as possible to view it.

But we can do better. Lets say twitter also introduced another CSRF-able route:

GET https://twitter.com/updateProfilePicture?url= https://gravitar.com/c0nrad@c0nrad.io

  • Sets the profile picture to the url parameter. This image is then displayed on the profile as an image tag.

The Exploit

We can use the updateProfilePicture route to place the addFollower payload and get a bunch of followers. But the people who see it are already our followers. Instead we want the worm to propagate by itself.

The updateProfilePicture route can be used to spread the worm. We can embed the addFollower payload in a couple of ‘setProfilePicture layers’, so when our followers see our profile picture, their profile picture becomes a smaller version of the worm. 

So we could ‘link’ a bunch of CSRFs together to make something like:



So the first time someone see’s this in an image tag, the CSRF will be executed, and their profile image will be the same URL except one ‘link’ smaller.

Anyone who then see’s this profile picture will then copy the URL and become one link smaller.


After the worm has spread for awhile the very last link in the chain will become the profile picture. So now anytime someone views the profile/feed of that user they will follow xc0nradx.

CSRF_Exploit (1).png

Hopefully by this time the worm has spread to a bunch of users. Now all of our friends and their friends and their friends are helping us get followers. Thanks friends!


The only benefit this worm really gives is a better launching point for your original addFollower.

But it doesn’t abuse HTML at all! It should work fine with CSP and XSS encoding frameworks? You might have to be careful about URL encoding and parsing.

Also the chains will probably unlink really fast. Anytime you view yourself you’ll unlink another chain yourself.

And you don’t need to include the https://twitter.com in each stage. Just use the relative URL, but it’s easier to read with the full hostname. The max length of a URL is ~2000.


We created a worm-able CSRF exploit that carried our original CSRF exploit to a bigger userbase. Fun stuff. Feel free to email/comment if you have any more ideas.

ECB Byte at a Time

ECB Byte at a Time is a fun crypto attack that doesn’t require any math knowledge. Just an understanding of the systems work and how they interact.

Lets imagine you had some session cookie or token that was constructed like:


It’s possible to determine SECRET with only control of INPUT! You won’t be able to determine key though. The value of SECRET depends on the target, but SECRETS are usually secret for a reason.

The actual encryption algorithm doesn’t matter either (in this case AES), as long it’s block based and uses ECB.


Electronic Code Book (ECB) is a mode for block based encryption. Block based encryption algorithms can only take input of a specific size (such as 16 bytes) and output to another specific size.

So if:

  • Your input is < 16 bytes, you have to pad to 16 bytes.
  • If you input is 16 bytes, perfect! proceed to encryption
  • If you input is >16 bytes, you need use the encryption algorithm a couple of times on all the 16 byte blocks.

The mode is how you tie those multiple 16 byte blocks together.

ECB mode is the simplest of the modes, you just take your input that is over 16 bytes and chop it into 16 byte blocks and encrypt each block separately.

For example if we had aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab.


Notice how the first two blocks have the same output because they have the same input (‘a’ * 16).

So if we have two 16 byte blocks with the same input, we’ll get the same output. This is the info leak we’ll be abusing.

The Attack Setup

So how can we use this knowledge to help us?

Lets say we found a website that was generating session cookies based on:


And we have the ability to change USERNAME (as long as it’s not already being used) and get the resulting ciphertext. Our goal is to create a valid token for the pre-existing ‘admin’ user.

ECB Byte At a Time

Lets say we crafted a username with 15 ‘a’s.ecb_1 (1).png

The 16 byte block consist of 15 ‘a’s, and one unknown character from the SECRET.

Now that we know the result of that block, we can iterate through all possible 16 byte blocks starting with 15 ‘a’s. When we find the block that has the same output, we know what the input to that block must have been.


Since the block with the ‘c’ and the unknown secret are equal, we know the first character is ‘c’!

Now we repeat this process with 14 ‘a’s, the ‘c’ from SECRET and the next unknown character. We set our username to aaaaaaaaaaaaa.

ecb_3 (1).png

And then we iterate through all possible blocks that start with aaaaaaaaaaaaaac.

ecb_4 (1).png

Since the block with ‘0’ and the unknown character are equal, we know the next character must be zero. So the secret starts with ‘c0’.

Repeat this process till the entire secret is decoded. In this case the secret was c0nrad.

To generate an admin session, simply set your username to ‘admin’+ ‘c0nrad’ + 5pad. And copy the first block as your session secret.


Using ECB at a time we were able to determine the appended secret.

If you want to write your own solver, here’s a demo server you can exploit. code. An example solution can be found here.



Edit: Correction by reddit/u/oottppxx, mistakenly inserted the ‘c’ manually on letter 2. Use ‘c’ from SECRET.

Playing With Ethereum

I’ve been skirting around Ethereum for awhile. Now and then I see a post about it in hacker news, or people circle jerking over the DAO. But it is pretty confusing. I decided to dive in yesterday and see what you can do with Ethereum. Smart contracts are only starting to make sense now that I’ve been playing with them.

This was my favorite intro article:

This is the online IDE I used:

And I used the Wallet from the main website:


So if I understand it correctly. A bunch of people (miners) setup Ethereum nodes which are just computational machines running all over the world.

Normal people can then issue jobs to these machines and the world can see the results. It cost money (Ether/Gas) to run these jobs.

In my limited understanding there’s three different jobs.

  1. send money (Ether) to someone else, like bitcoin
  2. create smart contracts. These are bundles of codes that are “public” to everyone that can later be interacted with publicly
  3. interact with smart contracts (hey smart contract XXXX, go send 5 eth to this other contract)


To perform any actions, you need Ether. Which was a pain to get. I used coinbase to get some bitcoins, and then used the Shifty widget built into the Ethereum wallet. Probably not the most cost efficient way.


This doc has some real contracts to help get you started. http://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html#a-simple-smart-contract

If you don’t want to read the docs, here’s two simple contracts I created that do nothing important:

contract Stack {

// push(x): add an item on the top
// pop: remove the item at the top
// peek: return the item at the top (without removing it)
// size: return the number of items in the stack
// isEmpty: return whether the stack has no items

  string[] public stack;
  uint  _size;
  address public owner;

  function Stack(uint swag) {
    owner = msg.sender;
    _size = 0;

  function push(string key) public {
    _size += 1;

  function pop() returns (string) {
    string val = stack[_size-1];
    delete stack[_size-1];
    _size -= 1;
    return val;

  function peek() constant returns (string value) {
    return stack[_size-1];

  function size() constant returns (uint) {
      return _size;

  function isEmpty() constant returns (bool) {
      return (_size == 0);

  function die() public {
      if (msg.sender == owner) {

This is simply a stack data structure. Once you send it off to the blockchain, anyone can interact with the contract. My crappy code now exist all over the world!

This is what it looks like to deploy code to the blockchain:


And now I (and others) can call methods on this Stack implementation I just created. Here’s me calling “pop()” on the stack:


And this is all public. Everyone can now inspect the block chain and see that I called pop.

Interacting With Other Contracts

Contracts can also interact with each other. Here’s a simple “guestbook” that takes the address of the previous stack implementation, and allows people to push messages.

I added an admin function to remove the most previous entry off the stack (even though anyone can call the stack directly and call pop(), but you get the idea). You also need to include the code from the other contract so Solidity (the Ethereum programming language), knows how to interact with the remote address.

contract Stack{function Stack(uint256 swag);function die();function push(string key);function peek()constant returns(string value);function isEmpty()constant returns(bool );function owner()constant returns(address );function size()constant returns(uint256 );function pop()returns(string );function stack(uint256 )constant returns(string );}

contract Guestbook {
  address public ownerAddr;
  address public stackAddr;

  function Guestbook(address _stack) {
    ownerAddr = msg.sender;
    stackAddr = _stack;

  function signGuestBook(string message) {
    Stack s = Stack(stackAddr);

  function removeRecentEntry() {
    if (msg.sender == ownerAddr) {
      Stack s = Stack(stackAddr);

  function die() public {
    if (msg.sender == ownerAddr) {
//Previous Stack Contract:
// 0x700de3d287A6857D1653A0A804b838e131AB41E7

After we deploy this code we can call “Sign Guest Book” with the value of “Hawllo Wourld”:

Screen Shot 2016-06-22 at 8.25.21 PM.png

And then once this executes, we can go back to our stack contract, and see that it’s been updated!

Screen Shot 2016-06-22 at 8.25.56 PM.png



The real uses of Ethereum actually do something useful, like provable odds in gambling, fair voting, kick starters with refunds.

Do I think Ethereum has a future? ¯\_(ツ)_/¯ #yolo

BSON and Golang Interfaces

This weekend I decided to implement BSON.


BSON is just a binary representation of JSON with some extra types and traversal speed improvements.

Traversal speed is important for rapidly scanning a group of BSON objects (called Documents) for specific pieces of information.

Lets imagine you had a list of JSON like the following, and you were searching for the information under the key value “secret”.

{ “aaaaaaaaaaaaaa…..aaaaaaaaaaaa”: “world”, “secret”: “IMPORTANT INFO” } { ‘aaaaaa’: 123, “secret”: “more important info”}

A scanner has to linearly read each character one at a time since it doesn’t know when the ‘a’s end. If that list of ‘a’ was 10 megabytes long, we’re going to waste a second or two every time we want to read the value of ‘secret’.

BSON makes this simpler by pre-pending string lengths so if you can jump throughout the Document for much quicker scanning. BSON leaves little clues about the contents of each element so you can jump around without having to scan the entire contents.


BSON is binary JSON with some extra types. The top level object in BSON is a Document. A document is a collection elements. Each element contains three things:

  • The Type Identifier (byte)
  • Element Name (string)
  • Contents (string,date,int,subdocument)

And that’s it!


Normally when I implement something like this, I jump write into implementing the Marshal/Unmarshal code (serialize/deserialize).

This time I decided to take a different approach and instead focus on the types.

I started with the base types, and how they should be represented in BSON.

So types like int32, int64, double, cstring, string.

type Double float64
type Int32 int32
type Int64 int64
type CString string
type String string

And for each newly defined type, I made sure they implemented the BSON interface I created:

type BSON interface {
   ToBSON() []byte
   ToString() string

Once I had all the base types complete, I started implementing the core of BSON, the elements. I also wanted all the elements to implement the BSON interface. This was super simple thanks to the fact that all of the children types were already implementing the BSON interface:

type Element struct {
   Identifier byte
   EName CString
   Data BSON

func (e Element) ToBSON() []byte {
   out := []byte{}
   out = append(out, e.Identifier)
   out = append(out, e.EName.ToBSON()...)
   out = append(out, e.Data.ToBSON()...)
   return out

func (e Element) ToString() string {
    return e.EName.ToString() + ": " + e.Data.ToString()

After that, all I had left to do was define the types that used the Elements, and make sure they also implemented the BSON interface, which was simple since all their children already knew how to represent themselves too.

type Document ElementList
type ElementList []Element

And I was done!

So now I can create new Documents, and just call ToBSON(), and the document asks all it’s children to represent themselves in BSON, which ask their children to represent themselves in BSON.

Closing Remarks

What I really like about this implementation is that now I can use this library (probably for a fuzzer), and have it generate BSON for any type in the entire stack. Every type corresponds to BSON making the library much simpler than only operating on documents.

You can check out the implementation here:


Intro to SameSite Cookies (CSRF Protection)

A pretty common web attack involves hijacking a user’s session to get them to perform actions on your behalf.

An example attack:

Lets say Bob signs into his bank account at bank.com

Untitled drawing (2).png

From now on, whenever Bob interacts with bank.com the browser will send his cookies so that bank.com knows that the request was made by Bob.

Lets say Eve knows that he is logged into bank.com and sends him a message like:

Hey Bob,

Check out this sweet cat picture:

<img src=”https://bank.com/transfer.php?amount=10000&from=bob&t0=eve”&gt;



When Bob loads this message, his browser will make a web request to load the image.  The session cookies will be sent. But it’s not actually in image (the browser doesn’t know this), it’s a bank transfer. A bank transfer will be performed and Bob just lost all his money.

Normally you’d protect against this using csrf tokens, and use a http POST for this state changing request. See here for more information.

SameSite Cookie Flag

A new protection was recently introduced into Chrome that allows servers to instruct clients on when to send session cookies.

The problem in the bank.com CSRF attack is tricky. The browser did the right thing by trying to load the image, and it did the right thing by sending the cookies to bank.com (bank.com told the browser to always send the cookies). But the bank still failed bob. Confused deputy.

SameSite cookie flag is a way for bank.com to protect their users against this attack. When Eve sent bob the message that had the embedded image, did cookies really need to be sent to load an image? Probably not.

Using SameSite, websites can tell clients to only send cookies if the request originated from the same site.

Once you’re on bank.com it makes sense to initiate transfers. But it doesn’t make sense to initiate transfers from gmail.com or any other website. So in the previous attack example, since the transfer didn’t originate on bank.com, Bob will probably see a login page instead of a transaction receipt.

Using SameSite Cookie Flag

To set cookie, simply add the SameSite flag to the cookie like:

Set-Cookie: Session=6fa459ea-ee8a-3ca4-894e-db77e160355e; SameSite=Strict

You can specify how strict you want the SameSite restrictions to be. I’d recommend just using Strict and playing with the website for a bit, specially if you’re using a SPA.

The three options are None, Lax, and Strict. None is what a normal cookie uses. The different between Lax and Strict is mainly whether or not full page loads (like clicking on a link to bank.com) will send the cookies. Lax will send the cookies.

To read more, checkout the RFC draft. Or google it.

Some Thoughts