Showing posts with label IIS. Show all posts
Showing posts with label IIS. Show all posts

Sunday, 27 September 2015

IIS App Pool Credentials Exposed

Last week I was looking at changing the periodic restart for an app pool using the appcmd tool and I found something very interesting. Using this tool can reveal the username and password used for the app pool.

See below:
PS C:\Windows\system32\inetsrv> whoami
dev\crminstall
PS C:\Windows\system32\inetsrv> .\appcmd list apppool /"apppool.name:CRMApppool" -config
<add name="CRMAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Classic">
  <processModel identityType="SpecificUser" userName="dev\crmapppool" password="MyPassword" idleTimeout="1.01:00:00" />
  <recycling>
    <periodicRestart time="1.05:00:00">
      <schedule>
      </schedule>
    </periodicRestart>
  </recycling>
  <failure />
  <cpu />
</add>
The user in question was a local administrator (member of the local Administrators group) and the command was run from PowerShell with elevated permissions.

So you might need to be logged in as an administrator but you should under no circumstances be able to see another user's password. This is a pretty big security hole, IMHO.

I've only tried on Windows 2012 and 2012 R2, but the behaviour seems consistent.

Incidentally, this does not seem to be the first case where credentials are exposed like this, see this post. It's fair to mention that the issue on the link was eventually fixed.

Monday, 10 August 2015

Removing HTTP Headers for an ARR/MS Dynamics CRM/Sharepoint 2013 system

We had a pen test carried out last week and one of the outcomes was that we were leaking information with our HTTP headers and they must be removed.

Our environment consists of a web layer (IIS using ARR) and then an app layer (MS Dynamics CRM and MS SharePoint)

Personally I think this is a bit of security through obscurity but needs must so here we go:

X-AspNet-Version Header:

MS Dynamics CRM 2013

In the web.config, <drive>:Program Files\Microsoft Dynamics CRM\CRMWeb  add enableVersionHeader="false" to the httpRuntime element, normally you'll end up with something like this:

<httpRuntime executionTimeout="300" maxRequestLength="32768" requestValidationMode="3.0" encoderType="Microsoft.Crm.CrmHttpEncoder, Microsoft.Crm" enableVersionHeader="false"/>

MS SharePoint 2013

In the web.config,  <drive>:inetpub\wwwroot\wss\VirtualDirectories\80\ add enableVersionHeader="false" to the httpRuntime element, normally you'll end up with something like this:

<httpRuntime maxRequestLength="51200" requestValidationMode="2.0" enableVersionHeader="False" />

X-Powered-By Header:

From IIS Manager -> Server -> HTTP Response Headers




Server Header:

The simplest way I found is to use URL Rewrite to blank this header, which works very well for our system as we're using ARR already so just need to do this one on the web layer ... from IIS Manager -> Url Rewrite -> Add Rule

Select Blank Outbound Rule


Fill in the details as below

Don't forget to click Apply when you've finished.

It's worth pointing out  that this will simply blank out the value of the Server Header, rather than remove it completely.

If you want to remove it completely you will need to install urlscan.

This approach can be used for all the other headers above I suppose.

X-Powered-By: ARR/2.5 Header

From a powershell console with elevated permissions go to C:\Windows\system32\inetsrv and run this command:

.\appcmd.exe set config -section:webFarms /"[name='serverfarmname'].applicationRequestRouting.protocol.arrResponseHeader:false" /commit:apphost

Tuesday, 10 February 2015

Brain Dump 6 - Allow requests of any length in IIS

The same request from two different browsers to a custom WCF service.

First in Firefox:

