# Predicting SSH keys in Open SSH Memory dumps

Florian Rascoussier

► To cite this version:

Florian Rascoussier. Predicting SSH keys in Open SSH Memory dumps. Universität Passau (Allemagne); INSA Lyon. 2024, pp.148. hal-04562462

HAL Id: hal-04562462

https://hal.science/hal-04562462

Submitted on 29 Apr 2024

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_1.png" /></figure>
# Predicting SSH keys in Open SSH Memory dumps

Florian Rascoussier

► To cite this version:

Florian Rascoussier. Predicting SSH keys in Open SSH Memory dumps. Universität Passau (Allemagne); INSA Lyon. 2024, pp.148. hal-04562462

HAL Id: hal-04562462

https://hal.science/hal-04562462v1

Submitted on 29 Apr 2024

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_1.png" /></figure>

Distributed under a Creative Commons Attribution 4.0 International License
Masterarbeit

Predicting SSH keys in Open SSH Memory
dumps

A report by

Rascoussier, Florian Guillaume Pierre

Matrikelnummer (Passau): 112485

Matrikelnummer (INSA): 4018543

ORCID: 0009-0005-3253-9814

Erstprüfer

Prof. Dr. Harald Kosch

Zweitprüfer

Prof. Dr. Michael Granitzer

Betreuer

Christofer Fellicious

Prof. Dr. Pierre-Edouard Portier

Prof. Dr. Elöd Egyed-Zsigmond
Masterarbeit

# Predicting SSH keys in Open SSH Memory dumps

A report by

Rascoussier, Florian Guillaume Pierre

Matrikelnummer (Passau): 112485

Matrikelnummer (INSA): 4018543

ORCID: 0009-0005-3253-9814

Erstprüfer

Prof. Dr. Harald Kosch

Zweitprüfer

Prof. Dr. Michael Granitzer

Betreuer

Christofer Fellicious

Prof. Dr. Pierre-Edouard Portier

Prof. Dr. Elöd Egyed-Zsigmond
Abstract

As the digital landscape evolves, cybersecurity has become an indispensable focus of IT systems. Its ever-escalating challenges have amplified the importance of digital forensics, particularly in the analysis of heap dumps from main memory. In this context, the Secure Shell protocol (SSH) designed for encrypted communications, serves as both a safeguard and a potential veil for malicious activities. This research project focuses on predicting SSH keys in OpenSSH memory dumps, aiming to enhance protective measures against illicit access and enable the development of advanced security frameworks or tools like honeypots.

This Masterarbeit is situated within the broader SmartVMI project, a collaborative research initiative with the objective to advance artificial intelligence-based mechanisms for attack detection and digital forensics. Specifically, this work seeks to build upon existing research on key prediction in OpenSSH heap dumps. Utilizing machine learning and deep learning models, the study aims to refine feature for embedding techniques and explore innovative methods for effective key detection. The objective is to accurately predict the presence and location of SSH keys within memory dumps. This work builds upon, and aims to enhance, the foundations laid by SSHkex [0] and SmartKex [0], enriching both the methodology and the results of the original research while exploring the untapped potential of newly proposed approaches.

The current thesis dives into memory graph modelization from raw binary heap dump files. Each memory graph can support a range of embeddings than can be used directly for model training, through the use of classic ML models and graph neural network. The report encapsulates the progress of a year-long Master's thesis research project executed between October 2022 and October 2023. Conducted within the framework of the PhDTrack program between the University of Passau and INSA Lyon, the research has been supervised by Prof. Dr. Michael Granitzer and Christofer Fellicious from the University of Passau, as well as Prof. Dr. Pierre-Edouard Portier from INSA Lyon. It offers an in-depth discussion on the current state-of-the-art in key prediction for OpenSSH memory dumps, research questions, experimental setups, programs development, results as well as discussing potential future directions.
Abstract

As the digital landscape evolves, cybersecurity has become an indispensable focus of IT systems. Its ever-escalating challenges have amplified the importance of digital forensics, particularly in the analysis of heap dumps from main memory. In this context, the Secure Shell protocol (SSH) designed for encrypted communications, serves as both a safeguard and a potential veil for malicious activities. This research project focuses on predicting SSH keys in OpenSSH memory dumps, aiming to enhance protective measures against illicit access and enable the development of advanced security frameworks or tools like honeypots.

This Masterarbeit is situated within the broader SmartVMI project, a collaborative research initiative with the objective to advance artificial intelligence-based mechanisms for attack detection and digital forensics. Specifically, this work seeks to build upon existing research on key prediction in OpenSSH heap dumps. Utilizing machine learning and deep learning models, the study aims to refine feature for embedding techniques and explore innovative methods for effective key detection. The objective is to accurately predict the presence and location of SSH keys within memory dumps. This work builds upon, and aims to enhance, the foundations laid by SSHkex [0] and SmartKex [0], enriching both the methodology and the results of the original research while exploring the untapped potential of newly proposed approaches.

The current thesis dives into memory graph modelization from raw binary heap dump files. Each memory graph can support a range of embeddings than can be used directly for model training, through the use of classic ML models and graph neural network. The report encapsulates the progress of a year-long Master's thesis research project executed between October 2022 and October 2023. Conducted within the framework of the PhDTrack program between the University of Passau and INSA Lyon, the research has been supervised by Prof. Dr. Michael Granitzer and Christofer Fellicious from the University of Passau, as well as Prof. Dr. Pierre-Edouard Portier from INSA Lyon. It offers an in-depth discussion on the current state-of-the-art in key prediction for OpenSSH memory dumps, research questions, experimental setups, programs development, results as well as discussing potential future directions.
Acknowledgements

First acknowledgement goes to Christofer Fellicious, my supervisor at the University of Passau,
for his guidance, support and feedback during the Masterarbeit.

I want to express my sincere gratitude to my colleague and friend, Clément Lahoche, whose
human and technical skills have been a great source of inspiration and motivation throughout this
project; especially considering that we have been working on closely related subjects. It has been
a great pleasure to share our ideas and insights, and to collaborate on the development of several
programs necessary for the experimentation.

Another acknowledgements go to my esteemed supervisors Prof. Dr. Granitzer and Prof. Dr. Portier for their support and feedback during the Masterarbeit.

I would also like to express my sincere gratitude to all the persons that have helped me, even
punctually, during the Masterarbeit with their valuable help, insights, discussions and contribu-
tions as well as all the persons involved in the PhDTrack program that made this Masterarbeit
possible, including but not limited to:

* Lionel Brunie, Director of CS Department at INSA Lyon, that makes this PhDTrack program possible from the French side.

* Harald Kosch, Head of the Chair of Distributed Information Systems at the University of Passau, that makes this PhDTrack program possible from the German side.

* Natalia Lucari, PhDTrack coordinator at INSA Lyon, for her support and help during the PhDTrack program.

* Ophelie Coueffe, PhDTrack coordinator at the University of Passau, for her patience, support and invaluable help during the PhDTrack program.

* Elöd Egyed-Zsigmond, PhDTrack coordinator at INSA Lyon, for the subject selection, admin-
istrative support and final proofreading.

* All the other PhDTrack students for the great atmosphere, mutual help and the interesting
discussions during almost two years.

I cannot forget to mention my many friends from Lyon to Passau and beyond, for their encour-
agements during this Masterarbeit.

Finally, my last acknowledgements go to my family whose support has been precious throughout
the two years of the PhDTrack program.
**Acknowledgements**

First acknowledgement goes to Christofer Fellicious, my supervisor at the University of Passau, for his guidance, support and feedback during the Masterarbeit.

I want to express my sincere gratitude to my colleague and friend, Clément Lahoche, whose human and technical skills have been a great source of inspiration and motivation throughout this project; especially considering that we have been working on closely related subjects. It has been a great pleasure to share our ideas and insights, and to collaborate on the development of several programs necessary for the experimentation.

Another acknowledgements go to my esteemed supervisors Prof. Dr. Granitzer and Prof. Dr. Portier for their support and feedback during the Masterarbeit.

I would also like to express my sincere gratitude to all the persons that have helped me, even punctually, during the Masterarbeit with their valuable help, insights, discussions and contributions as well as all the persons involved in the PhDTrack program that made this Masterarbeit possible, including but not limited to:

* Lionel Brunie, Director of CS Department at INSA Lyon, that makes this PhDTrack program possible from the French side.

* Harald Kosch, Head of the Chair of Distributed Information Systems at the University of Passau, that makes this PhDTrack program possible from the German side.

* Natalia Lucari, PhDTrack coordinator at INSA Lyon, for her support and help during the PhDTrack program.

* Ophelie Coueffe, PhDTrack coordinator at the University of Passau, for her patience, support and invaluable help during the PhDTrack program.

* Elöd Egyed-Zsigmond, PhDTrack coordinator at INSA Lyon, for the subject selection, administrative support and final proofreading.

* All the other PhDTrack students for the great atmosphere, mutual help and the interesting discussions during almost two years.

I cannot forget to mention my many friends from Lyon to Passau and beyond, for their encouragements during this Masterarbeit.

Finally, my last acknowledgements go to my family whose support has been precious throughout the two years of the PhDTrack program.
# Contents

## 1 Introduction 1

1.1 Research Questions 2

1.2 Commitment to Open Science and Reproducibility 3

1.2.1 GitHub Repositories 3

1.2.2 Datasets 4

1.3 Structure of the Thesis 4

## 2 Background 6

2.1 SSH and OpenSSH Implementation 6

2.1.1 Basics of the Secure Shell Protocol (SSH) 6

2.1.1.1 SSH design and origin 6

2.1.1.2 SSH keys 7

2.1.1.3 SSH key encryption 7

2.1.2 OpenSSH Implementation 8

2.1.2.1 OpenSSH components 8

2.1.2.2 OpenSSH hashing 9

2.1.3 The state of SSH security 10

2.1.3.1 SSH security issues 10

2.1.3.2 SSH vulnerabilities 11

2.1.3.3 SSH and cyber-attacks 11

2.1.4 The Imperative of SSH Honeypots in Cybersecurity Monitoring 12

2.1.5 Research context and motivation for this Masterarbeit 13

2.2 Previous Work on OpenSSH key extraction 13

2.2.1 SSHKex 13

2.2.2 SmartKex 14

2.2.2.1 Baseline brute-force method 15

2.2.2.2 SmartKex machine-learning method 15
# Contents

## 1 Introduction 1

1.1 Research Questions 2

1.2 Commitment to Open Science and Reproducibility 3

1.2.1 GitHub Repositories 3

1.2.2 Datasets 4

1.3 Structure of the Thesis 4

## 2 Background 6

2.1 SSH and OpenSSH Implementation 6

2.1.1 Basics of the Secure Shell Protocol (SSH) 6

2.1.1.1 SSH design and origin 6

2.1.1.2 SSH keys 7

2.1.1.3 SSH key encryption 7

2.1.2 OpenSSH Implementation 8

2.1.2.1 OpenSSH components 8

2.1.2.2 OpenSSH hashing 9

2.1.3 The state of SSH security 10

2.1.3.1 SSH security issues 10

2.1.3.2 SSH vulnerabilities 11

2.1.3.3 SSH and cyber-attacks 11

2.1.4 The Imperative of SSH Honeypots in Cybersecurity Monitoring 12

2.1.5 Research context and motivation for this Masterarbeit 13

2.2 Previous Work on OpenSSH key extraction 13

2.2.1 SSHKex 13

2.2.2 SmartKex 14

2.2.2.1 Baseline brute-force method 15

