#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# estr2bc.py
#
# Convert arbitrary string input to Erlang bytecode
#
# Jeremy Brown [jbrown3264/gmail]
# Dec 2020
#
# Example
# > estr2bc.py "ps -aux"
# [112,115,32,45,97,117,120]
#
# > rpc:call('node', file, write_file, ["test", [112,115,32,45,97,117,120]]).
#
# There's probably a native way to do this within Erlang, but this script is
# useful in the exploit chain eg. for generating Riak file:write_file payloads
#

import os
import sys
import argparse
import string

#
# enough for most things
#
string_special_1 = ' !"#$%&\'()*+,-./'
string_special_2 = ':;<=>?@'
string_special_3 = '[\\]^_`'

class Estr2bc(object):
	def __init__(self, args):
		self.input = args.input

	def run(self):
		special_1 = dict()
		for i, c in enumerate(string_special_1):
			special_1[c] = i + 32

		numbers = dict()
		for i, c in enumerate(string.digits):
			numbers[c] = i + 48

		special_2 = dict()
		for i, c in enumerate(string_special_2):
			special_2[c] = i + 58

		alpha_upper = dict()
		for i, c in enumerate(string.ascii_uppercase):
			alpha_upper[c] = i + 65

		special_3 = dict()
		for i, c in enumerate(string_special_3):
			special_3[c] = i + 91

		alpha_lower = dict()
		for i, c in enumerate(string.ascii_lowercase):
			alpha_lower[c] = i + 97

		bytecode = ""

		for c in self.input:
			if(c in string_special_1):
				bc = str(special_1[c])
			elif(c in string.digits):
				bc = str(numbers[c])
			elif(c in string_special_2):
				bc = str(special_2[c])
			elif(c in string.ascii_uppercase):
				bc = str(alpha_upper[c])
			elif(c in string_special_3):
				bc = str(special_3[c])
			elif(c in string.ascii_lowercase):
				bc = str(alpha_lower[c])
			else:
				print("error: can't map character '%s'" % (c))
				return -1

			bytecode += bc + ','

		bytecode = bytecode[:-1]

		print("[%s]" % bytecode)

		return 0

def arg_parse():
	parser = argparse.ArgumentParser()

	parser.add_argument("input",
						type=str,
						help="String you wish to convert to bytecode")

	args = parser.parse_args()

	return args

def main():
	args = arg_parse()

	esb = Estr2bc(args)
	result = esb.run()

	if(result != 0):
		sys.exit(-1)

if(__name__ == '__main__'):
	main()