-
-
Save nstarke/41073639476fcc712ccd09fd5f58745f to your computer and use it in GitHub Desktop.
Reverse engineered partial Aruba PAPI implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hashlib | |
from struct import * | |
""" | |
This implementation was reverse engineered using Wireshark (and source code), strace and two excelent articles: | |
- https://x-c3ll.github.io/posts/CVE-2018-7081-RCE-ArubaOS/ | |
- https://packetstormsecurity.com/files/136997/Aruba-Authentication-Bypass-Insecure-Transport-Tons-Of-Issues.html | |
""" | |
def papi_encrypt(data): | |
decrypted = '' | |
for c in data: | |
decrypted += chr(c ^ 0x93) | |
return bytes(decrypted, 'latin-1') | |
def papi_header(dst_host, src_host, dst_port, src_port, sequence_number, message_code, body, calculate_checksum): | |
header = b'\x49\x72' # Magic Header for PAPI message | |
header += b'\x00\x03' # Protocol Version ??? I have observed values 1 and 3 | |
header += bytes(map(int, dst_host.split('.'))) # Destination host | |
header += bytes(map(int, src_host.split('.'))) # Source host | |
header += b'\x00\x00' # NAT Port number | |
header += b'\x00\x00' # "garbage" | |
header += pack('>H', dst_port) # Destination port | |
header += pack('>H', src_port) # Source port | |
header += b'\x20\x04' # Packet type ??? | |
header += b'\x00\x00' # Packet size ??? Seems unused in version 3 | |
header += pack('>H', sequence_number) # sequence_number | |
header += pack('>H', message_code) # PAPI message code - application specific | |
checksum = b'\x00'*16 # Empty checksum | |
padding = b'\x00'*32 # Header padding | |
if calculate_checksum: | |
m = hashlib.md5() | |
m.update(header + checksum + padding + body) | |
key = b'asdf;lkj763' | |
m.update(key) | |
checksum = m.digest() # Calculated checksum | |
header += checksum | |
header += padding | |
return header | |
def sxdr_write_ip(str_ip): | |
msg = b'\x05' | |
msg += bytes(map(int, str_ip.split('.')))[::-1] #??? | |
return msg | |
def sxdr_write_u8(value): | |
msg = b'\x02' | |
msg += pack('B', value) | |
return msg | |
def sxdr_write_u16(value): | |
msg = b'\x03' | |
msg += pack('>H', value) | |
return msg | |
def sxdr_write_u32(value): | |
msg = b'\x04' | |
msg += pack('>I', value) | |
return msg | |
def sxdr_write_bool(value): | |
msg = b'\x07' | |
if value: | |
msg += sxdr_write_u8(1) | |
else: | |
msg += sxdr_write_u8(0) | |
return msg | |
def sxdr_write_str(value): | |
msg = b'\x00' | |
msg += pack('>H', len(value)) | |
msg += bytes(value, 'latin-1') | |
return msg | |
def sxdr_write_str2(value): | |
msg = b'\x00' | |
msg += pack('B', len(value)) | |
msg += bytes(value, 'latin-1') | |
return msg |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment