🇵🇸free palestine🍉

i'm arfat.
i build the parts of software nobody sees.
auth, infra, the security layer that gets bolted on last.

Backend engineer at SageTeck in Islamabad. Evenings go to security tooling — mostly looking at how AI-assisted codebases get exploited in ways that reviews miss.

My senior project at FAST-NUCES was IntraSec, a client-less network vulnerability scanner. Building it is what made this feel real. There's a writeup.

currently backend at SageTeck · Islamabad


Inside IntraSec: building a client-less network vulnerability scanner

more writing →



github · linkedin · arfat@duck.com

p.s. — there's a small thing about an astronaut if you go looking.

more soon.

Inside IntraSec: building a client-less network vulnerability scanner

IntraSec was my senior project at FAST-NUCES, built with Muhammad Ahmad Hanif and supervised by Dr. Muhammad Asim. The brief: scan an internal corporate network for vulnerabilities without installing an agent on any machine. The client-less constraint sounds like a limitation someone added to make the project harder. It's actually the whole problem — everything interesting in the architecture comes from that one decision.

The asset inventory problem

Active Directory is supposed to be the source of truth for machines on a corporate network. In practice it's more of a historical record. It has entries for machines decommissioned two years ago. It's missing the server someone spun up for a client demo and forgot to register. It has no idea about the Raspberry Pi plugged into a conference room ethernet port. The gap between "what AD says" and "what's actually responding on the wire" is exactly where the unmanaged, unpatched, and forgotten machines live — and those are the machines that tend to become problems.

A scanner that starts from the AD inventory inherits all those gaps. So IntraSec builds its own picture of the network first, using AD as a starting point but not as a boundary. Only after we have that picture do we ask what's wrong with each thing in it.

Why five services

The system is five microservices behind a Gateway API, with a Next.js frontend, communicating over REST. We didn't split it up for architectural points — the problem genuinely resists a single language or runtime. Network enumeration needs concurrency, and Go's goroutine model handles hundreds of simultaneous LDAP queries and PowerShell sessions cleanly. Risk scoring runs numerical algorithms that are better expressed in Python, with scientific libraries that don't have Go equivalents worth using. CVE lookup is a search problem, and fighting a relational database into doing CPE string matching with version ranges is the wrong fight. Each service got the runtime that made its specific problem easier to write correctly.

How discovery actually works

The Go service authenticates to LDAP, pages through computer objects in batches of 1000, then checks each host is actually reachable before touching it. The reachability check runs three probes in order: TCP on SMB port 445, TCP on RPC port 135, ping as a fallback. Offline machines get flagged and skipped — there's no silent dropout from the inventory. For hosts that pass the check, the scanner opens a PowerShell remote session to pull the software inventory: installed applications (both 32-bit and 64-bit registry paths, plus per-user installs), running services, open TCP ports, and system info. You get structured, specific data, not fingerprinting guesses.

The real constraint is WinRM. If PowerShell remoting isn't enabled on a machine — restrictive firewall rules, explicit GPO disabling it — the session won't open and the software inventory won't come back. In a domain environment this is usually a one-line GPO fix. Outside a corporate domain, it's a prerequisite that may not be negotiable.

Four feeds, one index

The vulnerability database pulls from four sources into Elasticsearch. NIST NVD is the foundation — CVE descriptions, CVSS scores, CPE mappings. FIRST.org's EPSS adds exploit probability scores, which is where things get interesting: a CVE can have a critical CVSS score but a 0.1% chance of being exploited in the next 30 days, or a medium CVSS score and already showing up in active campaigns. CISA's Known Exploited Vulnerabilities catalog tells you the second case directly — if it's on KEV, someone is using it right now. VulnCheck fills gaps in NVD and adds ransomware association data that NVD doesn't track.

Elasticsearch was the right call for the CVE index. Matching a software inventory against millions of CVEs is CPE string matching with version range logic — that's a search problem, not a join problem. The nested document model for CPE lists fits naturally in a way it wouldn't in Postgres. Lookups run in parallel across a thread pool and results are cached in Redis for 24 hours, so rescanning a network that hasn't changed much is fast. The query itself runs three tiers in order: exact CPE match (highest boost), wildcard version match, then generalized vendor/product match as a fallback — so you get precise hits where the data supports it without dropping results when version strings don't align exactly.