2.2.2.2 SmartKex machine-learning method 15
<table>
  <tbody>
    <tr>
      <td>2.2.3</td>
      <td>Objectives of the present work</td>
      <td>16</td>
    </tr>
    <tr>
      <td>2.3</td>
      <td>Graph-based memory modelization</td>
      <td>16</td>
    </tr>
    <tr>
      <td>2.3.1</td>
      <td>Defining memory concepts and modelization</td>
      <td>17</td>
    </tr>
    <tr>
      <td>2.3.1.1</td>
      <td>Endianness</td>
      <td>18</td>
    </tr>
    <tr>
      <td>2.3.1.2</td>
      <td>The role of entropy in forensic analysis</td>
      <td>18</td>
    </tr>
    <tr>
      <td>2.3.2</td>
      <td>Graphs and Knowledge Graphs</td>
      <td>19</td>
    </tr>
    <tr>
      <td>2.3.2.1</td>
      <td>Defining Graph Theory concepts</td>
      <td>19</td>
    </tr>
    <tr>
      <td>2.3.2.2</td>
      <td>Graphs types</td>
      <td>20</td>
    </tr>
    <tr>
      <td>2.3.2.3</td>
      <td>Graph vs Knowledge Graph</td>
      <td>21</td>
    </tr>
    <tr>
      <td>2.3.2.4</td>
      <td>Ontologies</td>
      <td>21</td>
    </tr>
    <tr>
      <td>2.3.2.5</td>
      <td>Inductive Reasoning and Learning</td>
      <td>22</td>
    </tr>
    <tr>
      <td>2.4</td>
      <td>Data preprocessing for Machine Learning</td>
      <td>22</td>
    </tr>
    <tr>
      <td>2.4.1</td>
      <td>Feature engineering</td>
      <td>23</td>
    </tr>
    <tr>
      <td>2.4.1.1</td>
      <td>Types of Features</td>
      <td>23</td>
    </tr>
    <tr>
      <td>2.4.1.2</td>
      <td>The Curse of Dimensionality</td>
      <td>23</td>
    </tr>
    <tr>
      <td>2.4.1.3</td>
      <td>Feature Engineering techniques</td>
      <td>24</td>
    </tr>
    <tr>
      <td>2.4.1.4</td>
      <td>Evaluating Features with Correlation Tests</td>
      <td>25</td>
    </tr>
    <tr>
      <td>2.4.2</td>
      <td>Embeddings</td>
      <td>26</td>
    </tr>
    <tr>
      <td>2.4.2.1</td>
      <td>Embedding Creation vs Feature Engineering</td>
      <td>26</td>
    </tr>
    <tr>
      <td>2.4.2.2</td>
      <td>Embeddings for graphs</td>
      <td>26</td>
    </tr>
    <tr>
      <td>2.4.2.3</td>
      <td>Word Embeddings</td>
      <td>28</td>
    </tr>
    <tr>
      <td>2.4.3</td>
      <td>Other preprocessing techniques for Machine Learning</td>
      <td>29</td>
    </tr>
    <tr>
      <td>2.4.3.1</td>
      <td>Data Cleaning</td>
      <td>29</td>
    </tr>
    <tr>
      <td>2.4.3.2</td>
      <td>Dataset splitting and sampling</td>
      <td>30</td>
    </tr>
    <tr>
      <td>2.4.3.3</td>
      <td>Dealing with Imbalanced Datasets</td>
      <td>31</td>
    </tr>
    <tr>
      <td>2.5</td>
      <td>Machine Learning and Deep Learning</td>
      <td>31</td>
    </tr>
    <tr>
      <td>2.5.1</td>
      <td>Machine Learning</td>
      <td>32</td>
    </tr>
    <tr>
      <td>2.5.1.1</td>
      <td>What is Machine Learning</td>
      <td>32</td>
    </tr>
    <tr>
      <td>2.5.1.2</td>
      <td>Model Evaluation</td>
      <td>32</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>2.2.3</td>
      <td>Objectives of the present work</td>
      <td>16</td>
    </tr>
    <tr>
      <td>2.3</td>
      <td>Graph-based memory modelization</td>
      <td>16</td>
    </tr>
    <tr>
      <td>2.3.1</td>
      <td>Defining memory concepts and modelization</td>
      <td>17</td>
    </tr>
    <tr>
      <td>2.3.1.1</td>
      <td>Endianness</td>
      <td>18</td>
    </tr>
    <tr>
      <td>2.3.1.2</td>
      <td>The role of entropy in forensic analysis</td>
      <td>18</td>
    </tr>
    <tr>
      <td>2.3.2</td>
      <td>Graphs and Knowledge Graphs</td>
      <td>19</td>
    </tr>
    <tr>
      <td>2.3.2.1</td>
      <td>Defining Graph Theory concepts</td>
      <td>19</td>
    </tr>
    <tr>
      <td>2.3.2.2</td>
      <td>Graphs types</td>
      <td>20</td>
    </tr>
    <tr>
      <td>2.3.2.3</td>
      <td>Graph vs Knowledge Graph</td>
      <td>21</td>
    </tr>
    <tr>
      <td>2.3.2.4</td>
      <td>Ontologies</td>
      <td>21</td>
    </tr>
    <tr>
      <td>2.3.2.5</td>
      <td>Inductive Reasoning and Learning</td>
      <td>22</td>
    </tr>
    <tr>
      <td>2.4</td>
      <td>Data preprocessing for Machine Learning</td>
      <td>22</td>
    </tr>
    <tr>
      <td>2.4.1</td>
      <td>Feature engineering</td>
      <td>23</td>
    </tr>
    <tr>
      <td>2.4.1.1</td>
      <td>Types of Features</td>
      <td>23</td>
    </tr>
    <tr>
      <td>2.4.1.2</td>
      <td>The Curse of Dimensionality</td>
      <td>23</td>
    </tr>
    <tr>
      <td>2.4.1.3</td>
      <td>Feature Engineering techniques</td>
      <td>24</td>
    </tr>
    <tr>
      <td>2.4.1.4</td>
      <td>Evaluating Features with Correlation Tests</td>
      <td>25</td>
    </tr>
    <tr>
      <td>2.4.2</td>
      <td>Embeddings</td>
      <td>26</td>
    </tr>
    <tr>
      <td>2.4.2.1</td>
      <td>Embedding Creation vs Feature Engineering</td>
      <td>26</td>
    </tr>
    <tr>
      <td>2.4.2.2</td>
      <td>Embeddings for graphs</td>
      <td>26</td>
    </tr>
    <tr>
      <td>2.4.2.3</td>
      <td>Word Embeddings</td>
      <td>28</td>
    </tr>
    <tr>
      <td>2.4.3</td>
      <td>Other preprocessing techniques for Machine Learning</td>
      <td>29</td>
    </tr>
    <tr>
      <td>2.4.3.1</td>
      <td>Data Cleaning</td>
      <td>29</td>
    </tr>
    <tr>
      <td>2.4.3.2</td>
      <td>Dataset splitting and sampling</td>
      <td>30</td>
    </tr>
    <tr>
      <td>2.4.3.3</td>
      <td>Dealing with Imbalanced Datasets</td>
      <td>31</td>
    </tr>
    <tr>
      <td>2.5</td>
      <td>Machine Learning and Deep Learning</td>
      <td>31</td>
    </tr>
    <tr>
      <td>2.5.1</td>
      <td>Machine Learning</td>
      <td>32</td>
    </tr>
    <tr>
      <td>2.5.1.1</td>
      <td>What is Machine Learning</td>
      <td>32</td>
    </tr>
    <tr>
      <td>2.5.1.2</td>
      <td>Model Evaluation</td>
      <td>32</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>2.5.2</td>
      <td>Machine Learning Models for Binary Classification</td>
      <td>33</td>
    </tr>
    <tr>
      <td>2.5.3</td>
      <td>Deep Learning</td>
      <td>34</td>
    </tr>
    <tr>
      <td>2.5.3.1</td>
      <td>Recurrent Neural Networks (RNN)</td>
      <td>35</td>
    </tr>
    <tr>
      <td>2.5.3.2</td>
      <td>Long Short-Term Memory (LSTM)</td>
      <td>35</td>
    </tr>
    <tr>
      <td>2.5.3.3</td>
      <td>Gated Recurrent Units (GRU)</td>
      <td>35</td>
    </tr>
    <tr>
      <td>2.5.3.4</td>
      <td>Convolutional Neural Networks (CNN)</td>
      <td>36</td>
    </tr>
    <tr>
      <td>2.5.3.5</td>
      <td>Graph Convolutional Networks (GCN)</td>
      <td>36</td>
    </tr>
    <tr>
      <td>2.5.4</td>
      <td>Graph Neural Networks</td>
      <td>37</td>
    </tr>
    <tr>
      <td>2.5.4.1</td>
      <td>Recursive Graph Neural Networks (RecGNNs)</td>
      <td>37</td>
    </tr>
    <tr>
      <td>2.5.4.2</td>
      <td>Convolutional Graph Neural Networks (ConvGNNs)</td>
      <td>38</td>
    </tr>
    <tr>
      <td><b>3</b></td>
      <td><b>Methods</b></td>
      <td><b>41</b></td>
    </tr>
    <tr>
      <td>3.1</td>
      <td>Hardware and software architecture</td>
      <td>41</td>
    </tr>
    <tr>
      <td>3.1.1</td>
      <td>Hardware development and testing environment</td>
      <td>41</td>
    </tr>
    <tr>
      <td>3.1.2</td>
      <td>Software, languages and tools</td>
      <td>42</td>
    </tr>
    <tr>
      <td>3.1.2.1</td>
      <td>Packaging and deployment</td>
      <td>43</td>
    </tr>
    <tr>
      <td>3.2</td>
      <td>OpenSSH memory dumps dataset.</td>
      <td>44</td>
    </tr>
    <tr>
      <td>3.2.1</td>
      <td>Assumptions</td>
      <td>47</td>
    </tr>
    <tr>
      <td>3.2.2</td>
      <td>Dataset production system information</td>
      <td>47</td>
    </tr>
    <tr>
      <td>3.2.3</td>
      <td>Conventions and vocabulary</td>
      <td>48</td>
    </tr>
    <tr>
      <td>3.2.4</td>
      <td>Estimating the dataset balancing for key prediction.</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.2.5</td>
      <td>Dataset validation</td>
      <td>50</td>
    </tr>
    <tr>
      <td>3.2.5.1</td>
      <td>Automatic annotation validation</td>
      <td>50</td>
    </tr>
    <tr>
      <td>3.2.6</td>
      <td>Dataset cleaning</td>
      <td>53</td>
    </tr>
    <tr>
      <td>3.2.7</td>
      <td>Exploring patterns in RAW heap dump files</td>
      <td>53</td>
    </tr>
    <tr>
      <td>3.2.7.1</td>
      <td>Detecting potential pointers</td>
      <td>53</td>
    </tr>
    <tr>
      <td>3.2.7.2</td>
      <td>Detecting potential keys</td>
      <td>57</td>
    </tr>
    <tr>
      <td>3.2.8</td>
      <td>Data structure exploration</td>
      <td>61</td>
    </tr>
    <tr>
      <td>3.2.8.1</td>
      <td>How malloc handles Heap Allocation</td>
      <td>61</td>
    </tr>
    <tr>
      <td>3.2.8.2</td>
      <td>Chunk chaining</td>
      <td>64</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>2.5.2</td>
      <td>Machine Learning Models for Binary Classification</td>
      <td>33</td>
    </tr>
    <tr>
      <td>2.5.3</td>
      <td>Deep Learning</td>
      <td>34</td>
    </tr>
    <tr>
      <td>2.5.3.1</td>
      <td>Recurrent Neural Networks (RNN)</td>
      <td>35</td>
    </tr>
    <tr>
      <td>2.5.3.2</td>
      <td>Long Short-Term Memory (LSTM)</td>
      <td>35</td>
    </tr>
    <tr>
      <td>2.5.3.3</td>
      <td>Gated Recurrent Units (GRU)</td>
      <td>35</td>
    </tr>
    <tr>
      <td>2.5.3.4</td>
      <td>Convolutional Neural Networks (CNN)</td>
      <td>36</td>
    </tr>
    <tr>
      <td>2.5.3.5</td>
      <td>Graph Convolutional Networks (GCN)</td>
      <td>36</td>
    </tr>
    <tr>
      <td>2.5.4</td>
      <td>Graph Neural Networks</td>
      <td>37</td>
    </tr>
    <tr>
      <td>2.5.4.1</td>
      <td>Recursive Graph Neural Networks (RecGNNs)</td>
      <td>37</td>
    </tr>
    <tr>
      <td>2.5.4.2</td>
      <td>Convolutional Graph Neural Networks (ConvGNNs)</td>
      <td>38</td>
    </tr>
    <tr>
      <td><b>3</b></td>
      <td><b>Methods</b></td>
      <td><b>41</b></td>
    </tr>
    <tr>
      <td>3.1</td>
      <td>Hardware and software architecture</td>
      <td>41</td>
    </tr>
    <tr>
      <td>3.1.1</td>
      <td>Hardware development and testing environment</td>
      <td>41</td>
    </tr>
    <tr>
      <td>3.1.2</td>
      <td>Software, languages and tools</td>
      <td>42</td>
    </tr>
    <tr>
      <td>3.1.2.1</td>
      <td>Packaging and deployment</td>
      <td>43</td>
    </tr>
    <tr>
      <td>3.2</td>
      <td>OpenSSH memory dumps dataset</td>
      <td>44</td>
    </tr>
    <tr>
      <td>3.2.1</td>
      <td>Assumptions</td>
      <td>47</td>
    </tr>
    <tr>
      <td>3.2.2</td>
      <td>Dataset production system information</td>
      <td>47</td>
    </tr>
    <tr>
      <td>3.2.3</td>
      <td>Conventions and vocabulary</td>
      <td>48</td>
    </tr>
    <tr>
      <td>3.2.4</td>
      <td>Estimating the dataset balancing for key prediction</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.2.5</td>
      <td>Dataset validation</td>
      <td>50</td>
    </tr>
    <tr>
      <td>3.2.5.1</td>
      <td>Automatic annotation validation</td>
      <td>50</td>
    </tr>
    <tr>
      <td>3.2.6</td>
      <td>Dataset cleaning</td>
      <td>53</td>
    </tr>
    <tr>
      <td>3.2.7</td>
      <td>Exploring patterns in RAW heap dump files</td>
      <td>53</td>
    </tr>
    <tr>
      <td>3.2.7.1</td>
      <td>Detecting potential pointers</td>
      <td>53</td>
    </tr>
    <tr>
      <td>3.2.7.2</td>
      <td>Detecting potential keys</td>
      <td>57</td>
    </tr>
    <tr>
      <td>3.2.8</td>
      <td>Data structure exploration</td>
      <td>61</td>
    </tr>
    <tr>
      <td>3.2.8.1</td>
      <td>How malloc handles Heap Allocation</td>
      <td>61</td>
    </tr>
    <tr>
      <td>3.2.8.2</td>
      <td>Chunk chaining</td>
      <td>64</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>3.2.8.3 Chunk chaining example</td>
      <td>67</td>
    </tr>
    <tr>
      <td>3.2.8.4 Distinguishing between free and allocated chunks</td>
      <td>68</td>
    </tr>
    <tr>
      <td>3.2.8.5 Chunk footer</td>
      <td>70</td>
    </tr>
    <tr>
      <td>3.2.9 Discussing chunk parsing for problem scale reduction</td>
      <td>70</td>
    </tr>
    <tr>
      <td>3.2.9.1 From a block-based to a chunk-based approach</td>
      <td>72</td>
    </tr>
    <tr>
      <td>3.2.9.2 Using chunk footer for filtering is not possible</td>
      <td>72</td>
    </tr>
    <tr>
      <td>3.2.9.3 Chunk filtering</td>
      <td>73</td>
    </tr>
    <tr>
      <td>3.3 Graph-based memory dumps embedding</td>
      <td>74</td>
    </tr>
    <tr>
      <td>3.3.1 Initial work from Python to Rust</td>
      <td>74</td>
    </tr>
    <tr>
      <td>3.3.2 Memory Graph Representation</td>
      <td>75</td>
    </tr>
    <tr>
      <td>3.4 From heap dump to memory graph embeddings</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.4.1 Initialization and data checking</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.4.1.1 Graph Construction steps</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.4.1.2 Graph Annotation</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.4.1.3 Custom Graph-Based Embeddings</td>
      <td>78</td>
    </tr>
    <tr>
      <td>3.4.1.4 Exporting the Graph</td>
      <td>79</td>
    </tr>
    <tr>
      <td>3.5 A wide range of features and embeddings</td>
      <td>80</td>
    </tr>
    <tr>
      <td>3.5.1 Embeddings based on custom features</td>
      <td>80</td>
    </tr>
    <tr>
      <td>3.5.1.1 Remark on the collaborative work</td>
      <td>80</td>
    </tr>
    <tr>
      <td>3.5.1.2 Semantic graph embedding</td>
      <td>80</td>
    </tr>
    <tr>
      <td>3.5.1.3 Semantic features from essential chunks attributes</td>
      <td>82</td>
    </tr>
    <tr>
      <td>3.5.1.4 Statistical Embedding</td>
      <td>82</td>
    </tr>
    <tr>
      <td>3.5.1.5 Start-bytes Embedding</td>
      <td>82</td>
    </tr>
    <tr>
      <td>3.5.2 Embedding transformations depending on the model</td>
      <td>82</td>
    </tr>
    <tr>
      <td>3.5.2.1 Node filtering to feature</td>
      <td>83</td>
    </tr>
    <tr>
      <td>3.5.3 Graph-agnostic Embeddings</td>
      <td>83</td>
    </tr>
    <tr>
      <td>3.5.3.1 RandomWalk</td>
      <td>83</td>
    </tr>
    <tr>
      <td>3.5.3.2 Node2Vec</td>
      <td>83</td>
    </tr>
    <tr>
      <td>3.6 Machine Learning Binary Classification</td>
      <td>84</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>3.2.8.3 Chunk chaining example</td>
      <td>67</td>
    </tr>
    <tr>
      <td>3.2.8.4 Distinguishing between free and allocated chunks</td>
      <td>68</td>
    </tr>
    <tr>
      <td>3.2.8.5 Chunk footer</td>
      <td>70</td>
    </tr>
    <tr>
      <td>3.2.9 Discussing chunk parsing for problem scale reduction</td>
      <td>70</td>
    </tr>
    <tr>
      <td>3.2.9.1 From a block-based to a chunk-based approach</td>
      <td>72</td>
    </tr>
    <tr>
      <td>3.2.9.2 Using chunk footer for filtering is not possible</td>
      <td>72</td>
    </tr>
    <tr>
      <td>3.2.9.3 Chunk filtering</td>
      <td>73</td>
    </tr>
    <tr>
      <td>3.3 Graph-based memory dumps embedding</td>
      <td>74</td>
    </tr>
    <tr>
      <td>3.3.1 Initial work from Python to Rust</td>
      <td>74</td>
    </tr>
    <tr>
      <td>3.3.2 Memory Graph Representation</td>
      <td>75</td>
    </tr>
    <tr>
      <td>3.4 From heap dump to memory graph embeddings</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.4.1 Initialization and data checking</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.4.1.1 Graph Construction steps</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.4.1.2 Graph Annotation</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.4.1.3 Custom Graph-Based Embeddings</td>
      <td>78</td>
    </tr>
    <tr>
      <td>3.4.1.4 Exporting the Graph</td>
      <td>79</td>
    </tr>
    <tr>
      <td>3.5 A wide range of features and embeddings</td>
      <td>80</td>
    </tr>
    <tr>
      <td>3.5.1 Embeddings based on custom features</td>
      <td>80</td>
    </tr>
    <tr>
      <td>3.5.1.1 Remark on the collaborative work</td>
      <td>80</td>
    </tr>
    <tr>
      <td>3.5.1.2 Semantic graph embedding</td>
      <td>80</td>
    </tr>
    <tr>
      <td>3.5.1.3 Semantic features from essential chunks attributes</td>
      <td>82</td>
    </tr>
    <tr>
      <td>3.5.1.4 Statistical Embedding</td>
      <td>82</td>
    </tr>
    <tr>
      <td>3.5.1.5 Start-bytes Embedding</td>
      <td>82</td>
    </tr>
    <tr>
      <td>3.5.2 Embedding transformations depending on the model</td>
      <td>82</td>
    </tr>
    <tr>
      <td>3.5.2.1 Node filtering to feature</td>
      <td>83</td>
    </tr>
    <tr>
      <td>3.5.3 Graph-agnostic Embeddings</td>
      <td>83</td>
    </tr>
    <tr>
      <td>3.5.3.1 RandomWalk</td>
      <td>83</td>
    </tr>
    <tr>
      <td>3.5.3.2 Node2Vec</td>
      <td>83</td>
    </tr>
    <tr>
      <td>3.6 Machine Learning Binary Classification</td>
      <td>84</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>3.6.1 Classic Models of Machine Learning</td>
      <td>84</td>
    </tr>
    <tr>
      <td>3.6.1.1 Random Forest</td>
      <td>84</td>
    </tr>
    <tr>
      <td>3.6.1.2 Logistic Regression</td>
      <td>85</td>
    </tr>
    <tr>
      <td>3.6.1.3 SGD Classifier</td>
      <td>85</td>
    </tr>
    <tr>
      <td>3.6.2 Graph Convolutional Networks (GCN)</td>
      <td>86</td>
    </tr>
    <tr>
      <td>3.6.2.1 Very Simple GCN</td>
      <td>86</td>
    </tr>
    <tr>
      <td>3.6.2.2 Simple GCN Models</td>
      <td>86</td>
    </tr>
    <tr>
      <td>3.6.2.3 First GCN Model</td>
      <td>87</td>
    </tr>
    <tr>
      <td>3.6.3 The Impact of Complexity</td>
      <td>87</td>
    </tr>
    <tr>
      <td>3.6.4 Understanding Dropout in GCNs</td>
      <td>87</td>
    </tr>
    <tr>
      <td>3.6.4.1 Effect on Binary Classification</td>
      <td>88</td>
    </tr>
    <tr>
      <td>3.6.4.2 Batch Normalization</td>
      <td>88</td>
    </tr>
    <tr>
      <td>3.6.5 More Complex GCN Models</td>
      <td>88</td>
    </tr>
    <tr>
      <td>3.6.5.1 GCN with Dropout and Batch Normalization</td>
      <td>88</td>
    </tr>
    <tr>
      <td>3.6.5.2 Advanced GCN</td>
      <td>89</td>
    </tr>
    <tr>
      <td><b>4 Results</b></td>
      <td><b>90</b></td>
    </tr>
    <tr>
      <td>4.1 Developed programs</td>
      <td>90</td>
    </tr>
    <tr>
      <td>4.1.1 Mem2Graph</td>
      <td>90</td>
    </tr>
    <tr>
      <td>4.1.2 Machine Learning Pipelines Runner</td>
      <td>90</td>
    </tr>
    <tr>
      <td>4.1.3 Other programs</td>
      <td>91</td>
    </tr>
    <tr>
      <td>4.2 Experimental Setup</td>
      <td>93</td>
    </tr>
    <tr>
      <td>4.2.1 Generation of the memgraph datasets</td>
      <td>93</td>
    </tr>
    <tr>
      <td>4.2.2 Sanity checking and preloading the generated memgraph datasets</td>
      <td>94</td>
    </tr>
    <tr>
      <td>4.2.3 Launching the experiments</td>
      <td>95</td>
    </tr>
    <tr>
      <td>4.2.4 Dealing with hyperparameter tuning</td>
      <td>96</td>
    </tr>
    <tr>
      <td>4.2.4.1 Limited number of input graphs due to compute time and memory usage</td>
      <td>97</td>
    </tr>
    <tr>
      <td>4.2.4.2 Parallel launch of experiments for hyperparameters tuning</td>
      <td>97</td>
    </tr>
    <tr>
      <td>4.2.4.3 Description of the results.csv File</td>
      <td>98</td>
    </tr>
    <tr>
      <td>4.3 Obtained Results</td>
      <td>100</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>3.6.1 Classic Models of Machine Learning</td>
      <td>84</td>
    </tr>
    <tr>
      <td>3.6.1.1 Random Forest</td>
      <td>84</td>
    </tr>
    <tr>
      <td>3.6.1.2 Logistic Regression</td>
      <td>85</td>
    </tr>
    <tr>
      <td>3.6.1.3 SGD Classifier</td>
      <td>85</td>
    </tr>
    <tr>
      <td>3.6.2 Graph Convolutional Networks (GCN)</td>
      <td>86</td>
    </tr>
    <tr>
      <td>3.6.2.1 Very Simple GCN</td>
      <td>86</td>
    </tr>
    <tr>
      <td>3.6.2.2 Simple GCN Models</td>
      <td>86</td>
    </tr>
    <tr>
      <td>3.6.2.3 First GCN Model</td>
      <td>87</td>
    </tr>
    <tr>
      <td>3.6.3 The Impact of Complexity</td>
      <td>87</td>
    </tr>
    <tr>
      <td>3.6.4 Understanding Dropout in GCNs</td>
      <td>87</td>
    </tr>
    <tr>
      <td>3.6.4.1 Effect on Binary Classification</td>
      <td>88</td>
    </tr>
    <tr>
      <td>3.6.4.2 Batch Normalization</td>
      <td>88</td>
    </tr>
    <tr>
      <td>3.6.5 More Complex GCN Models</td>
      <td>88</td>
    </tr>
    <tr>
      <td>3.6.5.1 GCN with Dropout and Batch Normalization</td>
      <td>88</td>
    </tr>
    <tr>
      <td>3.6.5.2 Advanced GCN</td>
      <td>89</td>
    </tr>
    <tr>
      <td><b>4 Results</b></td>
      <td><b>90</b></td>
    </tr>
    <tr>
      <td>4.1 Developed programs</td>
      <td>90</td>
    </tr>
    <tr>
      <td>4.1.1 Mem2Graph</td>
      <td>90</td>
    </tr>
    <tr>
      <td>4.1.2 Machine Learning Pipelines Runner</td>
      <td>90</td>
    </tr>
    <tr>
      <td>4.1.3 Other programs</td>
      <td>91</td>
    </tr>
    <tr>
      <td>4.2 Experimental Setup</td>
      <td>93</td>
    </tr>
    <tr>
      <td>4.2.1 Generation of the memgraph datasets</td>
      <td>93</td>
    </tr>
    <tr>
      <td>4.2.2 Sanity checking and preloading the generated memgraph datasets</td>
      <td>94</td>
    </tr>
    <tr>
      <td>4.2.3 Launching the experiments</td>
      <td>95</td>
    </tr>
    <tr>
      <td>4.2.4 Dealing with hyperparameter tuning</td>
      <td>96</td>
    </tr>
    <tr>
      <td>4.2.4.1 Limited number of input graphs due to compute time and memory usage</td>
      <td>97</td>
    </tr>
    <tr>
      <td>4.2.4.2 Parallel launch of experiments for hyperparameters tuning</td>
      <td>97</td>
    </tr>
    <tr>
      <td>4.2.4.3 Description of the results.csv File</td>
      <td>98</td>
    </tr>
    <tr>
      <td>4.3 Obtained Results</td>
      <td>100</td>
    </tr>
  </tbody>
</table>
<table><tr><td>4.3.1 Feature Engineering results</td><td>100</td></tr><tr><td>4.3.2 Classic Model results</td><td>103</td></tr><tr><td>4.3.3 Deep Learning GCN Model results</td><td>104</td></tr><tr><td>4.4 Compared Performances of models and embeddings</td><td>105</td></tr></table>

# 5 Discussion 108

<table><tr><td>5.1 Discussion of the results</td><td>108</td></tr><tr><td>5.1.1 Objectives of the experiments</td><td>108</td></tr><tr><td>5.1.2 Discussing features and embeddings</td><td>108</td></tr><tr><td>5.1.3 Classic ML models performances</td><td>109</td></tr><tr><td>5.1.3.1 Logistic Regression</td><td>109</td></tr><tr><td>5.1.3.2 Random Forest</td><td>109</td></tr><tr><td>5.1.3.3 SGD Classifier</td><td>109</td></tr><tr><td>5.1.3.4 Comparison</td><td>110</td></tr><tr><td>5.1.4 GCN models performances</td><td>110</td></tr><tr><td>5.1.4.1 Very Simple GCN</td><td>110</td></tr><tr><td>5.1.4.2 Simple GCN</td><td>110</td></tr><tr><td>5.1.4.3 First GCN</td><td>110</td></tr><tr><td>5.1.4.4 GCN with Dropout</td><td>110</td></tr><tr><td>5.1.4.5 Advanced GCN</td><td>111</td></tr><tr><td>5.1.4.6 Layer Complexity</td><td>111</td></tr><tr><td>5.1.5 Comparing the embeddings impact on the models</td><td>111</td></tr><tr><td>5.1.6 Comparing GCN and classical ML models</td><td>112</td></tr><tr><td>5.1.6.1 Overall Performance</td><td>112</td></tr><tr><td>5.1.6.2 Precision</td><td>112</td></tr><tr><td>5.1.6.3 Recall</td><td>112</td></tr><tr><td>5.1.6.4 Class Separation (AUC)</td><td>112</td></tr><tr><td>5.1.6.5 Considerations for Small Datasets</td><td>113</td></tr><tr><td>5.1.6.6 Summary</td><td>113</td></tr><tr><td>5.2 Limitations of the Experiments</td><td>113</td></tr></table>
<table><tr><td>4.3.1 Feature Engineering results</td><td>100</td></tr><tr><td>4.3.2 Classic Model results</td><td>103</td></tr><tr><td>4.3.3 Deep Learning GCN Model results</td><td>104</td></tr><tr><td>4.4 Compared Performances of models and embeddings</td><td>105</td></tr></table>

# 5 Discussion 108

<table><tr><td>5.1 Discussion of the results</td><td>108</td></tr><tr><td>5.1.1 Objectives of the experiments</td><td>108</td></tr><tr><td>5.1.2 Discussing features and embeddings</td><td>108</td></tr><tr><td>5.1.3 Classic ML models performances</td><td>109</td></tr><tr><td>5.1.3.1 Logistic Regression</td><td>109</td></tr><tr><td>5.1.3.2 Random Forest</td><td>109</td></tr><tr><td>5.1.3.3 SGD Classifier</td><td>109</td></tr><tr><td>5.1.3.4 Comparison</td><td>110</td></tr><tr><td>5.1.4 GCN models performances</td><td>110</td></tr><tr><td>5.1.4.1 Very Simple GCN</td><td>110</td></tr><tr><td>5.1.4.2 Simple GCN</td><td>110</td></tr><tr><td>5.1.4.3 First GCN</td><td>110</td></tr><tr><td>5.1.4.4 GCN with Dropout</td><td>110</td></tr><tr><td>5.1.4.5 Advanced GCN</td><td>111</td></tr><tr><td>5.1.4.6 Layer Complexity</td><td>111</td></tr><tr><td>5.1.5 Comparing the embeddings impact on the models</td><td>111</td></tr><tr><td>5.1.6 Comparing GCN and classical ML models</td><td>112</td></tr><tr><td>5.1.6.1 Overall Performance</td><td>112</td></tr><tr><td>5.1.6.2 Precision</td><td>112</td></tr><tr><td>5.1.6.3 Recall</td><td>112</td></tr><tr><td>5.1.6.4 Class Separation (AUC)</td><td>112</td></tr><tr><td>5.1.6.5 Considerations for Small Datasets</td><td>113</td></tr><tr><td>5.1.6.6 Summary</td><td>113</td></tr><tr><td>5.2 Limitations of the Experiments</td><td>113</td></tr></table>
<table><tr><td>5.2.1 Limited number of input graphs</td><td>114</td></tr><tr><td>5.2.2 Duration of the experiments</td><td>114</td></tr><tr><td><b>6 Conclusion</b></td><td><b>116</b></td></tr><tr><td>6.1 Summary of Results</td><td>116</td></tr><tr><td>6.1.1 Dataset Exploration</td><td>116</td></tr><tr><td>6.1.2 Memory Graph Generation</td><td>117</td></tr><tr><td>6.1.3 Feature Engineering and Embeddings</td><td>117</td></tr><tr><td>6.1.4 Conclusion on Model Performances</td><td>117</td></tr><tr><td>6.2 Outlook on Future Work</td><td>118</td></tr><tr><td>.1 Code and files</td><td>119</td></tr><tr><td>.2 Memory Graphs</td><td>120</td></tr><tr><td>.3 Latest ML Experiment results</td><td>123</td></tr><tr><td><b>Acronyms</b></td><td><b>125</b></td></tr><tr><td><b>Glossary</b></td><td><b>127</b></td></tr><tr><td><b>References</b></td><td><b>128</b></td></tr><tr><td><b>Additional bibliography</b></td><td><b>133</b></td></tr></table>

