userbot.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. """
  2. CREDITS:
  3. EVAL AND SH FUNCTION IN THIS MODULE IS WRITTEN BY @Pokurt.
  4. SOURCE:
  5. https://github.com/pokurt/Nana-Remix/blob/master/nana/plugins/devs.py
  6. """
  7. import os
  8. import re
  9. import subprocess
  10. import sys
  11. import traceback
  12. from html import escape
  13. from inspect import getfullargspec
  14. from io import StringIO
  15. from pyrogram import filters
  16. from pyrogram.errors import MessageNotModified
  17. from pyrogram.types import Message, ReplyKeyboardMarkup
  18. from wbb import app # don't remove
  19. from wbb import SUDOERS, USERBOT_PREFIX, app2, arq
  20. from wbb.core.decorators.misc import exec_time
  21. # Eval and Sh module from nana-remix
  22. m = None
  23. p = print
  24. r = None
  25. exec_time = exec_time
  26. arq = arq
  27. async def aexec(code, client, message):
  28. exec(
  29. "async def __aexec(client, message): "
  30. + "".join(f"\n {a}" for a in code.split("\n"))
  31. )
  32. return await locals()["__aexec"](client, message)
  33. async def edit_or_reply(msg: Message, **kwargs):
  34. func = msg.edit_text if msg.from_user.is_self else msg.reply
  35. spec = getfullargspec(func.__wrapped__).args
  36. return await func(
  37. **{k: v for k, v in kwargs.items() if k in spec}
  38. )
  39. @app2.on_message(
  40. filters.user(SUDOERS)
  41. & ~filters.forwarded
  42. & ~filters.via_bot
  43. & filters.command("py", prefixes=USERBOT_PREFIX)
  44. )
  45. async def executor(client, message: Message):
  46. global m, p, r
  47. try:
  48. cmd = message.text.split(" ", maxsplit=1)[1]
  49. except IndexError:
  50. return await message.delete()
  51. if message.chat.type == "channel":
  52. return
  53. m = message
  54. p = print
  55. # To prevent keyboard input attacks
  56. if m.reply_to_message:
  57. r = m.reply_to_message
  58. if r.reply_markup:
  59. if isinstance(r.reply_markup, ReplyKeyboardMarkup):
  60. return await m.edit("INSECURE!")
  61. old_stderr = sys.stderr
  62. old_stdout = sys.stdout
  63. redirected_output = sys.stdout = StringIO()
  64. redirected_error = sys.stderr = StringIO()
  65. stdout, stderr, exc = None, None, None
  66. try:
  67. await aexec(cmd, client, message)
  68. except Exception as e:
  69. exc = str(e)
  70. stdout = redirected_output.getvalue()
  71. stderr = redirected_error.getvalue()
  72. sys.stdout = old_stdout
  73. sys.stderr = old_stderr
  74. evaluation = ""
  75. if exc:
  76. evaluation = exc
  77. elif stderr:
  78. evaluation = stderr
  79. elif stdout:
  80. evaluation = stdout
  81. else:
  82. evaluation = "Success"
  83. final_output = f"**→**\n`{escape(evaluation.strip())}`"
  84. if len(final_output) > 4096:
  85. filename = "output.txt"
  86. with open(filename, "w+", encoding="utf8") as out_file:
  87. out_file.write(str(evaluation.strip()))
  88. await message.reply_document(
  89. document=filename,
  90. caption=f"`→`\n **Attached Document**",
  91. quote=False,
  92. )
  93. os.remove(filename)
  94. else:
  95. mid = message.message_id
  96. # Edit the output if input is edited
  97. if message.edit_date:
  98. async for m in app2.iter_history(message.chat.id):
  99. # If no replies found, reply
  100. if m.message_id == mid:
  101. break
  102. if (
  103. not m.from_user
  104. or not m.text
  105. or not m.reply_to_message
  106. ):
  107. continue
  108. if m.reply_to_message.message_id == mid:
  109. if m.from_user.id == message.from_user.id:
  110. if "→" in m.text:
  111. try:
  112. return await m.edit(final_output)
  113. except MessageNotModified:
  114. return
  115. await message.reply(final_output, quote=True)
  116. @app2.on_message(
  117. filters.user(SUDOERS)
  118. & ~filters.forwarded
  119. & ~filters.via_bot
  120. & ~filters.edited
  121. & filters.command("sh", prefixes=USERBOT_PREFIX),
  122. )
  123. async def shellrunner(client, message: Message):
  124. if len(message.command) < 2:
  125. return await edit_or_reply(
  126. message, text="**Usage:**\n/sh git pull"
  127. )
  128. if message.reply_to_message:
  129. r = message.reply_to_message
  130. if r.reply_markup:
  131. if isinstance(r.reply_markup, ReplyKeyboardMarkup):
  132. return await message.edit("INSECURE!")
  133. text = message.text.split(None, 1)[1]
  134. if "\n" in text:
  135. code = text.split("\n")
  136. output = ""
  137. for x in code:
  138. shell = re.split(
  139. """ (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x
  140. )
  141. try:
  142. process = subprocess.Popen(
  143. shell,
  144. stdout=subprocess.PIPE,
  145. stderr=subprocess.PIPE,
  146. )
  147. except Exception as err:
  148. print(err)
  149. await edit_or_reply(
  150. message,
  151. text=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{escape(err)}```",
  152. )
  153. output += f"**{code}**\n"
  154. output += process.stdout.read()[:-1].decode("utf-8")
  155. output += "\n"
  156. else:
  157. shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text)
  158. for a in range(len(shell)):
  159. shell[a] = shell[a].replace('"', "")
  160. try:
  161. process = subprocess.Popen(
  162. shell,
  163. stdout=subprocess.PIPE,
  164. stderr=subprocess.PIPE,
  165. )
  166. except Exception as err:
  167. print(err)
  168. exc_type, exc_obj, exc_tb = sys.exc_info()
  169. errors = traceback.format_exception(
  170. etype=exc_type,
  171. value=exc_obj,
  172. tb=exc_tb,
  173. )
  174. return await edit_or_reply(
  175. message,
  176. text=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{''.join(errors)}```",
  177. )
  178. output = process.stdout.read()[:-1].decode("utf-8")
  179. if str(output) == "\n":
  180. output = None
  181. if output:
  182. if len(output) > 4096:
  183. with open("output.txt", "w+") as file:
  184. file.write(output)
  185. await app2.send_document(
  186. message.chat.id,
  187. "output.txt",
  188. reply_to_message_id=message.message_id,
  189. caption=escape(text),
  190. )
  191. return os.remove("output.txt")
  192. await edit_or_reply(
  193. message,
  194. text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT:**\n```{escape(output)}```",
  195. )
  196. else:
  197. await edit_or_reply(
  198. message,
  199. text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT: **\n`No output`",
  200. )
  201. def shell(cmd: list) -> tuple:
  202. proc = subprocess.run(
  203. cmd,
  204. stdout=subprocess.PIPE,
  205. stderr=subprocess.PIPE,
  206. )
  207. stdout, stderr = proc.stdout, proc.stderr
  208. stdout = stdout.decode() if stdout else None
  209. stderr = stderr.decode() if stderr else None
  210. return stdout, stderr