Skip to content

Advantages over similar obfuscators

Qian Wang edited this page Feb 28, 2018 · 1 revision

This project is inspired by simple-obfs and ShadowsocksR's tls1.2_ticket_auth mode. Based on the idea of obfuscating shadowsocks traffic as TLS traffic, this plugin made significant improvements on making the traffic more similiar to actual TLS traffic, and defending against active probing, which was what effectively killed Tor inside the GFW. This article addressed some potential weakness of these two pioneer obfuscators and how GoQuiet fixes them. But do take a pinch of salt on my analysis as I'm very inexperienced in coding. Criticisms are welcomed.

In comparison to simple-obfs

Well, first of all, simple-obfs is simple, also the obfuscations is exprimental

It simulates the handshake and redirects any non-TLS traffic to a web address. This is the code that does the check, from obfs_tls.c

/*
 * obfs_tls.c - Implementation of tls obfuscating
 *
 * Copyright (C) 2013 - 2016, Max Lv <max.c.lv@gmail.com>
 *
 * This file is part of the simple-obfs.
 *
 * simple-obfs is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * simple-obfs is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with simple-obfs; see the file COPYING. If not, see
 * <tls://www.gnu.org/licenses/>.
 */
static int
check_tls_request(buffer_t *buf)
{
    char *data = buf->data;
    int len    = buf->len;

    if (len < 11)
        return OBFS_NEED_MORE;

    if (data[0] == 0x16
        && data[1] == 0x03
        && data[2] == 0x01
        && data[5] == 0x01
        && data[9] == 0x03
        && data[10] == 0x03)
        return OBFS_OK;
    else
        return OBFS_ERROR;
}

As we can see, only 6 static bytes are checked. Anyone, including the GFW, can send these 6 bytes in this particular order to be reconised as SS traffic, even when the content is totally malformed. The expected behaviour of a web server upon receiving a malformed TLS message is to give error immediately and refuse to proceed the handshake, but it's not the case here. This is very prone to probing.

In addition, the making of the content of Server Name Extension and Session Ticket are not yet implemented.

In GoQuiet, the identification of the incoming connection relies on cryptography. The data transmitted in the handshake is actually meaningful, not solely for the purpose of showing GFW that this is a TLS traffic.

In comparison to SSR

I'm not quite sure how SSR implemented its tls1.2_ticket_auth. The C# implementation doesn't seem to have session_id field which is essential for a Hello message and the libev implementation doesn't seem to implement session_ticket (it is possible to do session resumption with only session_id). But in either case, there doesn't seem to be any validation and replays can be easily made.

Clone this wiki locally