userbot.py 6.7 KB

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