您的位置:首页 > 其它

smartconfig 工作原理

2016-02-29 18:18 453 查看
Initially TI clearly documented how the SSID and password were transmitted to a CC3000 enabled device in their "CC3000
First Time Configuration" document. However with release
1.10 they changed the approach to one called Smart Config and now document the API but
no longer explain what is happening at the network level. Here I cover this missing information for the new approach.

So let's start at the start - we have a problem - we want to send two pieces of information, an SSID and the keyphrase, from one party that is already a member of the wifi network to an external party who can monitor all the encrypted wifi traffic but who cannot
decrypt it.

Someone who cannot decrypt the wifi traffic can still see quite a lot of information, e.g. they can see the source and receiver MAC addresses of every packet sent.

They can also see the length of the data portion of the packets. The encryption affects that size of the packets sent but in a consistent manner, e.g. if one sends n bytes of data in a given packet then the encrypted
packet will contain (n + x) bytes where x is constant across all packets.

So the solution to our problem is to encode the information in the size of the packets sent (the actual content is irrelevant).

The party on the secured network just sends UDP packets with particular lengths to another party on the network. That the other party is not interested in receiving the packets is not important.

The external party cannot tell directly that a packet that it is looking at contains UDP data, however the packets still include basic type information that allows many packets to be excluded from consideration, e.g. any packet that is not of 802.11 subtype
"QoS data" can be excluded.

As the external party does not know in advance which wifi channel to look at or which source and receiver address pair to pay attention to one must, in addition to the underlying data, i.e. encoded SSID etc., send regular repeating patterns that allow this
data to be spotted.

We convert our SSID and keyphrase into a sequence of tag values, string lengths, nibble values and separators values and then encode and transmit all these values as packet lengths.

Let's look in detail at the values sent.

We use two tags - an SSID tag with value 1399 and a keyphrase tag with value 1459 and one standard separator sequence consisting of two values - 3 followed by 23.

And we use two constants, L with value 28 and C with value 593, that we will see used below.

So for the SSID the following sequence of values are generated in this order:

The SSID tag 1399.
L plus the length of the SSID in bytes.
The two separator values 3 and 23.
Then we loop over each byte of the SSID and generate a set of four values for each:

Two values - one for each nibble of the byte, as described in the next section.

Followed by the two separator values 3 and 23.
Values are generated in an identical fashion for the keyphrase (except that the keyphrase tag 1459 is used in place of the SSID tag).

Note: the TI Android library and Java applet library generate values as described above, oddly the TI iOS library produces a slightly different ordering (which clearly
doesn't affect the CC3000's ability to decode the data). This difference can be seen in the example data length dumps shown latter.

