Can you share some of your experiences about the hackers?
Be happy to. Caveat: I have been retired the past 4 years so I've been out of touch a bit and I don't know what the current threat landscape is. Memory might be a little fuzzy too.
This is somewhat of an opinion, but I wouldn't mess around with Apache or trying to hide that you're running IIS. The hackers don't care if your site reports that it's IIS or Apache or CICS/COBOL. They're gong to throw every known exploit at you.
The biggest problem that we had was SQL injections. Some of our sites were ASP based and were particularly vulnerable. I implemented UrlScan to block certain requests. Later IIS versions have request filtering instead of urlscan.
https://blogs.iis.net/peterviola/blocking-sql-injection-with-iis-request-filtering
I wrote a VB script (circa 2002) to analyze the query strings in the IIS logs. What I noticed was that hacking requests usually contained 3 or more encoded spaces, "%20". They also had parens and brackets, "(" and "[". The script flagged these requests for me to analyze because sometimes they were legitimate requests. I also looked for ".exe" and ".dll" in the request.
I also see that at one point in time I was looking at these sequences. These came from UrlScan.
https://forums.iis.net/t/1165537.aspx
' .. ; Don't allow directory traversals
' ./ ; Don't allow trailing dot on a directory name
' \ ; Don't allow backslashes in URL
' : ; Don't allow alternate stream access
' % ; Don't allow escaping after normalization
' & ; Don't allow multiple CGI processes to run on a single request
I dug into my archives and here are the strings that I parsed out of my logs for UrlScan. Some might be redundant and as I mentioned earlier, memory might be a bit fuzzy here. You would need to do your own analysis on your logs to see what the current injection strings are.
%20and%20char(124)%2buser%2bchar(124)
%20as%20varchar(
%20as%20nvarchar
(select%20top%20
%20and%20db_name()
%20and%20%28db_name%28
%20from%20sysobjects%20where%20
%20varbinary(
%20cast(is_srvrolemember
%20table_name%20from%20information_schema.tables
(select%20top%201%20convert
select%20*%20from%20sysobjects)
cast(0x4400450043004c004100520045
cast(0x4445434c415245204054207661
%20and%20user%3e0%20and%20
)%2buser%2bchar(
%20from%20tbluser
%20cursor%20for%20select%20
%20from%20information_schema.columns%20
%20and%20user%2bchar(
)%2bdb_name()%2bchar(
%20and%20(select%20len
%20and%20len(db_name(
%20and%20unicode(substring
%20is_srvrolemember('sysadmin'
%20and%20'1'='1
%20and%20exists%20(select%20*%20from%20
select%20top%209%20userid%20from%20
=convert(int,(select%20top%20
%20and%20exists%20(select%20"
One final item was to look at any IP's that had high activity. We would block the IP's where the activity looked suspicious. As we moved sites to Akamai and behind content switches that kinda diminished in value. And the hackers would just move to different networks too. Still, it's something that you want to keep an eye on. The LogParser tool is great for that kind of analysis.
Wish I could help you more with request filtering but I left UrlScan in place and then with changes in my "work situation" I no longer cared if those folks got hacked or not.