Task Scheduler error “The user account is unknown, the password is incorrect

Windows Scheduled Task Errors

I have an website up-time script that I need to deploy in a test environment.
The script has to be run as a scheduled task in Windows Task Scheduler and is designed to be run on a 15 minute interval.

I couldn’t seem to be able to set a scheduled task if my life depended on it because something was killing it every time I would try to create it. 

The error I got was something like…

Task Scheduler – The user account is unknown, the password is incorrect, or the user account does not have permission to modify the task”

After 30 minutes of scouring the various blogs and tech boards, I had found one little hint that pointed my in the right direction.

Check Your Antivirus Software

One  post, that had not even gotten a vote up stated that I should check my Antivirus to see if it was restricting writing of files to the System32 directory in Windows.

Sure enough, I temporarily disabled Avast Antivirus which had been blocking the creation of the scheduled task and now my Uptime script is working as designed.

The morale of the story is always remember to check your Antivirus settings when you run out of checking permission settings as a troubleshooting step.  

Hope this helps somebody!
~Cyber Abyss

HTTP 302 Redirects Instead of 404 Page Not Found Error in IIS URL Rewrite

SEO: Google Web Master Report Showing Multiple 302 Redirects Instead of 404 Page Not Found Error with IIS URL Rewrite and Web.Config File Fix

While reviewing my Google Web Master Reports, I came across an odd error.

When a 404, Page Not Found, error should be showing for a page that has since been deleted, multiple 302s are generated and Google errors out with something like Err too many redirects.

The root cause was a reconfiguration in Microsoft IIS.

I have a custom 404 error page configuration that references the execution of a customer 404 page for a better customer experience.

Below is what the configuration looks like in IIS. It is set to execute a custom 404.asp page instead of the standard 404.htm page included with IIS.

Let’s zoom out and see that there is another error setting.

If we click to edit the “Error” feature setting, we will see another we are editing the custom 404 setting.

This is the correct setting that solved the issue!  Scroll down to see the wrong configuration.

This is the wrong or bad or incorrect configuration that caused me some grief.

Hope this helps somebody!


Catching Bad Guys using Web Server Logs & HTTP 404 Errors!

What is a HTTP 404 Error?

Hypertext Transport Protocol (HTTP) is the layer that webpage data is transmitted to your web browser that renders it on your computer screen.

OSI Presentation Layer
HTTP is on the OSI Presentation Layer

On the OSI model, HTTP is on the Presentation Layer.

HTTP also works on the client server model. The client, your web browser, requests a file from a web server via a URL. This page has a URL that brought you here.

If logging is enabled on your web server you will have a record of all HTTP requests to review. Try here is you need help configuring logging on IIS Server.

If a clients HTTP request was successful, the server returns the data and a “200” code that means OK.

If a clients HTTP request fails because the file you requested is missing, the server sends back a HTTP 404 error meaning “Not Found”.

Hackers, Recon and the HTTP 404 Error!

404 NOT FOUND pages in your web server logs are often the earliest signs of surveillance, foot printing or reconnaissance.

I guarantee you that unless your attacker has inside knowledge of the target, any recon attempts using HTTP will most likely be generating some 404 errors. You can’t avoid it as it is a byproduct of the enumeration process.

Video: Enumeration by HackerSploit

Early Recon Detection

Early recon detection along with early blocking actions can be a game changer in the never ending game of digital tag where you really don’t want to be it.

If you you’re doing this for a living and take the topic more seriously, I would use the word, countersurveillance, to describe what we need. Who is coming at us, where are they coming from and how can we mitigate risk?

Log Files & Free Analysis Tools

For this example I’m going to focus on Microsoft IIS web server logs as that is what I have handy.

Notice the naming of the log files in the screenshot below. They contain the start date of each log. Example: u_ex220916.log.

In this example, the logs are created, one per day. The server can be configured to make the logs run for a week or even for a month. I prefer smaller files.

NotePad++ for Reviewing Log Files

Most of the time I just use Notepad++ to review logs file on a daily or weekly basis. Notepad++ does a great job of searching all open files.

All I do is run a search across all open files for ” 404 “. Make sure to leave a space character on each side for this to work correctly.