List of Figures

<table><tr><td>2.1 Graphical representation of an rdf:Bag container.</td><td>22</td></tr><tr><td>3.1 Illustration of the Dataset Directory Structure</td><td>44</td></tr><tr><td>3.2 Binary RAW heap dump file loaded using vim and xxd, from /Training/Training/scp/V_7_8_P1/16/1010-1644391327-heap/raw, with highlight on rows with 12 hexadecimal digits followed by 4 zeros.</td><td>55</td></tr><tr><td>3.3 Diagram of an allocated chunk in GLIBC 2.28 [0].</td><td>63</td></tr><tr><td>3.4 Diagram of a free chunk in GLIBC 2.28 [0].</td><td>64</td></tr><tr><td>3.5 Attempt at malloc header detection in Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw, at heap start.</td><td>65</td></tr></table>
<table><tr><td>5.2.1</td><td>Limited number of input graphs</td><td>114</td></tr><tr><td>5.2.2</td><td>Duration of the experiments</td><td>114</td></tr><tr><td><b>6</b></td><td><b>Conclusion</b></td><td><b>116</b></td></tr><tr><td>6.1</td><td>Summary of Results</td><td>116</td></tr><tr><td>6.1.1</td><td>Dataset Exploration</td><td>116</td></tr><tr><td>6.1.2</td><td>Memory Graph Generation</td><td>117</td></tr><tr><td>6.1.3</td><td>Feature Engineering and Embeddings</td><td>117</td></tr><tr><td>6.1.4</td><td>Conclusion on Model Performances</td><td>117</td></tr><tr><td>6.2</td><td>Outlook on Future Work</td><td>118</td></tr><tr><td>.1</td><td>Code and files</td><td>119</td></tr><tr><td>.2</td><td>Memory Graphs</td><td>120</td></tr><tr><td>.3</td><td>Latest ML Experiment results</td><td>123</td></tr><tr><td><b>Acronyms</b></td><td></td><td><b>125</b></td></tr><tr><td><b>Glossary</b></td><td></td><td><b>127</b></td></tr><tr><td><b>References</b></td><td></td><td><b>128</b></td></tr><tr><td><b>Additional bibliography</b></td><td></td><td><b>133</b></td></tr></table>

List of Figures

<table><tr><td>2.1</td><td>Graphical representation of an rdf:Bag container.</td><td>22</td></tr><tr><td>3.1</td><td>Illustration of the Dataset Directory Structure</td><td>44</td></tr><tr><td>3.2</td><td>Binary RAW heap dump file loaded using vim and xxd, from /Training/Training/scp/V_7_8_P1/16/1010-1644391327-heap/raw, with highlight on rows with 12 hexadecimal digits followed by 4 zeros.</td><td>55</td></tr><tr><td>3.3</td><td>Diagram of an allocated chunk in GLIBC 2.28 [0].</td><td>63</td></tr><tr><td>3.4</td><td>Diagram of a free chunk in GLIBC 2.28 [0].</td><td>64</td></tr><tr><td>3.5</td><td>Attempt at malloc header detection in Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw, at heap start.</td><td>65</td></tr></table>
<table>
  <tbody>
    <tr>
      <td>3.6 Attempt at malloc header detection in Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw, at index 592<sub>10</sub> = 250<sub>16</sub>.</td>
      <td>65</td>
    </tr>
    <tr>
      <td>3.7 Heap dump showing a mix of free and in-use chunks. Note: each chunk immediately after a free chunk has a P flag set to 0. Each rectangle represents a chunk.</td>
      <td>68</td>
    </tr>
    <tr>
      <td>3.8 Visualization of the entropy distribution for all chunks of the phdtrack_data_clean/RAW heap dump dataset.</td>
      <td>73</td>
    </tr>
    <tr>
      <td>3.9 Visualization of a truncated memory graph generated from Training/basic/V_7_1-P1/24/17016-1643962152-heap/raw. The addresses are not displayed for improved readability. Version with addresses here .2.</td>
      <td>76</td>
    </tr>
    <tr>
      <td>3.10 Visualization of the chunk memory graph, with only Chunk Header Nodes representing chunks, generated from Training/scp/V_7_8_P1/16/585-1644391327-heap/raw.</td>
      <td>78</td>
    </tr>
    <tr>
      <td>4.1 Illustration of the Data Directory Structure</td>
      <td>94</td>
    </tr>
    <tr>
      <td>4.2 Feature correlation matrices on the different Mem2Graph-generated datasets. Used algorithm: Kendall.</td>
      <td>101</td>
    </tr>
    <tr>
      <td>4.3 Feature correlation matrices on the different Mem2Graph-generated datasets. Used algorithm: Pearson.</td>
      <td>102</td>
    </tr>
    <tr>
      <td>4.4 Feature correlation matrices on the different Mem2Graph-generated datasets. Used algorithm: Spearman.</td>
      <td>103</td>
    </tr>
    <tr>
      <td>4.5 Visualization of the result metrics use to compare model performance on memory graphs, for different embeddings and hyperparameters.</td>
      <td>106</td>
    </tr>
    <tr>
      <td>4.6 Visualization of the result metrics use to compare model performance per memory graph node embedding strategies.</td>
      <td>107</td>
    </tr>
    <tr>
      <td>1 Visualization of the full memory graph generated from Training/scp/V_7_8_P1/16/302-1644391327-heap/raw.</td>
      <td>120</td>
    </tr>
    <tr>
      <td>2 Visualization of the full memory graph generated from Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw.</td>
      <td>120</td>
    </tr>
    <tr>
      <td>3 Visualization of a truncated memory graph generated from Training/basic/V_7_1-P1/24/17016-1643962152-heap/raw. Here with real addresses.</td>
      <td>121</td>
    </tr>
    <tr>
      <td>4 Visualization of a chunk memory graph generated from Validation/Validation/basic/V_7_8_P1/24/8708-1643979488-heap/raw.</td>
      <td>122</td>
    </tr>
    <tr>
      <td>5 Visualization of a chunk memory graph generated from Training/Training/basic/V_6-8_P1/24/28621-1643890740-heap/raw.</td>
      <td>122</td>
    </tr>
  </tbody>
</table>

List of Tables

<table>
  <tr>
    <td>4.1 Code Statistics for Masterarbeit</td>
    <td>92</td>
  </tr>
</table>
<table>
  <tbody>
    <tr>
      <td>3.6 Attempt at malloc header detection in Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw, at index 592<sub>10</sub> = 250<sub>16</sub>.</td>
      <td>65</td>
    </tr>
    <tr>
      <td>3.7 Heap dump showing a mix of free and in-use chunks. Note: each chunk immediately after a free chunk has a P flag set to 0. Each rectangle represents a chunk.</td>
      <td>68</td>
    </tr>
    <tr>
      <td>3.8 Visualization of the entropy distribution for all chunks of the phdtrack_data_clean/RAW heap dump dataset.</td>
      <td>73</td>
    </tr>
    <tr>
      <td>3.9 Visualization of a truncated memory graph generated from Training/basic/V_7_1-P1/24/17016-1643962152-heap/raw. The addresses are not displayed for improved readability. Version with addresses here .2.</td>
      <td>76</td>
    </tr>
    <tr>
      <td>3.10 Visualization of the chunk memory graph, with only Chunk Header Nodes representing chunks, generated from Training/scp/V_7_8_P1/16/585-1644391327-heap/raw.</td>
      <td>78</td>
    </tr>
    <tr>
      <td>4.1 Illustration of the Data Directory Structure</td>
      <td>94</td>
    </tr>
    <tr>
      <td>4.2 Feature correlation matrices on the different Mem2Graph-generated datasets. Used algorithm: Kendall.</td>
      <td>101</td>
    </tr>
    <tr>
      <td>4.3 Feature correlation matrices on the different Mem2Graph-generated datasets. Used algorithm: Pearson.</td>
      <td>102</td>
    </tr>
    <tr>
      <td>4.4 Feature correlation matrices on the different Mem2Graph-generated datasets. Used algorithm: Spearman.</td>
      <td>103</td>
    </tr>
    <tr>
      <td>4.5 Visualization of the result metrics use to compare model performance on memory graphs, for different embeddings and hyperparameters.</td>
      <td>106</td>
    </tr>
    <tr>
      <td>4.6 Visualization of the result metrics use to compare model performance per memory graph node embedding strategies.</td>
      <td>107</td>
    </tr>
    <tr>
      <td>1 Visualization of the full memory graph generated from Training/scp/V_7_8_P1/16/302-1644391327-heap/raw.</td>
      <td>120</td>
    </tr>
    <tr>
      <td>2 Visualization of the full memory graph generated from Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw.</td>
      <td>120</td>
    </tr>
    <tr>
      <td>3 Visualization of a truncated memory graph generated from Training/basic/V_7_1-P1/24/17016-1643962152-heap/raw. Here with real addresses.</td>
      <td>121</td>
    </tr>
    <tr>
      <td>4 Visualization of a chunk memory graph generated from Validation/Validation/basic/V_7_8_P1/24/8708-1643979488-heap/raw.</td>
      <td>122</td>
    </tr>
    <tr>
      <td>5 Visualization of a chunk memory graph generated from Training/Training/basic/V_6-8_P1/24/28621-1643890740-heap/raw.</td>
      <td>122</td>
    </tr>
  </tbody>
</table>

List of Tables

<table>
  <tr>
    <td>4.1 Code Statistics for Masterarbeit</td>
    <td>92</td>
  </tr>
</table>
<table>
  <tbody>
    <tr>
      <td>4.2</td>
      <td>Best instances of model: logistic-regression.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.3</td>
      <td>Best instances of model: random-forest.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.4</td>
      <td>Best instances of model: sgd-classifier.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.5</td>
      <td>Best instances of model: very-simple-gcn.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.6</td>
      <td>Best instances of model: simple-gcn.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.7</td>
      <td>Best instances of model: first-gcn.</td>
      <td>105</td>
    </tr>
    <tr>
      <td>4.8</td>
      <td>Best instances of model: gcn-with-dropout.</td>
      <td>105</td>
    </tr>
    <tr>
      <td>4.9</td>
      <td>Best instances of model: advanced-gcn.</td>
      <td>105</td>
    </tr>
    <tr>
      <td>4.10</td>
      <td>Results for the model very-simple-gcn</td>
      <td>105</td>
    </tr>
    <tr>
      <td>5.1</td>
      <td>Duration times for duration of embedding generation in ML/DL/FE pipeline (in seconds).</td>
      <td>114</td>
    </tr>
    <tr>
      <td>5.2</td>
      <td>Duration times for duration of training and testing in ML/DL/FE pipeline (in seconds).</td>
      <td>115</td>
    </tr>
    <tr>
      <td>1</td>
      <td>Best instance for each model, with respect to accuracy.</td>
      <td>123</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Best instance for each model, with respect to precision.</td>
      <td>123</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Best instance for each model, with respect to recall.</td>
      <td>123</td>
    </tr>
    <tr>
      <td>5</td>
      <td>Best model instance for each metric.</td>
      <td>124</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Best instance for each model, with respect to f1 score.</td>
      <td>124</td>
    </tr>
  </tbody>
</table>

## Listings

<table>
  <tbody>
    <tr>
      <td>3.1</td>
      <td>16 bytes per line visualization of a Hex Dump from Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw</td>
      <td>45</td>
    </tr>
    <tr>
      <td>3.2</td>
      <td>8 bytes per line visualization of a Hex Dump from Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw</td>
      <td>45</td>
    </tr>
    <tr>
      <td>3.3</td>
      <td>Complete JSON example, from Training/basic/V_7_8_P1/16/5070-1643978841.json</td>
      <td>46</td>
    </tr>
    <tr>
      <td>3.4</td>
      <td>Command and logs of the C-library version used for the dataset generation</td>
      <td>48</td>
    </tr>
    <tr>
      <td>3.5</td>
      <td>Command and logs of the Linux Standard Base Release used for the dataset generation</td>
      <td>48</td>
    </tr>
    <tr>
      <td>3.6</td>
      <td>Command and logs of the OS and kernel version used for the dataset generation</td>
      <td>48</td>
    </tr>
    <tr>
      <td>3.7</td>
      <td>Count all dataset files</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.8</td>
      <td>Get the total size of the dataset</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.9</td>
      <td>Find the number of RAW files in the dataset</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.10</td>
      <td>Find the number of bytes of RAW files in the dataset</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.11</td>
      <td>Missing keys in JSON annotation file Training/basic/V_6_0_P1/16/24375-1644243522.json</td>
      <td>50</td>
    </tr>
    <tr>
      <td>3.12</td>
      <td>Command and logs of counting the number of RAW files in the cleaned dataset.</td>
      <td>53</td>
    </tr>
    <tr>
      <td>3.13</td>
      <td>Vim command to find potential pointers</td>
      <td>54</td>
    </tr>
    <tr>
      <td>3.14</td>
      <td>Conversions function from hex strings to decimal int values.</td>
      <td>56</td>
    </tr>
    <tr>
      <td>3.15</td>
      <td>8 bytes per line visualization of a Hex Dump from Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw</td>
      <td>56</td>
    </tr>
    <tr>
      <td>3.16</td>
      <td>Python function to check if a potential pointer is 8-bytes aligned</td>
      <td>57</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>4.2</td>
      <td>Best instances of model: logistic-regression.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.3</td>
      <td>Best instances of model: random-forest.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.4</td>
      <td>Best instances of model: sgd-classifier.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.5</td>
      <td>Best instances of model: very-simple-gcn.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.6</td>
      <td>Best instances of model: simple-gcn.</td>
      <td>104</td>
    </tr>
    <tr>
      <td>4.7</td>
      <td>Best instances of model: first-gcn.</td>
      <td>105</td>
    </tr>
    <tr>
      <td>4.8</td>
      <td>Best instances of model: gcn-with-dropout.</td>
      <td>105</td>
    </tr>
    <tr>
      <td>4.9</td>
      <td>Best instances of model: advanced-gcn.</td>
      <td>105</td>
    </tr>
    <tr>
      <td>4.10</td>
      <td>Results for the model very-simple-gcn</td>
      <td>105</td>
    </tr>
    <tr>
      <td>5.1</td>
      <td>Duration times for duration of embedding generation in ML/DL/FE pipeline (in seconds).</td>
      <td>114</td>
    </tr>
    <tr>
      <td>5.2</td>
      <td>Duration times for duration of training and testing in ML/DL/FE pipeline (in seconds).</td>
      <td>115</td>
    </tr>
    <tr>
      <td>1</td>
      <td>Best instance for each model, with respect to accuracy.</td>
      <td>123</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Best instance for each model, with respect to precision.</td>
      <td>123</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Best instance for each model, with respect to recall.</td>
      <td>123</td>
    </tr>
    <tr>
      <td>5</td>
      <td>Best model instance for each metric.</td>
      <td>124</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Best instance for each model, with respect to f1 score.</td>
      <td>124</td>
    </tr>
  </tbody>
</table>

## Listings

<table>
  <tbody>
    <tr>
      <td>3.1</td>
      <td>16 bytes per line visualization of a Hex Dump from Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw</td>
      <td>45</td>
    </tr>
    <tr>
      <td>3.2</td>
      <td>8 bytes per line visualization of a Hex Dump from Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw</td>
      <td>45</td>
    </tr>
    <tr>
      <td>3.3</td>
      <td>Complete JSON example, from Training/basic/V_7_8_P1/16/5070-1643978841.json</td>
      <td>46</td>
    </tr>
    <tr>
      <td>3.4</td>
      <td>Command and logs of the C-library version used for the dataset generation</td>
      <td>48</td>
    </tr>
    <tr>
      <td>3.5</td>
      <td>Command and logs of the Linux Standard Base Release used for the dataset generation</td>
      <td>48</td>
    </tr>
    <tr>
      <td>3.6</td>
      <td>Command and logs of the OS and kernel version used for the dataset generation</td>
      <td>48</td>
    </tr>
    <tr>
      <td>3.7</td>
      <td>Count all dataset files</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.8</td>
      <td>Get the total size of the dataset</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.9</td>
      <td>Find the number of RAW files in the dataset</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.10</td>
      <td>Find the number of bytes of RAW files in the dataset</td>
      <td>49</td>
    </tr>
    <tr>
      <td>3.11</td>
      <td>Missing keys in JSON annotation file Training/basic/V_6_0_P1/16/24375-1644243522.json</td>
      <td>50</td>
    </tr>
    <tr>
      <td>3.12</td>
      <td>Command and logs of counting the number of RAW files in the cleaned dataset.</td>
      <td>53</td>
    </tr>
    <tr>
      <td>3.13</td>
      <td>Vim command to find potential pointers</td>
      <td>54</td>
    </tr>
    <tr>
      <td>3.14</td>
      <td>Conversions function from hex strings to decimal int values.</td>
      <td>56</td>
    </tr>
    <tr>
      <td>3.15</td>
      <td>8 bytes per line visualization of a Hex Dump from Training/basic/V_7_8_P1/16/5070-1643978841-heap/raw</td>
      <td>56</td>
    </tr>
    <tr>
      <td>3.16</td>
      <td>Python function to check if a potential pointer is 8-bytes aligned</td>
      <td>57</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>3.17</td>
      <td>Python function to compute the Shannon entropy of a given block of 8 bytes</td>
      <td>60</td>
    </tr>
    <tr>
      <td>3.18</td>
      <td>Logs from chunk exploration script, related to the last chunk of the file Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw.</td>
      <td>63</td>
    </tr>
    <tr>
      <td>3.19</td>
      <td>Malloc header definition in GLIBC 2.28</td>
      <td>64</td>
    </tr>
    <tr>
      <td>3.20</td>
      <td>Vim command to find potential malloc headers</td>
      <td>64</td>
    </tr>
    <tr>
      <td>3.21</td>
      <td>Testing chunk parsing on Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw.</td>
      <td>67</td>
    </tr>
    <tr>
      <td>3.22</td>
      <td>Printing some free and in-use chunks from Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw.</td>
      <td>70</td>
    </tr>
    <tr>
      <td>3.23</td>
      <td>Printing cleaned dataset chunk parsing global statistics.</td>
      <td>70</td>
    </tr>
    <tr>
      <td>3.24</td>
      <td>Command used to generate the memory graph visualization of Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.25</td>
      <td>A comment field example for a node with embedding. Output is cropped.</td>
      <td>79</td>
    </tr>
    <tr>
      <td>3.26</td>
      <td>A memgraph comment field example containing JSON serialized object with embedding type and feature names. Output is cropped.</td>
      <td>79</td>
    </tr>
    <tr>
      <td>4.1</td>
      <td>Command used to count the number of lines of code in the phdtrack directory, containing the reposiroties of the present thesis.</td>
      <td>92</td>
    </tr>
    <tr>
      <td>4.2</td>
      <td>Sample of final logs of the Mem2Graph program, after generating 6 memgraph datasets from the cleaned heap dump dataset.</td>
      <td>93</td>
    </tr>
    <tr>
      <td>4.3</td>
      <td>Result logs of the memory_graph_gcn/src/sanity_check_gv_files.py program.</td>
      <td>95</td>
    </tr>
    <tr>
      <td>4.4</td>
      <td>Command used to launch final experiments, on Drogon server.</td>
      <td>96</td>
    </tr>
    <tr>
      <td>4.5</td>
      <td>JSON hyperparameters used during experiments</td>
      <td>97</td>
    </tr>
    <tr>
      <td>4.6</td>
      <td>JSON hyperparameters used during experiments</td>
      <td>98</td>
    </tr>
    <tr>
      <td>1</td>
      <td>The DOT file of uncompressed block memgraph, here Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw, with real addresses. Output is cropped.</td>
      <td>119</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Command used to generate the memory graph visualization of Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw here using real addresses.</td>
      <td>121</td>
    </tr>
  </tbody>
</table>
<table>
  <tbody>
    <tr>
      <td>3.17</td>
      <td>Python function to compute the Shannon entropy of a given block of 8 bytes</td>
      <td>60</td>
    </tr>
    <tr>
      <td>3.18</td>
      <td>Logs from chunk exploration script, related to the last chunk of the file Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw.</td>
      <td>63</td>
    </tr>
    <tr>
      <td>3.19</td>
      <td>Malloc header definition in GLIBC 2.28</td>
      <td>64</td>
    </tr>
    <tr>
      <td>3.20</td>
      <td>Vim command to find potential malloc headers</td>
      <td>64</td>
    </tr>
    <tr>
      <td>3.21</td>
      <td>Testing chunk parsing on Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw.</td>
      <td>67</td>
    </tr>
    <tr>
      <td>3.22</td>
      <td>Printing some free and in-use chunks from Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw.</td>
      <td>70</td>
    </tr>
    <tr>
      <td>3.23</td>
      <td>Printing cleaned dataset chunk parsing global statistics.</td>
      <td>70</td>
    </tr>
    <tr>
      <td>3.24</td>
      <td>Command used to generate the memory graph visualization of Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw</td>
      <td>77</td>
    </tr>
    <tr>
      <td>3.25</td>
      <td>A comment field example for a node with embedding. Output is cropped.</td>
      <td>79</td>
    </tr>
    <tr>
      <td>3.26</td>
      <td>A memgraph comment field example containing JSON serialized object with embedding type and feature names. Output is cropped.</td>
      <td>79</td>
    </tr>
    <tr>
      <td>4.1</td>
      <td>Command used to count the number of lines of code in the phdtrack directory, containing the reposiroties of the present thesis.</td>
      <td>92</td>
    </tr>
    <tr>
      <td>4.2</td>
      <td>Sample of final logs of the Mem2Graph program, after generating 6 memgraph datasets from the cleaned heap dump dataset.</td>
      <td>93</td>
    </tr>
    <tr>
      <td>4.3</td>
      <td>Result logs of the memory_graph_gcn/src/sanity_check_gv_files.py program.</td>
      <td>95</td>
    </tr>
    <tr>
      <td>4.4</td>
      <td>Command used to launch final experiments, on Drogon server.</td>
      <td>96</td>
    </tr>
    <tr>
      <td>4.5</td>
      <td>JSON hyperparameters used during experiments</td>
      <td>97</td>
    </tr>
    <tr>
      <td>4.6</td>
      <td>JSON hyperparameters used during experiments</td>
      <td>98</td>
    </tr>
    <tr>
      <td>1</td>
      <td>The DOT file of uncompressed block memgraph, here Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw, with real addresses. Output is cropped.</td>
      <td>119</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Command used to generate the memory graph visualization of Training/basic/V_7_1_P1/24/17016-1643962152-heap/raw here using real addresses.</td>
      <td>121</td>
    </tr>
  </tbody>
