WEP (Shared Key Authentication), how is the 136 byte challenge response formed? - rc4-cipher

I am playing around with WEP(Shared key authentication) challenge/response mechanism at the moment and I hope someone could help me out.
The AP sends a challenge text to the STA. The challenge text is 128 bytes
The STA encrypts the challenge and sends it back to the AP. This is 136 bytes (data) in wireshark.
My Question:
Can someone tell me the make-up of the 136 byte data challenge response and why it is this size.
Why is it not Enc([challengetext (128)] + [icv(4)]) = 132 bytes?
Thanks.

You forgot the 4 bytes of the IV in the beginning.

I'm not an expert and I'm using personal experience to confirm the answer to the question. Feel free to edit eventual wrong terms.
TL;DR
Encrypted frame send by the STA contains:
802.11 parameters (24 bytes)
WEP parameters (clear IV + key index) (4 bytes)
management headers (encrypted) (8 bytes)
data (encrypted) (128 bytes)
ICV (encrypted) (4 bytes)
Total is 168 bytes, total of encrypted data without ICV is 136 bytes.
The encrypted data shown by Wireshark and Cie is 8 bytes longer than clear text challenge because it also carries the management headers (encrypted but predictable).
What does the AP send?
Clear text challenge frame sent by the AP is 160 bytes long, and the encrypted challenge response frame is 168 bytes long. That is not the question, but let's make things clear.
In the clear text AP messages, the management headers are also clear text:
Authentication algorithm (2 bytes)
Authentication SEQ (2 bytes)
status code (2 bytes)
tag number (1 byte)
tag length (1 byte)
(challenge) ('tag length' bytes)
The management header are 8 bytes long.
What does the STA send?
In the STA encrypted message, everything over 802.11 layer is considered as "data" as this is encrypted gibberish. Before this data, you can find (part of the 802.11 layer) the WEP parameters: IV (3 bytes) and key index (1 bytes). This is clear text. You also have the ICV, the very last 4 bytes of the frame. Those are 8 bytes that appear in all WEP encrypted frames.
The "data" section contains the encrypted challenge and the encrypted management headers (that's what answers your question).
Your question
If you have 8 more bytes in the WEP frame that actually seem to compensate the 8 bytes management headers, then why your encrypted challenge data is 8 bytes longer?
This is not because of IV or ICV, as we saw before, as they are not part of the challenge data. Those 8 bytes are actually from the management headers, that are encrypted within the "data" section. The frame containing the encrypted challenge is also a management frame, but you can't see the headers as they are encrypted. Those are your 8 mysterious bytes (see simplified frame skeletons below)
I will finish on the fact that those shared key authentications permit you to do offline dictionnary or bruteforce attacks on WEP authentication captures without any IV (except the one used to encrypt the challenge of course). The fact that the first 8 encrypted bytes are management headers makes them predictable (it's always the same). So in a bruteforce implementation, you can just RC4 the first 4 or 8 bytes of the frame, instead of the whole 136 bytes, which leads to way better performance on huge dictionnary/full bruteforce attacks.
Authentication frames skeleton
Management frame with cleartext challenge
--------------------------------------------------------------
(ieee 802.11 headers) -> 24 bytes
--------------------------------------------------------------
---------------- 8 bytes management headers ------------------
ieee 802.11 Wireless Management:
[0][1] == Authentication algo (int16) == 0x0100 (Shared Key)
[2][3] == Authentication SEQ (int16) == 0x0002
[4][5] == Status code (int16) == 0x0000 (Successful)
[6] == Tag Number (int8) == 0x10 (Challenge text)
[7] == Tag length (int8) == 0x80 (128 bytes long challenge)
--------------------------------------------------------------
---------------------- 128 bytes data ------------------------
[0:128]== Challenge text
--------------------------------------------------------------
24 + 8 + 128 = 160 bytes frame
Encrypted frame with predictable encrypted management headers
--------------------------------------------------------------
(ieee 802.11 headers) -> 24 bytes
--------------------------------------------------------------
------------------ 4 bytes WEP parameters --------------------
[0][1][2] == IV (3 bytes, clear text)
[3] == key index (int8) (should be 0)
--------------------------------------------------------------
---------------- 8 bytes management headers ------------------
From here, everything is encrypted
[0][1] == Authentication algo (int16) == 0x0100 (Shared Key)
[2][3] == Authentication SEQ (int16) == 0x0003 (incremented since last frame)
[4][5] == Status code (int16) == 0x0000 (Successful)
[6] == Tag Number (int8) == 0x10 (Challenge text)
[7] == Tag length (int8) == 0x80 (128 bytes long challenge)
--------------------------------------------------------------
---------------------- 128 bytes data ------------------------
[0:128]== Encrypted data challenge
--------------------------------------------------------------
---------------------- 4 bytes ICV ---------------------------
[0:4] == WEP ICV
--------------------------------------------------------------
24 + 4 + 8 + 128 + 4 = 168 bytes frame
8 + 128 = 136 bytes "data" (as wireshark interprets it)
The only thing that changes from the previous one in the management headers of the encrypted frame is the SEQ number.

Related

inspect inner geneve packet using tcpdump

I want to put filters on inner packets encapsulated by geneve.
If I put a filter like
tcpdump -vnn udp -i eth0
It filters all geneve packets as the header above geneve is udp.
How to filter the packets which are inside geneve which has proto field set to udp?
I managed to find a sample capture file online that contains Geneve traffic. It's the geneve.pcap file available at Cloudshark.
I download this file and modified one of the packets so the inner encapsulated protocol was UDP instead of ICMP. I was then able to come up with a capture filter to isolate that packet while testing with tcpdump. Here's the command with capture filter that I used to test this:
tcpdump -r geneve_udp.pcap "(udp port 6081) and (udp[10:2] = 0x6558) and (udp[(8 + (4 * (2 + (udp[8:1] & 0x3f))) + 12):2] = 0x0800) and (udp[8 + (4 * (2 + (udp[8:1] & 0x3f))) + 14 + 9:1] = 17)"
Explanation of the capture filter:
udp port 6081: This part just filters for Geneve packets, as identified by the UDP port number.
udp[10:2] = 0x6558: This part filters for Geneve packets with a Protocol Type of "Transparent Ethernet bridging".
udp[(8 + (4 * (2 + (udp[8:1] & 0x3f))) + 12):2] = 0x0800: This somewhat complicated part filters for encapsulated Ethernet frames having an Ethertype of 0x0800 (IPv4). It does this by:
Skipping the 8 bytes of the UDP header itself.
Skipping the Geneve Header, which is 8 bytes plus 4 times the Opt Len, which we must isolate from the byte because this field is only contained within the lower 6 bits.
Skipping to the Ethertype field of the encapsulated Ethernet header.
And finally comparing the 2-byte value found there to the IPv4-assigned Ethertype of 0x0800.
udp[8 + (4 * (2 + (udp[8:1] & 0x3f))) + 14 + 9:1] = 17: This somewhat complicated part filters for encapsulated IPv4 headers having a Protocol field as 17 (UDP). It does this by:
Skipping the 8 bytes of the UDP header itself.
Skipping the Geneve Header, which is 8 bytes plus 4 times the Opt Len, which we must isolate from the byte because this field is only contained within the lower 6 bits.
Skipping the 14 bytes of the encapsulated Ethernet header.
Skipping the 1st 9 bytes of the encapsulated IP header to get to the proper offset of the IPv4 Protocol field.
And finally comparing the value of that field with the UDP-assigned protocol value of 17.
If the Geneve protocol encapsulates UDP within IPv6 instead of IPv4, then you'll have to modify the capture filter accordingly.
NOTE: I'm not sure if I should just delete my original answer or not? For now, I'll just leave it below ...
I'm not familiar with this Geneve protocol, nor do I have any capture files to test with, but you should be able to use the slice operator (i.e., []) if you know the offset to the field containing the desired value indicating that the inner protocol is UDP.
For illustrative purposes, I'll assume that if the Protocol Type field of the Geneve Header contains the value 17, then this indicates an encapsulated UDP packet. Assuming this is correct, then a filters such as follows may help:
"udp[10:2] = 17"
This filter compares the 2 bytes at offset 10 of the UDP data to the value of 17, which as I understand it, is the location of the Protocol Type field of the Geneve Header. You'll obviously need to adjust the offset if this assumption or my understanding of the protocol isn't correct.
Refer to the pcap-filter man page for more help on the capture filter syntax.

How do I find password related information of a password protected PDF?

I was trying to gather information about password used to protect a PDF. I used PeePDF and xxd editor to view all the objects of password protected PDF.I came to know password info is stored in trailer part of PDF structure.When I run this command , I got
xxd my_encrypted.pdf | tail -n 4
00022c60: 5d0a 2f49 6e66 6f20 3220 3020 520a 2f45 ]./Info 2 0 R./E
00022c70: 6e63 7279 7074 2034 2030 2052 0a3e 3e0a ncrypt 4 0 R.>>.
00022c80: 7374 6172 7478 7265 660a 3134 3139 3934 startxref.141994
00022c90: 0a25 2545 4f46 0a .%%EOF.
So, I understood that /Encrypt dictionary is in object 4. Now using PeePDF, I tried
PPDF> object 4
<< /O ��%�}�&��
v����o
B��z���B�
/Filter /Standard
/Length 128
/V 2
/U ZM����S��3�
fmL
/R 3
/P -1 >>
/O is owner password
/U is user password of PDF
PPDF> info 4
Offset: 699
Size: 206
MD5: 8a74ac53f9e6c1f4da44bcdbb65509e9
Object: dictionary
References: []
I got this info . I didn't even get the hash of password. What is that junk text represent ? Is it encrypted password ? What is MD5 hash represent ?
please tell me if there are any other tools that could analyse PDFs and get hash of password that is protecting PDF.
Thank you
If nothing else helps, read the specification.
In the case at hand the specification to read is the PDF specification, i.e. ISO 32000-1 and ISO 32000-2.
A copy of ISO 32000-1 is published by Adobe at https://www.adobe.com/go/pdfreference/ (beware, the exact location has moved around a bit over the years) - it is complete and merely has the official ISO headers replaced by Adobe headers. Read section 7.6 Encryption therein.
In case of your PDF the encryption dictionary entry V with value 2 indicates the use of "Algorithm 1: Encryption of data using the RC4 or AES algorithms" in 7.6.2, "General Encryption Algorithm," but permitting encryption key lengths greater than 40 bits. The entry R with value 3 indicates the revision of the standard security handler. This algorithm/handler pair already is explained in ISO 32000-1.
In particular you can read there how the O and U values are calculated:
Algorithm 3: Computing the encryption dictionary’s O (owner password) value
a)Pad or truncate the owner password string as described in step (a) of "Algorithm 2: Computing an encryption key". If there is no owner password, use the user password instead.
b)Initialize the MD5 hash function and pass the result of step (a) as input to this function.
c)(Security handlers of revision 3 or greater) Do the following 50 times: Take the output from the previous MD5 hash and pass it as input into a new MD5 hash.
d)Create an RC4 encryption key using the first n bytes of the output from the final MD5 hash, where n shall always be 5 for security handlers of revision 2 but, for security handlers of revision 3 or greater, shall depend on the value of the encryption dictionary’s Length entry.
e)Pad or truncate the user password string as described in step (a) of "Algorithm 2: Computing an encryption key".
f)Encrypt the result of step (e), using an RC4 encryption function with the encryption key obtained in step (d).
g)(Security handlers of revision 3 or greater) Do the following 19 times: Take the output from the previous invocation of the RC4 function and pass it as input to a new invocation of the function; use an encryption key generated by taking each byte of the encryption key obtained in step (d) and performing an XOR (exclusive or) operation between that byte and the single-byte value of the iteration counter (from 1 to 19).
h)Store the output from the final invocation of the RC4 function as the value of the O entry in the encryption dictionary.
and
Algorithm 5: Computing the encryption dictionary’s U (user password) value (Security handlers of revision 3 or greater)
a)Create an encryption key based on the user password string, as described in "Algorithm 2: Computing an encryption key".
b)Initialize the MD5 hash function and pass the 32-byte padding string shown in step (a) of "Algorithm 2: Computing an encryption key" as input to this function.
c)Pass the first element of the file’s file identifier array (the value of the ID entry in the document’s trailer dictionary; see Table 15) to the hash function and finish the hash.
d)Encrypt the 16-byte result of the hash, using an RC4 encryption function with the encryption key from step (a).
e)Do the following 19 times: Take the output from the previous invocation of the RC4 function and pass it as input to a new invocation of the function; use an encryption key generated by taking each byte of the original encryption key obtained in step (a) and performing an XOR (exclusive or) operation between that byte and the single-byte value of the iteration counter (from 1 to 19).
f)Append 16 bytes of arbitrary padding to the output from the final invocation of the RC4 function and store the 32-byte result as the value of the U entry in the encryption dictionary.
In both cases step (a) of "Algorithm 2: Computing an encryption key" is referenced:
Algorithm 2: Computing an encryption key
a)Pad or truncate the password string to exactly 32 bytes. If the password string is more than 32 bytes long, use only its first 32 bytes; if it is less than 32 bytes long, pad it by appending the required number of additional bytes from the beginning of the following padding string:
< 28 BF 4E 5E 4E 75 8A 41 64 00 4E 56 FF FA 01 08
2E 2E 00 B6 D0 68 3E 80 2F 0C A9 FE 64 53 69 7A >
That is, if the password string is n bytes long, append the first 32 - n bytes of the padding string to the end of the password string. If the password string is empty (zero-length), meaning there is no user password, substitute the entire padding string in its place.
...

