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

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:
- Open IIS Manager
- Click the server name
- Double click on Default Document
- On the right side, click “Disable”
- Steps to disable default page:
- 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 siteon 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
- Get the physical path of the default website ( it is not always c:/inetpub )
- Check if that directory / physical path is present
- Get the list of files inside the document root/physical path
- Get the default document configuration of your IIS default site. ( index.html, index.htm etc etc)
- Find out which default document is actually present on the physical path
- Hit the URL to validate the old page content ( the default iis page)
- using win_template copy the custom HTML file from local to remote windows server and replace the default HTML
- 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
tasks:
- 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
win_stat:
path: "{{docroot}}"
register: file
- name: Fail if the directory is not present
fail:
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
win_stat:
path: "{{docroot}}/{{item}}"
register: defdoc
with_items: "{{defaultdocs.stdout_lines}}"
- name: Hitting the Local URL
win_uri:
return_content: true
url: http://localhost
method: GET
register: httpoutputbefore
- name: Before removing/renaming the file site output
vars:
msg: |
– ---------------------------------------------
AFTER: HTML Response from http://localhost
– ---------------------------------------------
{{httpoutputbefore.content}}
– ---------------------------------------------
debug:
msg: "{{ msg.split('\n') }}"
- name: Copy the file from local to the remote and replace the file
vars:
- 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`]' }}"
win_template:
src: 'test.html'
dest: '{{docroot}}/{{filename}}'
backup: yes
- name: Hitting the Local URL
win_uri:
return_content: true
url: http://localhost
method: GET
register: httpoutputafter
ignore_errors: True
- name: After removing/renaming the file site output
vars:
msg: |
– ---------------------------------------------
AFTER: HTML Response from http://localhost
– ---------------------------------------------
{{httpoutputafter.content}}
– ---------------------------------------------
debug:
msg: "{{ msg.split('\n') }}"
when: httpoutputafter.content is defined
Conclusion.
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_Shellmodule example - How to validate if directory is present or not with
win_stat - How to list a directory with
win_shell - Use
win_urito 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
Cheers
Sarav AK
Follow me on Linkedin My Profile Follow DevopsJunction onFacebook orTwitter For more practical videos and tutorials. Subscribe to our channel
Signup for Exclusive "Subscriber-only" Content




