Skip to content

Hackmud: Solving T3 NPCs

Updated: at 01:04 AM

header

Introduction

I’ve recently been playing the puzzle programming RPG Hackmud. The concept is pretty interesting. You are a user in a retro-style multi-user domain. Inside of this domain there are other players, as well as npc entities. Everything is accomplished by running scripts. The scripts are basically javascript functions with some custom language. Users can publish their script so that other players can use them. The scripts are used for a wide varity of purposes, from buying and selling items, to tracking down npc locations to hack.

There are risks involved with running the scripts of other players, and npc corps. Each script has a security level, from FULLSEC to NULLSEC. FULLSEC scripts can’t do much harm to your system, but as you go into lower and lower security scripts, more damage can be done to you. Things like having your money taken, your system upgrades taken, your user location leaked, and worse.

NPC locations can be hacked for money and upgrades, with better gold and upgrade rewards coming from higher tier npcs. Hacking higher tier npcs introduces more risk into your system, with most T3 locations being LOWSEC, capable of stealing your upgrades and money, even leaking your location. Publicly available hacking scripts also require these same permissions, and I’m not willing to risk it. So, I’m rolling my own. Tier 1 and 2 NPCs are basically solved due to the large number of publicly available scripts. The real trouble begins with Tier 3 NPCs.

Tier 3 NPCs

Hacking T3 NPCs breaks down into a few broad steps:

Scanning for T3 Corps

There are several npc prefixes:

futuretech,nuutec,core,halperyon,light,archaic,context,sn_w

and several suffixes:

priv,employee_login,internal,employees,emplogin,private,intern

We combine each together and check their security level with scripts.get_level, if it returns a valid number, we know that domain is up and working. Once we know that its up, we can begin the next step.

Hacking into T3 Corp Locations

Going to one of the available locations, we get the following view, using archaic.emplogin as an example:

Archaic Labs
Welcome to YOUR #FUTUREtech employee pro¦uctivity suite

enter in your username and 4 digit pin to continue.

Before we get started, you’re going to need to have some method of detecting timeouts and tracking state information for the scrape, my state information looks something like this:

      state_info = {
        script: context.this_script,
        caller,
        last_run_date: current_date,
        stage: 0,
        username: 0,
        pin: 0,
        data_object: {}

This state should be placed in the database for each step, since you will likely not hack the pin in one script call. /auto is your friend!

Finding Usernames

username is pretty easy. I’ve you’ve worked your way up to T3, you should already have harvested a large list of usernames and stored them in your personal database.

The best way through this is to specify a random username until you get a similar response:

Archaic Labs
Welcome to YOUR #FUTUREtech employee producti§ity suite

please provide pin as text.

A bad username will give a response like this:

Archaic Labs
Welcome to YOUR #FUTUREtech empl¡yee productivity suite

employee bad_user does not exist.

Finding Pin

There is no secret to this step. You simply have to guess every pin until you get the right one.

I’ve been running into issues with this part of the script. I don’t know if you’ve noticed, but hackmud’s text output is corrupted, with random characters being replaced with garbage chars. In the past, I’ve corrected this by simply running each command twice and filtering corruptions, but I don’t think that will be sutable for this. Instead, I’m going for fuzzy matching.

  function handle_find_pin(){
    state_info.data_object = { username, pin:pad(state_info.pin,4,"0") };
    tc()
    if (fuzzyLast(response, "incorrect pin.", 1)){
      return state_info.pin = state_info.pin+1;
    } else {
      return state_info.stage++;
    }
  }

  function fuzzyLast(input, m, a) {
    //input, match string, misses
    let sub = input.substr(input.length - m.length),
      c = 0;
    fz_compare = sub+"\n"+m;
    for (let i = 0; i < sub.length; i++) {
      if (sub[i] === m[i]) {
        c = c + 1;
      }
    }
    return sub.length - c <= a;
  }

You’ll know when you succeed when you hit a prompt like this:

Archaic Labs

perform

+~~~~~~~~~~~+ +~~©~~~~~~~~+
+  Enhance  + + Synergize +
'~~~~~~~~~~~' '~~~~~~~~~~~'

+~~~~~~~~~~~+ +~~~~~~~~~~~+
+   Flow    + +  Á¡ ¡ÁzÃ`Ã`  +
'~~~~~~~~~~~' '~~~~~~~~~~~'

Collect Info from Calendar

From this point on you’re on a time crunch. You need to figure this out fast before the locations rotate.

It’s easy to get a little mixed up here, but you can bypass this section by adding a_t:"w_ek", perform:"flow", work:"calendar" to your args.

This gives you screen that looks like this:

2061AD
-D076----+D077----+D078----+D079----+
- mdnkyr | y5lhve |        | bjbc84 -
- zxt59h |        |        |        -
-        |        |        |        -
-        |        |        |        -
-D080----+D081----+D082----+D083----+
- jk8new | 3p6ijg | sagog8 | 1fzxi8 -
- dyneci |        |        | o5nw79 -
-        |        |        |        -
-        |        |        |        -
-D084----+D085----+D086----+D087----+
- qy3ej4 |        |        | z8e4nj -
- zjjc6g |        |        | 2vr835 -
-        |        |        | pgpc40 -
-        |        |        |        -
=====================================

Those 6 digit codes look interesting, lets save them for later. Specifying an index i:xxxx gives you output something like this:

>>core.employee_login{username: "b3nd3r",pin: "5016",i: "ximboc", a_t: "work", perform: "flow", work: "calendar"}
calendar- 

LNk8qkcO0yTt3Or63C1oiEPQtkvtHunMPDJEhQUtu+3J25dQkUX7dZsLeOiV16WyGE6PHk5+K9xGKUYeejfo/Ms0lzEUzAou4+vhzXZKg1YewT/tFJoEmjEbvxLtmKRZD/XHQ7hDddGo/IP
zliVbvxkA4PD+3aiEgxXCC3IKXCl09VXx=WdzN=2ZClxogzjHrTfLLd84pTpgxxD53f4PzT1d

These are clearly some kind of encrypted text. We should save them for later.

Finding the backup server

Keep pulling calendar entries until you find an unencrypted loc with the name of the user you’re logged in as.

Scrape backup server for key

When you access the backup server, you’re going to want to use the pin that you learned earlier in this run. Look for the entry with “key”, avoid the rest of them as they will delete your upgrades or worse. The key is always 7 characters.

Decrypt calendar info

Using the newly found key, attempt to decrypt the entries from calendar. This is where I’m stuck at currently. If anyone has tips on how to actually decrypt the lines in the calendar entries, please shoot me an email. I’m going to continue trying various things.


Previous Post
New PC Build
Next Post
Hiking Plans