9

the way of storing cookie for SAFARI has changed whith SAFARI 5.1 and that they add a kind of integrity control code in the last 8 bytes of the file :

The file is %APPDATA%\Apple Computer\Safari\Cookies\Cookies.binarycookies

Does anybody know what s the last 8 bytes corresponds to ?

CRC32 check ?

Please help

stracktracer
  • 1,862
  • 5
  • 24
  • 37
user382591
  • 1,320
  • 5
  • 19
  • 39
  • Do you know any other details about the structure of this binary format? Seems to have a kind of header with length information, then the contents and some flags. – stracktracer Sep 25 '11 at 14:22
  • yes there are length information, then the cookies and at least 8 bytes with a kind of controle code. I hope that someone know what they are... – user382591 Sep 25 '11 at 14:30
  • Do you have any detailed specs about that format except the presumed checksum, or did you just reverse engineer? On my computer, the last four bytes are always 07 17 20 05 (HEX), it seems regardless of the number and type of cookies in the file. The bytes before seem to belong to the last cookie entry. – stracktracer Sep 25 '11 at 14:51
  • So where's the integrity control? – stracktracer Sep 25 '11 at 15:00
  • My last 4 bytes are also 07 17 20 05 in HEX. I've just reverse engineered the file and noticed that if you delete a cookie with Safari, the 2 bytes before 07 17 20 05 change. Close Safari, then if you change a simple bit in a cookie URL in that file and launch Safari again, it says that is corrupted...So that I presumed it was a kind of control code, but maybe I m wrong. Any idea ? – user382591 Sep 25 '11 at 15:13
  • These 2 bytes dont belong to a cookie, their purpose is anything else, like a control code – user382591 Sep 25 '11 at 15:15
  • Right, looks as if these two bytes are the integrity check. Maybe we can figure it out. Some examples of values I found: 1A 0C, FD EE, 3B BE, 1B 2D. Do they have something in common? The empty cookies file does not have this checksum. As you say, changing one bit already lets Safari recognize that the file is modified, so every byte (maybe except the introducing header 636F6F6B and the cookie counter in the next four bytes) must be included in the calculation. How would I implement such a chek? Maybe sum all the bytes and use the two rightmost of the sum. Or modulo another number? – stracktracer Sep 25 '11 at 16:23
  • Well I hope someone can find how they are generated – user382591 Sep 25 '11 at 20:50
  • Offering a bounty for complete specs of the Safari 5.1 cookie format. – stracktracer Sep 27 '11 at 14:26
  • 4
    simply viewing the cookie file in a HEX editor is not called reverse engineering. You are doing only the research part. When you get the exact algorithm that creates the cookie in the same way as Safari does, then its called reverse engineering. – mahen23 Oct 04 '11 at 07:36

5 Answers5

18

Cookie.binarycookies:

I think this will be helpful. I reversed engineer the file with an hex-editor and start changing the cookies.

General description:

The file is composed of several pages, each one can have one or more cookies inside. Each page has a header, which is variable, 0x10, 0x14 and 0x1c are common values we can see.

File:

The file start with an 4 bytes header that is of no interest.

The next 4 bytes are of real interest because they indicate the number of pages there are in the file.

Then we have the length of each page, also represented by an 4 byte number. It's important to know that all these numbers are written in big-endian. So, we have 4*number of pages of bytes and then the pages.

We have 8 bytes at the end which also are of no interest.

Page:

Each page has a header whose length can change from one page to another. To know the length of the header, we must discard the first five bytes and the next 4 bytes will indicate the length of the header.

Following the header we will have the length of the cookie represented by 4 bytes, ordered in little-endian! This length also includes the 4 bytes needed for representing the length.

When this cookie ends another will start and so on to the end of the page.

Cookie:

The date of each cookies starts at 0x2B. The date is composed by 4 bytes ordered in little-endian. The date is represented in seconds but not since epoch so we need to subtract this number: 1706047360. (It only works for until some day in 2017)

The next field of interest starts from 0x38. This fields are dynamic fields so they are separated by an NULL “0x00” byte and are in this order: name, value, url, path.

