Faking Web to SMS so Synology can Notify via Slack

As bits of hackery go, this is pretty niche. I have a bunch of storage in a Synology Diskstation – this can send various notifications in case disks fail, components get too hot, or other bits of the system break down in ways that require immediate attention. It can send emails, you can use their app to enable push notifications to your phone and if you really want to you can have it send you SMS (actual SMS, in 2017?!). What it can’t do out of the box is send a message to a Slack channel.

I really like Slack. As well as running a paid instance of Slack with my teams at FISCAL, I have a separate (free) one for friends and family and for running experiments with bots and other integrations. So I wanted the Synology, like most of my other house/home automation devices, to talk to Slack. The easy way would be to make the Synology send an email to the Slack email integration – except the email->Slack integration is only available to paid Slack instances. So what to do? Continue reading

Connect IFTTT to Internal Node Server

I spent a bit of time last night putting together the final pieces of code that’ll connect alerts on IFTTT to devices and systems on my internal network, via a simple node.js server. It sits on the edge of my network listening for some JSON to be POSTed at it, and then relays the JSON to a machine inside the network. Initially just one machine – the Plex HTPC in the living room, but eventually I’ll add more logic. Continue reading

FindTheHole.vbs

Recently I needed to write a script that could locate a folder on a system that had particular characteristics.  I was looking for hidden folders that the logged on user had rights to read, write/append and execute on.  ie, they can drop a binary into the folder and then run it.

This is the script I came up with.  It uses a WMI query and method to first locate all the hidden folders on the system, and then compare each ones effective permissions to a mask I created:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!" & strComputer & "rootcimv2")
Set colFiles = objWMIService.ExecQuery _
("Select * from Win32_Directory Where Hidden = True")
wscript.echo "Hidden folders which you can write to..."
intW = 0 ' initialise Writable folder count
' Iterate through each hidden folder on the computer
For Each objFile in colFiles
	' Ignore some well known hidden folders
	If InStr(lcase(objFile.Name), "documents and settings") or _
		InStr(lcase(objFile.Name), "$nt") or _
		InStr(lcase(objFile.Name), "$hf_mig$") or _
		InStr(lcase(objFile.Name), "ie7updates") or _
		InStr(lcase(objFile.Name), "visual studio") or _
		InStr(lcase(objFile.Name), "dllcache") or _
		InStr(lcase(objFile.Name), "$patchcache$") Then
	Else
		' Can we read (1), write (2, 4), and execute (32) in this folder?
		intPermissions = 39
		' Use WMI method to compare permissions
		If objFile.GetEffectivePermission(intPermissions) Then
			wscript.echo objFile.Name
			intW = intW + 1
		End If
	End If
Next
wscript.echo intW & " vulnerable folders."

This was important as part of a wider effort to prove a particular vulnerability existed.  Imagine the scenario where a standard user is prevented from running unknown binaries except for one hidden folder somewhere on the system which is excluded from this protection.  If one could quickly find that folder, the user could run whatever he liked.

I’m aware that there are plenty of command line tools that would have helped in this endeavour (such as AccessChk) but remember: this is a system where unauthorised apps can not be run.  It’s VBScript or nothing.

LDAP Query based on account SID in VBscript

This is a bit of code I wish I’d found sooner. There is a – it seems mostly undocumented – feature of the ldap provider in Server 2003 that allows you to form an ldap query just on the SID of an account:

bindSid = "LDAP://<sid =" & SID & ">"
set oVal = GetObject(bindSid)
Result = oVal.Get("cn")
set oVal = Nothing

So if you have a list of SIDs and want to translate them into meaningful account names, this will do it without relying on using WMI – which on a lot of secure networks is locked down (or at least should be!).

Why do I need this? It’s a part of a larger script I’m writing that will archive specific Group Policy Objects from the \SYSVOL\<domainname>\Policies\ folder of a PDCe. One of the files in a GPO is the GptTmpl.inf file which gives a list of the User Rights Assignments (SeBackupPrivilege, SeShutdownPrivileg etc) along with the SIDs of the accounts that have been given those privileges (e.g. S-1-5-19). I wrote a script that reads the SIDs and queries the DC for the account names. This code fragment works more reliably (and I think faster) than the WMI calls I was previously using.