http://devbox.dev.com:8732/Mock.svc/Mock/GetPartNumber?data=N^99ac52cd-142b-4b84-8b8e-849e320ee8cc^GetPartNumber^%3Ccontent%3E%3CGetPartNumber%3E%3Cid%3E99ac52cd-142b-4b84-8b8e-849e320ee8cc%3C/id%3E%3CsupplierDetails%3E%3CsupplierNameLine1%3EsupplierNameLine1%3C/supplierNameLine1%3E%3CsupplierNameLine2%3EsupplierNameLine2%3C/supplierNameLine2%3E%3CsupplierAddressLine1%3EsupplierAddressLine1%3C/supplierAddressLine1%3E%3CsupplierAddressLine2%3EsupplierAddressLine2%3C/supplierAddressLine2%3E%3CsupplierAddressLine3%3EsupplierAddressLine3%3C/supplierAddressLine3%3E%3CsupplierAddressLine4%3EsupplierAddressLine4%3C/supplierAddressLine4%3E%3CsupplierTownOrCity%3EsupplierTownOrCity%3C/supplierTownOrCity%3E%3CsupplierCounty%3EsupplierCounty%3C/supplierCounty%3E%3CsupplierCountry%3EsupplierCountry%3C/supplierCountry%3E%3CsupplierPostCode%3EsupplierPostCode%3C/supplierPostCode%3E%3C/supplierDetails%3E%3CcustomerDetails%3E%3CcustomerName%3EcustomerName%3C/customerName%3E%3CaddressLine1%3EaddressLine1%3C/addressLine1%3E%3CaddressLine2%3EaddressLine2%3C/addressLine2%3E%3CaddressLine3%3EaddressLine3%3C/addressLine3%3E%3CaddressLine4%3EaddressLine4%3C/addressLine4%3E%3CtownOrCity%3EtownOrCity%3C/townOrCity%3E%3Ccounty%3Ecounty%3C/county%3E%3Ccountry%3EUnited%20Kingdom%3C/country%3E%3CpostCode%3EpostCode%3C/postCode%3E%3C/customerDetails%3E%3CvatNumber%3EGB12345%3C/vatNumber%3E%3CdocumentNumberPrefix%3ESIA%3C/documentNumberPrefix%3E%3CdocumentNumber%3E1%3C/documentNumber%3E%3CtransactionNumber%3E1%3C/transactionNumber%3E%3CdateDocumentRaised%3E2014-09-19%3C/dateDocumentRaised%3E%3CdescriptionOfItemSold%3EdescriptionOfItemSold%3C/descriptionOfItemSold%3E%3CquantitySold%3E1%3C/quantitySold%3E%3CitemCostNet%3E80.00%3C/itemCostNet%3E%3CtotalNetCostOfItems%3E80.00%3C/totalNetCostOfItems%3E%3CnetTotal%3E80.00%3C/netTotal%3E%3CnetDiscount%3E0.00%3C/netDiscount%3E%3CvatRate%3E25.00%3C/vatRate%3E%3CvatAmount%3E20.00%3C/vatAmount%3E%3CgrossTotal%3E100.00%3C/grossTotal%3E%3CformatDocumentNumber%3ESIA000000001%3C/formatDocumentNumber%3E%3CgenesesData%3E%3CbookingReference%3E79bbec92-5bca-44d2-8e61-bde366a0379b%3C/bookingReference%3E%3C/genesesData%3E%3C/GetPartNumber%3E%3C/content%3E

This is approximately 2193 characters and thus bytes, assuming ascii encoding

An now in IE:

http://devbox.dev.com:8732/Mock.svc/Mock/GetPartNumber?data=N^99ac52cd-142b-4b84-8b8e-849e320ee8cc^GetPartNumber^<content><GetPartNumber><id>99ac52cd-142b-4b84-8b8e-849e320ee8cc</id><supplierDetails><supplierNameLine1>supplierNameLine1</supplierNameLine1><supplierNameLine2>supplierNameLine2</supplierNameLine2><supplierAddressLine1>supplierAddressLine1</supplierAddressLine1><supplierAddressLine2>supplierAddressLine2</supplierAddressLine2><supplierAddressLine3>supplierAddressLine3</supplierAddressLine3><supplierAddressLine4>supplierAddressLine4</supplierAddressLine4><supplierTownOrCity>supplierTownOrCity</supplierTownOrCity><supplierCounty>supplierCounty</supplierCounty><supplierCountry>supplierCountry</supplierCountry><supplierPostCode>supplierPostCode</supplierPostCode></supplierDetails><customerDetails><customerName>customerName</customerName><addressLine1>addressLine1</addressLine1><addressLine2>addressLine2</addressLine2><addressLine3>addressLine3</addressLine3><addressLine4>addressLine4</addressLine4><townOrCity>townOrCity</townOrCity><county>county</county><country>United Kingdom</country><postCode>postCode</postCode></customerDetails><vatNumber>GB12345</vatNumber><documentNumberPrefix>SIA</documentNumberPrefix><documentNumber>1</documentNumber><transactionNumber>1</transactionNumber><dateDocumentRaised>2014-09-19</dateDocumentRaised><descriptionOfItemSold>descriptionOfItemSold</descriptionOfItemSold><quantitySold>1</quantitySold><itemCostNet>80.00</itemCostNet><totalNetCostOfItems>80.00</totalNetCostOfItems><netTotal>80.00</netTotal><netDiscount>0.00</netDiscount><vatRate>25.00</vatRate><vatAmount>20.00</vatAmount><grossTotal>100.00</grossTotal><formatDocumentNumber>SIA000000001</formatDocumentNumber><genesesData><bookingReference>79bbec92-5bca-44d2-8e61-bde366a0379b</bookingReference></genesesData></GetPartNumber></content>

This is approximately 1863 characters and thus bytes, assuming ascii encoding

This means that the first request makes IIS choke and the second one works fine, as it's below the 2 KB limit

There is a relatively simple solution. Modify the web.config of the WCF service, where length is the number of bytes:

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxQueryString="length"/>
    </requestFiltering>
  </security>
</system.webServer>