The risk math

Risk scoring uses the model from Reyes et al. [2022]. For each host, we compute a probability of occurrence:

PO = ((avg_TR + avg_EP) / 2) × ((POE + POP) / 2) × AVT

TR is threat reliability from CVE reference counts. EP is exploit probability from EPSS. POE is this host's share of total network CVEs. POP is its share of open ports. AVT is a network-wide age-weighted score — it goes up the longer vulnerabilities stay unpatched, which means a host with a two-year-old unpatched CVE scores worse than one with a new one at the same severity. Final risk is PO × avg_impact, bucketed LOW to HIGH.

The thing I keep coming back to in this model: most scanners treat a 6-month-old unpatched CVE the same as a day-old one. AVT doesn't. It creates pressure to actually remediate old findings instead of letting them age out of attention.

The implementation separates the two signals. PO is returned as its own field alongside the per-CVE impact average — so the risk view can show you worst-severity vulnerabilities without the probabilistic weighting burying them. Both numbers come from the same formula; they're just surfaced independently.

What I'd do differently

Scan jobs are kicked off over REST and you poll /refresh-status for progress. It works. It's also annoying — push the job, get a receipt, receive a completion event when it's done. The architecture would have supported a task queue; we just didn't add one.

The WinRM coverage gap. Unreachable hosts get flagged in the backend — the online check runs before any session attempt, errors are preserved rather than swallowed. What's missing is a frontend view that surfaces this clearly. There's no dashboard widget that says "these 12 machines haven't been scanned." The data exists; it just doesn't get in your face the way it should. A scan that looks complete but has silent gaps is worse than one that shows you the gaps explicitly.

And observability. We had logs. When a scan ran slow, debugging it meant reading timestamps and doing arithmetic. Traces from day one would have saved hours. This is the lesson I keep relearning on every project.

Full requirements, data models, and test cases are in the project report (PDF).

IntraSec

Senior project · FAST-NUCES

A client-less network vulnerability scanner. Microservices, real-time asset inventory, AD integration. My senior project — the most useful thing I built as a student.

  • Python
  • Go
  • ElasticSearch
  • Active Directory

CTFd First Blood plugin

Contract · Trillium Infosec

A custom scoring plugin for CTFd implementing parabolic decay scoring. Deployed at the Ignite Pakistan cybersecurity competition.

  • Python
  • Flask
  • JavaScript
  • SQLAlchemy

shell_shook — NasCon24 CTF challenge

CTF challenge design · NasCon24

Designed and deployed a Shellshock CTF challenge for NasCon24. Intentionally vulnerable CGI backend, JavaScript-obfuscated client, Docker-isolated per-team instances with unique flags. 60+ teams competed — one solved it.

  • Shell
  • Docker
  • CTFd
  • Shellshock

Hospitality SaaS platform

Current · SageTeck

Backend on a multi-tenant SaaS — auth, service orchestration, deployment pipelines across distributed services.

  • Azure
  • Multi-tenant
  • PHP
  • MySQL

Digital Signage Platform

Production

Backend infra for a cloud signage platform serving 1000+ screens across WebOS, Android, and Windows. Built the CMS, the WebOS player, and per-screen licensing.

  • PHP
  • CodeIgniter
  • MySQL
  • WebOS

SuiteCRM customizations

Production

Module customization, REST integrations, and role-based access controls across four enterprise CRM deployments.

  • PHP
  • SuiteCRM
  • MySQL

Dropella analytics APIs

Production

Product database and sales-tracking APIs at the core of an e-commerce analytics platform. Multi-threaded request handling cut p99 by ~30% at peak load.

  • Python
  • FastAPI
  • REST

Backend for managing lost-and-found items in institutional settings. Real-time notifications, user accounts, item search.

  • Java
  • MongoDB

Automated scraper for movie data and subtitles. An early Python project, kept around for posterity.

  • Python

Classic brick breaker game written in x86 Assembly. Direct hardware interaction, no runtime, no stdlib.

  • x86 Assembly