</table>
# 1 Introduction

The digital age has brought with it an unprecedented increase in the volume and complexity of data that is being generated, stored, and processed. This data is often sensitive in nature, and its security is of paramount importance, making cybersecurity a critical focus area. This evolving landscape is fraught with challenges that continue to amplify the importance of digital forensics in IT systems. One area that stands out for its widespread use and importance is the Secure Shell protocol (SSH) and its most popular implementation, OpenSSH. SSH is a cryptographic network protocol widely used for secure remote access to systems. It is also used for secure file transfer, and as a secure tunnel for other applications. SSH is a key component of IT systems whose encryption capabilities are critical to the security of IT systems. However, it also presents a unique set of challenges, most notably the concealment of malicious activities.

A common case is when an unauthorized actor gains access to SSH keys so as to get access to a system. This can happen through a malicious human actor, but more commonly through automated processes such as malwares and botnets. This situation presents a formidable and growing threat to cybersecurity, affecting a broad range of stakeholders from governments and financial institutions to individual users. In just 2019, the number of Command and Control (C&C) servers for botnets increased by 71.5%, leading to an estimated $19 billion in advertising theft [0]. Many malwares and botnets «have in common that they have used as attack vector the Secure Shell (SSH) remote access service» [0].

At the heart of the issue lies the fact that SSH veils its communications through encryption, making it difficult to detect malicious activities. To be able to detect those potential malicious actors, it is possible to replace SSH by a honeypot that enables to monitor pseudo-SSH activities. There is a range of readily available honeypots, such as Kippo or Cowrie, which are designed to emulate a vulnerable SSH system and attract attackers [0]. The problem lies that those honeypots are not able to mimic perfectly a real system, which makes them easy to detect by experienced attackers. As stated by „Analysis of SSH Honeypot Effectiveness“: «The ability to collect meaningful malware from attackers depends on how the attackers receive the honeypot. Most attackers fingerprint targets before they launch their attack, so it would be very beneficial for security researchers to understand how to hide honeypots from fingerprinting and trick the attackers into depositing malware. [...] What is certain is that if a cautious attacker believes they are in a honeypot, they will leave without depositing malware onto the system, which reduces the effectiveness of the honeypot» [0].

There are other approaches that allow to decrypt SSH connections without relying on a honeypot, like the man-in-the-middle or binary manipulation with their own set of challenges [0]. Instead of relying on softwares that mimics or modify a real system, it is possible to use a real unmodified system directly. The idea is to be able to decrypt SSH connection channels, which is possible if the SSH keys are known. Since SSH encryption keys are typically stored in the main memory of a system, it is possible for the administrators to extract them through the exploitation of memory dumps of a targeted system. In this context, the ability to detect SSH keys in memory dumps, and specifically OpenSSH keys, is critical to the development of effective SSH honeypot-like systems. The research introduced by the SmartVMI project with SSHKex, SmartKex, the present thesis and the future related work could be used to develop such a new type of system-monitoring tools. This new kind of tools would be very difficult to detect by attackers, increasing their effectiveness, and wouldn't require the alteration of the system. The present report is focused on the SSH key detection in memory dumps, which is a key component allowing to decode SSH communications such that it becomes possible to intercept malicious communications and to detect malicious
# 1 Introduction

The digital age has brought with it an unprecedented increase in the volume and complexity of data that is being generated, stored, and processed. This data is often sensitive in nature, and its security is of paramount importance, making cybersecurity a critical focus area. This evolving landscape is fraught with challenges that continue to amplify the importance of digital forensics in IT systems. One area that stands out for its widespread use and importance is the Secure Shell protocol (SSH) and its most popular implementation, OpenSSH. SSH is a cryptographic network protocol widely used for secure remote access to systems. It is also used for secure file transfer, and as a secure tunnel for other applications. SSH is a key component of IT systems whose encryption capabilities are critical to the security of IT systems. However, it also presents a unique set of challenges, most notably the concealment of malicious activities.

A common case is when an unauthorized actor gains access to SSH keys so as to get access to a system. This can happen through a malicious human actor, but more commonly through automated processes such as malwares and botnets. This situation presents a formidable and growing threat to cybersecurity, affecting a broad range of stakeholders from governments and financial institutions to individual users. In just 2019, the number of Command and Control (C&C) servers for botnets increased by 71.5%, leading to an estimated $19 billion in advertising theft [0]. Many malwares and botnets «have in common that they have used as attack vector the Secure Shell (SSH) remote access service» [0].

At the heart of the issue lies the fact that SSH veils its communications through encryption, making it difficult to detect malicious activities. To be able to detect those potential malicious actors, it is possible to replace SSH by a honeypot that enables to monitor pseudo-SSH activities. There is a range of readily available honeypots, such as Kippo or Cowrie, which are designed to emulate a vulnerable SSH system and attract attackers [0]. The problem lies that those honeypots are not able to mimic perfectly a real system, which makes them easy to detect by experienced attackers. As stated by „Analysis of SSH Honeypot Effectiveness“: «The ability to collect meaningful malware from attackers depends on how the attackers receive the honeypot. Most attackers fingerprint targets before they launch their attack, so it would be very beneficial for security researchers to understand how to hide honeypots from fingerprinting and trick the attackers into depositing malware. [...] What is certain is that if a cautious attacker believes they are in a honeypot, they will leave without depositing malware onto the system, which reduces the effectiveness of the honeypot» [0].

There are other approaches that allow to decrypt SSH connections without relying on a honeypot, like the man-in-the-middle or binary manipulation with their own set of challenges [0]. Instead of relying on softwares that mimics or modify a real system, it is possible to use a real unmodified system directly. The idea is to be able to decrypt SSH connection channels, which is possible if the SSH keys are known. Since SSH encryption keys are typically stored in the main memory of a system, it is possible for the administrators to extract them through the exploitation of memory dumps of a targeted system. In this context, the ability to detect SSH keys in memory dumps, and specifically OpenSSH keys, is critical to the development of effective SSH honeypot-like systems. The research introduced by the SmartVMI project with SSHKex, SmartKex, the present thesis and the future related work could be used to develop such a new type of system-monitoring tools. This new kind of tools would be very difficult to detect by attackers, increasing their effectiveness, and wouldn't require the alteration of the system. The present report is focused on the SSH key detection in memory dumps, which is a key component allowing to decode SSH communications such that it becomes possible to intercept malicious communications and to detect malicious
# 1.1 Research Questions

At the very beginning of this thesis, first questions were:

* What is the state of the art in the field of security key detection in heap dump memory?

* What are the challenges of security key detection in heap dump memory?

* How can the existing methods for detecting SSH keys in OpenSSH heap dumps be improved?

The SmartVMI project has already made significant progress in the detection of SSH keys in OpenSSH heap dumps. An open dataset of memory dumps has been created, and a simple yet effective method for detecting SSH keys has been developed. The dataset has been used to train and test simple machine learning algorithms, and the results have been promising. The research has been published in the form of two papers, SSHkex [0] and SmartKex [0], which is the basis of this thesis.

However, there is still room for improvement, particularly in the area of machine learning algorithms. This thesis seeks to build upon the existing research by refining feature extraction techniques and exploring innovative methods for effective key detection prediction. The objective is to accurately predict the presence and location of SSH keys within memory dumps. Rooted in this context, this Masterarbeit aims to address several key research questions:

* **Memory graph:** How can we develop a memory graph representation to improve the prediction of SSH keys in memory dumps?

* **Memory graph embedding:** How can we develop a memory graph embedding representation to improve the prediction of SSH keys in memory dumps?

* **Feature importance:** What features are most indicative of SSH keys in memory dumps?

* **Feature extraction:** How can these features be extracted from memory dumps and used to train machine learning algorithms?

* **ML for key prediction:** How can machine learning algorithms be optimized for the prediction of SSH keys in memory dumps?

* **Graph Convolutional Networks for key prediction:** How can GCN be used to improve the prediction of SSH keys in memory dumps, and how does it compare to traditional machine learning algorithms?

By tackling these research questions, this thesis seeks not only to advance the academic understanding of SSH key prediction and digital forensics but also to provide practical insights that could lead to the development of more secure and effective systems.
# 1.1 Research Questions

At the very beginning of this thesis, first questions were:

* What is the state of the art in the field of security key detection in heap dump memory?

* What are the challenges of security key detection in heap dump memory?

* How can the existing methods for detecting SSH keys in OpenSSH heap dumps be improved?

The SmartVMI project has already made significant progress in the detection of SSH keys in OpenSSH heap dumps. An open dataset of memory dumps has been created, and a simple yet effective method for detecting SSH keys has been developed. The dataset has been used to train and test simple machine learning algorithms, and the results have been promising. The research has been published in the form of two papers, SSHkex [0] and SmartKex [0], which is the basis of this thesis.

However, there is still room for improvement, particularly in the area of machine learning algorithms. This thesis seeks to build upon the existing research by refining feature extraction techniques and exploring innovative methods for effective key detection prediction. The objective is to accurately predict the presence and location of SSH keys within memory dumps. Rooted in this context, this Masterarbeit aims to address several key research questions:

* **Memory graph:** How can we develop a memory graph representation to improve the prediction of SSH keys in memory dumps?

* **Memory graph embedding:** How can we develop a memory graph embedding representation to improve the prediction of SSH keys in memory dumps?

* **Feature importance:** What features are most indicative of SSH keys in memory dumps?

* **Feature extraction:** How can these features be extracted from memory dumps and used to train machine learning algorithms?

* **ML for key prediction:** How can machine learning algorithms be optimized for the prediction of SSH keys in memory dumps?

* **Graph Convolutional Networks for key prediction:** How can GCN be used to improve the prediction of SSH keys in memory dumps, and how does it compare to traditional machine learning algorithms?

By tackling these research questions, this thesis seeks not only to advance the academic understanding of SSH key prediction and digital forensics but also to provide practical insights that could lead to the development of more secure and effective systems.
## 1.2 Commitment to Open Science and Reproducibility

In alignment with the principles of Open Science, this thesis aims to be not just a scholarly report but also a comprehensive guide for anyone who wishes to understand, replicate, or extend the work presented. Open Science is a movement that advocates for the transparent and accessible sharing of scientific research, data, and dissemination processes [0]. It is built on six fundamental principles [0]:

1. **Open Methodology:** Detailed methodologies are provided to ensure that the experiments can be replicated.

2. **Open Source:** All code used in this research is available for scrutiny and reuse. As such, all code including the LATEX code for the present report <fnref n="1" /> is properly documented and can be accessed on GitHub.

3. **Open Data:** Raw data and the data processing techniques are made publicly available.

4. **Open Access:** The research is published in a manner that is free for all to read and download.

5. **Open Peer Review:** The peer review process is transparent. In the case of this Masterarbeit, the research is reviewed by the supervisors of the project.

6. **Open Educational Resources:** Any educational content produced is shared openly.

To ensure the highest level of reproducibility and accessibility, this thesis includes what might seem like exhaustive details, such as hardware or software specifications, precise shell commands and some code implementations used during the research. These are included to provide a complete picture and to minimize the friction for those who wish to replicate the experiments, whatever their level of expertise may be. By adhering to the principles of Open Science, this thesis aims to contribute to a more transparent, collaborative, and efficient scientific community.

### 1.2.1 GitHub Repositories

In the context of the present Masterarbeit, a number of GitHub repositories have been created to facilitate the sharing of code and data. These repositories are listed below:

* **masterarbeit_report_onyr:** Repository containing the LaTeX code for the report as well as several scripts related to dataset exploration: https://github.com/passau-masterarbeit-2023/masterarbeit_report_onyr

* **mem2graph:** Memory graph creation utility built in Rust, featuring different graph creation and embedding strategies. Collaboration with Clément Lahoche: https://github.com/passau-masterarbeit-2023/mem2graph

* **research-base:** Custom Python framework for developing programs that include all the basics of a research project, such as logging, environment and argument loading, result keeping, and more. Collaboration with Clément Lahoche: https://github.com/0nyr/research-base

<footnote n="1">¹The present report repository can be found here: https://github.com/0nyr/masterarbeit_report</footnote>
## 1.2 Commitment to Open Science and Reproducibility

In alignment with the principles of Open Science, this thesis aims to be not just a scholarly report but also a comprehensive guide for anyone who wishes to understand, replicate, or extend the work presented. Open Science is a movement that advocates for the transparent and accessible sharing of scientific research, data, and dissemination processes [0]. It is built on six fundamental principles [0]:

1. **Open Methodology**: Detailed methodologies are provided to ensure that the experiments can be replicated.

2. **Open Source**: All code used in this research is available for scrutiny and reuse. As such, all code including the LATEX code for the present report <fnref n="1" /> is properly documented and can be accessed on GitHub.

3. **Open Data**: Raw data and the data processing techniques are made publicly available.

4. **Open Access**: The research is published in a manner that is free for all to read and download.

5. **Open Peer Review**: The peer review process is transparent. In the case of this Masterarbeit, the research is reviewed by the supervisors of the project.

6. **Open Educational Resources**: Any educational content produced is shared openly.

To ensure the highest level of reproducibility and accessibility, this thesis includes what might seem like exhaustive details, such as hardware or software specifications, precise shell commands and some code implementations used during the research. These are included to provide a complete picture and to minimize the friction for those who wish to replicate the experiments, whatever their level of expertise may be. By adhering to the principles of Open Science, this thesis aims to contribute to a more transparent, collaborative, and efficient scientific community.

### 1.2.1 GitHub Repositories

In the context of the present Masterarbeit, a number of GitHub repositories have been created to facilitate the sharing of code and data. These repositories are listed below:

* **masterarbeit_report_onyr**: Repository containing the LaTeX code for the report as well as several scripts related to dataset exploration: https://github.com/passau-masterarbeit-2023/masterarbeit_report_onyr

* **mem2graph**: Memory graph creation utility built in Rust, featuring different graph creation and embedding strategies. Collaboration with Clément Lahoche: https://github.com/passau-masterarbeit-2023/mem2graph

* **research-base**: Custom Python framework for developing programs that include all the basics of a research project, such as logging, environment and argument loading, result keeping, and more. Collaboration with Clément Lahoche: https://github.com/Onyr/research-base

<footnote n="1">¹The present report repository can be found here: https://github.com/Onyr/masterarbeit_report</footnote>
* **data_processing**: Python program for data processing and machine learning for SSH key prediction. This repository contains tests on machine learning model training and evaluation for classical .csv based embedding files from *mem2graph*: https://github.com/passau-masterarbeit-2023/data_processing

* **phdtrack_project_3**: Legacy repository containing the first version of the memory graph creation utility and the first version of the dataset creation script. Collaboration with Clément Lahoche. https://github.com/Onyr/phdtrack_project_3

* **memory_graph_gcn**: Main Python program and scripts around GCN for SSH key prediction. This program leverages the modified DOT file with embedding generated by *mem2graph*: https://github.com/passau-masterarbeit-2023/memory_graph_gcn

* **phdtrack_server scripts**: Scripts for the servers used for computing experiments. This repository contains the scripts used to install the necessary tooling and run the experiments on the different servers we used. Collaboration with Clément Lahoche: https://github.com/passau-masterarbeit-2023/phdtrack_server scripts

### 1.2.2 Datasets

All datasets used in this research are publicly available and can be accessed on the Zenodo. The datasets are organized in the following manner:

* **Original Heap Dumps Dataset**: This is the raw dataset used for the research and produced by the SmartKex team [0]. It contains the original heap dumps in the form of *.heap/raw* files with *.json* annotation files. The dataset is available here: https://zenodo.org/records/6537904.

* **Cleaned Heap Dumps Dataset**: This dataset contains heap dumps with annotation files but has been parsed as described in section 3.2. The dataset is available here: https://doi.org/10.5281/zenodo.10514199.

As one can see, and considering the collaborative work effort that has been, it has been decided to regroup all repositories related to the OpenSSH heap dump exploration in a single GitHub organization, *passau-masterarbeit-2023* https://github.com/passau-masterarbeit-2023.

## 1.3 Structure of the Thesis

The present thesis is organized in a manner that ensures a coherent and logical flow of information, following the standard structure of a Masterarbeit report. The structure is designed to gradually guide the reader from understanding the context and background of the research to the intricacies of the methods employed, and finally to the interpretation of the results. Below is a breakdown of each section:

* **Background Section**: This section serves as an introduction to the research context and establishes the foundation for the thesis. It outlines the previous work and state of the art, providing the reader with an understanding of existing knowledge and identifying gaps that this research aims to address. Key concepts, terminologies, and theories relevant to the study are introduced, setting the stage for the subsequent sections.
* **data_processing**: Python program for data processing and machine learning for SSH key prediction. This repository contains tests on machine learning model training and evaluation for classical .csv based embedding files from *mem2graph*: https://github.com/passau-masterarbeit-2023/data_processing

* **phdtrack_project_3**: Legacy repository containing the first version of the memory graph creation utility and the first version of the dataset creation script. Collaboration with Clément Lahoche. https://github.com/Onyr/phdtrack_project_3

* **memory_graph_gcn**: Main Python program and scripts around GCN for SSH key prediction. This program leverages the modified DOT file with embedding generated by *mem2graph*: https://github.com/passau-masterarbeit-2023/memory_graph_gcn

* **phdtrack_serverScripts**: Scripts for the servers used for computing experiments. This repository contains the scripts used to install the necessary tooling and run the experiments on the different servers we used. Collaboration with Clément Lahoche: https://github.com/passau-masterarbeit-2023/phdtrack_serverScripts

### 1.2.2 Datasets

All datasets used in this research are publicly available and can be accessed on the Zenodo. The datasets are organized in the following manner:

* **Original Heap Dumps Dataset**: This is the raw dataset used for the research and produced by the SmartKex team [0]. It contains the original heap dumps in the form of *.heap/raw* files with *.json* annotation files. The dataset is available here: https://zenodo.org/records/6537904.

* **Cleaned Heap Dumps Dataset**: This dataset contains heap dumps with annotation files but has been parsed as described in section 3.2. The dataset is available here: https://doi.org/10.5281/zenodo.10514199.

As one can see, and considering the collaborative work effort that has been, it has been decided to regroup all repositories related to the OpenSSH heap dump exploration in a single GitHub organization, *passau-masterarbeit-2023* https://github.com/passau-masterarbeit-2023.

## 1.3 Structure of the Thesis

The present thesis is organized in a manner that ensures a coherent and logical flow of information, following the standard structure of a Masterarbeit report. The structure is designed to gradually guide the reader from understanding the context and background of the research to the intricacies of the methods employed, and finally to the interpretation of the results. Below is a breakdown of each section:

* **Background Section**: This section serves as an introduction to the research context and establishes the foundation for the thesis. It outlines the previous work and state of the art, providing the reader with an understanding of existing knowledge and identifying gaps that this research aims to address. Key concepts, terminologies, and theories relevant to the study are introduced, setting the stage for the subsequent sections.
* **Methods Section:** This section meticulously describes the methods and approaches employed during the research. From the creation of the dataset to the selection and implementation of machine learning algorithms, this section ensures that the research process is transparent and reproducible.

* **Results Section:** The results' section presents the data obtained from the experiments conducted, outlining both the layout of programs used and the raw results. It provides a factual account of the findings without delving into interpretation or discussion.

* **Discussion Section:** This section offers an analysis and interpretation of the results obtained. It explores the implications of the findings, discusses the limitations of the study, and contextualizes the results within the broader research landscape.

* **Conclusion:** The concluding section succinctly recall the salient points of the thesis. It underscores the contributions made to the field and suggests avenues for future research, providing a fitting closure to the report.

In structuring the thesis in this manner, the intention is to provide the reader with a comprehensive yet accessible insight into the research undertaken all along this year-long project.
* **Methods Section:** This section meticulously describes the methods and approaches employed during the research. From the creation of the dataset to the selection and implementation of machine learning algorithms, this section ensures that the research process is transparent and reproducible.

* **Results Section:** The results' section presents the data obtained from the experiments conducted, outlining both the layout of programs used and the raw results. It provides a factual account of the findings without delving into interpretation or discussion.

* **Discussion Section:** This section offers an analysis and interpretation of the results obtained. It explores the implications of the findings, discusses the limitations of the study, and contextualizes the results within the broader research landscape.

* **Conclusion:** The concluding section succinctly recall the salient points of the thesis. It underscores the contributions made to the field and suggests avenues for future research, providing a fitting closure to the report.

In structuring the thesis in this manner, the intention is to provide the reader with a comprehensive yet accessible insight into the research undertaken all along this year-long project.
# 2 Background

This section is dedicated to the background information needed to understand the work developed in the thesis. It provides the necessary context for the research, including the problem being solved, why it's important, and the related state-of-the-art and background information. It also includes fundamental concepts and theories, terminology definitions, and a high-level overview of the problem domain. Likewise, it serves as a primer to the rest of the report, providing the necessary context for the research and is intended for readers who may not be experts in the specific area of the research but have some knowledge of the broader field.

## 2.1 SSH and OpenSSH Implementation

### 2.1.1 Basics of the Secure Shell Protocol (SSH)