computing the exchange hash for ecdsa-sha2-nistp256

I am writing code for an SSH server and can not get past the Elliptic Curve Diffie-Hellman Key Exchange Reply part of the connection. The client also closes the connection and says "Host Key does not match the signature supplied".
I am using putty as the client and a PIC micro-controller is running the server code.
From RFC 5656 [SSH ECC Algorithm Integration] :
"The hash H is formed by applying the algorithm HASH on a
concatenation of the following:
string V_C, client's identification string (CR and LF excluded)
string V_S, server's identification string (CR and LF excluded)
string I_C, payload of the client's SSH_MSG_KEXINIT
string I_S, payload of the server's SSH_MSG_KEXINIT
string K_S, server's public host key
string Q_C, client's ephemeral public key octet string
string Q_S, server's ephemeral public key octet string
mpint K, shared secret
"
the host key algorithm and key exchange algorithm is ecdsa-sha2-nistp256 and ecdh-sha2-nistp256 respectively.
referring to RFC 4251 for data type representations, as well as the source code in openSHH (openBSD) this is what I have concatenated.
4 bytes for then length of V_C followed by V_C
4 bytes for then length of V_S followed by V_S
4 bytes for length of I_C followed by I_C (payload is from Message Code to the start of Random Padding)
4 bytes for length of I_S followed by I_S (payload is from Message Code to the start of Random Padding)
4 bytes for the length of K_S followed by K_S (for K_S I used the same group of bytes that is used to calculate the fingerprint)
4 bytes for the length of Q_C followed by Q_C (i used the uncompressed string which has length of 65 - 04||X-coordinate||Y-coordinate)
4 bytes for the length of Q_S followed by Q_S
4 bytes for the length of K followed by K (length is 32 or 33 depending is the leading bit is set or not. If it is set then K is preceded by a 00 byte)
Once concatenated I hash it with SHA256 because I'm using NISTP256. SHA256 outputs 32 bytes which is the size of the curve, so I take the whole SHA256 output and perform the signature algorithm on it.
I can never get the correct signature from my message concatenation.
I know my signature algorithm is correct because given the message hash output I can get the correct signature.
I know my shared secret is correct because I get the same output as online shared secret calculators.
I know the SHA256 is correct because I get the same result using online calculators.
This leads me to assume the error is in the concatenation of the exchange hash.
Any help is greatly appreciated, thanks.
ECDSA signature generation is non-deterministic, i.e. part of the input is the hash and part of the input consists of random bytes. So whatever you do, you will always get a different signature. This is all right because signature verification will still work.
The only way to get a repeated signature is to mess with the random number generator (during testing, you don't want to sign two values using the same random number: you'd expose the private key!).