Open multiple files at one time using Notepad++

CTRL+F to Find our 404’s

With Notepad++ opening all of our files, we’ll user CTRL+F to open the Find dialog window. Type in ” 404 ”

Actual Recon 404 Errors from IIS Log

Actual IIS Log with HTTP 404 errors showing recon event identified

Where are the 404s?

Most of the log entries are very long and difficult to display online.

This 2nd screenshot shows where the actual 404 error is on each line in the server log. It is towards the end of each line.

Log Parser 2.2

Log Parser 2.2 is what I use for parsing larger amounts of log IIS log files. Log Parser lets you use SQL like commands to query the data which can be output to CSV files. Download Log Parser 2.2 here.

I’ll be coming back to add some log parser query examples as soon as I can get them from my work notes.

C:\temp\logs\logparser "select * from u_ex180131.log" -o:datagrid

After running this command log parser will open with your log data. You can copy it out to excel where you can do your analysis.

Also, I came across this page for a freeware OLEDB extension that says you can use it to query any OLEDB datasource which log parser doesn’t support natively.


Video: How to Use Log Parser 2.2

Countersurveillance and SiteSpy

Now that I’ve covered how to find recon attempts in a log file using Notepad++ and Log Parser, I’ll share my personal “Ace in the hole”, SiteSpy.

SiteSpy is an application monitor I originally developed back in 2002 by accident when I was teaching web programming at Modesto Institute of Technology (MIT).

SiteSpy takes advantage of some existing Microsoft technologies, by running a monitor in the same memory space as the web application.

SiteSpy sniffs out the session connections in real-time and displays them in a webpage that is refreshed frequently. Items of interest bubble up to the top for review. Bot traffic can be filtered to increase recon sensitivity. It works well but is not 100% effective.

SiteSpy Recon Detection Example

This is a probing event I caught was using the IP, bypassing DNS while probing for non-existent file called “/admin/config.php” all the way from Ramallah Palestine. 

SiteSpy showed me a hit on the 404 page after they got the initial 404 error. Otherwise, I would not had seen it until much later. I was able to update the firewall within minutes, denying them time and space to do more recon or an actual attack from that IP range for now.

In Conclusion

You don’t need a lot of fancy Cybersecurity tools to do a little blue teaming. Just Notepad++ and the desire to learn.

The most important thing when reviewing a web application’s log files is to first know the application and all possible URL patterns.

Once you have established normal patterns, you can more easily find things that seem out of place.

Hope this helps someone!

Cyber Abyss

Classic ASP Sleep Function or How to Delay a HTTP Response in Classic ASP – Explanation & Alternative Solutions

Is There a Sleep Method in Classic ASP?

First, and sorry, there is no built in sleep method in classic ASP. Probably for good reason though. Keep reading for background on why and I’ll offer some possible alternatives.

VBScript Sleep Function Code Example

Normally, when I think of a sleep function, I think of the built-in VBScript Sleep Function where we can set a delay in seconds to pause some code in a function.

WScript.Echo("5 seconds have passed.")

What is Classic ASP?

Classic ASP is VBScript interpreted rather than compiled on the IIS web server then converted into 100% HTML before it is delivered to the client / web browser in a HTTP call.

I’ll emphasize, with Classic ASP, the client never sees the underlying VBScript, only rendered HTML.

The Refresh Meta Tag / Wait vs. Sleep

An alterative to “Sleep” might be delay or wait. We can use the Meta Tag, “Refresh”, if you just need a web page to wait for a number of seconds before refreshing which includes redirecting the page on refresh to another URL.

You would include the meta refresh tag inside the web page’s head tags as shown in the code example below.

Meta Refresh Tag Example Code

        <title>Meta Tag Refresh Example</title>
        <meta http-equiv="refresh" content="5"; url="Test.html" />  

Custom ASP Sleep Function Alternative

As a prerequisite, I can’t imagine why you would want to delay a Classic ASP page from being served to a user’s web browser for 10 seconds. That’s a long time to make a user wait but you can do anything with code.

I will warn you, if you cause the HTTP Response to delay for a User Agent like Google bot, Google will probably exclude your website from their search indexes so I typically would not do this in practice on a website that needed any kind of Search Engine Optimization (SEO) friendliness.

DIY Classic ASP Sleep Function?

With Classic ASP, since we don’t have a native sleep or delay method, we can just build our own. By default, I’m going to stay with a delay of specific number of seconds as our end goal.

I’m sure we can come up with a few ways to solve for this but this solution is mine.

Building the Sleep Function from Scratch

  • We will set some variables for a start time and a current time.
  • Then start a While Loop that watches for # of seconds we’ve chosen.
  • We update the current time at each iteration of the loop and check it at start of each loop iteration.
  • Once current time increments by 10 seconds, loop completes giving you a delay of specified seconds.

Classic ASP Sleep Function Code

Sub Delay(intSeconds)
	StartTime = Now()
	CurrentTime = Now()
	While DateDiff("s",StartTime,CurrentTime) < intSeconds
		CurrentTime = Now()
End Sub

call Delay(10)
Response.Write("Something 10 seconds later")

Another reason I would not recommend this approach is that we are tying up the CPU while running this loop waiting for the time to change. Making this more of a weapon than a tool.

From a bad guy perspective, if you could get this code loaded and running on multiple pages with lots of traffic you could really degrade the performance of the server.

I hope this helps you if you were looking for a simple Classic ASP HTTP Response delay function but be careful how you use it.

Hope this helps you in your search for a VBScript Sleep Function.

~Cyber Abyss

VBScript: Zip & Organize Files by Year / Month

Organizing large amounts of files can be a real pain in the ass! If you’ve ever had the need to organize large numbers of files then you probably had a script or really wish your had a script to do this incredibly boring and monotonous task.

I had just such a task in my role as a site reliability engineer for a set of load balanced IIS web servers a couple of years ago. I needed to archive the IIS web server log files by server / year / month.

The VBScript I’m sharing with you in this article, archives two kinds of files for the example. In this example they live in the same folder but most likely in the real world they won’t so adjust the script to your needs. I just show you two ways to parse the date out of files named differently.

  1. IIS Log File
  2. Custom CSV Log File

This example does not delete the original file after a copy has been moved to the zip folder. You can add that later or just manually delete all the files after they are all moved to zipped files.

From the example you should be able to figure out to implement this in your own use case. Good luck!

Organizing Files Using VBScript

This is one of my favorite VBScripts even though I did not write all of it myself. I’ve left credit in the comments for the zip file code I borrowed and implemented in this solution.

VBScript Code

'File System Object Prep
Const ForReading = 1
Const ForWriting = 2

sFolder = InputBox("Enter log folder path:","Select a Log Folder to Compress","C:\inetpub\logs\LogFiles\W3SVC3")
Set oFSO = CreateObject("Scripting.FileSystemObject")

For Each oFile In oFSO.GetFolder(sFolder).Files

	on error resume next
	'Breakdown file name
    strFileType = Right(oFile.Name,3)

	if strFileType = "csv" then
		strTemp = Replace(Mid(oFile.Name,20,Len(oFile.Name)-4),".csv","")
		arrDate = Split(strTemp,"_")
		iYear = Left(arrDate(0),2)
		iMonth = arrDate(1)
		if Len(iMonth) < 2 then
			iMonth = "0" & iMonth
		end if
		CheckValue = arrDate(1)
		CurrentMonth = Mid(DatePart("yyyy", Now()),3,2) & DatePart("m", Now())

        if iYear & iMonth = CurrentMonth and (strFileType = "log" OR strFileType = "csv")	then
            'Do not process current month file, only archive previous months
             'msgbox("Skipping " & sFolder & "\" & oFile.Name)
            WindowsZip sFolder & "\" & oFile.Name, sFolder & "\" & iYear & iMonth & ".zip"
		end if
	end if
    if strFileType = "log" then	
		iYear = Mid(oFile.Name,5,2)
		iMonth = Mid(oFile.Name, 7,2)
		CheckValue = iYear & iMonth
		CurrentMonth = Mid(DatePart("yyyy", Now()),3,2) & DatePart("m", Now())

        if iYear & iMonth = CurrentMonth and (strFileType = "log" OR strFileType = "csv")	then
            'Do not process current month file, only archive previous months
            'msgbox("Skipping " & sFolder & "\" & oFile.Name)
            WindowsZip sFolder & "\" & oFile.Name, sFolder & "\" & iYear & iMonth & ".zip"
        end if
	end if


Function WindowsUnZip(sUnzipFileName, sUnzipDestination)
 'This script is provided under the Creative Commons license located
  'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not
  'be used for commercial purposes with out the expressed written consent
  'of NateRice.com

  Set oUnzipFSO = CreateObject("Scripting.FileSystemObject")
  If Not oUnzipFSO.FolderExists(sUnzipDestination) Then
  End If

  With CreateObject("Shell.Application")
       .NameSpace(sUnzipDestination).Copyhere .NameSpace(sUnzipFileName).Items
  End With

  Set oUnzipFSO = Nothing
End Function

'To Test Windows Zip Function Separately 
'WindowsZip "C:\test\test2.txt","C:\test\test.zip"

Function WindowsZip(sFile, sZipFile)
  'This script is provided under the Creative Commons license located
  'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not
  'be used for commercial purposes with out the expressed written consent
  'of NateRice.com

  Set oZipShell = CreateObject("WScript.Shell") 
  Set oZipFSO = CreateObject("Scripting.FileSystemObject")

  If Not oZipFSO.FileExists(sZipFile) Then
  End If

  Set oZipApp = CreateObject("Shell.Application")
  sZipFileCount = oZipApp.NameSpace(sZipFile).items.Count
  aFileName = Split(sFile, "\")
  sFileName = (aFileName(Ubound(aFileName)))

  sDupe = False

  For Each sFileNameInZip In oZipApp.NameSpace(sZipFile).items
    If LCase(sFileName) = LCase(sFileNameInZip) Then
      sDupe = True
      Exit For
    End If
  If Not sDupe Then
    oZipApp.NameSpace(sZipFile).Copyhere sFile
    'Keep script waiting until Compressing is done
    On Error Resume Next
    sLoop = 0
    Do Until sZipFileCount < oZipApp.NameSpace(sZipFile).Items.Count
      sLoop = sLoop + 1
    On Error GoTo 0
  End If
End Function

Sub NewZip(sNewZip)
  'This script is provided under the Creative Commons license located
  'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not
  'be used for commercial purposes with out the expressed written consent
  'of NateRice.com

  Set oNewZipFSO = CreateObject("Scripting.FileSystemObject")
  Set oNewZipFile = oNewZipFSO.CreateTextFile(sNewZip)

  oNewZipFile.Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0)

  Set oNewZipFSO = Nothing
End Sub

How to Transfer Files from Windows PC to Linux Server Using Putty’s PSCP Command

Many blogs and web applications are being hosted on cloud based web servers. Of those web servers, many are running some flavor of the Linux operating system (OS).

If you’re a Windows PC user who is using a Linux web server for your online project then you have unique challenge that comes with being a dual OS user.

How will we transfer our files from our Windows development PC to our Linux cloud hosted blog or web app? Enter Putty and the PSCP command line tool!

What is Putty?

Putty is a Client application that handles connections to remote computers via the Telnet, SFTP and SSH protocols.

Putty Screenshot

What is PSCP?

PSCP is a command line application that is typically included in the Putty installation. PSCP transfers files between two computers from the Windows command line as long as firewalls allow the traffic on the designated ports for each type of traffic.

Transferring Files with PSCP from the Command Line

If you’ve installed Putty in the default directory, it will be here.

C:\Program Files\PuTTY

Open a Windows command line by clicking on the Windows start menu icon then entering “cmd” in the search field then find and click on the cmd icon.

Navigate to the Putty Directory by entering the command below.

C:\>CD c:\Program Files\Putty

Let’s look at an example PSCP command to transfer a file from a Windows PC to a Linux cloud web server with a fake user named root, IP of and a target folder of /var/www/html

PSCP Copy Files from Windows PC to Linux Web Server Example

PSCP Command Line Example:

c:\>C:\Program Files\Putty\pscp c:\temp\sample.txt root@

Copying Files from Linux Web Server to Window PC

C:\Program Files\PuTTY>pscp root@* c:\temp
 >root@'s password: [Enter Your Password]

That’s all you should need to know about connecting to a Linux cloud based web server from a Windows PC using the Putty SSH client.

Hope this helps you on your Cyber journey!

~Cyber Abyss

How to Build Your Own Website Uptime Monitoring Script using VBScript: Part 1

Website Uptime Monitoring: The Basics

There are lots of website uptime monitoring services out there but all the components you need to build your own website monitoring tool can be found in good ole’ Microsoft VBScript.

Stop laughing, I’m not kidding!

In this article, I’ll share with you some scripts and tips I’ve used successfully in the past for monitoring website uptime even if your website is running in a complex load balanced enterprise environment which some of mine are.

VBScript Components for Uptime Monitor

Most people don’t know that VBScript can make Ajax HTTP calls but it can.

We will use VBScript’s ability to make Ajax HTTP calls to our website to see if it responds then put some simple logic around that response to log the results in a text/csv file.

It really is amazingly simple once you get all the code components together.

The ISWebSiteUp Function

The ISWebsiteUp function in my code example takes a URL string and makes an Ajax HTTP call to see if we get a HTTP code 200 or 404 returned meaning website loaded OK.

Once we get our 200 or 404 HTTP response code that, script returns true in the form of a text message box or if script times out you’ll get a false in an error message box.

You might be saying to yourself about now, what about the 404 response code for page not found. Yes, you might want to add some more code to handle that differently than a 2oo OK response but for this script, we just want to know if server is up. If we are pointing to a page at the root of a domain, we don’t typically get 404 errors in reality.

The Script Code

To use this code, copy it in to a text file and save it with a .vbs file extension for VBScript. Once you have the .vbs file, double click on it. You will see the message box with the message, “is up” or “is down”. A super simple example for our core application.

'isWebsiteUp: Takes String URL 
'isWebsiteUp: Returns strMessage in Message Box
Function isWebsiteUp(strURL)

	On Error Resume Next

	Set http = CreateObject("MSXML2.ServerXMLHTTP")
 	'Set http = CreateObject("Microsoft.XmlHttp")
	http.open "GET", strURL, False
	http.send ""

	'Only check for error of the HTTP Get request for 200 or 404 code returned. If any status is returned then the server is up
	if http.responseText <> "" AND err.number = 0 then
		'Commented out showing the response text. Use this for troubleshooting or exploring.
		isWebsiteUp = true
		strMessage = "is up"
		isWebsiteUp = false
		strMessage = "is down"
	end if
	Set http = Nothing	

	msgbox(strURL & ":" & strMessage)
End Function

call isWebsiteUp("https://www.google.com") 

What the Web Server Sees in the HTTP call: WinHTTPRequest User Agent

The VBScript Ajax HTTP call to the web server presents itself as a web browser asking for the home page.

In the server logs a server admin may see this “User Agent” in their logs.

Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)

Script Errors & Blocked HTTP Calls

This script works out of the box. Google is the most open website in the world in terms of IPs that their servers accept traffic from as they are in the business of collecting data about everything including every system that connects to it.

Other web servers, like ones I run, may not be so forgiving. Many server admins use many tools at their disposal to filter HTTP request at various levels.

Here are some examples of tools Windows Server Admin have at their disposal to block or filter your script from connecting to their web servers.

Windows Server Admin Tools for Handling HTTP Traffic

  • Firewall IP Restrictions (Window Server Admin)
  • HTTP Response Filtering (IIS Application Server Admin)
  • IP Restrictions (IIS Application Server Admin)

VBScript WMI: How to Get Computer Serial Number from Local or Remote Windows PC

This Windows WMI script using VBScript, retrieves the serial number of the local or networked computer.

To use this code, copy it in to a text file and save it with a .vbs file extension for VBScript. Once you have the .vbs file, double click on it and you should get a message box with the names of the logged in user on the specified Windows PC on your network.

Windows WMI VBScript

Function GetComputerSerialNumber(strComputer)
	Set objWMIService = GetObject("winmgmts:" _
		& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 

	Set colComputer = objWMIService.ExecQuery _
		("SELECT * FROM Win32_ComputerSystemProduct",,48)
	For Each objComputer in colComputer
		GetComputerSerialNumber = objComputer.IdentifyingNumber
End Function

'strComputer = "XPS1234"
strComputer = "."

' Pass a . to run this on your own PC or add a string value for another on your network
call msgbox(GetComputerSerialNumber(strComputer))

How to Retrieve Logged in User from a Windows PC using VBScript WMI

If your in need of finding out who is logged on to a specific Windows PC on your network, run the VBScript below.

When executed, you’ll see a message box with the name of the account currently logged in the computer specified.

The VBScript Code

To use this code, copy it in to a text file and save it with a .vbs file extension for VBScript. Once you have the .vbs file, double click on it and you should get a message box with the names of the logged in user on the specified Windows PC on your network.

Function GetLoggedinUser(strComputer)
	Set objWMIService = GetObject("winmgmts:" _
		& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 

	Set colComputer = objWMIService.ExecQuery _
		("Select * from Win32_ComputerSystem")
	For Each objComputer in colComputer
		Wscript.Echo "Logged-on user: " & objComputer.UserName
End Function

' Pass a . to run this on your own PC or add a string value name for PC on your network
'strComputer = "XPS1234"
strComputer = "."

call msgbox(GetLoggedinUser(strComputer))

Stay tuned for more scripts in upcoming blog posts!

Hope this helps somebody!
~Cyber Abyss

VBScript WMI: Get List of Administrators from Windows PC

I’m breaking down a large VBScript I wrote as part of a larger computer inventory system prototype I built for what later became a much larger company.

This project was a big time investment for me that provided a lot of value to the company until they went out and purchased a commercial product and even then, the commercial product had things it did not do as well as my prototype.

The scanning volume eventually got so big that I had to run copies of the script on different parts of Active Directory at the same time to try and scale the scanning of computers on the network with all the data being stored in a SQL database backend.

This script and others I’ll be sharing in this series were contained within a loop of Active Directory computer records for a good size enterprise with about 10,000 desktops and laptops for some Active Directory OUs.

This script leverages Windows Management Instrumentation (WMI) to query what’s going on with this Windows network PC.

The first piece of code I’m sharing is for querying the Windows WMI to get a list of Administrators from a Windows PC. This code was used as part of a project to determine if any computers had unauthorized admin accounts we didn’t know about.

GetAdminstrators Function

To use this code, copy it in to a text file and save it with a .vbs file extension for VBScript. Once you have the .vbs file, double click on it and you should get a message box with the names of the admin accounts from the target device.

Function GetAdministrators(strComputerName)
On Error Resume Next

    Dim objWMIService, strQuery, colItems, Path, strMembers, strAdminList, iCounter
	iCounter = 0
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputerName & "\root\cimv2")
    strQuery = "select * from Win32_GroupUser where GroupComponent = " & chr(34) & "Win32_Group.Domain='" & strComputerName & "',Name='Administrators'" & Chr(34)
    Set ColItems = objWMIService.ExecQuery(strQuery,,48)
    strMembers = ""
    For Each Path In ColItems
		Dim strMemberName, NamesArray, strDomainName, DomainNameArray
        NamesArray = Split(Path.PartComponent,",")
		strMemberName = Replace(Replace(NamesArray(1),Chr(34),""),"Name=","")
		DomainNameArray = Split(NamesArray(0),"=")
        strDomainName = Replace(DomainNameArray(1),Chr(34),"")
        If strDomainName <> strComputerName Then
            strMemberName = strDomainName & "\" & strMemberName
			if iCounter = 0 then
				strAdminList =  strMemberName
				strAdminList = strAdminList & " > " & strMemberName 
			end if
			iCounter = iCounter + 1
        End If
	GetAdministrators = strAdminList
End Function
' Pass a . to run this on your own PC or add a string value for another on your network
call msgbox(GetAdministrators("."))
call msgbox(GetAdministrators("NetworkComputer1"))

Stay tuned for more scripts in upcoming blog posts!

Hope this helps somebody!
~Cyber Abyss