Example:

http://i52.tinypic.com/2qcqix2.jpg

The length of the entire cookie will be 0x82. Next to this cookie will start another one in exactly the same format if corresponds with the page length.

lambshaanxy
  • 22,552
  • 10
  • 68
  • 92
AGG88
  • 196
  • 4
  • Sorry to post like that the image, but as i'm a new user with less than 10 points of reputation i can't upload images! – AGG88 Oct 19 '11 at 05:08
  • Ok thanks. What are the last 8 bytes at the end of the file ? – user382591 Oct 20 '11 at 05:10
  • they are of interest because if you just change them and restart Safari. It will complain about integrity. That s the question. – user382591 Oct 20 '11 at 05:13
  • Thanks, this is about what I reverse engineered, however info about the "checksum" in the footer is missing... – stracktracer Nov 21 '11 at 15:54
  • 1
    Oh my... big endian, page size, record size, unused bytes? Isn't that like the variable record length format as used by mainframes? – Leonardo Herrera Jan 17 '12 at 15:20
  • 2
    FYI, the following blog post describes this format description as "helpful but wrong", and goes on to provide a detailed alternative: http://it.toolbox.com/blogs/locutus/understanding-the-safari-cookiesbinarycookies-file-format-49980 – lambshaanxy Jan 18 '12 at 05:57
3

This isn't going to answer your question exactly, but hopefully it gets to the heart of what you're trying to do.

You can read the contents of the binary cookie file located at ~/Library/Cookies/Cookies.binarycookies using the NSHTTPCookieStorage class, as shown in the following snippet:

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *c in [cookieStorage cookies])
{
    NSLog(@"%@", c);
}
pwc
  • 7,043
  • 3
  • 29
  • 32
  • Could this be used in Windows, too? – stracktracer Oct 05 '11 at 06:34
  • 1
    Nice one! I created a simple command line tool which exports the cookies from Cookies.binarycookies into cookies.txt format. You can find it here: https://github.com/talkative/exportCookies (binary is available in downloads) – iceydee Oct 05 '11 at 07:19
3

I've written a MacRuby script to do what you're looking for:

https://gist.github.com/1385008

#!/usr/bin/env macruby
require 'csv'
framework 'Foundation'

CSV_Headers = %w[domain path expiresDate name value].to_csv

class NSHTTPCookie
  def to_csv
    [domain, path, expiresDate, name, value].to_csv
  end
end

store   = NSHTTPCookieStorage.sharedHTTPCookieStorage
cookies = store.cookies
raw_csv = cookies.map(&:to_csv)

puts CSV_Headers
puts raw_csv.join

You need to install MacRuby, but then this will print out your cookies in a CSV format. It can easily be made to be cookies.txt compatible, as well.

Conrad Frix
  • 51,984
  • 12
  • 96
  • 155
sgonyea
  • 31
  • 2
  • 1
    Welcome to Stackoverflow. Its probably better to make sure that answers can stand on there own. So I added the code from your linked answer. – Conrad Frix Nov 22 '11 at 06:25
  • I need to understand what the last 8 bytes of %APPDATA%\Apple Computer\Safari\Cookies\Cookies.binarycookies are... – user382591 Nov 29 '11 at 11:27
1

I wrote a parser for Swift that can do this for you. I needed this because NSHTTPCookieStorage.sharedHTTPCookieStorage() doesn't give you access to the global cookies when sandboxed.

https://github.com/icodeforlove/BinaryCookies.swift

You can use it like this

BinaryCookies.parse(NSHomeDirectory() + "/Library/Cookies/Cookies.binarycookies", callback: {
    (error:BinaryCookiesError?, cookies) in

    if let cookies = cookies {
        print(cookies);
    } else {
        print(error);
    }
});

Currently there are a few projects that can do this in other languages as well:

Chad Cache
  • 9,668
  • 3
  • 56
  • 48
1

I just got a list of urls from: $ strings Cookies.binarycookies | grep '^A\.' | uniq

BillyBuggy
  • 51
  • 2