The Secure Shell Protocol, commonly known as SSH, is designed to facilitate secure remote login and other secure network services over insecure networks. SSH has been designed since its inception with security in mind, as a successor of the Telnet protocol, which is not secure, and other «unsecured remote shell protocols such as rlogin, rsh and reexec» [0].

#### 2.1.1.1 SSH design and origin

As stated by the authors of the SSH Annual Report 2018, «The founder of SSH, Tatu Ylönen, designed the first version of the SSH protocol after a password-sniffing attack at his university network. Tatu released his implementation as freeware in July 1995, and the tool quickly gained in popularity. Towards the end of 1995, the SSH user base had grown to 20,000 users in fifty countries. By 2000, there were an estimated 2,000,000 users of the protocol. Today, more than 95% of the servers used to power the Internet have SSH installed in them. The SSH protocol is truly one of the cornerstones of a safe Internet.» [0].

SSH is defined in *The Secure Shell (SSH) Protocol Architecture* [0]. It is divided into three major components:

* **Transport Layer Protocol:** This provides server authentication, confidentiality, and integrity. It can also optionally provide compression. Typically, the transport layer runs over a TCP/IP connection but can also be used on top of any other reliable data stream.

* **User Authentication Protocol:** Running over the transport layer, this protocol authenticates the client-side user to the server. Multiple methods of authentication such as password and public key are supported.

* **Connection Protocol:** This multiplexes the encrypted tunnel established by the preceding layers into several logical channels. Channels can be used for various purposes, such as setting up secure interactive shell sessions or tunneling arbitrary TCP/IP ports.

«The client sends a service request once a secure transport layer connection has been established. A second service request is sent after user authentication is complete. This allows new protocols to be defined and coexist with the protocols listed above» [0].
# 2 Background

This section is dedicated to the background information needed to understand the work developed in the thesis. It provides the necessary context for the research, including the problem being solved, why it's important, and the related state-of-the-art and background information. It also includes fundamental concepts and theories, terminology definitions, and a high-level overview of the problem domain. Likewise, it serves as a primer to the rest of the report, providing the necessary context for the research and is intended for readers who may not be experts in the specific area of the research but have some knowledge of the broader field.

## 2.1 SSH and OpenSSH Implementation

### 2.1.1 Basics of the Secure Shell Protocol (SSH)

The Secure Shell Protocol, commonly known as SSH, is designed to facilitate secure remote login and other secure network services over insecure networks. SSH has been designed since its inception with security in mind, as a successor of the Telnet protocol, which is not secure, and other «unsecured remote shell protocols such as rlogin, rsh and reexec» [0].

#### 2.1.1.1 SSH design and origin

As stated by the authors of the SSH Annual Report 2018, «The founder of SSH, Tatu Ylönen, designed the first version of the SSH protocol after a password-sniffing attack at his university network. Tatu released his implementation as freeware in July 1995, and the tool quickly gained in popularity. Towards the end of 1995, the SSH user base had grown to 20,000 users in fifty countries. By 2000, there were an estimated 2,000,000 users of the protocol. Today, more than 95% of the servers used to power the Internet have SSH installed in them. The SSH protocol is truly one of the cornerstones of a safe Internet.» [0].

SSH is defined in *The Secure Shell (SSH) Protocol Architecture* [0]. It is divided into three major components:

*   **Transport Layer Protocol:** This provides server authentication, confidentiality, and integrity. It can also optionally provide compression. Typically, the transport layer runs over a TCP/IP connection but can also be used on top of any other reliable data stream.

*   **User Authentication Protocol:** Running over the transport layer, this protocol authenticates the client-side user to the server. Multiple methods of authentication such as password and public key are supported.

*   **Connection Protocol:** This multiplexes the encrypted tunnel established by the preceding layers into several logical channels. Channels can be used for various purposes, such as setting up secure interactive shell sessions or tunneling arbitrary TCP/IP ports.

«The client sends a service request once a secure transport layer connection has been established. A second service request is sent after user authentication is complete. This allows new protocols to be defined and coexist with the protocols listed above» [0].
### 2.1.1.2 SSH keys

For the purposes of this Masterarbeit, a comprehensive understanding of SSH's key exchange and encryption mechanism is important. As outlined in SSHKex [0], the SSH protocol utilizes a key exchange procedure that culminates in a derived master key $K$ and a hash value $h$. These components are pivotal for encrypting client-server communications and identifying sessions.

During the key exchange process, Diffie-Hellman is employed to negotiate an ephemeral shared key between the client and the server [0] [0]. The Diffie-Hellman key exchange is a method of securely exchanging cryptographic keys over a public channel. Proposed by Whitfield Diffie and Martin Hellman in 1976, this protocol is one of the first practical implementations of public key exchange. The fundamental principle behind Diffie-Hellman is the difficulty of solving discrete logarithm problems [0]. This ephemeral key is then signed by the server using either RSA, DSA, or another suitable signature algorithm (see 2.1.2.2). The signed key confirms to the client that the negotiated key is indeed from the intended server and not an imposter or a middleman, thereby preventing man-in-the-middle (MITM) attacks.

In addition, the host key of the server is used to sign the Diffie-Hellman parameters. This key is not to be confused with the client key listed in the server's authorized_keys file, which is used later for client authentication.

The key exchange process results in multiple session keys computed for various purposes:

* **Initialization Vectors:** Key A and Key B are designated for initialization vectors from the client to the server and vice versa.

* **Encryption Keys:** Key C and Key D act as encryption keys for client-to-server and server-to-client communications, respectively.

* **Integrity Keys:** Key E and Key F are utilized to preserve the integrity of data transmitted between the client and server.

This approach provides forward secrecy: if the private key is stolen, it does not compromise the encryption of old sessions. This is because the Diffie-Hellman parameters are ephemeral and discarded once they are no longer needed. Therefore, the only long-lasting keypair is used for authentication purposes.

### 2.1.1.3 SSH key encryption

These keys are computed using hash functions that take the master key $K$ and a hash value $H$, a unique letter (A, B, C, D, E, or F), and the session ID as inputs. This is summarized in „The OpenSSH Protocol under the Hood“: « The equations used for deriving the above vectors and keys are taken from RFC 4253 [0]. In the following, the $||$ symbol stands for concatenation, $K$ is encoded as mpint, $K$ is already a number (hash), "A" as byte and $session_id$ as raw data. Any letter, such as the "A" (in quotation marks) means the single character A, or ASCII 65.

* Initial IV client to server: $HASH(K||H||"A"||session_id)$.

* Initial IV server to client: $HASH(K||H||"B"||session_id)$.

* Encryption key client to server: $HASH(K||H||"C"||session_id)$.
### 2.1.1.2 SSH keys

For the purposes of this Masterarbeit, a comprehensive understanding of SSH's key exchange and encryption mechanism is important. As outlined in SSHKex [0], the SSH protocol utilizes a key exchange procedure that culminates in a derived master key $K$ and a hash value $h$. These components are pivotal for encrypting client-server communications and identifying sessions.

During the key exchange process, Diffie-Hellman is employed to negotiate an ephemeral shared key between the client and the server [0] [0]. The Diffie-Hellman key exchange is a method of securely exchanging cryptographic keys over a public channel. Proposed by Whitfield Diffie and Martin Hellman in 1976, this protocol is one of the first practical implementations of public key exchange. The fundamental principle behind Diffie-Hellman is the difficulty of solving discrete logarithm problems [0]. This ephemeral key is then signed by the server using either RSA, DSA, or another suitable signature algorithm (see 2.1.2.2). The signed key confirms to the client that the negotiated key is indeed from the intended server and not an imposter or a middleman, thereby preventing man-in-the-middle (MITM) attacks.

In addition, the host key of the server is used to sign the Diffie-Hellman parameters. This key is not to be confused with the client key listed in the server's authorized_keys file, which is used later for client authentication.

The key exchange process results in multiple session keys computed for various purposes:

* **Initialization Vectors:** Key A and Key B are designated for initialization vectors from the client to the server and vice versa.

* **Encryption Keys:** Key C and Key D act as encryption keys for client-to-server and server-to-client communications, respectively.

* **Integrity Keys:** Key E and Key F are utilized to preserve the integrity of data transmitted between the client and server.

This approach provides forward secrecy: if the private key is stolen, it does not compromise the encryption of old sessions. This is because the Diffie-Hellman parameters are ephemeral and discarded once they are no longer needed. Therefore, the only long-lasting keypair is used for authentication purposes.

### 2.1.1.3 SSH key encryption

These keys are computed using hash functions that take the master key $K$ and a hash value $H$, a unique letter (A, B, C, D, E, or F), and the session ID as inputs. This is summarized in „The OpenSSH Protocol under the Hood": « The equations used for deriving the above vectors and keys are taken from RFC 4253 [0]. In the following, the $||$ symbol stands for concatenation, $K$ is encoded as mpint, $K$ is already a number (hash), "A" as byte and $session_id$ as raw data. Any letter, such as the "A" (in quotation marks) means the single character A, or ASCII 65.

* Initial IV client to server: $HASH(K||H||"A"||session_id)$.

* Initial IV server to client: $HASH(K||H||"B"||session_id)$.

* Encryption key client to server: $HASH(K||H||"C"||session_id)$.
* Encryption key server to client: $HASH(K||H||"D"||session_id)$.

* Integrity key client to server: $HASH(K||H||"E"||session_id)$.

* Integrity key server to client: $HASH(K||H||"F"||session_id)$.

» [0]. Details about the hash function are given in the next section.

The most interesting keys are the encryption keys, as they are used to encrypt the communication between the client and the server. The other keys are used for integrity checks and initialization vectors. Decrypting encrypted SSH communication necessitates either to retrieve these session keys and variables so as to recompute the keys, or to retrieve those keys directly, which is the focus of this Masterarbeit.

## 2.1.2 OpenSSH Implementation

OpenSSH (OpenBSD Secure Shell) is an open-source implementation written in C of the SSH protocol suite, and it is the most widely used SSH implementation [0]. It is the default SSH implementation on most Linux distributions, and it is also available for Windows. OpenSSH is used for a wide range of purposes, including remote command-line login and remote command execution. It is also used for port forwarding, tunneling, and transferring files via SCP and SFTP either manually or via automated processes, such as backup systems, configuration management tools, and automated software deployment tools.

### 2.1.2.1 OpenSSH components

OpenSSH is composed of several tools and daemons, including client and server components [0]:

* **ssh**: The basic client program that allows to log into and execute commands on a remote machine.

* **sftp**: An interactive file transfer program that uses SSH to secure the connection.

* **sshd**: This is the SSH daemon that runs on the server. This is used for connecting to a remote machine when using the SSH client from another system.

* **ssh-agent**: The program that holds private keys in memory, so one doesn't have to enter one's passphrase every time.

* **ssh-add**: A program for adding RSA or DSA identities to the authentication agent.

* **ssh-keygen**: A utility for creating and managing SSH keys.

* **ssh-keyscan**: A utility for gathering public SSH host keys from a number of hosts.

* **ssh-keychk**: A utility for checking the validity of SSH keys.

* Several other tools to support the SSH protocol and the OpenSSH implementation.
* Encryption key server to client: $HASH(K||H||"D"||session_id)$.

* Integrity key client to server: $HASH(K||H||"E"||session_id)$.

* Integrity key server to client: $HASH(K||H||"F"||session_id)$.

» [0]. Details about the hash function are given in the next section.

The most interesting keys are the encryption keys, as they are used to encrypt the communication between the client and the server. The other keys are used for integrity checks and initialization vectors. Decrypting encrypted SSH communication necessitates either to retrieve these session keys and variables so as to recompute the keys, or to retrieve those keys directly, which is the focus of this Masterarbeit.

## 2.1.2 OpenSSH Implementation

OpenSSH (OpenBSD Secure Shell) is an open-source implementation written in C of the SSH protocol suite, and it is the most widely used SSH implementation [0]. It is the default SSH implementation on most Linux distributions, and it is also available for Windows. OpenSSH is used for a wide range of purposes, including remote command-line login and remote command execution. It is also used for port forwarding, tunneling, and transferring files via SCP and SFTP either manually or via automated processes, such as backup systems, configuration management tools, and automated software deployment tools.

### 2.1.2.1 OpenSSH components

OpenSSH is composed of several tools and daemons, including client and server components [0]:

* **ssh**: The basic client program that allows to log into and execute commands on a remote machine.

* **sftp**: An interactive file transfer program that uses SSH to secure the connection.

* **sshd**: This is the SSH daemon that runs on the server. This is used for connecting to a remote machine when using the SSH client from another system.

* **ssh-agent**: The program that holds private keys in memory, so one doesn't have to enter one's passphrase every time.

* **ssh-add**: A program for adding RSA or DSA identities to the authentication agent.

* **ssh-keygen**: A utility for creating and managing SSH keys.

* **ssh-keyscan**: A utility for gathering public SSH host keys from a number of hosts.

* **ssh-keychk**: A utility for checking the validity of SSH keys.

* Several other tools to support the SSH protocol and the OpenSSH implementation.
### 2.1.2.2 OpenSSH hashing

OpenSSH employs a variety of hash functions and algorithms to secure data, most commonly using SHA1. However, SHA1 is increasingly seen as weak due to its vulnerability to collision attacks [0]. In light of this, the contemporary standard leans towards SHA512. The hash functions are used alongside cipher algorithms like «Advance Encryption Standard (AES) Cipher Block Chaining (CBC), AES Counter (AES-CTR), and ChaCha20» [0]. The Message Authentication Code (MAC) typically uses either MD5 or SHA1 hash algorithms in combination with a secret key. Since cybersecurity and cryptography are constantly evolving, so do SSH and OpenSSH. Depending on the version [0], the available hash options include:

* **ssh-dss:** (disabled at run-time since OpenSSH 7.0 released in 2015) SSH-1 version using Digital Signature Algorithm (DSA) from the Digital Signature Standard (DSS). Originally popular but phased out due to vulnerabilities to collision attacks for DSA Key in a 1024-bit modulus. As stated by *Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH)*: «These attacks are still computationally very difficult to perform, but it is desirable that any key exchange using SHA-1 be phased out as soon as possible» [0] [0].

* **ssh-rsa:** (disabled at run-time since OpenSSH 8.8 released in 2021) It refers to the use of RSA (Rivest-Shamir-Adleman) encryption algorithm. In the context of SSH-1, this version had to be replaced due to the related to key size issue similar to DSS: «RSA 1024-bit keys have approximately 80 bits of security strength»... «which may not be sufficient for most users.» [0] [0].

* **ecdsa-sha2-nistp256:** (since OpenSSH 5.7 released in 2011) Uses the SHA-2 family for hashing and the NIST P-256 curve. It is considered secure and efficient, with an Estimated Security Strength (ESS) of 128 bits [0] [0].

* **ecdsa-sha2-nistp384:** (since OpenSSH 5.7) Utilizes the SHA-2 family and the larger NIST P-384 curve for additional security at the cost of performance. It has an ESS of 192 bits [0] [0].

* **ecdsa-sha2-nistp521:** (since OpenSSH 5.7) Employs SHA-2 and the even larger NIST P-521 curve for maximal security with an ESS of 256 bits [0]. It is less commonly used due to performance considerations [0].

* **ssh-ed25519:** (since OpenSSH 6.5 released in 2014) Known for high security and performance efficiency; employs the Ed25519 elliptic curve with an ESS of 128 bits [0] which is similar to ecdsa-sha2-nistp256, and has been more prevalent following the 2013 suspicions of NSA backdoors in NIST curves [0] following the Snowden revelations [0] [0] [0].

* **rsa-sha2-256:** (since OpenSSH 7.2 released in 2016) An upgrade from ssh-rsa, using SHA-256 (with ESS of 128 bits) for hashing to improve security without major performance hits [0].

* **rsa-sha2-512:** (since OpenSSH 7.2) Similar to rsa-sha2-256 but employs SHA-512 for even stronger security, albeit with some performance cost [0].

* **ecdsa-sk:** (since OpenSSH 8.2 released in 2020) Security Key-enabled, uses NIST curves and is geared towards modern hardware-based authentication [0].

* **ed25519-sk:** (since OpenSSH 8.2) Similar to ssh-ed25519 but integrates hardware-based Security Keys for an additional layer of security [0].
### 2.1.2.2 OpenSSH hashing

OpenSSH employs a variety of hash functions and algorithms to secure data, most commonly using SHA1. However, SHA1 is increasingly seen as weak due to its vulnerability to collision attacks [0]. In light of this, the contemporary standard leans towards SHA512. The hash functions are used alongside cipher algorithms like «Advance Encryption Standard (AES) Cipher Block Chaining (CBC), AES Counter (AES-CTR), and ChaCha20» [0]. The Message Authentication Code (MAC) typically uses either MD5 or SHA1 hash algorithms in combination with a secret key. Since cybersecurity and cryptography are constantly evolving, so do SSH and OpenSSH. Depending on the version [0], the available hash options include:

* **ssh-dss:** (disabled at run-time since OpenSSH 7.0 released in 2015) SSH-1 version using Digital Signature Algorithm (DSA) from the Digital Signature Standard (DSS). Originally popular but phased out due to vulnerabilities to collision attacks for DSA Key in a 1024-bit modulus. As stated by *Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH)*: «These attacks are still computationally very difficult to perform, but it is desirable that any key exchange using SHA-1 be phased out as soon as possible» [0] [0].

* **ssh-rsa:** (disabled at run-time since OpenSSH 8.8 released in 2021) It refers to the use of RSA (Rivest-Shamir-Adleman) encryption algorithm. In the context of SSH-1, this version had to be replaced due to the related to key size issue similar to DSS: «RSA 1024-bit keys have approximately 80 bits of security strength»... «which may not be sufficient for most users.» [0] [0].

* **ecdsa-sha2-nistp256:** (since OpenSSH 5.7 released in 2011) Uses the SHA-2 family for hashing and the NIST P-256 curve. It is considered secure and efficient, with an Estimated Security Strength (ESS) of 128 bits [0] [0].

* **ecdsa-sha2-nistp384:** (since OpenSSH 5.7) Utilizes the SHA-2 family and the larger NIST P-384 curve for additional security at the cost of performance. It has an ESS of 192 bits [0] [0].

* **ecdsa-sha2-nistp521:** (since OpenSSH 5.7) Employs SHA-2 and the even larger NIST P-521 curve for maximal security with an ESS of 256 bits [0]. It is less commonly used due to performance considerations [0].

* **ssh-ed25519:** (since OpenSSH 6.5 released in 2014) Known for high security and performance efficiency; employs the Ed25519 elliptic curve with an ESS of 128 bits [0] which is similar to ecdsa-sha2-nistp256, and has been more prevalent following the 2013 suspicions of NSA backdoors in NIST curves [0] following the Snowden revelations [0] [0] [0].

* **rsa-sha2-256:** (since OpenSSH 7.2 released in 2016) An upgrade from ssh-rsa, using SHA-256 (with ESS of 128 bits) for hashing to improve security without major performance hits [0].

* **rsa-sha2-512:** (since OpenSSH 7.2) Similar to rsa-sha2-256 but employs SHA-512 for even stronger security, albeit with some performance cost [0].

* **ecdsa-sk:** (since OpenSSH 8.2 released in 2020) Security Key-enabled, uses NIST curves and is geared towards modern hardware-based authentication [0].

* **ed25519-sk:** (since OpenSSH 8.2) Similar to ssh-ed25519 but integrates hardware-based Security Keys for an additional layer of security [0].
* **NTRU Prime-x25519: (since OpenSSH 9.0)** A new, highly secure algorithm focused on post-quantum cryptography, providing future-proof security [0] [0].

These hashes have fixed lengths such that key lengths range between 12 and 64 bytes [0]. Since high-quality random number generation is crucial to ensure that those keys are secure and difficult to predict, it can thus be assumed that those key have a high entropy [0]. This is a crucial assumption as it is the basis for the use of both brute force and machine learning algorithms to predict the presence and location of SSH keys in memory dumps.

The keys generated by these hash functions are pseudo-random numbers stored in the system's RAM. Following the Kerckhoffs' principle: that «a cryptosystem should be secure, even if everything about the system, except the key, is public knowledge», the code for the OpenSSH implementation is open-source and available on GitHub [0]. This allows for the analysis of the code and the identification of the memory structures where the keys are stored.

### 2.1.3 The state of SSH security

Since its origins, SSH has been developed with cybersecurity in mind, and is generally considered a secure method for remote login and other secure network services over an insecure network. However, as with any technology, it can be exploited if not configured or managed correctly. The protocol is used by system administrators to manage remote systems, and it is also used by automated processes to transfer data and perform other tasks. This makes SSH a valuable target for attackers. In fact, SSH has been a popular target for cyber-attacks. Due to being so prevalent, it is often used by threat actors either as a vector for initial access, as a means to move laterally across a network or as a covered exit for exfiltration of sensitive data [0]. The encrypted nature of its communications makes it an attractive option for attackers, as it can be difficult to detect malicious activity.

#### 2.1.3.1 SSH security issues

Here are some cases where SSH can involve in cyber-attacks, although it's important to note that SSH itself is not inherently insecure:

* **SSH Brute-Force Attacks:** One of the most common types of attacks involving SSH is a brute-force attack, where an attacker tries to gain access by repeatedly attempting to log in with different username-password combinations. These attacks are not sophisticated but can be effective if strong authentication measures are not in place. For instance, the botnet *Chabulo* was used to launch a large-scale brute-force attack «through compromised SSH servers and IoT devices» in 2018 [0].

* **SSH Key Theft:** In some advanced attacks, threat actors have stolen SSH keys to move laterally across a network after initial entry. This allows them to authenticate as a legitimate user and can make detection much more challenging. It can «occur when users have their SSH password or unencrypted keys stolen through a variety of methods (sniffed via a key-logging console program, shoulder-surfed via bad security awareness, poor key management practices, etc.).» [0].

* **Man-in-the-Middle Attacks:** Although SSH is designed to be secure, it can be susceptible to man-in-the-middle attacks if proper verification of SSH keys is not done during the initial connection setup [0].
* **NTRU Prime-x25519: (since OpenSSH 9.0)** A new, highly secure algorithm focused on post-quantum cryptography, providing future-proof security [0] [0].