Once we have all these values then UDP packets, each with an amount of data corresponding to one of these values, are sent from the machine running the Smart Config
application, i.e. the one that has generated the values just described, to another system on the same network (currently always the network's default gateway).

The values are sent repeatedly until the external party, i.e. the CC3000 enabled device, successfully sifts them out from all the other network traffic and uses them
to connect to the network, at which point it advertises
its presence on the network in a manner that the transmitting application can detect and which causes it to stop transmitting.

Note that the range of packet lengths that need to be supported places a lower bound on the maximum transmission unit (MTU) for the network. Currently the Smart Config
client application expects the MTU to be 1500 or greater (this is a reasonable expectation on any normal network).

The TI Smart Config reference implementation resends the full set of UDP packets corresponding to the SSID and keyphrase repeatedly. The TI Java applet library pauses
100ms after each complete transmission of the full set of values, the Android and iOS libraries do not bother pausing.


Encoding the characters of the SSID or keyphrase.

If an SSID consists of n characters 0 to n
- 1 then we generate 2n corresponding
values.

Note: according to IEEE standard 802.11i-2004,
Annex H.4.1, users may enter keys as a string of 64 hexadecimal digits (or alternatively as a passphrase of printable ASCII characters). Presumably WEP and WPA specify similar restrictions. The SSID must be a sequence of between 1 and 32 bytes, there is no
mandated character set (more details in this
StackOverflow answer) and how the SSID is displayed is left up to the end user application (however many routers apparently only accept printable ASCII characters
for the SSID).

So if we assume ASCII characters encoded as 8 bit values then each value consists of a high and low nibble.

E.g. 'M' in ASCII is hex 0x4D, the high nibble is 0x4 and the lower nibble is 0xD.

If we maintain a sequence number starting from 0 and increment it each time we generate a value then for character i of
the SSID, consisting of a high and low nibble Hi and
Li, we generate two values with
sequence number 2i and (2i
+ 1) respectively. Each of these values has a high and low nibble calculated as follows:

Seq.HighLow
2iLi-1 ^ (2i % 16)Hi
2i+1Hi ^ ((2i + 1) % 16)Li
Note that the value containing the high nibble of i is
generated before the one containing the low nibble of i. And note that caret, i.e. '^', is used here to mean XOR,
rather than power of.

The following shows how the SSID "MyPlace" would be split up into high and low nibbles:

 'M''y''P''l''a''c''e'
Hex:0x4D0x790x500x6C0x610x630x65
Nibbles:0x40xD0x70x90x50x00x60xC0x60x10x60x30x60x5
H0L0H1L1H2L2H3L3H4L4H5L5H6L6
For each 4 bit nibble we generate a value whose lower 4 bits consist of the nibble itself and whose higher 4 bits consist of the current sequence number XORed with
the value of the previously used nibble value. We then add the constant C mentioned above, i.e. 593, to each value generated in this way and this becomes the length of the packet that encodes such a value.

Note that the 4 bit constraint means that we only use the lower 4 bits of the current sequence number, i.e. if the sequence number S is
above 15 then we use S % 16.

This results in the generation of 14 values for the 7 character of the SSID name "MyPlace" like so:

C

h

a

r
S

e

q
HiLoByteHiLoHiLoSumLen
'M'0 0x0H0 0x4D0x00x4 0x00x4 0x04 + 593 597
1H0 ^ 0x1L00x4 ^ 0x10xD0x50xD0x5D + 593686
'y'2L0 ^ 0x2H10x790xD ^ 0x20x70xF0x70xF7 + 593840
3H1 ^ 0x3L10x7 ^ 0x30x90x40x90x49 + 593666
'P'4L1 ^ 0x4H20x500x9 ^ 0x40x50xD0x50xD5 + 593806
5H2 ^ 0x5L20x5 ^ 0x50x00x00x00x00 + 593593
'l'6L2 ^ 0x6H30x6C0x0 ^ 0x60x60x60x60x66 + 593695
7H3 ^ 0x7L30x6 ^ 0x70xC0x10xC0x1C + 593621
'a'8L3 ^ 0x8H40x610xC ^ 0x80x60x40x60x46 + 593663
9H4 ^ 0x9L40x6 ^ 0x90x10xF0x10xF1 + 593834
'c'10L4 ^ 0xAH50x630x1 ^ 0xA0x60xB0x60xB6 + 593775
11H5 ^ 0xBL50x6 ^ 0xB0x30xD0x30xD3 + 593804
'e'12L5 ^ 0xCH60x650x3 ^ 0xC0x60xF0x60xF6 + 593839
13H6 ^ 0xDL60x6 ^ 0xD0x50xB0x50xB5 + 593774
The keyphrase is encoded in the same way, note that the sequence number starts again from 0 when encoding the keyphrase, i.e. the value is not carried over from encoding
the SSID.

Currently Smart Config enforces an upper limit of 32 characters on the keyphrase length, i.e. shorter than the maximum length allowed by the relevant WPA2 standard.

I find the approach used to actively leak information from a secure wireless network to an external party (that does not have the relevant network keyphrase) interesting
and would like to hear if anyone has come across it before or whether it is novel? I asked about this on Stack Overflow but have since moved the question to
the sister site crypto.stackexchange.com after people suggested it was more appropriate there.

Update Oct 21, 2013: I've now got at least one good answer.
In a paper from 2007 by P. Martin called "Covert
channels in secure wireless networks" you can find section 4.4.2 "UDP Packet Size vs MAC Frame Size Experiment" that essentially describes exactly the process
used by Smart Config. The question of patents has come up once or twice in relation to Smart Config (though no one has ever provided pointers to any actual patent applications or granted patent numbers). The answers and other comments on my question would
seem to suggest that there's definitely prior art for the fundamental idea behind Smart Config.


Choosing the destination for the UDP packets

The current logic always sends the UDP messages, that encode the SSID etc., to the default gateway address. However it doesn't actually matter what address they're
sent to as long as it's the address of another machine on the network that actually exists and is capable of receiving packets. However it makes sense to have decided on a definite address.

The CC3000 doesn't support ad hoc networks so you are never going to get a situation where it is used on a network that doesn't have an access point (AP), and in most
normal setups the AP is also the default gateway. However I don't think a default gateway is mandatory (someone can correct me on this?), one can imagine a self contained wifi network where the AP isn't a gateway to anywhere else.

I wonder why TI didn't choose on the address of the AP rather than the default gateway. Even if the two are almost always the same I think an end user is probably likely
to have much more luck, if needed, asking Google or their ISP first level technical support how they find the address of their wifi AP than asking about default gateways.

Note: in a network using an AP all traffic goes via the AP, so even if one chose the address of a machine other than the AP the traffic would still be received by the
AP and retransmitted by the AP to the destination machine. This doesn't cause an issue if you try it with the CC3000 but it does mean the traffic in pointlessly duplicated.


Further details of the Smart Config library

The sections above cover the heart of how Smart Config works, the following covers details of TI's Smart Config Java applet library that don't immediately seem relevant
- they may be left over from the development process and have just never been cleaned out or they may relate to non-default functionality that it's possible to use if a particular CC3000 device is configured in a particular way.

One can set the DatagramSocket used to send the UDP packets to something other than one simply setup to bind to any available port on the local machine.
One can set the port to which the UDP packets are sent to something other than 15000.
One can set the port on which mDNS UDP messages are expected to something other than 5353.
One can set can the timeout, i.e. the time the application waits, for the CC3000 enabled device to connect to something other than 5 minutes.
One can set the number of times all the details are retransmitted before taking a 100ms pause. By default this is 1, i.e. the logic takes a 100ms pause between every full transmission of the
details.
One can set the two separators values, i.e. 3 and 23 mentioned above, to different values and more bizarrely set the characters used to make up the packets with these lengths.

These features are available in the library but are never made use of by the TI Smart Config application built on top of this library.

One can also set the network interface of the socket used to listen for mDNS message. However this seems completely pointless as this just affects outgoing multicast datagrams and the relevant logic is only looking for incoming datagrams.

With one exception all of this configurability looks pointless.

It's hard to think of why one might want to specify the bind address of the DatagramSocket used to send the UDP packets.
The machine receiving the packets will ignore them and so choosing a particular port seems irrelevant and with encrypted network traffic one cannot see port information so it shouldn't be relevant
to the CC3000 device's ability to detect the relevant traffic.
mDNS always uses port 5353 and given how mDNS is used it's hard to imagine that port number being changed on a particular network.
The timeout is fairly arbitrary, 5 minutes seems extremely long so it does seem reasonable to adjust it down if one really cares about this.
Being able to set the number of full retransmits before a pause has no obvious benefits.

That leaves us with being able to change the separator lengths. Perhaps this is configurable on CC3000 devices. I can't see a reason why you'd want to change the default values. And if one did I suspect one would have to be careful what values one chose. The
tag values for SSID and keyphrase, and the constants C and L mentioned above, along with the two separator length values, all seem to have been chosen to ensure no overlap in values between one kind of thing and another, the current setup means no packet length
encoding a nibble of an SSID character or keyphrase will end up with a length equal to the tags or separator values.

Note: the port number 15000 mentioned above has not been registered by TI and actually belongs to a legitimate service called "hydap"
which has been registered by HYPACK Inc. with IANA. This shouldn't be an issue for anyone.


Multicast mDNS

Above you saw some mention of mDNS. This is involved in detecting that a CC3000 device has successfully connected to the network and is discussed in more detail in this
post.


What character set does the CC3000 use?

The Smart Config Java applet library stores the SSID etc. as standard Java strings, i.e. sequences of Unicode characters. It converts back and forward between these strings and arrays of bytes at various points, but takes
no care of character sets, e.g. when it calls String.getBytes() it always uses the form that uses the platform's default character set. This will work on most systems, including pretty much everything in the US and Western Europe, but will obviously be an
issue elsewhere. The CC3000 presumably has a fixed character set and this should be used explicitly in the library when converting between characters and bytes.

Update: experimentation shows that while the TI Java applet library just uses the default character set of the machine it's running on, when converting to and from bytes, the TI iOS and Android apps both seem
to consistently use UTF-8.


Packet length dumps from the TI Smart Config applications

If any of the above wasn't too clear, hopefully this section will help with a practical example of the packet lengths generated by the TI Smart Config applications when sending the SSID "MyPlace" and the password "LetMeIn".

The first dump shows the packet lengths generated by the Android and Java applet applications. The first colum just shows the UNIX
time the packet was sent at, the second column shows the length of the packet and this is then followed by an indication of what the length of packet is encoding.

1381084544.032552000 1399 <----- SSID tag

1381084544.033572000 35 <----- SSID length + 28

1381084544.033589000 3 <--+-- separator

1381084544.033594000 23 <--'

1381084544.033667000 597 <----- 'M' hi-nibble

1381084544.033675000 3 <--+-- separator

1381084544.033723000 23 <--'

1381084544.034369000 686 <----- 'M' lo-nibble

1381084544.035385000 3 <--+-- separator

1381084544.036271000 23 <--'

1381084544.036448000 840 <----- 'y' hi-nibble

1381084544.036467000 3 <--+-- separator

1381084544.036481000 23 <--'

1381084544.036541000 666 <----- 'y' lo-nibble

1381084544.037262000 3 <--+-- separator

1381084544.037271000 23 <--'

1381084544.037496000 806 <----- 'P' hi-nibble

1381084544.038019000 3 <--+-- separator

1381084544.038032000 23 <--'

1381084544.038097000 593 <----- 'P' lo-nibble

1381084544.043096000 3 <--+-- separator

1381084544.044209000 23 <--'

1381084544.044785000 695 <----- 'l' hi-nibble

1381084544.045422000 3 <--+-- separator

1381084544.045855000 23 <--'

1381084544.048359000 621 <----- 'l' lo-nibble

1381084544.049327000 3 <--+-- separator

1381084544.049347000 23 <--'

1381084544.049406000 663 <----- 'a' hi-nibble

1381084544.049412000 3 <--+-- separator

1381084544.049416000 23 <--'

1381084544.049568000 834 <----- 'a' lo-nibble

1381084544.050052000 3 <--+-- separator

1381084544.050067000 23 <--'

1381084544.050808000 775 <----- 'c' hi-nibble

1381084544.051463000 3 <--+-- separator

1381084544.052082000 23 <--'

1381084544.055415000 804 <----- 'c' lo-nibble

1381084544.056319000 3 <--+-- separator

1381084544.056334000 23 <--'

1381084544.056398000 839 <----- 'e' hi-nibble

1381084544.056404000 3 <--+-- separator

1381084544.056407000 23 <--'

1381084544.056644000 774 <----- 'e' lo-nibble

1381084544.058021000 3 <--+-- separator

1381084544.058034000 23 <--'

1381084544.059236000 1459 <----- passphrase tag1381084544.059252000 35 <----- passphrase length + 281381084544.059255000 3 <--+-- separator1381084544.059258000 23 <--'1381084544.059261000 597 <----- 'L' hi-nibble1381084544.059937000 3 <--+-- separator

1381084544.059949000 23 <--'

1381084544.060043000 685 <----- 'L' lo-nibble

1381084544.060723000 3 <--+-- separator

1381084544.060729000 23 <--'

1381084544.060884000 823 <----- 'e' hi-nibble

1381084544.061407000 3 <--+-- separator

1381084544.061411000 23 <--'

1381084544.061954000 678 <----- 'e' lo-nibble

1381084544.062651000 3 <--+-- separator

1381084544.062709000 23 <--'

1381084544.063217000 616 <----- 't' hi-nibble

1381084544.063696000 3 <--+-- separator

1381084544.063699000 23 <--'

1381084544.064344000 629 <----- 't' lo-nibble

1381084544.064893000 3 <--+-- separator

1381084544.064897000 23 <--'

1381084544.065561000 629 <----- 'M' hi-nibble

1381084544.066131000 3 <--+-- separator

1381084544.066221000 23 <--'

1381084544.066947000 654 <----- 'M' lo-nibble

1381084544.066955000 3 <--+-- separator

1381084544.067371000 23 <--'

1381084544.067491000 679 <----- 'e' hi-nibble

1381084544.067871000 3 <--+-- separator

1381084544.068325000 23 <--'

1381084544.069089000 838 <----- 'e' lo-nibble

1381084544.069097000 3 <--+-- separator

1381084544.069593000 23 <--'

1381084544.069711000 837 <----- 'I' hi-nibble

1381084544.070191000 3 <--+-- separator

1381084544.070656000 23 <--'

1381084544.074244000 842 <----- 'I' lo-nibble

1381084544.074259000 3 <--+-- separator

1381084544.075225000 23 <--'

1381084544.075286000 679 <----- 'n' hi-nibble

1381084544.075291000 3 <--+-- separator

1381084544.075293000 23 <--'

1381084544.075521000 783 <----- 'n' lo-nibble

1381084544.075533000 3 <--+-- separator

1381084544.076058000 23 <--'-------------------------- No delay on Android, 100ms delay with Java applet library, then repeat from start again.

1381084544.076246000 1399 <----- SSID tag

1381084544.076850000 35 <----- SSID length + 28...

The output generated by the TI iOS and Java applet Smart Config applications is identical (except for the noted 100ms delay). However oddly the iOS Smart Config application does not interleave the separator values 3 and 23 between the characters of the SSID
and keyphrase, instead it always sends out a sequence of 10 separator value pairs as shown here and then sends out the SSID and keyphrase. So here one can hardly call 3 and 23 separators but I've stuck with this name here:

1381085051.154799000 3 <--+-- separator 1

1381085051.159414000 23 <--'

1381085051.164143000 3 <--+-- separator 2

1381085051.170050000 23 <--'

1381085051.174861000 3 <--+-- separator 3

1381085051.179503000 23 <--'

1381085051.185282000 3 <--+-- separator 4

1381085051.190274000 23 <--'

1381085051.195296000 3 <--+-- separator 5

1381085051.200047000 23 <--'

1381085051.206394000 3 <--+-- separator 6

1381085051.211076000 23 <--'

1381085051.215383000 3 <--+-- separator 7

1381085051.225363500 23 <--'

1381085051.235344000 3 <--+-- separator 8

1381085051.235459000 23 <--'

1381085051.236902000 3 <--+-- separator 9

1381085051.241718000 23 <--'

1381085051.249366000 3 <--+-- separator 10

1381085051.253099000 23 <--'

1381085051.257767000 1399 <----- SSID tag

1381085051.262315500 35 <----- SSID length + 28

1381085051.266864000 597 <----- 'M' hi-nibble

1381085051.273117000 686 <----- 'M' lo-nibble

1381085051.278023500 840 <----- 'y' hi-nibble

1381085051.282930000 666 <----- 'y' lo-nibble

1381085051.291178000 806 <----- 'P' hi-nibble

1381085051.294688000 593 <----- 'P' lo-nibble

1381085051.299266000 695 <----- 'l' hi-nibble

1381085051.308603000 621 <----- 'l' lo-nibble

1381085051.311723000 663 <----- 'a' hi-nibble

1381085051.315706000 834 <----- 'a' lo-nibble

1381085051.321567000 775 <----- 'c' hi-nibble

1381085051.326156000 804 <----- 'c' lo-nibble

1381085051.332654000 839 <----- 'e' hi-nibble

1381085051.337025000 774 <----- 'e' lo-nibble

1381085051.342818000 1459 <----- passphrase tag

1381085051.346519000 35 <----- passphrase length + 28

1381085051.353083000 597 <----- 'L' hi-nibble

1381085051.359196000 685 <----- 'L' lo-nibble

1381085051.362984000 823 <----- 'e' hi-nibble

1381085051.366772000 678 <----- 'e' lo-nibble

1381085051.373192000 616 <----- 't' hi-nibble

1381085051.382117000 629 <----- 't' lo-nibble

1381085051.386131000 629 <----- 'M' hi-nibble

1381085051.390145000 654 <----- 'M' lo-nibble

1381085051.393997000 679 <----- 'e' hi-nibble

1381085051.400047000 838 <----- 'e' lo-nibble

1381085051.404880000 837 <----- 'I' hi-nibble

1381085051.412003000 842 <----- 'I' lo-nibble

1381085051.414365000 679 <----- 'n' hi-nibble

1381085051.420336000 783 <----- 'n' lo-nibble--------------------------- No delay then repeat from start again.

1381085051.432048500 3 <--+-- separator 1

1381085051.443761000 23 <--'...


Dumping and decrypting wifi packets using tshark

The above dumps were produced with the command line version of the well known packet analyser tool Wireshark that's
called tshark. Wireshark is available
for Mac OS X, Windows and Linux. The following shows how I used it to produce these dumps.

First I started it off recording packets before doing anything with the particular TI Smart Config application I was working with like so:

$ tshark -i en0 -I -w output.pcap

Note that the -I flag puts your machine's wifi network interface into monitor mode, this disables standard network access for everything else on the machine while tshark
is running but allows tshark to see all the traffic on the network, not just traffic intended for the machine that it's running on. On my Mac putting the network interface into monitor mode works fine but on other platforms this can be far more complicated
- I'll discuss this further in a later post.

I then ran the particular Smart Config application on a different machine, i.e. an iPhone, an Android phone or a different desktop machine. I hit the start button that you find in each Smart Config application that tells
it to start transmitting the SSID etc., and let it run for a while. There's no requirement to have an actual CC3000 enabled device listening for the data. After a few seconds I killed the tshark process with control-C and hit stop in the Smart Config application.

The resulting network traffic ends up in the file output.pcap, note the size of this file can grow very quickly as we're recording all traffic on a given wifi channel, not just the Smart Config related traffic.

Then we can filter out the Smart Config traffic and dump it out as above like so:

$ tshark -r output.pcap -o 'wlan.enable_decryption:TRUE' \ -Y 'wlan.fc.retry == 0 && !icmp && udp && ip.src == 192.168.1.177 && ip.dst == 192.168.1.1 && udp.dstport == 15000' -T fields -e frame.time_epoch -e data.len | head -n 512ip.src must to
be changed to the IP address of the device running the Smart Config application, e.g. an iPhone, and ip.dst must be the IP address used as the gateway by the application.

Note that I exclude icmp packets, these are control packets that can contain embedded UDP packets that would be matched by the udp filter. In our case icmp packets are generated to tell us that the port we are sending the packets to is unreachable. With the
wlan.fc.retry filter I also exclude retransmitted packets - I'll discuss this more in a later post.

As shown here tshark can actually decrypt the wifi packets (something which a CC3000 enabled device that's waiting for the network password obviously cannot do). Having done so it can then filter the traffic using higher level network terms like the IP protocol,
in this case UDP, and IP addresses.

If the option wlan.enable_decryption is set to TRUE, as shown above, tshark will
search for the keyphrase necessary to do the decryption in the file ~/.wireshark/80211_keys where it will expect to find something like:

"wpa-pwd","LetMeIn:MyPlace"

Note that the keyphrase comes before the SSID and that storing keys (in plain text, yes) in the file 80211_keys is
relatively new to wireshark/tshark. For earlier versions of tshark you may have to specify the key information as a command line option - Google for what works for your version.

However even if it has the keyphrase it can only decrypt the traffic if your pcap file contains the EAPOL packets
that are generated when the device designated by ip.src goes through the initial negotiation of a secure connection with the AP. To force my devices to generate such packets I flipped the phones in and out of airplane mode and on my desktops I temporarily
disabled and then reenabled wifi. This didn't always seem to work - I don't know if even on being disabled and reenabled a device can sometimes avoid having to renegotiate its connection. One can check if the pcap file
contains EAPOL packets like so:

$ tshark -r sc-ios.pcap -Y eapol

You should see about four packets which correspond to your device (check that the displayed MAC addresses match the MAC address of the device).

Obviously the CC3000 cannot decrypt the packets like this - I'll discuss in a later post how it does much the same as we've done here but without having the relevant decryption information.

- See more at: http://depletionregion.blogspot.ch/2013/10/cc3000-smart-config-transmitting-ssid.html#sthash.hcSxoH32.dpuf

转自: http://home.eeworld.com.cn/my/space-uid-361439-blogid-253367.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息