padding about OpenSSL heartbleed

I have something not understand about the padding part of the heartbeat in openSSL.
In the code of openssl 1.0.1g, it shows as the followings:
n2s(p, payload);
if (1 + 2 + payload + 16 > s->s3->rrec.length)
return 0; /* silently discard per RFC 6520 sec. 4 */
pl = p;
It shows that the length of padding is 16, however in the RFC6520, it says that the padding length is at least 16 bytes. Then if the client send a heartbeat with the padding (32 bytes or bigger), does the code of OpenSSL still has vulnerability?
1 + 2 + payload + 16 is the minimum message length; it might be less than a corresponding message length, but it cannot be greater. Thus, the test says that if that calculated value is greater than the actual message length, which is inconsistent with a well constructed heartbeat, the message should be discarded, preventing the bug.

Maximum size of ICMP IPv6 packet

With reference to this question and to ASIO libary, I would like to know what is the maximum size of ICMP v6 reply packet. I'm using ASIO library to listen for and receive ICMPv6 packets, but I don't know what size of buffer to use in order to prevent buffer over flow. I'm confused by IPv6 supporting extension headers.
Ex code:
asio::streambuf replyBuffer;
replyBuffer.consume(replyBuffer.size());
size_t length = icmpV6Socket->receive(replyBuffer.prepare(65536) );
One of the great features of Boost.Asio's buffers is that they provide protection against buffer overruns. Boost.Asio's buffers pair together a handle to the actual memory and the size. Thus, as long as the size is properly set or deduced, then Boost.Asio operations will not produce buffer overruns.
Nevertheless, the details for ICMPv6 sizes are as follows. IPv6 Header is 40 bytes, and reserves 2 bytes to represent the Payload Length. Thus, the max payload for IPv6, including extension headers, is 65,535. This differs from IPv4, where the Total Length included the header itself. The ICMPv6 Echo Reply header is 8 bytes.
Therefore:
The maximum IPv6 packet is 65,575 bytes (max payload of 65,535 + header of 40).
The maximum IPv6 payload is 65,535 bytes.
The maximum ICMPv6 Echo Reply body is 65,527 bytes. (max payload of 65,535 - ICMPv6 Echo Reply Header of 8).