I'm a backend engineer in Islamabad. I write Python and Go, ship PHP and CodeIgniter at my day job, and most of my evenings turn into security tooling.

What I keep coming back to is how much code ships without anyone really reading it. Security shows up on the roadmap around the same time the first incident does. That gap is the work I want to do.

My senior project at FAST-NUCES was IntraSec, a client-less network vulnerability scanner in Python and Go, supervised by the Dr. Muhammad Asim. Building it is what made me want to do this for real.

These days it's a multi-tenant hospitality SaaS at SageTeck — REST APIs, auth, deployment pipelines. On the side, I look at how AI-assisted codebases get exploited: vulnerabilities most reviews miss because they're too new to have names yet.

For the stack details, see my CV.

Outside that: چائے

building something in backend, infra, or security? or just want to compare notes.
arfat@duck.com →

may 2026  what is /now?

working on

  • multi-tenant SaaS infra at SageTeck.
  • reviewing AI-generated codebases for recurring vulnerability patterns.

learning

  • Designing Data-Intensive Applications — haven't started yet.
  • AppSec deep-dive on auth and SSRF.
  • PortSwigger Web Security Academy labs. , maybe ?

writing

for fun

  • The Finals , sometimes

work / IntraSec

client-less network vulnerability scanner and asset management for Active Directory environments.

roleSenior project · FAST-NUCES year2024 – 2025 stackNext.js · Go · Python · FastAPI · Elasticsearch · PostgreSQL · Redis supervisorDr. Muhammad Asim · HOD, Cyber Security

Built with Muhammad Ahmad Hanif

Enterprise networks don't match their own inventories. Active Directory has stale records — decommissioned machines, unregistered hosts, ghost assets. A scanner that trusts the inventory misses these gaps.

The constraint the project set itself was no agents. No agents means you can't just install software on each machine and ask it what's running. You have to figure it out from the outside — scanning, LDAP queries, remote sessions.

IntraSec microservices architecture diagram

IntraSec is a Gateway API in front of five microservices. Each handles one thing. REST between them. Frontend is Next.js.

  • Asset Discovery — Go service. Authenticates against LDAP, enumerates all AD-joined computers, opens PowerShell sessions on each to collect software inventory. Stores results in PostgreSQL.
  • Risk Assessment — Python + FastAPI. Matches the software inventory against CVE/CPE data, runs the risk scoring algorithm, produces per-host and network-wide risk metrics.
  • Vulnerability DB — Python service that ingests CVE and CPE data from NIST NVD into Elasticsearch. Keeps the local vulnerability index in sync with upstream feeds.
  • Report Generation — Produces structured reports from risk assessment output, exportable for audits.
  • Alerts — Real-time notifications for high-severity findings, with configurable thresholds.

Redis for caching. PostgreSQL for assets, patches, reports. Elasticsearch for CVE/CPE because you need to search millions of records fast.

IntraSec deployment diagram

The Go service authenticates to LDAP, queries for all computer objects, then opens a PowerShell remote session on each to collect software, services, and open ports. Results go into PostgreSQL and downstream to risk assessment.

If a host returns no data, it's not that nothing is installed — it means the host is offline, unreachable, has remoting disabled, or the credentials don't have access. That's flagged separately.

Go for this because handling hundreds of concurrent LDAP queries and PowerShell sessions needs proper concurrency primitives. Python for the risk scoring because the math libraries are there.

Risk scoring is based on the Reyes et al. [2022] model. For each host, the algorithm calculates a probability of occurrence (PO) factoring in:

  • POE — probability of exploit, weighted by how many CVEs affect this host vs. the network total
  • POP — probability of port exploitation, proportional to open ports
  • AVT — network-wide age-weighted vulnerability time: older unpatched CVEs score higher
  • CVSS impact score — the severity multiplier from NIST

Final risk factor: risk = PO × avg_impact, where PO = ((avg_TR + avg_EP) / 2) × ((POE + POP) / 2) × AVT. Hosts are then bucketed into LOW / MEDIUM-LOW / MEDIUM / MEDIUM-HIGH / HIGH.

