guest - flak

exfiltration via receive timing

Another similar way to create a backchannel but without transmitting anything is to introduce delays in the receiver and measure throughput as observed by the sender. All we need is a protocol with transmission control. Hmmm.

Actually, it’s easier (and more reliable) to code this up using a plain pipe, but the same principle applies to networked transmissions.

First the reader code. We’ll assume an input string of decimal digits, 1-9.

void
reader(char *data, int fd)
{
        int delay;
        char buf[32 * 1024];

        while (*data) {
                sleep(*data - '0');
                data++;
                read(fd, buf, sizeof buf);
        }
        exit(0);
}

For every digit we want to “send” back, we sleep a few seconds, then drain the pipe. We don’t care about the data, although if this were a video file or an OS update, we could probably do something useful with it.

Now the writer side.

void
writer(int fd)
{
        char buf[1024];
        time_t before, after;
        int rv;

        while (1) {
                before = time(NULL);
                rv = write(fd, buf, sizeof buf);
                after = time(NULL);
                if (rv == -1)
                        break;
                if (after - before)
                        printf("%c\n", '0' + after - before);
        }
        exit(0);
}

Continuously fill the pipe with junk data. If (when) we block, calculate the difference between before and after. This is a our secret backchannel data. (The reader and writer use different buffer sizes because on OpenBSD at least, a writer will stay blocked even after a read depending on the space that opens up. Even simple demos have real world considerations.)

The main driver is just pipe and fork.

int
main(int argc, char **argv)
{
        int fds[2];

        pipe(fds);
        if (fork()) {
                close(fds[0]);
                writer(fds[1]);
        } else {
                close(fds[1]);
                reader(argv[1], fds[0]);
        }
}

In this simple example, the secret data (argv) is shared by the processes, but we can see that the writer isn’t printing them from its own address space. Nevertheless, it works.

./a.out 321856
3
2
1
8
5
6

Time to add random delays and buffering to firewalls? Probably not.

Posted 2016-12-22 15:20:19 by tedu Updated: 2016-12-22 15:20:39
Tagged: c network programming security