Skip to content

Instantly share code, notes, and snippets.

@nstarke
Forked from eriknl/papi.py
Created September 24, 2019 14:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nstarke/41073639476fcc712ccd09fd5f58745f to your computer and use it in GitHub Desktop.
Save nstarke/41073639476fcc712ccd09fd5f58745f to your computer and use it in GitHub Desktop.
Reverse engineered partial Aruba PAPI implementation
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