Find and Replace Default HTML in IIS Windows - Ansible

In this post we are going to see how to handle the Default webpage vulnerability in IIS with Ansible.

The Default WebPage Vulnerability is flagged by Security Analysts and Pen testers cause it can reveal that the server is powered by IIS and it would let the hacker to try various other attempts

IIS default page

So it is always advised to not keep the default page in any webserver you take. Let it be Apache/IIS/nginx

Having the default page in the IIS web server also mean that server may be not be in use.

So there are few ways to handle this vulnerability.

  • Disable the Default page
    • Steps to disable default page:
      1. Open IIS Manager
      2. Click the server name
      3. Double click on Default Document
      4. On the right side, click “Disable”
  • Stop the server if it is not in use.
  • Update or Replace your default HTML file

We are going to see the third solution here to change the default HTML file with our content.

By doing this. you can have your IIS web server running but the default page would no longer reveal that the server is IIS.

 Be informed that this playbook consider only the Default web site on the IIS. not other websites hosted. but you can tweak this playbook to suit your needs

List of tasks in this playbook

Here is the ansible playbook that performs the following tasks

  1. Get the physical path of the default website ( it is not always c:/inetpub )
  2. Check if that directory / physical path is present
  3. Get the list of files inside the document root/physical path
  4. Get the default document configuration of your IIS default site. ( index.html, index.htm etc etc)
  5. Find out which default document is actually present on the physical path
  6. Hit the URL to validate the old page content ( the default iis page)
  7. using win_template copy the custom HTML file from local to remote windows server and replace the default HTML
  8. Hit the URL to revalidate that the default document is not returned

Ansible playbook to replace a default HTML in IIS

we have already listed out the list of tasks this playbook is going to be doing.

So we are not going to go any deeper to explain it. but if you have any questions please reach us at comment section

with no further ado, here is the playbook.

- name: Windows Tasks
  hosts: win
    - name:  Get the Default website path
      win_shell: |
        Import-Module WebAdministration
        (Get-Item 'iis:\sites\Default Web Site').physicalpath 
      register: shellout

    - set_fact: 
        docroot: "{{ shellout.stdout | trim | regex_replace('%SystemDrive%', ansible_env.SystemDrive) }}"

    - name: Check if directory present
        path: "{{docroot}}"
      register: file
    - name: Fail if the directory is not present 
        msg: "{{docroot}} directory is not present - Stopping the execution"
      when: file.stat.exists == 'false'

    - name:  Get the files inside the docroot
      win_shell: |
        Get-ChildItem {{docroot}} -File
      register: listoffiles

    - set_fact: 
        filenames: "{{listoffiles.stdout_lines | trim }}"

    - name: Get the list of Default Documents configured on IIS Site
      win_shell: |
        Get-WebConfiguration -Filter "system.webserver/defaultdocument/files/*" -PSPath "IIS:\sites\Default Web Site"|foreach {$_.value} 
      register: defaultdocs

    - name: Trying to find out which default document is present on the Docroot
        path: "{{docroot}}/{{item}}"
      register: defdoc
      with_items: "{{defaultdocs.stdout_lines}}"

    - name: Hitting the Local URL
        return_content: true
        url: http://localhost
        method: GET
      register: httpoutputbefore

    - name: Before removing/renaming the file site output
        msg: |
          – ---------------------------------------------
          AFTER: HTML Response from http://localhost 
          – ---------------------------------------------
          – ---------------------------------------------
        msg: "{{ msg.split('\n') }}"

    - name: Copy the file from local to the remote and replace the file 
        - filename: "{{ defdoc.results | selectattr('stat.exists','==','true') | map(attribute='stat.filename') | first }}"
        # In oldversions of Ansible the JINJA SelectAttr method does not work properly in such case comment the previous line and uncomment next line
        #- filename: "{{ defdoc.results | json_query('[?stat.exists==`true`]' }}"
        src: 'test.html'
        dest: '{{docroot}}/{{filename}}'
        backup: yes

    - name: Hitting the Local URL
        return_content: true
        url: http://localhost
        method: GET
      register: httpoutputafter
      ignore_errors: True
    - name: After removing/renaming the file site output
        msg: |
          – ---------------------------------------------
          AFTER: HTML Response from http://localhost 
          – ---------------------------------------------
          – ---------------------------------------------
        msg: "{{ msg.split('\n') }}"
      when: httpoutputafter.content is defined




Besides the primary objective of replacing the default html file of the default website on IIS with Ansible.

we also have covered few interesting ansible sub topics in this same playbook. take a look once again if you have missed it

  • Windows Win_Shell module example
  • How to validate if directory is present or not with win_stat
  • How to list a directory with win_shell
  • Use win_uri to access the web page
  • How to Customize the ansible msg with formatting

Hope this helps.

For any Ansible, DevSecOps, Cloud related professional support and projects reach out to us at Gritfy

Sarav AK

Follow me on Linkedin My Profile
Follow DevopsJunction onFacebook orTwitter
For more practical videos and tutorials. Subscribe to our channel

Buy Me a Coffee at

Signup for Exclusive "Subscriber-only" Content