A BOFH Generator in C

// gcc bofh.c -o bofh
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUM_QUOTES 10

const char* bofh_quotes[NUM_QUOTES] = {
    "No, my powers can only be used for good.",
    "It must be a hardware problem.",
    "I'm sorry, we don't support that feature.",
    "That's a PEBCAK error (Problem Exists Between Chair And Keyboard).",
    "Have you tried turning it off and on again?",
    "The BOFH Excuse Server is down.",
    "It works for me.",
    "I'm afraid I can't help you with that.",
    "According to the manual, it should work.",
    "You must have done something wrong."
};

int main() {
    srand(time(NULL));  // seed the random number generator

    int random_index = rand() % NUM_QUOTES;
    const char* quote = bofh_quotes[random_index];

    printf("%s\n", quote);

    return 0;
}

Writing a portscan utility in .NET

I’m working on a side project that is a portscan utility written in VB.net. Here’s my progress so far, and it is working.

There’s some way to go on this little project. I think I can optimize it further, clean up the code, and fix my logic for many of the options. See an earlier post about handling command line arguments I wrote which is what class I use for handling the arguments.

Check out my C port scanner which is significantly faster (65k ports in < 30 seconds).

Pennsylvania COVID-19 Data Scraping with Python

Over the last few weeks I’ve been using Python to scrape the Pennsylvania Department of Health’s Coronavirus page. Over time the page has evolved and even split into sub-pages which contain table date of cases, deaths and other statistics.

I’ve decided to put my Python script on GitHub for public consumption. Initially when I had created the script, it was used to send me alerts when the reported numbers changed as there was no set time during the day that the website was updated, so I wanted to set up a cron job to check the website and alert me of new updates.

Below you’ll find the main script. Note that the code below may be out of date, so please check my GitHub repository for the latest. The code changes almost daily as it seems Pennsylvania Dept. of Health changes the structure, or adds new data, to the webpage which throws off my code.

Python Script

import pandas as pd
from bs4 import BeautifulSoup
import requests
import os
import re
url = r'https://www.health.pa.gov/topics/disease/coronavirus/Pages/Cases.aspx'
html_content = requests.get(url).text
lastupdatedfile = "lastupdated.txt"
soup = BeautifulSoup(html_content, "lxml")
stats = soup.find("span",attrs={"class": "ms-rteStyle-Quote"})
#TODO: byte / string issue here on updatecheck
updatecheck = stats.text[stats.text.find("at "):][3:]
if os.path.isfile(lastupdatedfile):
	lastupdate = open(lastupdatedfile).read()
	if lastupdate == updatecheck:
		print("Skipping check, no new update.")
		os._exit(0)
	else:
		print("***UPDATE***\nOld: {}".format(lastupdate))
		print("New: {}".format(updatecheck))
tables = pd.read_html(html_content, header=0)
df = tables[3]
totalCounties = 67
print("Pennsylvania Data ({})".format(updatecheck))
deathsTotal = int(df["Deaths"].sum())
casesTotal  = int(df["Number of Cases"].sum())
mortalityPercent = round((deathsTotal / casesTotal) * 100,2)
reportingTotal = int(df["County"].count())
reportingCases = df["Number of Cases"]
reportingCasesPct = round((reportingCases.count() / totalCounties) * 100,2)
reportingDeathsObj = df.apply(lambda x: True if x['Deaths'] > 0 else False, axis=1)
reportingDeaths = len(reportingDeathsObj[reportingDeathsObj == True].index)
reportingDeathsPct = round((reportingDeaths / reportingTotal) * 100,2)
print("Total Cases: {}".format(casesTotal))
print("Total Deaths: {}".format(deathsTotal))
print("Mortality Rate(%): {}".format(mortalityPercent))
print("Counties Reporting Cases: {}".format(reportingCases.count()))
print("Counties Reporting Cases(%): {}".format(reportingCasesPct))
print("Counties Reporting Deaths: {}".format(reportingDeaths))
print("Counties Reporting Deaths(% of counties reporting cases): {}".format(reportingDeathsPct))
f=open(lastupdatedfile,"w")
f.write(updatecheck)
f.close()
# Add some notification stuff here...

Output Example

Pennsylvania Data (12:00 p.m. on 3/28/2020)
Total Cases: 2751
Total Deaths: 34
Mortality Rate(%): 1.24
Counties Reporting Cases: 56
Counties Reporting Cases(%): 83.58
Counties Reporting Deaths: 13
Counties Reporting Deaths(% of counties reporting cases): 23.21

Allscripts Vision User Reporting

A quick Powershell script I hacked together that will enumerate all Active Directory users, and build an XML file for an application I wrote that generates user reports for a specific application.

The output file format is similar to:

<quickreports>
  <report name=Organizational Unit>
  <database name=v001/>
  <usrlogin name=jdoe01/>
</report>
<quickreports>
$ErrorActionPreference= 'silentlycontinue'
$arr=@{}
foreach ($usr in Get-ADUser -Filter *  | select samaccountname) {
$user = get-aduser -identity $usr.samaccountname -ErrorAction SilentlyContinue
$userou = (($user.DistinguishedName -split =,2)[-1].split(,)[1] -split =,2)[-1]
$key = $userou
$value = $usr.samaccountname
if ($arr.ContainsKey($userou)) {
$arr[$userou] += $usr.samaccountname
} else {
$arr[$userou] = @()
$arr.add($key,$value)
}
}
$foo = <?xml version=1.0 encoding=utf-8?>`r`n
$foo += <quickreports>`r`n
$foo += foreach ($ou in $arr.keys) {
    write-output   <report name=$ou>`r`n
    foreach ($u in $arr[$ou]) {
                if ($u.contains(01)) {
                    write-output <database name=v001/>`r`n
                } elseif ($u.contains(04)) {
                    write-output <database name=v004/>`r`n
                } else {
                    write-output <database name=/>`r`n
                }
        write-output <usrlogin name=$u/>`r`n
}
    write-output </report>`r`n
}
$foo += </quickreports>
$foo | out-file quickreport.xml
# for some reason the outputted file was dumping 0x00 into the file.  Eventually
# I'll clean all this up and just write all the attributes and elements from up above
# but now is not the time as this is just a quick and dirty POC
$fn = quickreport.xml
$xmlDoc = [system.xml.xmldocument](get-content $fn)
$xmlDoc.save($fn)