These hashes have fixed lengths such that key lengths range between 12 and 64 bytes [0]. Since high-quality random number generation is crucial to ensure that those keys are secure and difficult to predict, it can thus be assumed that those key have a high entropy [0]. This is a crucial assumption as it is the basis for the use of both brute force and machine learning algorithms to predict the presence and location of SSH keys in memory dumps.

The keys generated by these hash functions are pseudo-random numbers stored in the system's RAM. Following the Kerckhoffs' principle: that «a cryptosystem should be secure, even if everything about the system, except the key, is public knowledge», the code for the OpenSSH implementation is open-source and available on GitHub [0]. This allows for the analysis of the code and the identification of the memory structures where the keys are stored.

### 2.1.3 The state of SSH security

Since its origins, SSH has been developed with cybersecurity in mind, and is generally considered a secure method for remote login and other secure network services over an insecure network. However, as with any technology, it can be exploited if not configured or managed correctly. The protocol is used by system administrators to manage remote systems, and it is also used by automated processes to transfer data and perform other tasks. This makes SSH a valuable target for attackers. In fact, SSH has been a popular target for cyber-attacks. Due to being so prevalent, it is often used by threat actors either as a vector for initial access, as a means to move laterally across a network or as a covered exit for exfiltration of sensitive data [0]. The encrypted nature of its communications makes it an attractive option for attackers, as it can be difficult to detect malicious activity.

#### 2.1.3.1 SSH security issues

Here are some cases where SSH can involve in cyber-attacks, although it's important to note that SSH itself is not inherently insecure:

* **SSH Brute-Force Attacks:** One of the most common types of attacks involving SSH is a brute-force attack, where an attacker tries to gain access by repeatedly attempting to log in with different username-password combinations. These attacks are not sophisticated but can be effective if strong authentication measures are not in place. For instance, the botnet *Chabulo* was used to launch a large-scale brute-force attack «through compromised SSH servers and IoT devices» in 2018 [0].

* **SSH Key Theft:** In some advanced attacks, threat actors have stolen SSH keys to move laterally across a network after initial entry. This allows them to authenticate as a legitimate user and can make detection much more challenging. It can «occur when users have their SSH password or unencrypted keys stolen through a variety of methods (sniffed via a key-logging console program, shoulder-surfed via bad security awareness, poor key management practices, etc.).» [0].

* **Man-in-the-Middle Attacks:** Although SSH is designed to be secure, it can be susceptible to man-in-the-middle attacks if proper verification of SSH keys is not done during the initial connection setup [0].
* **Misconfiguration:** As with any technology, misconfiguration can lead to security issues. For example, leaving default passwords, using weak encryption algorithms, or enabling root login can all make an SSH-enabled system vulnerable [0].

### 2.1.3.2 SSH vulnerabilities

In cybersecurity, it is generally considered that any system that is connected to the Internet will be attacked at some point. Similarly, it is a common saying that no system is 100% secure. This is true for SSH as well. Although it is a secure protocol, it can be exploited if not configured or managed correctly.

Some vulnerabilities have also been discovered in the protocol itself, although these are rare.

* **SSH-1 Vulnerabilities:** A series of vulnerabilities in the first implementation of SSH were discovered from 1998 to 2001, with its subsequent fixes leading to unauthorized content insertion and arbitrary code execution. SSH-1 had many design flows and is now considered obsolete. [0], [0].

* **CBC Plaintext Recovery:** A theoretical vulnerability discovered in 2008 affecting all versions of SSH, allowing the recovery of up to 32 bits of plaintext from CBC-encrypted ciphertext [0].

* **Suspected Decryption by NSA:** Leaked information in 2014 suggested that the NSA might be able to decrypt some SSH traffic, although the protocol itself was not confirmed to be compromised [0].

### 2.1.3.3 SSH and cyber-attacks

SSH has been used in many high-profile cyber-attacks and malwares, including the following:

* **Operation Windigo:** This was a large-scale campaign that infected over 25,000 UNIX servers. SSH was one of the vectors used for maintaining control over compromised servers. A report by ESET mentions that the OpenSSH backdoor Linux/Ebury was first discovered in 2011 as a component of the aforementioned operation. «This operation has been ongoing since at least 2011 and has affected high profile servers and companies, including cPanel - the company behind the famous web hosting control panel - and Linux Foundation's kernel.org - the main repository of source code for the Linux kernel» [0].

* **Linux/Hydra:** Initially unleashed in 2008, this malware is a fast login cracker that targets a range of popular protocols including SSH. Hence, SSH is one of its primary vectors to gain initial access to Internet of Things (IoT) devices. Once a device is infected by Linux/Hydra, it joins an IRC channel and initiates a SYN Flood attack [0].

* **Psyb0t:** Discovered in early 2009, Psyb0t is an IRC-controlled malware specifically designed to target devices with MIPS architecture, such as routers and modems. Notably, it was responsible for orchestrating a DDoS attack against the DroneBL service, infecting up to 100,000 devices for this purpose. The malware is equipped to conduct UDP and ICMP flood attacks and employs a brute-force attack mechanism against Telnet and SSH ports. Remarkably, it uses a pre-configured list of 6,000 usernames and 13,000 passwords to perform these attacks [0].
* **Misconfiguration:** As with any technology, misconfiguration can lead to security issues. For example, leaving default passwords, using weak encryption algorithms, or enabling root login can all make an SSH-enabled system vulnerable [0].

### 2.1.3.2 SSH vulnerabilities

In cybersecurity, it is generally considered that any system that is connected to the Internet will be attacked at some point. Similarly, it is a common saying that no system is 100% secure. This is true for SSH as well. Although it is a secure protocol, it can be exploited if not configured or managed correctly.

Some vulnerabilities have also been discovered in the protocol itself, although these are rare.

* **SSH-1 Vulnerabilities:** A series of vulnerabilities in the first implementation of SSH were discovered from 1998 to 2001, with its subsequent fixes leading to unauthorized content insertion and arbitrary code execution. SSH-1 had many design flows and is now considered obsolete. [0], [0].

* **CBC Plaintext Recovery:** A theoretical vulnerability discovered in 2008 affecting all versions of SSH, allowing the recovery of up to 32 bits of plaintext from CBC-encrypted ciphertext [0].

* **Suspected Decryption by NSA:** Leaked information in 2014 suggested that the NSA might be able to decrypt some SSH traffic, although the protocol itself was not confirmed to be compromised [0].

### 2.1.3.3 SSH and cyber-attacks

SSH has been used in many high-profile cyber-attacks and malwares, including the following:

* **Operation Windigo:** This was a large-scale campaign that infected over 25,000 UNIX servers. SSH was one of the vectors used for maintaining control over compromised servers. A report by ESET mentions that the OpenSSH backdoor Linux/Ebury was first discovered in 2011 as a component of the aforementioned operation. «This operation has been ongoing since at least 2011 and has affected high profile servers and companies, including cPanel - the company behind the famous web hosting control panel - and Linux Foundation's kernel.org - the main repository of source code for the Linux kernel» [0].

* **Linux/Hydra:** Initially unleashed in 2008, this malware is a fast login cracker that targets a range of popular protocols including SSH. Hence, SSH is one of its primary vectors to gain initial access to Internet of Things (IoT) devices. Once a device is infected by Linux/Hydra, it joins an IRC channel and initiates a SYN Flood attack [0].

* **Psyb0t:** Discovered in early 2009, Psyb0t is an IRC-controlled malware specifically designed to target devices with MIPS architecture, such as routers and modems. Notably, it was responsible for orchestrating a DDoS attack against the DroneBL service, infecting up to 100,000 devices for this purpose. The malware is equipped to conduct UDP and ICMP flood attacks and employs a brute-force attack mechanism against Telnet and SSH ports. Remarkably, it uses a pre-configured list of 6,000 usernames and 13,000 passwords to perform these attacks [0].
* **Chuck Noris:** Similar to Psyb0t in its objectives and methods, Chuck Noris targets routers and DSL modems, focusing on SoHo (small office/home office) devices. However, unlike Psyb0t, which uses ICMP flood attacks, Chuck Noris deploys ACK flood attacks. The malware carries out brute-force attacks on Telnet and SSH open ports, drawing parallels to the tactics employed by Psyb0t but with the specific variation in flooding techniques [0].

It's worth noting that in many of these cases, SSH was not the initial attack vector but was used at some stage in the attack lifecycle. Properly configured and managed SSH is still considered a secure and robust protocol for remote access and data transfer. In all those situations, a tool monitoring the SSH traffic could have detected the malicious activities and prevented the attack.

### 2.1.4 The Imperative of SSH Honeypots in Cybersecurity Monitoring

SSH (Secure Shell) has become an indispensable protocol for secure communication but can also conceal malicious agents. This reality underscores the urgency for robust monitoring mechanisms capable of identifying suspicious activities in real-time. Among various countermeasures, SSH honeypots have emerged as a particularly effective tool for monitoring and gathering intelligence on potential threats.

An SSH honeypot is a decoy server or service that mimics legitimate SSH services. The primary aim is to attract cybercriminals and study their tactics, thereby offering an active form of surveillance and data collection. Unlike traditional intrusion detection systems, honeypots do not merely identify an attack; they engage the attacker in a controlled environment, enabling detailed observation and logging of the intruder's actions. This allows for the collection of valuable information, such as the attacker's IP address, the tools used, and the techniques employed. This data can then be used to enhance security measures and develop more robust countermeasures [0].

SSH honeypots serve as an invaluable asset in the cybersecurity arsenal, providing not just a reactive but a proactive measure against evolving cyber threats. They can collect actionable intelligence on new hacking methods, malware, and exploitation scripts. This information can be crucial for proactively securing actual production environments. The data collected can also be used to trace back to the origin of the attack, facilitating legal pursuits against the perpetrators. By diverting attackers to decoy servers, honeypots also protect real assets from being targeted, saving both computational resources and administrative effort needed for post-incident recovery.

Popular SSH honeypots include Kippo, Cowrie, and HoneySSH. Cowrie is a fork of Kippo, with additional features such as logging of attacker's keystrokes and file transfer.

* **Kippo:** Kippo is a medium-interaction honeypot that logs the attacker's shell interaction. It specializes in capturing brute force and Telnet-based attacks [0].

* **Cowrie:** Serving as Kippo's successor, Cowrie emulates various protocols including SSH, SFTP, and SCP. It logs events in JSON format, making it particularly useful for detecting brute force and Telnet-based attacks, as well as spoofing attacks [0].

* **IoTPOT:** This IoT-focused honeypot supports multiple CPU architectures and can detect a variety of attacks including brute force, DoS, and sniffing attacks on Telnet, SSH, and HTTP ports [0].

* **HoneySSH:** HoneySSH is a low-interaction honeypot that emulates an SSH server and logs the attacker's IP address, username, and password [0].
* **Chuck Noris:** Similar to Psyb0t in its objectives and methods, Chuck Noris targets routers and DSL modems, focusing on SoHo (small office/home office) devices. However, unlike Psyb0t, which uses ICMP flood attacks, Chuck Noris deploys ACK flood attacks. The malware carries out brute-force attacks on Telnet and SSH open ports, drawing parallels to the tactics employed by Psyb0t but with the specific variation in flooding techniques [0].

It's worth noting that in many of these cases, SSH was not the initial attack vector but was used at some stage in the attack lifecycle. Properly configured and managed SSH is still considered a secure and robust protocol for remote access and data transfer. In all those situations, a tool monitoring the SSH traffic could have detected the malicious activities and prevented the attack.

### 2.1.4 The Imperative of SSH Honeypots in Cybersecurity Monitoring

SSH (Secure Shell) has become an indispensable protocol for secure communication but can also conceal malicious agents. This reality underscores the urgency for robust monitoring mechanisms capable of identifying suspicious activities in real-time. Among various countermeasures, SSH honeypots have emerged as a particularly effective tool for monitoring and gathering intelligence on potential threats.

An SSH honeypot is a decoy server or service that mimics legitimate SSH services. The primary aim is to attract cybercriminals and study their tactics, thereby offering an active form of surveillance and data collection. Unlike traditional intrusion detection systems, honeypots do not merely identify an attack; they engage the attacker in a controlled environment, enabling detailed observation and logging of the intruder's actions. This allows for the collection of valuable information, such as the attacker's IP address, the tools used, and the techniques employed. This data can then be used to enhance security measures and develop more robust countermeasures [0].

SSH honeypots serve as an invaluable asset in the cybersecurity arsenal, providing not just a reactive but a proactive measure against evolving cyber threats. They can collect actionable intelligence on new hacking methods, malware, and exploitation scripts. This information can be crucial for proactively securing actual production environments. The data collected can also be used to trace back to the origin of the attack, facilitating legal pursuits against the perpetrators. By diverting attackers to decoy servers, honeypots also protect real assets from being targeted, saving both computational resources and administrative effort needed for post-incident recovery.

Popular SSH honeypots include Kippo, Cowrie, and HoneySSH. Cowrie is a fork of Kippo, with additional features such as logging of attacker's keystrokes and file transfer.

* **Kippo:** Kippo is a medium-interaction honeypot that logs the attacker's shell interaction. It specializes in capturing brute force and Telnet-based attacks [0].

* **Cowrie:** Serving as Kippo's successor, Cowrie emulates various protocols including SSH, SFTP, and SCP. It logs events in JSON format, making it particularly useful for detecting brute force and Telnet-based attacks, as well as spoofing attacks [0].

* **IoTPOT:** This IoT-focused honeypot supports multiple CPU architectures and can detect a variety of attacks including brute force, DoS, and sniffing attacks on Telnet, SSH, and HTTP ports [0].

* **HoneySSH:** HoneySSH is a low-interaction honeypot that emulates an SSH server and logs the attacker's IP address, username, and password [0].
* **Sarracenia (SSHKex):** Introduced in 2018, Sarracenia is a high-interaction SSH honeypot that has been enhanced by SSHKex. Instead of «requiring the VM to be paused for every incoming or outgoing packet, which degrades the server performance» [0], SSHKex allows for the extraction of derived SSH session keys. This reduces the performance degradation significantly, as the VM is paused less frequently [0] [0].

These honeypots are useful tools for gathering intelligence on potential threats. However, they are not without their limitations.

### 2.1.5 Research context and motivation for this Masterarbeit

Security and malware detection are active areas of research, with SSH honeypots being a particularly promising tool for gathering intelligence on potential threats. However, they are not without their limitations. For instance, they are not able to perfectly mimic a real system, such that attackers might be able to detect them [0].

As explained in „Analysis of SSH Honeypot Effectiveness": «As attackers become more sophisticated with their ransomware and malware campaigns, there is a significant need for security researchers to assist the greater community by running vulnerable honeypot machines to collect malicious software». Hetzler, Chen, and Khan explain that «the ability to collect meaningful malware from attackers depends on how the attackers receive the honeypot. Most attackers fingerprint targets before they launch their attack, so it would be very beneficial for security researchers to understand how to hide honeypots from fingerprinting and trick the attackers into depositing malware.» They conclude that «What is certain is that if a cautious attacker believes they are in a honeypot, they will leave without depositing malware onto the system, which reduces the effectiveness of the honeypot for security research.» We can extrapolate this conclusion to SSH honeypots, which are also vulnerable to fingerprinting and detection by attackers.

Hence, the need for more advanced SSH honeypots-inspired tools that can leverage data forensic and machine learning techniques so as to be able to use directly a real server as a honeypot, without the need to emulate a system. The current master's thesis is aligned with this ongoing research (see 2.2), further enhancing the state of SSH honeypots. It aims to develop algorithms, proof of concepts and tools that can extract SSH keys from memory dumps of a real server, and use them to decrypt SSH traffic. This could lead to the development of new tools for SSH monitoring, as discussed in the future work section 6.2.

## 2.2 Previous Work on OpenSSH key extraction

Now that the necessary context has been established, this section will present the related work in the field of machine learning for memory forensics in the context of OpenSSH. It is divided into two parts. The first part will present the related work in the field of memory forensics, and the second part will present the related work in the field of machine learning for memory forensics.

### 2.2.1 SSHKex

SSHKex is a research project that aims to address the challenges of analyzing encrypted SSH traffic by leveraging Virtual Machine Introspection (VMI) techniques. Developed by Sentanoe
* **Sarracenia (SSHKex):** Introduced in 2018, Sarracenia is a high-interaction SSH honeypot that has been enhanced by SSHKex. Instead of «requiring the VM to be paused for every incoming or outgoing packet, which degrades the server performance» [0], SSHKex allows for the extraction of derived SSH session keys. This reduces the performance degradation significantly, as the VM is paused less frequently [0] [0].

These honeypots are useful tools for gathering intelligence on potential threats. However, they are not without their limitations.

### 2.1.5 Research context and motivation for this Masterarbeit

Security and malware detection are active areas of research, with SSH honeypots being a particularly promising tool for gathering intelligence on potential threats. However, they are not without their limitations. For instance, they are not able to perfectly mimic a real system, such that attackers might be able to detect them [0].

As explained in „Analysis of SSH Honeypot Effectiveness": «As attackers become more sophisticated with their ransomware and malware campaigns, there is a significant need for security researchers to assist the greater community by running vulnerable honeypot machines to collect malicious software». Hetzler, Chen, and Khan explain that «the ability to collect meaningful malware from attackers depends on how the attackers receive the honeypot. Most attackers fingerprint targets before they launch their attack, so it would be very beneficial for security researchers to understand how to hide honeypots from fingerprinting and trick the attackers into depositing malware.» They conclude that «What is certain is that if a cautious attacker believes they are in a honeypot, they will leave without depositing malware onto the system, which reduces the effectiveness of the honeypot for security research.» We can extrapolate this conclusion to SSH honeypots, which are also vulnerable to fingerprinting and detection by attackers.

Hence, the need for more advanced SSH honeypots-inspired tools that can leverage data forensic and machine learning techniques so as to be able to use directly a real server as a honeypot, without the need to emulate a system. The current master's thesis is aligned with this ongoing research (see 2.2), further enhancing the state of SSH honeypots. It aims to develop algorithms, proof of concepts and tools that can extract SSH keys from memory dumps of a real server, and use them to decrypt SSH traffic. This could lead to the development of new tools for SSH monitoring, as discussed in the future work section 6.2.

## 2.2 Previous Work on OpenSSH key extraction

Now that the necessary context has been established, this section will present the related work in the field of machine learning for memory forensics in the context of OpenSSH. It is divided into two parts. The first part will present the related work in the field of memory forensics, and the second part will present the related work in the field of machine learning for memory forensics.

### 2.2.1 SSHKex

SSHKex is a research project that aims to address the challenges of analyzing encrypted SSH traffic by leveraging Virtual Machine Introspection (VMI) techniques. Developed by Sentanoe
and Reiser, the project focuses on extracting SSH keys and decrypting SSH network traffic in a stealthy, non-intrusive manner while maintaining evidence integrity [0]. This paper is itself a continuation of the work presented in „Sarracenia: Enhancing the Performance and Stealthisness of SSH Honeypots Using Virtual Machine Introspection“ [0], which introduced Sarracenia, a high-interaction SSH honeypot. It is also related to a range of other research projects and papers [0, section 5.6 and 6].

The SSHKex approach combines standard network traffic capturing methods with dynamic SSH session key extraction. It assumes that the SSH implementation running on the server is known, which is crucial for the key extraction process. The project employs VMI tools like LibVMI and Volatility to gain a complete and untainted view of all guest VM's state information. This allows to efficiently locate SSH session keys in the main memory of a Linux machine.

Here is a summary of the SSHKex methodology for key extraction:

1. **Data Structure Information:** The method leverages detailed knowledge about the data structures used to store the keys. Specific debugging symbols corresponding to the SSH implementation version on the target system provide essential offset values to facilitate the extraction of key material. The structures of interest include `struct ssh`, `struct session_`-state, `struct newkeys`, and `struct sshenc`. These structures store a range of information such as IP addresses, ports, session states, and encryption keys.

2. **Tracing OpenSSH Functions:** Function tracing is employed to identify the precise locations of data structures and to extract keys at the right time. The focus is on two key functions: `kex_derive_keys` (which initiates key generation) and `do_authentication2` (which kicks off user authentication).

3. **Breakpoints Injection:** Software breakpoints are intentionally placed in the program execution to facilitate debugging. SSHKex utilizes Virtual Machine Introspection (VMI) to inject these breakpoints at the initial points of the two aforementioned key functions.

4. **Key Extraction:** Upon calling the `kex_derive_keys` function, SSHKex initially stores the address of the `ssh struct`. The actual keys are extracted from memory when the `do_authentication2` function is subsequently called, adhering to the known structures.

5. **Key Indexing:** OpenSSH stores client-to-server and server-to-client keys in distinct indices of the `newkeys` structure. SSHKex extracts keys based on these specific indices.

6. **Handling Multiple Connections:** To manage multiple SSH connections, OpenSSH spawns child processes. SSHKex extends its key extraction strategy to each child process by identifying them through their unique process IDs.

One of the key strengths of SSHKex is its focus on stealthiness, preservation, and evidence integrity. The approach aims to be as unobtrusive as possible, avoiding any modifications to the system under investigation. This is particularly important in forensic contexts, where the integrity of the evidence is crucial [0].

### 2.2.2 SmartKex

SmartKex is a direct followup project that focuses on the extraction of SSH keys from heap memory dumps. Its primary objective is to automate the process of SSH key extraction from heap memory dumps. The project introduces a machine learning-assisted methodology that
and Reiser, the project focuses on extracting SSH keys and decrypting SSH network traffic in a stealthy, non-intrusive manner while maintaining evidence integrity [0]. This paper is itself a continuation of the work presented in „Sarracenia: Enhancing the Performance and Stealthisness of SSH Honeypots Using Virtual Machine Introspection“ [0], which introduced Sarracenia, a high-interaction SSH honeypot. It is also related to a range of other research projects and papers [0, section 5.6 and 6].

