Nucu Car: Devlog 0x01

Hello everyone,

A while ago I started working on a pet project called NucuCar. It’s a platform written in .NET for the Raspberry Pi in which I’m trying to implement various utility functions to create a complete piece of software that can be used to build a remote controlled car for the Pi.

The project is open source and it can be found on GitHub: https://github.com/dnutiu/NucuCar

Since I didn’t buy a toy car and I don’t have much space in my apartment I was working only on the sensors module, which currently has support for the BME680 environment sensor and the CPU temperature sensor build in the Pi.

The idea behind this is to make a daemon that polls the sensor, publishes telemetry data and can be easily configured. This is the configuration file:

The Telemetry block configures which telemetry publisher to use Azure or Disk (for the moment, can be extended) and the interval in which to publish the telemetry data. The other two blocks configure whether the sensors and telemetry collection is enabled or not. That’s about it.

To develop this I’ve been using Github, a free Jira instance and JetBrains’ Rider.


Running on the Pi

I’ve build the project and uploaded it on the Pi, running it will all the options enabled yields the following htop result:

We have lots of processes which are in interruptible sleep, about 7.8% CPU time which went to 0.7% after a while and around 5.5MB or ram usage. That’s not bad, considering that we’re running C#. Oh, and I forgot to mention, the BME680 sensor is exposed via a gRPC server. 🙂

Telemetry Data

While running the program, the telemetry data from the sensor was collected and saved to the disk. Here’s how an entry looks like:

{
   "source":"NucuCar.Sensors",
   "timestamp":"2019-12-01T23:26:13.5537227+02:00",
   "data":[
      {
         "sensor_state":2,
         "temperature":32.65558333857916,
         "humidity":100.0,
         "pressure":62228.49565168124,
         "voc":0.0,
         "_id":"Bme680-Sensor"
      },
      {
         "sensor_state":2,
         "cpu_temperature":48.849998474121094,
         "_id":"CpuTemperature"
      }
   ]
}

Then I wrote a Python script to plot the available data, skipping the first 10 results.

Thanks for reading!

References:

PicoCTF 2019: whats-the-difference (Points 200)

Can you spot the difference? kitters cattos. They are also available at /problems/whats-the-difference… on the shell server

In order to easily solve this challenge, I’ve used xxd and cut to generate an ascii hexdump of the images:

➜  Downloads xxd kitters.jpg | cut -d ' ' -f 11 > kittens_text.txt

➜  Downloads xxd cattos.jpg  | cut -d ' ' -f 11 > cattos_text.txt

Since I wanted to do a per character diff I wrote the following Python script:

def main():
    new = open("cattos_text.txt")
    old = open("kittens_text.txt")
    old_file = old.readlines()
    new_file = new.readlines()
    print("Loaded lines", len(old_file), len(new_file))
    for line in zip(old_file, new_file):
        for number, old_char  in enumerate(line[0]):
            if old_char != line[1][number]:
                print(line[1][number], end="")

main()

And finally run the script:

➜  Downloads python diff.py
Loaded lines 212919 212919
picoCTF{th3yr3_a5_d1ff3r3nt_4s_bu773r_4nd_j311y_*}%

Bypassing ptrace calls with LD_PRELOAD on Linux

Hello,

Here’s a quick article on how to bypass calls to ptrace when debugging a Linux executable.

By calling ptrace with the PTRACE_TRACEME option, a process can detect if it’s being debugged and execute different instructions. This an effective anti-debugging technique.

For example, take the following C program:

#include <stdio.h>
#include <sys/ptrace.h>

int main() {
    if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
      printf("I'm being debugged!n");
    } else {
      printf("Normal flown");
    }
    return 0;
}

If we execute the program from above we get Normal flow on our screen but if we debug it with gdb we get Err: I'm being debugged!

root@kali:~/Downloads# strace ./a.out 
...
munmap(0x7fb7c945e000, 90919)           = 0
ptrace(PTRACE_TRACEME)                  = -1 EPERM (Operation not permitted)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
brk(NULL)                               = 0x55c2d37e6000
brk(0x55c2d3807000)                     = 0x55c2d3807000
write(1, "Err: I'm being debugged!n", 25Err: I'm being debugged!
) = 25
exit_group(0)                           = ?
+++ exited with 0 +++

To bypass this, we can use the LD_PRELOAD environment variable. It lets us control the loading path of a shared library, which allows us to stub out library functions such as ptrace.

We can create the following file:

long ptrace(int request, int pid, void *addr, void *data) {
    return 0;
}

And compile it as a shared library with the following command:

gcc -shared ptrace.c -o ptrace.so

Next, we can set the environment variable LD_PRELOAD using the following commands:

  • in the shell: export LD_PRELOAD=./ptrace.so
  • in gdb: set environment LD_PRELOAD=./ptrace.so

Demo:

gdb-peda$ file a.out 
Reading symbols from a.out...
(No debugging symbols found in a.out)
gdb-peda$ r
Starting program: /root/Downloads/a.out 
Err: I'm being debugged!
[Inferior 1 (process 1939) exited normally]
Warning: not running
gdb-peda$ set environment LD_PRELOAD=./ptrace.so
gdb-peda$ r
Starting program: /root/Downloads/a.out 
Normal flow
[Inferior 1 (process 1946) exited normally]
Warning: not running
gdb-peda$ 

Thanks for reading!