The vulnerability database is fed from four APIs to get a complete picture of each CVE:

  • NIST NVD — authoritative CVE and CPE data, CVSS scores
  • FIRST.org EPSS — exploit prediction scores: probability a CVE gets exploited in the wild
  • CISA KEV — known exploited vulnerabilities catalog, actively exploited in the wild
  • VulnCheck — enriched CVE intelligence including ransomware associations
CVE Elasticsearch index schema
CVE index schema
CPE Elasticsearch index schema
CPE index schema
IntraSec network risk graph visualization
network risk graph — each node is a host, edges show exposure relationships
IntraSec main dashboard
main dashboard
Host detail view
host detail
Software with associated CVEs
software → CVE mapping
Risk analysis dashboard
risk analysis
CVE prioritization interface
CVE prioritization
Risk report summary
risk report

Scan operations are currently request-response via REST. A message queue (RabbitMQ, Kafka) would let scans run async without polling for status. Right now we're building status tracking on top of HTTP.

PowerShell remoting is the first choice but fragile. A fallback chain would help: WMI if remoting fails, SNMP if that fails, passive fingerprinting as last resort. We'd catch more hosts at the cost of more code paths.

Logging came late. Should have added distributed tracing from the start — hard to debug why a scan hit a 10-minute timeout without traces across service boundaries.

← all work

Experience

SageTeck 2025 – present

Full Stack Developer

  • Backend systems on a multi-tenant hospitality SaaS platform on Azure — authentication, service orchestration, deployment pipelines across distributed services.
  • Tenant-isolated data flows, inter-service REST APIs, and role-based access controls across multiple enterprise CRM products.
  • SuiteCRM v7 & v8 customisations: custom logic hooks, scheduler jobs, module development, MySQL schema design and migrations.
Systems Limited 2024

Software Engineer Intern

  • Worked on enterprise backend systems during a summer internship.
  • Gained exposure to large-scale software delivery pipelines and development practices.
Dropella.io 2021 – 2022

API Developer

  • Built the Product Database and Sales Tracking APIs at the core of an e-commerce analytics platform using Python and FastAPI.
  • Multi-threaded request handling reduced response times by ~30% at peak load.
FAST-NUCES 2021 – 2022

Teaching Assistant — Data Structures

  • Conducted lab sessions, marked assignments, and supported students in DS fundamentals.
Rex Media Group 2021 – 2022

WordPress Developer

  • Built and maintained WordPress sites; plugin integrations and theme customisations for client projects.

Education

FAST-NUCES, Islamabad 2021 – 2025

BS Computer Science

  • Dean's Honor List.
  • Senior project: IntraSec — client-less network vulnerability scanner in Python & Go, supervised by Dr. Muhammad Asim, HOD of Cyber Security.

Skills

Languages Python · Go · C/C++ · Java · PHP · JavaScript · SQL Frameworks FastAPI · Flask · Django · CodeIgniter · SuiteCRM Infrastructure Docker · Nginx · Azure · CI/CD · Kafka · Redis · ElasticSearch Data MySQL · PostgreSQL · MSSQL · MongoDB Tools Git · Linux · REST APIs · Microservices

← home

VS Code

main editor. extensions: Pylance, Go, GitLens, REST Client. nothing exotic.

Zsh on Ubuntu or Windows Terminal (on a bad day)

Make your life easier by not using Windows

Git + GitHub

GitHub Desktop, because life is too short for horrendous CLI commands /həˈrɛn.dəs/.

Python

default for scripting, APIs, security tooling. FastAPI for anything that needs to be fast.

Go

network code, anything concurrent. wrote the discovery worker in IntraSec in Go — right choice.

PHP + CodeIgniter + SuiteCRM

day job. not glamorous. but it ships.

Docker

everything runs in containers. if it doesn't work in Docker, it doesn't work.

Nginx

reverse proxy, rate limiting, the usual. Caddy when I want something simpler.

Azure

what SageTeck runs on. not my preference but I know it well now.

Hand-coded site

hand-coded if claude code had hands.

Spectral + Space Mono

Spectral for body and headings (serif, readable). Space Mono for UI and code (monospace, distinctive).

← home

← home

This was the hero of the old site. It set a certain tone.

hero image from the previous version of arfat.me

He got retired to a small sigil in the corner. If you clicked him to get here: nice work.