The SSHKex approach combines standard network traffic capturing methods with dynamic SSH session key extraction. It assumes that the SSH implementation running on the server is known, which is crucial for the key extraction process. The project employs VMI tools like LibVMI and Volatility to gain a complete and untainted view of all guest VM's state information. This allows to efficiently locate SSH session keys in the main memory of a Linux machine.

Here is a summary of the SSHKex methodology for key extraction:

1. **Data Structure Information:** The method leverages detailed knowledge about the data structures used to store the keys. Specific debugging symbols corresponding to the SSH implementation version on the target system provide essential offset values to facilitate the extraction of key material. The structures of interest include `struct ssh`, `struct session_-state`, `struct newkeys`, and `struct sshenc`. These structures store a range of information such as IP addresses, ports, session states, and encryption keys.

2. **Tracing OpenSSH Functions:** Function tracing is employed to identify the precise locations of data structures and to extract keys at the right time. The focus is on two key functions: `kex_derive_keys` (which initiates key generation) and `do_authentication2` (which kicks off user authentication).

3. **Breakpoints Injection:** Software breakpoints are intentionally placed in the program execution to facilitate debugging. SSHKex utilizes Virtual Machine Introspection (VMI) to inject these breakpoints at the initial points of the two aforementioned key functions.

4. **Key Extraction:** Upon calling the `kex_derive_keys` function, SSHKex initially stores the address of the `ssh struct`. The actual keys are extracted from memory when the `do_authentication2` function is subsequently called, adhering to the known structures.

5. **Key Indexing:** OpenSSH stores client-to-server and server-to-client keys in distinct indices of the `newkeys` structure. SSHKex extracts keys based on these specific indices.

6. **Handling Multiple Connections:** To manage multiple SSH connections, OpenSSH spawns child processes. SSHKex extends its key extraction strategy to each child process by identifying them through their unique process IDs.

One of the key strengths of SSHKex is its focus on stealthiness, preservation, and evidence integrity. The approach aims to be as unobtrusive as possible, avoiding any modifications to the system under investigation. This is particularly important in forensic contexts, where the integrity of the evidence is crucial [0].

### 2.2.2 SmartKex

SmartKex is a direct followup project that focuses on the extraction of SSH keys from heap memory dumps. Its primary objective is to automate the process of SSH key extraction from heap memory dumps. The project introduces a machine learning-assisted methodology that
significantly improves the efficiency and accuracy of key extraction compared to traditional brute-force methods. This method is also significantly more straightforward to implement compared to the previous SSHKex approach, which requires detailed knowledge of the SSH implementation and the ability to inject breakpoints into the program execution.

SmartKex discusses two distinct methods for SSH key extraction:

* **Brute-Force Baseline Method:** This is a traditional approach that scans through the heap memory to identify potential keys based on known patterns.

* **Machine Learning-Assisted Method:** This approach uses a Random Forest algorithm trained on a highly imbalanced dataset using SMOTE balancing. The machine learning model is designed to identify SSH keys with high precision and recall rates, but is not exact as compared to the brute-force method since it is based on a probabilistic model.

### 2.2.2.1 Baseline brute-force method

Here is a summary of SmartKex's brute-force method for SSH key extraction from heap dumps [0]:

1. **Heap Dump Generation:** Heap dump binary files of OpenSSH server process have been generated (ASK HOW) and serves as the input for the key extraction process. The exact process and architecture is not described in SmartKex paper, but we suppose it was done on a *linux-x86_64* architecture.

2. **Data Reduction:** To minimize the heap size, the method removes memory pages that are irrelevant (empty) based on Hamming distance.

3. **Brute-force key search:** Starting from the first byte, a key length of 128 bytes is taken from the heap dump as the potential key. The algorithm iterates over the entire heap, continuously updating the potential key until the heap's end is reached.

4. **Decryption Attempt:** For every potential key, an attempt is made to decrypt network packets. If decryption fails, the process is repeated with a new potential key.

Although the brute-force approach is exact, it is computationally expensive. It performs poorly especially when keys are located at the end of the heap dump [0, section 6.2].

### 2.2.2.2 SmartKex machine-learning method

The real innovation of SmartKex is its machine learning-assisted methodology for SSH key extraction. At the cost of exactness, this approach is significantly faster than the brute-force method and has a high degree of accuracy in identifying encryption keys. It also allows for the heap size to be reduced to less than 2% of its original size, further optimizing the extraction process.

Here is a summary of SmartKex's machine learning-assisted method for SSH key extraction from heap dumps [0]:

1. **Heap Dump inputs:** Similarly to the brute-force method, heap dump binary files of OpenSSH also serve as inputs for the key extraction process.
significantly improves the efficiency and accuracy of key extraction compared to traditional brute-force methods. This method is also significantly more straightforward to implement compared to the previous SSHKex approach, which requires detailed knowledge of the SSH implementation and the ability to inject breakpoints into the program execution.

SmartKex discusses two distinct methods for SSH key extraction:

* **Brute-Force Baseline Method:** This is a traditional approach that scans through the heap memory to identify potential keys based on known patterns.

* **Machine Learning-Assisted Method:** This approach uses a Random Forest algorithm trained on a highly imbalanced dataset using SMOTE balancing. The machine learning model is designed to identify SSH keys with high precision and recall rates, but is not exact as compared to the brute-force method since it is based on a probabilistic model.

### 2.2.2.1 Baseline brute-force method

Here is a summary of SmartKex's brute-force method for SSH key extraction from heap dumps [0]:

1. **Heap Dump Generation:** Heap dump binary files of OpenSSH server process have been generated (ASK HOW) and serves as the input for the key extraction process. The exact process and architecture is not described in SmartKex paper, but we suppose it was done on a *linux-x86_64* architecture.

2. **Data Reduction:** To minimize the heap size, the method removes memory pages that are irrelevant (empty) based on Hamming distance.

3. **Brute-force key search:** Starting from the first byte, a key length of 128 bytes is taken from the heap dump as the potential key. The algorithm iterates over the entire heap, continuously updating the potential key until the heap's end is reached.

4. **Decryption Attempt:** For every potential key, an attempt is made to decrypt network packets. If decryption fails, the process is repeated with a new potential key.

Although the brute-force approach is exact, it is computationally expensive. It performs poorly especially when keys are located at the end of the heap dump [0, section 6.2].

### 2.2.2.2 SmartKex machine-learning method

The real innovation of SmartKex is its machine learning-assisted methodology for SSH key extraction. At the cost of exactness, this approach is significantly faster than the brute-force method and has a high degree of accuracy in identifying encryption keys. It also allows for the heap size to be reduced to less than 2% of its original size, further optimizing the extraction process.

Here is a summary of SmartKex's machine learning-assisted method for SSH key extraction from heap dumps [0]:

1. **Heap Dump inputs:** Similarly to the brute-force method, heap dump binary files of OpenSSH also serve as inputs for the key extraction process.
2. **Preprocessing:** The raw heap dump is resized into an $N \times 8$ matrix. High entropy parts of the heap dump, which are likely to be encryption keys, are identified using the logical AND operation on the vertical and horizontal differences of adjacent bytes. This creates an array that flags potential key locations.

3. **Training:** A Random Forest algorithm is trained on 128-byte slices of the preprocessed heap. The dataset is imbalanced, with the slices that contain keys being rare. A stacked classifier approach is used, comprising a high precision classifier and a high recall classifier.

4. **Key Identification:** The machine learning model is used to predict which 128-byte slices of the heap dump are likely to contain encryption keys. These slices are then subjected to a brute-force method to actually extract the keys.

SmartKex is significantly faster than the brute-force method alone and has a high degree of accuracy in identifying encryption keys. It also allows for the heap size to be reduced to less than 2% of its original size, further optimizing the extraction process.

SmartKex has broad applications in the field of cybersecurity, particularly in memory forensics. Its machine learning-assisted methodology can be adapted for other types of sensitive data extraction, making it a versatile tool for researchers and practitioners alike. The project is open-source, with the code available on GitHub<fnref n="1" />.

### 2.2.3 Objectives of the present work

This Masterarbeit can be seen as a direct followup to the paper „SmartKex: Machine Learning Assisted SSH Keys Extraction From The Heap Dump“. The present work aims to improve the SmartKex methodology by exploring new machine learning architectures and algorithms. The goal is to improve the accuracy of the machine learning model and to reduce the computational complexity of the overall process.

To do so, this work has significantly broadened the research area by exploring entirely new ways to deal with the dataset by leveraging memory graph representation, feature engineering, new machine learning and deep learning model architectures, and new training strategies. A range of different tools and script, with a focus on code quality and reproducibility with careful packaging using Nix ensure that the present research can be easily extended and reproduced by other researchers.

## 2.3 Graph-based memory modelization

In the following section, we present important concepts that will be used for the memory modelization of the heap dump.

Because the dataset used is composed of RAW heap dump files from OpenSSH, it is a critical aspect to understand how memory works at a low level point of view. This section aims to provide an in-depth understanding of how memory is managed in C, the language used in the OpenSSH implementation of SSH, for a *linux-x86_64* architecture. We will explore the fundamental concepts of memory management, including the heap and the stack, memory allocation, and the role of

<footnote n="1">¹https://github.com/smartvmi/Smart-and-Naive-SSH-Key-Extraction</footnote>
2. **Preprocessing:** The raw heap dump is resized into an $N \times 8$ matrix. High entropy parts of the heap dump, which are likely to be encryption keys, are identified using the logical AND operation on the vertical and horizontal differences of adjacent bytes. This creates an array that flags potential key locations.

3. **Training:** A Random Forest algorithm is trained on 128-byte slices of the preprocessed heap. The dataset is imbalanced, with the slices that contain keys being rare. A stacked classifier approach is used, comprising a high precision classifier and a high recall classifier.

4. **Key Identification:** The machine learning model is used to predict which 128-byte slices of the heap dump are likely to contain encryption keys. These slices are then subjected to a brute-force method to actually extract the keys.

SmartKex is significantly faster than the brute-force method alone and has a high degree of accuracy in identifying encryption keys. It also allows for the heap size to be reduced to less than 2% of its original size, further optimizing the extraction process.

SmartKex has broad applications in the field of cybersecurity, particularly in memory forensics. Its machine learning-assisted methodology can be adapted for other types of sensitive data extraction, making it a versatile tool for researchers and practitioners alike. The project is open-source, with the code available on GitHub<fnref n="1" />.

### 2.2.3 Objectives of the present work

This Masterarbeit can be seen as a direct followup to the paper „SmartKex: Machine Learning Assisted SSH Keys Extraction From The Heap Dump“. The present work aims to improve the SmartKex methodology by exploring new machine learning architectures and algorithms. The goal is to improve the accuracy of the machine learning model and to reduce the computational complexity of the overall process.

To do so, this work has significantly broadened the research area by exploring entirely new ways to deal with the dataset by leveraging memory graph representation, feature engineering, new machine learning and deep learning model architectures, and new training strategies. A range of different tools and script, with a focus on code quality and reproducibility with careful packaging using Nix ensure that the present research can be easily extended and reproduced by other researchers.

## 2.3 Graph-based memory modelization

In the following section, we present important concepts that will be used for the memory modelization of the heap dump.

Because the dataset used is composed of RAW heap dump files from OpenSSH, it is a critical aspect to understand how memory works at a low level point of view. This section aims to provide an in-depth understanding of how memory is managed in C, the language used in the OpenSSH implementation of SSH, for a *linux-x86_64* architecture. We will explore the fundamental concepts of memory management, including the heap and the stack, memory allocation, and the role of

<footnote n="1">¹https://github.com/smartvmi/Smart-and-Naive-SSH-Key-Extraction</footnote>
pointers. These concepts will serve later as the foundation for our graph-based approach to
memory modelization.

This section will also introduce many graph theory and Knowledge Graph (KG) concepts. We will explore the fundamentals of graph theory, including the definition of a graph, its components, and its properties. We will also discuss the concept of a Knowledge Graph (KG), which is a type of graph that stores information in the form of nodes and edges, and its applications in the field of machine learning.

2.3.1 Defining memory concepts and modelization

Memory management in C is a complex task that requires a deep understanding of the language's features, the operating system's capabilities and the compiler used. In C, memory is primarily managed through two built-in functions: `malloc` (memory allocation) and `free` (memory deallocation). These functions operate on two primary types of memory: the heap and the stack.

* **Heap vs Stack:** The heap is used for dynamic memory allocation, where variables are allocated and freed at runtime. In contrast, the stack is used for static memory allocation, where variables are allocated and deallocated automatically. The stack is faster but has a limited size, while the heap is more flexible but requires manual management to prevent memory leaks.

* **Heap Dump:** A heap dump is a snapshot of the heap's state at a given time. It provides valuable information about the memory layout, active pointers, and data stored in the heap. Analyzing heap dumps can help in debugging memory-related issues and understanding the program's behavior.

* **Memory Addresses:** Each location in memory is identified by a unique memory address. These addresses are usually represented in hexadecimal notation. Note that the address `0x0` is reserved for the `NULL` pointer, which is used to indicate that a pointer does not point to any memory location.

* **Pointer:** A pointer is a variable that stores the memory address of another variable. It is used to indirectly access the value of the variable it points to. Pointers are used extensively in C, particularly for dynamic memory allocation.

* **Data Structure:** A data structure is a collection of data values, the relationships among them, and the functions or operations that can be applied to the data. In the context of C programming, data structures are declared using the keyword `struct` and are byte aligned. This means that the size of the data structure is always a multiple of the size of the largest member of the structure. Structures can be nested within each other, and pointers can be used to indirectly access the members of a structure. Data structures are often stored in the heap using `malloc`.

* **Malloc headers:** When `malloc` is called, it allocates a block of memory in the heap and returns a pointer to the first byte of the block. The heap manager keeps track of these allocations through metadata, often stored in headers preceding the allocated blocks. These headers contain information such as the size of the allocated block and whether it is free or occupied. Note that the pointer returned by `malloc` in C points to the first byte of the block of memory that has been allocated for your use, not to the `malloc` header. The `malloc` header, is managed internally by the memory allocator and is not exposed to the programmer, but is visible in the heap dump.
pointers. These concepts will serve later as the foundation for our graph-based approach to
memory modelization.

This section will also introduce many graph theory and Knowledge Graph (KG) concepts. We will explore the fundamentals of graph theory, including the definition of a graph, its components, and its properties. We will also discuss the concept of a Knowledge Graph (KG), which is a type of graph that stores information in the form of nodes and edges, and its applications in the field of machine learning.

2.3.1 Defining memory concepts and modelization

Memory management in C is a complex task that requires a deep understanding of the language's features, the operating system's capabilities and the compiler used. In C, memory is primarily managed through two built-in functions: `malloc` (memory allocation) and `free` (memory deallocation). These functions operate on two primary types of memory: the heap and the stack.

* **Heap vs Stack:** The heap is used for dynamic memory allocation, where variables are allocated and freed at runtime. In contrast, the stack is used for static memory allocation, where variables are allocated and deallocated automatically. The stack is faster but has a limited size, while the heap is more flexible but requires manual management to prevent memory leaks.

* **Heap Dump:** A heap dump is a snapshot of the heap's state at a given time. It provides valuable information about the memory layout, active pointers, and data stored in the heap. Analyzing heap dumps can help in debugging memory-related issues and understanding the program's behavior.

* **Memory Addresses:** Each location in memory is identified by a unique memory address. These addresses are usually represented in hexadecimal notation. Note that the address `0x0` is reserved for the `NULL` pointer, which is used to indicate that a pointer does not point to any memory location.

* **Pointer:** A pointer is a variable that stores the memory address of another variable. It is used to indirectly access the value of the variable it points to. Pointers are used extensively in C, particularly for dynamic memory allocation.

* **Data Structure:** A data structure is a collection of data values, the relationships among them, and the functions or operations that can be applied to the data. In the context of C programming, data structures are declared using the keyword `struct` and are byte aligned. This means that the size of the data structure is always a multiple of the size of the largest member of the structure. Structures can be nested within each other, and pointers can be used to indirectly access the members of a structure. Data structures are often stored in the heap using `malloc`.

* **Malloc headers:** When `malloc` is called, it allocates a block of memory in the heap and returns a pointer to the first byte of the block. The heap manager keeps track of these allocations through metadata, often stored in headers preceding the allocated blocks. These headers contain information such as the size of the allocated block and whether it is free or occupied. Note that the pointer returned by `malloc` in C points to the first byte of the block of memory that has been allocated for your use, not to the `malloc` header. The `malloc` header, is managed internally by the memory allocator and is not exposed to the programmer, but is visible in the heap dump.
### 2.3.1.1 Endianness

Endianness refers to the byte order used to represent multibyte data types. In a little-endian system, the least significant byte is stored first, while in a big-endian system, the most significant byte is stored first. Knowing the endianness of the system is crucial for interpreting the content of memory [0].

For instance, the hexadecimal value `0x56343a198000` (taken from `"HEAP_START"` of 3.3) is represented as `550179058774` (≈ 5.50e + 11) in decimal basis in a little-endian system, while it is represented as `94782313037824` (≈ 9.48e + 13) in a big-endian system.

**Little-Indian Conversion** The conversion of a hexadecimal number in little-endian format to a decimal number is given by the following formula:

$$Decimal = \sum_{i=0}^{N-1} (HexDigit_i \times 16^i)$$

**Big-Indian conversion** And the conversion of a hexadecimal number in big-endian format to a decimal number is given by following formula:

$$Decimal = \sum_{i=0}^{N-1} (HexDigit_{N-1-i} \times 16^i)$$

Here, HexDigit$_i$ is the value of the i-th digit in the little-endian hexadecimal number, and N is the number of digits in the hexadecimal number. Note that HexDigit$_i$ should be converted to its decimal equivalent ('A' becomes 10, 'B' becomes 11, etc.) before performing the calculation.

These formulas will be used later to convert pointer addresses from hexadecimal to decimal format in *mem2graph*.

### 2.3.1.2 The role of entropy in forensic analysis

Entropy plays a pivotal role in forensic analysis, particularly in the context of memory dumps analysis. It serves as a measure of uncertainty and randomness, which can be crucial for tasks such as endianness detection and identifying encrypted keys in memory.

As defined by Shannon in the realm of information theory, it is a measure of the uncertainty or randomness associated with a set of possible outcomes [0] [0]. In digital applications, when calculated using the logarithm to base 2, entropy represents the amount of bits of information in a message.

**Entropy Formula** The entropy *H* of a message is calculated using the formula:

$$H = - \sum_{i=1}^{n} p_i \log_2 p_i$$

Where $p_1, p_2, \dots, p_n$ are the probabilities of the set of all possible messages [0].

Endianness, as presented before, refers to the byte order used to represent multibyte data types in computer memory [0]. It is necessary to know the endianness of the heap dump to correctly interpret the content of memory, and especially the addresses of potential pointers. In this context,
### 2.3.1.1 Endianness

Endianness refers to the byte order used to represent multibyte data types. In a little-endian system, the least significant byte is stored first, while in a big-endian system, the most significant byte is stored first. Knowing the endianness of the system is crucial for interpreting the content of memory [0].

For instance, the hexadecimal value `0x56343a198000` (taken from `"HEAP_START"` of 3.3) is represented as `550179058774` (≈ `5.50e+11`) in decimal basis in a little-endian system, while it is represented as `94782313037824` (≈ `9.48e+13`) in a big-endian system.

**Little-Indian Conversion** The conversion of a hexadecimal number in little-endian format to a decimal number is given by the following formula:

$$ \text{Decimal} = \sum_{i=0}^{N-1} (\text{HexDigit}_i \times 16^i) $$

**Big-Indian conversion** And the conversion of a hexadecimal number in big-endian format to a decimal number is given by following formula:

$$ \text{Decimal} = \sum_{i=0}^{N-1} (\text{HexDigit}_{N-1-i} \times 16^i) $$

Here, HexDigit$_i$ is the value of the i-th digit in the little-endian hexadecimal number, and N is the number of digits in the hexadecimal number. Note that HexDigit$_i$ should be converted to its decimal equivalent ('A' becomes 10, 'B' becomes 11, etc.) before performing the calculation.

These formulas will be used later to convert pointer addresses from hexadecimal to decimal format in *mem2graph*.

### 2.3.1.2 The role of entropy in forensic analysis

Entropy plays a pivotal role in forensic analysis, particularly in the context of memory dumps analysis. It serves as a measure of uncertainty and randomness, which can be crucial for tasks such as endianness detection and identifying encrypted keys in memory.

As defined by Shannon in the realm of information theory, it is a measure of the uncertainty or randomness associated with a set of possible outcomes [0] [0]. In digital applications, when calculated using the logarithm to base 2, entropy represents the amount of bits of information in a message.

**Entropy Formula** The entropy *H* of a message is calculated using the formula:

$$ H = - \sum_{i=1}^{n} p_i \log_2 p_i $$

Where $p_1, p_2, \dots, p_n$ are the probabilities of the set of all possible messages [0].

Endianness, as presented before, refers to the byte order used to represent multibyte data types in computer memory [0]. It is necessary to know the endianness of the heap dump to correctly interpret the content of memory, and especially the addresses of potential pointers. In this context,
entropy can be used to infer the endianness of a system by analyzing the distribution of byte values in a memory dump, as presented in „Inference of Endianness and Wordsize From Memory Dumps“ [0].

Entropy is also a key element for encryption key detection, since those should be random byte sequences with high entropy [0]. By examining 8-byte aligned data for high entropy, it is possible to detect potential keys in a heap dump. Techniques such as the calculation of discrete differences and logical operations can further refine this detection as described in „SmartKex: Machine Learning Assisted SSH Keys Extraction From The Heap Dump“ [0].

## 2.3.2 Graphs and Knowledge Graphs

In this project, we (i.e. Clément Lahoche and the author) have built a program called *mem2graph*, a generic tool developed in Rust for efficiency. It is used to convert a RAW memory dump into a graph representation. This graph is technically a directed Edge-labeled heterogeneous property graph, whose concepts are described later. As such, and while it is debatable whether or not *mem2graph* can be seen as building Knowledge Graphs (KGs), it relies on many concepts from the domain, necessitating a proper introduction.

