Introduction

This post is mostly for those careless whisperers programmers who write code with no care for exploitation.

What is exploitation? Wiktionary defines exploitation as “The act of utilizing something”. So how does one utilize programs? Installs, configures it and ensures that it runs as instruction specifies.

In order to make your program exploitatable you need to provide documentation for every of these three steps.

Truth is, it’s rare to see any documentation at all, so exploitation is done poorly. “It works somehow” approach. “Just reboot it” approach. All that stuff.

Here’re some tips on how to make web-services easy to exploitate. There’s some well known paper on that matter, which is more declarative, formal and extensive.

I do not discuss end-user installed programs, ‘cause it also requires a ton of information on distribution, which I’m not familiar with.

Standardize it!

By that I mean two things.

Make exploitation documentation standard

First, ask your exploitation department colleagues (DevOpses?). Especially if you already have some systems in exploitation (i.e. in production). What do they use? What information they lack?

Second, inspect your projects (both in exploitation and in early develoment). Think of all common bells and whistles to be configured, some situations that may occur. You may think your system is easy to understand for everybody. Truth is, it’s not.

After all common information gathered write a template of exploitation docs and show it to everybody. Discuss it, improve it.

But do not “carve this template in stone”. After every incident (especially post mortems) think of adding some things that could help exploitation team make it through harsh times without your help. Amend (but wisely!) it. Remove unused things.

Make it mandatory for every developer

This is a bit more difficult. If you’re at team lead/manager/big boss position, use your power to make documenting exploitation mandatory. If not, use social engineering, meritocracy, your boss, your reputation. Become an asshole. But force everybody to write that. Trust me, it will save your sleep at night (especially if you’re team lead/manager).

Make your system exploitatable

That’s complicated too. All that 12-factor apps stuff (and beyond) goes here.

Environment configuration files

First thing I encountered countless times is “environment configuration file”. God, please, get rid of it! If your config folder contains more than production and derived from it development and test configs, you’ve done bad.

Just imagine, what could happen if at 1:00 AM your DB server crashes without any chance to restore, but exploitation guys can quickly (within SLA time!) restore it with different IP address/domain name. How could you change your DB hostname on the go without redeploying your app if you have it (DB hostname) in git-controlled folder with no chance to change it “on the go”? Sleepless night will suddenly get into your life =)

So, to make your system configurable “on the go” either use some sort of config provider, or simply put everything into ENV-variables with default values. And voila, more sleep for your really tired brain that night!

Oh, and of course it (ENV-variables, config providers, etc.) well worth documenting. Trust me.

Add readiness and liveness checks

Or, as some call them, health checks. It’s not about K8s. Why? Your server needs to know when your app has loaded (readiness check) and when it has crashed (liveness check). For web apps just / with 200 OK usually is enough for both.

Then describe it in your exploitation documentation.

Add custom monitoring endpoint

Thing is, your exploitation team already has some tool to monitor your app. Help them!

You’re unsure of some really weird errors? Push those events to monitoring system! Has external systems? Check them!

We (on projects I developed) used /healthcheck with such content:

db ok
smtp ok
rabbitmq ok

Again, put that into exploitation documentation.

Describe every service

Use DBMS? Has web server? Send emails? Describe it!

For every service you should describe:

  1. Where to get. Code? Docker/rkt images? RPM-packages?
  2. How to start: commands and arguments, flags, etc.
  3. What to do at first start. Like putting in some seed data with specific command.
  4. Dependencies. I bet you don’t want to start your app-server before DB.
  5. Scalability. It’s easy to (auto)scale web service, but (auto)scaling DBMS is a painfull experience.
  6. Resources required. Memory, CPU, hard drives, sockets, inodes.
  7. Backups. What and how to backup and how to restore it.
  8. Purpose. What that thing exactly do. So when something doesn’t work one can just restart that exact service.

And remember: what you may call an “app” within your development team is a service too. Yep, rails-loaded puma is an http service worth describing. Phoenix-loaded cowboy is an http service. Spring-loaded java instance is a bad idea java is bad get rid of it like right now.

Networking

What services are exposed to the world and what connectivity your services require (interconnections, infranet endpoints). That’s some important info for bootstrapping whatever you shitcoded for months.

Handles

Have script to wash it out? Internal buttons to rebuild caches?
If not, make em.
Then describe em.

Some sort of conclusion

Do that and beyond. Do not just write code — build exploitable services instead. Mkay?