### 2.3.2.1 Defining Graph Theory concepts

Graph theory is a mathematical field concerned with the study of graphs. It has applications in various fields, including computer science, social sciences, or linguistics. Graphs are used to model pairwise relations between objects, and the study of graphs involves analyzing the properties of these relations. In a few words, a graph is just a collection of nodes and edges.

A graph can be formally defined as: «a pair $G = (S, A)$ where:

* $S$ is a finite set of vertices.

* $A$ is a set of pairs of vertices $(s_i, s_j) \in S^2$.

Graphs can be either directed or undirected. In a directed graph, the pairs $(s_i, s_j)$ are ordered, representing arcs from $s_i$ to $s_j$. In an undirected graph, the pairs are unordered, representing edges between $s_i$ and $s_j$ » [0]. Let's introduce some vocabulary to describe graphs:

* **Node (or Vertex)**: A single entity in the graph, often represented as a circle.

* **Edge (or Arc)**: A connection between two nodes, often represented as a line or arrow.

* **Degree**: The number of edges connected to a node.

* **Path**: A sequence of edges that connect two nodes.

* **Cycle**: A path that starts and ends at the same node.

* **Order**: The number of vertices in the graph.

* **Adjacency**: Two nodes are adjacent if there is an edge between them.

* **Loop**: An edge that connects a node to itself.
entropy can be used to infer the endianness of a system by analyzing the distribution of byte
values in a memory dump, as presented in „Inference of Endianness and Wordsize From Memory
Dumps“ [0].

Entropy is also a key element for encryption key detection, since those should be random byte
sequences with high entropy [0]. By examining 8-byte aligned data for high entropy, it is possible
to detect potential keys in a heap dump. Techniques such as the calculation of discrete differences
and logical operations can further refine this detection as described in „SmartKex: Machine
Learning Assisted SSH Keys Extraction From The Heap Dump“ [0].

2.3.2 Graphs and Knowledge Graphs

In this project, we (i.e. Clément Lahoche and the author) have built a program called *mem2graph*, a generic tool developed in Rust for efficiency. It is used to convert a RAW memory dump into a graph representation. This graph is technically a directed Edge-labeled heterogeneous property graph, whose concepts are described later. As such, and while it is debatable whether or not *mem2graph* can be seen as building Knowledge Graphs (KGs), it relies on many concepts from the domain, necessitating a proper introduction.

2.3.2.1 Defining Graph Theory concepts

Graph theory is a mathematical field concerned with the study of graphs. It has applications in
various fields, including computer science, social sciences, or linguistics. Graphs are used to model
pairwise relations between objects, and the study of graphs involves analyzing the properties of
these relations. In a few words, a graph is just a collection of nodes and edges.

A graph can be formally defined as: «a pair $G = (S, A)$ where:

• S is a finite set of vertices.

• A is a set of pairs of vertices (sᵢ, sⱼ) ∈ S².

Graphs can be either directed or undirected. In a directed graph, the pairs (sᵢ, sⱼ) are ordered, representing arcs from sᵢ to sⱼ. In an undirected graph, the pairs are unordered, representing edges between sᵢ and sⱼ » [0]. Let's introduce some vocabulary to describe graphs:

• **Node (or Vertex)**: A single entity in the graph, often represented as a circle.

• **Edge (or Arc)**: A connection between two nodes, often represented as a line or arrow.

• **Degree**: The number of edges connected to a node.

• **Path**: A sequence of edges that connect two nodes.

• **Cycle**: A path that starts and ends at the same node.

• **Order**: The number of vertices in the graph.

• **Adjacency**: Two nodes are adjacent if there is an edge between them.

• **Loop**: An edge that connects a node to itself.
* **Weight:** A value assigned to an edge.

* **Ancestors (parents) and Descendants (children):** A node $s_i$ is an ancestor of $s_j$ if there is a path from $s_i$ to $s_j$. A node $s_j$ is a descendant of $s_i$ if there is a path from $s_i$ to $s_j$.

Various other terminologies and concepts exist in graph theory, but these are the most important ones for our purposes. For a more in-depth understanding of graph theory, the reader is encouraged to consult the work by Solnon as a quick introduction, [0] or a more in-depth one by West et al. [0].

### 2.3.2.2 Graphs types

Graphs offer a flexible way to conceptualize, represent, and integrate diverse and incomplete data. Many graph models exist, each with its own advantages and disadvantages, as well as graph properties <fnref n="2" />. Those different types of graphs include:

* **Directed Edge-labelled Graphs (DEL):** The classic graph, set of nodes and edges that connect the nodes with in certain way. RDF is a popular DEL data model.

* **Heterogeneous Graphs:** Each node and edge is assigned one type, allowing for partitioning nodes according to their type, which is useful for machine learning.

* **Property Graphs:** Allows a set of property-value pairs and a label to be associated with nodes and edges. This model is used in Neo4j and offers great flexibility but is harder to handle and query.

* **Graph Dataset:** A set of named graphs, with a default graph with no ID. Useful when working with different sources.

* **Hypergraphs:** Hypergraphs generalize the concept of graphs by allowing edges, known as hyperedges, to connect any number of nodes, rather than just pairs. This means that a single hyperedge can link together two or more nodes, forming a subset of the hypergraph's node set. This feature makes hypergraphs particularly useful for modeling relationships in complex systems where connections are not merely binary. They are widely used in areas such as database design, combinatorial optimization, and complex network analysis, where multi-way relationships are prevalent.

A given graph can have a range of properties that give some insights into its structure. Here are some important properties of graphs:

* **Connected Graph:** A graph is connected if there is a path between every pair of nodes.

* **Disconnected Graph:** A graph is disconnected if there is at least one pair of nodes that are not connected by a path.

* **Cyclic Graph:** A graph is cyclic if it contains at least one cycle.

* **Acyclic Graph:** A graph is acyclic if it does not contain any cycles.

* **Complete Graph:** A graph is complete if there is an edge between every pair of nodes.

<footnote n="2">²Some parts of the following section are directly from a prior work for Seminar 5369S: Knowledge Graphs, written during summer 2023. As of the date of writing and to the best of my knowledge, this work has not been published, and as such, cannot be properly referenced</footnote>
* **Weight:** A value assigned to an edge.

* **Ancestors (parents) and Descendants (children):** A node $s_i$ is an ancestor of $s_j$ if there is a path from $s_i$ to $s_j$. A node $s_j$ is a descendant of $s_i$ if there is a path from $s_i$ to $s_j$.

Various other terminologies and concepts exist in graph theory, but these are the most important ones for our purposes. For a more in-depth understanding of graph theory, the reader is encouraged to consult the work by Solnon as a quick introduction, [0] or a more in-depth one by West et al. [0].

### 2.3.2.2 Graphs types

Graphs offer a flexible way to conceptualize, represent, and integrate diverse and incomplete data. Many graph models exist, each with its own advantages and disadvantages, as well as graph properties <fnref n="2" />. Those different types of graphs include:

* **Directed Edge-labelled Graphs (DEL):** The classic graph, set of nodes and edges that connect the nodes with in certain way. RDF is a popular DEL data model.

* **Heterogeneous Graphs:** Each node and edge is assigned one type, allowing for partitioning nodes according to their type, which is useful for machine learning.

* **Property Graphs:** Allows a set of property-value pairs and a label to be associated with nodes and edges. This model is used in Neo4j and offers great flexibility but is harder to handle and query.

* **Graph Dataset:** A set of named graphs, with a default graph with no ID. Useful when working with different sources.

* **Hypergraphs:** Hypergraphs generalize the concept of graphs by allowing edges, known as hyperedges, to connect any number of nodes, rather than just pairs. This means that a single hyperedge can link together two or more nodes, forming a subset of the hypergraph's node set. This feature makes hypergraphs particularly useful for modeling relationships in complex systems where connections are not merely binary. They are widely used in areas such as database design, combinatorial optimization, and complex network analysis, where multi-way relationships are prevalent.

A given graph can have a range of properties that give some insights into its structure. Here are some important properties of graphs:

* **Connected Graph:** A graph is connected if there is a path between every pair of nodes.

* **Disconnected Graph:** A graph is disconnected if there is at least one pair of nodes that are not connected by a path.

* **Cyclic Graph:** A graph is cyclic if it contains at least one cycle.

* **Acyclic Graph:** A graph is acyclic if it does not contain any cycles.

* **Complete Graph:** A graph is complete if there is an edge between every pair of nodes.

<footnote n="2">²Some parts of the following section are directly from a prior work for Seminar 5369S: Knowledge Graphs, written during summer 2023. As of the date of writing and to the best of my knowledge, this work has not been published, and as such, cannot be properly referenced</footnote>
### 2.3.2.3 Graph vs Knowledge Graph

A Knowledge Graph (KG) is a specialized form of graph intended to accumulate and convey real-world knowledge. As said before, we are not technically building KGs, but we rely on many concepts from the domain. Research on KG has further accelerated in recent years, and introduced significant improvement to Graph Theory, especially in the practical applications of graph construction and use for Machine Learning or Deep Learning [0]. They have a number of benefits when compared with a relational model or NoSQL alternatives, such as the ability for data to evolve in a more flexible manner, and the capacity to organize data in a way that is not hierarchical. They can represent incomplete information, and does not require a precise schema [0, p.2], which is invaluable in the context of memory analysis, where the structure of the heap is not known in advance.

While all KGs are graphs, not all graphs are KGs. However, the line between the two is often blurry, and the distinction is not always clear. The term "knowledge graph" first appeared in 1973, but really gained popularity through a 2012 blog post about Google's Knowledge Graph [0]. Several definition attempts have been made, but none of them are universally accepted. Below are listed some of the most common definitions of Knowledge Graphs:

* «A graph of data intended to accumulate and convey knowledge of the real world, whose nodes represent entities of interest and whose edges represent potentially different relations between these entities.» [0]

* «A graph of data consisting of semantically described entities and relations of different types that are integrated from different sources. Entities have a unique identifier. KG entities and relations are semantically described using an ontology or, more clearly, an ontological representation.» [0]

In KGs, edges are often labeled and may represent complex relationships like "is a subclass of" or "is married to", allowing for more expressive power. The very nature of KG makes any definition attempt difficult. Indeed, KG is a broad concept that can be applied to many domains, use cases and can have diverse implementations. The definition of KGs is thus very context-dependent, and it's debatable where the line between a graph and a KG is drawn.

For the purpose of this thesis, we won't focus on this distinction and just consider that we deal with memory *graphs*, which are graphs that are not necessarily KGs, but that can be used to represent complex relationships between entities extracted from memory dumps and be leveraged using KG-related techniques for advance tasks like feature engineering, automated embedding, inductive reasoning and learning.

### 2.3.2.4 Ontologies

An ontology is a formal representation of knowledge within a domain, providing a structured framework for organizing and interpreting information. It consists of a set of concepts, relationships, and rules that define how data is interconnected and how it can be reasoned about. Ontologies are often used to model a domain and support reasoning about entities and their relationships [0].

Ontologies play a crucial role in the development and utility of knowledge graphs. They provide a semantic layer to the knowledge graph, enabling machines to understand the meaning and context of the data. The axioms and rules in an ontology enable automated reasoning,
### 2.3.2.3 Graph vs Knowledge Graph

A Knowledge Graph (KG) is a specialized form of graph intended to accumulate and convey real-world knowledge. As said before, we are not technically building KGs, but we rely on many concepts from the domain. Research on KG has further accelerated in recent years, and introduced significant improvement to Graph Theory, especially in the practical applications of graph construction and use for Machine Learning or Deep Learning [0]. They have a number of benefits when compared with a relational model or NoSQL alternatives, such as the ability for data to evolve in a more flexible manner, and the capacity to organize data in a way that is not hierarchical. They can represent incomplete information, and does not require a precise schema [0, p.2], which is invaluable in the context of memory analysis, where the structure of the heap is not known in advance.

While all KGs are graphs, not all graphs are KGs. However, the line between the two is often blurry, and the distinction is not always clear. The term "knowledge graph" first appeared in 1973, but really gained popularity through a 2012 blog post about Google's Knowledge Graph [0]. Several definition attempts have been made, but none of them are universally accepted. Below are listed some of the most common definitions of Knowledge Graphs:

* «A graph of data intended to accumulate and convey knowledge of the real world, whose nodes represent entities of interest and whose edges represent potentially different relations between these entities.» [0]

* «A graph of data consisting of semantically described entities and relations of different types that are integrated from different sources. Entities have a unique identifier. KG entities and relations are semantically described using an ontology or, more clearly, an ontological representation.» [0]

In KGs, edges are often labeled and may represent complex relationships like "is a subclass of" or "is married to", allowing for more expressive power. The very nature of KG makes any definition attempt difficult. Indeed, KG is a broad concept that can be applied to many domains, use cases and can have diverse implementations. The definition of KGs is thus very context-dependent, and it's debatable where the line between a graph and a KG is drawn.

For the purpose of this thesis, we won't focus on this distinction and just consider that we deal with memory *graphs*, which are graphs that are not necessarily KGs, but that can be used to represent complex relationships between entities extracted from memory dumps and be leveraged using KG-related techniques for advance tasks like feature engineering, automated embedding, inductive reasoning and learning.

### 2.3.2.4 Ontologies

An ontology is a formal representation of knowledge within a domain, providing a structured framework for organizing and interpreting information. It consists of a set of concepts, relationships, and rules that define how data is interconnected and how it can be reasoned about. Ontologies are often used to model a domain and support reasoning about entities and their relationships [0].

Ontologies play a crucial role in the development and utility of knowledge graphs. They provide a semantic layer to the knowledge graph, enabling machines to understand the meaning and context of the data. The axioms and rules in an ontology enable automated reasoning,
allowing the knowledge graph to infer new facts from existing data. Ontologies also help in maintaining the quality and consistency of data by enforcing constraints and validation rules. Finally, ontologies enable interoperability by providing a common vocabulary for data exchange and integration. Different popular ontologies exist, such as Web Ontology Language (OWL) or Resource Description Framework (RDF).

By incorporating ontologies, knowledge graphs become more than just a collection of nodes and edges; they become a rich, interconnected web of semantically meaningful information that can be easily queried, analyzed, and extended. We will be referring to concepts that have been inspired by ontologies in the next sections, like *rdf:Bag*.

The *rdf:Bag* container is a part of the Resource Description Framework (RDF) used to represent collections where the order of elements is not significant. Unlike other containers such as *rdf:Seq* and *rdf:Alt*, *rdf:Bag* permits duplicate entries. It can be used to model unsorted collections of resources or literals. An instance of *rdf:Bag* can be represented as a graph where each node connected to the root node represents an item in the collection [0]. For example, consider a root node named "DataStructure" with a property *Address* specifying its malloc header address.

<figure><img src="image_2.png" /><figcaption>Figure 2.1: Graphical representation of an *rdf:Bag* container.</figcaption></figure>

This small example illustrates how we can represent a container, or a relationship of belonging, using a graph. This is a concept that will be used later in the memory modelization process.

### 2.3.2.5 Inductive Reasoning and Learning

Inductive reasoning in Knowledge Graphs (KGs) involves techniques like embedding and Graph Convolutional Networks (GCNs) to learn the potential underlying structure of the graph. This is particularly useful for tasks like link prediction, node classification, and clustering.

For the sake of clarity and grouping, we will present the concepts of graph embedding and GCNs in the next sections, but it is important to note that they are not mutually exclusive. In fact, GCNs can be used to generate embeddings, and embeddings can be used as input for GCNs. As such, they are often used together in the context of KGs, or in our case, memory graphs.

## 2.4 Data preprocessing for Machine Learning

Machine Learning (ML) is a subfield of Artificial Intelligence (AI) that focuses on the development of algorithms that can learn from data and make predictions. It is a powerful tool that has been used to solve a wide range of problems, including image classification, speech recognition, and natural language processing. Before we can apply machine learning algorithms to a dataset, we must first prepare the data by performing various preprocessing steps. In this section, we will discuss the most common data preprocessing techniques, including data cleaning, feature
allowing the knowledge graph to infer new facts from existing data. Ontologies also help in maintaining the quality and consistency of data by enforcing constraints and validation rules. Finally, ontologies enable interoperability by providing a common vocabulary for data exchange and integration. Different popular ontologies exists, such as Web Ontology Language (OWL) or Resource Description Framework (RDF).

By incorporating ontologies, knowledge graphs become more than just a collection of nodes and edges; they become a rich, interconnected web of semantically meaningful information that can be easily queried, analyzed, and extended. We will be referring to concepts that have been inspired by ontologies in the next sections, like *rdf:Bag*.

The *rdf:Bag* container is a part of the Resource Description Framework (RDF) used to represent collections where the order of elements is not significant. Unlike other containers such as *rdf:Seq* and *rdf:Alt*, *rdf:Bag* permits duplicate entries. It can be used to model unsorted collections of resources or literals. An instance of *rdf:Bag* can be represented as a graph where each node connected to the root node represents an item in the collection [0]. For example, consider a root node named "DataStructure" with a property *Address* specifying its malloc header address.

<figure><img src="image_2.png" /><figcaption>Figure 2.1: Graphical representation of an *rdf:Bag* container.</figcaption></figure>

This small example illustrates how we can represent a container, or a relationship of belonging, using a graph. This is a concept that will be used later in the memory modelization process.

### 2.3.2.5 Inductive Reasoning and Learning

Inductive reasoning in Knowledge Graphs (KGs) involves techniques like embedding and Graph Convolutional Networks (GCNs) to learn the potential underlying structure of the graph. This is particularly useful for tasks like link prediction, node classification, and clustering.

For the sake of clarity and grouping, we will present the concepts of graph embedding and GCNs in the next sections, but it is important to note that they are not mutually exclusive. In fact, GCNs can be used to generate embeddings, and embeddings can be used as input for GCNs. As such, they are often used together in the context of KGs, or in our case, memory graphs.

## 2.4 Data preprocessing for Machine Learning

Machine Learning (ML) is a subfield of Artificial Intelligence (AI) that focuses on the development of algorithms that can learn from data and make predictions. It is a powerful tool that has been used to solve a wide range of problems, including image classification, speech recognition, and natural language processing. Before we can apply machine learning algorithms to a dataset, we must first prepare the data by performing various preprocessing steps. In this section, we will discuss the most common data preprocessing techniques, including data cleaning, feature
engineering, and dataset splitting, as well as the importance of feature selection and dimensionality reduction. All those elements are crucial for the development of effective machine learning models for key extraction.

## 2.4.1 Feature engineering

In the realm of machine learning and data science, *features* refer to individual measurable attributes or characteristics of the phenomena under study. Those features can be of different types, and can be used to predict the value of a target variable.

### 2.4.1.1 Types of Features

Features can be of different types, depending on the nature of the data. The type of feature determines how it is processed and utilized by the model. The most common types of features include:

* **Numerical Features:** These are quantitative attributes representing measurements like height, weight, or age.

* **Categorical Features:** These are qualitative attributes representing discrete classes or labels, such as gender (Male, Female) or educational level (High School, Bachelor's, Master's).

* **Ordinal Features:** Similar to categorical features but with an inherent order, like ratings on a scale of 1 to 5.

* **Text Features:** These contain textual data and often require special preprocessing steps like tokenization and vectorization.

* **Temporal Features:** These are time-based attributes, such as timestamps, requiring special handling to capture time-dependent patterns.

* **Geospatial Features:** These attributes represent geographical or spatial coordinates.

Features are pivotal for the performance of machine learning models. The quality and pertinence of features can significantly influence the model's capability to discern underlying patterns in the data. Inadequately chosen, or irrelevant features can lead to a poorly performing model, while carefully selected, relevant features can result in a robust and accurate model.

### 2.4.1.2 The Curse of Dimensionality

The *curse of dimensionality* refers to a set of challenges that arise when dealing with high-dimensional data. As the number of features, or dimensions, in a dataset increases, the volume of the feature space grows exponentially. This exponential growth leads to several issues:

* **Data Sparsity:** In high-dimensional spaces, data points tend to be sparse, making it difficult for algorithms to identify patterns. The sparsity also means that the notion of "distance" becomes less meaningful, which is problematic for algorithms that rely on distance metrics.
engineering, and dataset splitting, as well as the importance of feature selection and dimensionality reduction. All those elements are crucial for the development of effective machine learning models for key extraction.

## 2.4.1 Feature engineering

In the realm of machine learning and data science, *features* refer to individual measurable attributes or characteristics of the phenomena under study. Those features can be of different types, and can be used to predict the value of a target variable.

### 2.4.1.1 Types of Features

Features can be of different types, depending on the nature of the data. The type of feature determines how it is processed and utilized by the model. The most common types of features include:

* **Numerical Features:** These are quantitative attributes representing measurements like height, weight, or age.

* **Categorical Features:** These are qualitative attributes representing discrete classes or labels, such as gender (Male, Female) or educational level (High School, Bachelor's, Master's).

* **Ordinal Features:** Similar to categorical features but with an inherent order, like ratings on a scale of 1 to 5.

* **Text Features:** These contain textual data and often require special preprocessing steps like tokenization and vectorization.

* **Temporal Features:** These are time-based attributes, such as timestamps, requiring special handling to capture time-dependent patterns.

* **Geospatial Features:** These attributes represent geographical or spatial coordinates.

Features are pivotal for the performance of machine learning models. The quality and pertinence of features can significantly influence the model's capability to discern underlying patterns in the data. Inadequately chosen, or irrelevant features can lead to a poorly performing model, while carefully selected, relevant features can result in a robust and accurate model.

### 2.4.1.2 The Curse of Dimensionality

The *curse of dimensionality* refers to a set of challenges that arise when dealing with high-dimensional data. As the number of features, or dimensions, in a dataset increases, the volume of the feature space grows exponentially. This exponential growth leads to several issues:

* **Data Sparsity:** In high-dimensional spaces, data points tend to be sparse, making it difficult for algorithms to identify patterns. The sparsity also means that the notion of "distance" becomes less meaningful, which is problematic for algorithms that rely on distance metrics.