# [Keynote] A Tale of Oxidation and Witchcraft

Jonathan Brossard

► To cite this version:

Jonathan Brossard. [Keynote] A Tale of Oxidation and Witchcraft. Doctoral. Jussieu, Paris, France. 2025. [hal-05130177](https://hal.science/hal-05130177v1)

HAL Id: hal-05130177

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

Submitted on 25 Jun 2025

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>
# A Tale of Oxidation and Witchcraft

Jonathan Brossard

June 2025, Paris, France

Systematic
Paris Region Deep Tech Ecosystem
Security Researcher
ORCID: 009-0004-8031-1438

CTO @ MOABI

Previously: Principal Engineer &
Director of Security at Salesforce
(San Francisco)

My work is partially sponsored by:

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

MOABI

salesforce

bpifrance

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

DEFCON

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

blackhat®
# A Malicious Counter History of the Mathematics of the XXth Century
2nd Congress of Mathematicians (Paris, 1900):

- 23 Problems (Matrixes of Lie, Zeros of the Riemann's Zeta function, axiomatization of Physics...)

- Secret goal : Axiomatization of all branches of Mathematics

- Then deduce all possible theorems from those axioms

Had 69 PhD students, including John von Neumann

<figure><img src="image_5.png" /><figcaption>David Hilbert</figcaption></figure>

HILBERT, David. Mathematische probleme. Nachrichten von der Koniglichen Gesellschaft der Wissenschaften zu Gottingen, 1900.
And then...

PhD thesis in 1931 (at 25 years old):

First incompleteness theorem:

"Any consistent formal system F within which a certain amount of elementary arithmetic can be carried out is incomplete; i.e. there are statements of the language of F which can neither be proved nor disproved in F." (Raatikainen 2020)

Those statements are named **undecidable**.

<figure><img src="image_6.png" /><figcaption>Kurt Gödel</figcaption></figure>

GÖDEL, Kurt. On formally undecidable propositions of principia mathematica and related systems i 1 (1931). In : Godel's Theorem in Focus. Routledge, 2012. p. 17-47.
# Algorithmic equivalents

PhD thesis (1953):

Any nontrivial semantic property about the language recognized by a
Turing machine is **undecidable**.

Corollary:

- Deciding if a piece of software contains malware is **undecidable**

- Deciding if a piece of software contains vulnerabilities is **undecidable**

<figure><img src="image_7.png" /><figcaption>Henry Gordon Rice</figcaption></figure>
Modern Equivalent

AGI (2020) is going to solve all our problems and magically solve undecidable problems.

<figure><img src="image_8.png" /><figcaption>Sam Altman</figcaption></figure>

<figure><img src="image_9.png" /></figure>
Modern Equivalent

AGI (2020) is going to solve all our problems and magically solve undecidable problems.

<figure><img src="image_10.png" /><figcaption>Sam Altman</figcaption></figure>

<figure><img src="image_11.png" /></figure>
Rust from a Security Perspective

<figure><img src="image_12.png" /></figure>
# Memory Corruptions

Memory Corruption vulnerabilities account for about 70% of exploitable vulnerabilities in modern software

Source: Google Project Zero, Microsoft MSRC)

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

Exploitable bugs in Chrome. Source: Google Project Zero
# Memory Corruptions : Rust binary Hardening (default)

```
 jonathan@blackbox:~/rust/openssl
```

Fichier Édition Affichage Rechercher Terminal Aide

jonathan@blackbox:~/rust/openssl$ checksec.sh --file target/release/openssl-test
RELRO                 STACK CANARY       NX                PIE                 RPATH              RUNPATH            FILE
Full RELRO            No canary found    NX enabled         PIE enabled         No RPATH           No RUNPATH         target/release/openssl-test

jonathan@blackbox:~/rust/openssl$
Memory Corruptions : MOABI Recommended Flags (x86_64)

CFLAGS="-fPIC -pie -fPIE -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,now "

CFLAGS_EXTRA="-fstack-clash-protection -fzero-call-used-regs=used-gpr -fcf-protection -fstack-check"
# Brief Taxonomy of Memory Corruptions

<figure><img src="image_14.png" /></figure>
Overflow : in any writable section

Stack overflow, heap
overflows, .bss/.data overflows

• jonathan@blackbox:~/rust/openssl

Fichier

Édition

Affichage

Rechercher

Terminal

Aide

jonathan@blackbox:~/rust/openssl$ eu-readelf -S target/release/openssl-test

There are 34 section headers, starting at offset 0x6af98:

Section Headers:

<table><thead><tr><th>[Nr]</th><th>Name</th><th>Type</th><th>Addr</th><th>Off</th><th>Size</th><th>ES</th><th>Flags</th><th>Lk</th><th>Inf</th><th>Al</th></tr></thead><tbody><tr><td>[0]</td><td></td><td>NULL</td><td>0000000000000000</td><td>00000000</td><td>00000000</td><td>0</td><td></td><td>0</td><td>0</td><td>0</td></tr><tr><td>[1]</td><td>.interp</td><td>PROGBITS</td><td>00000000000000350</td><td>00000350</td><td>0000001c</td><td>0</td><td>A</td><td>0</td><td>0</td><td>1</td></tr><tr><td>[2]</td><td>.note.gnuproperty</td><td>NOTE</td><td>00000000000000370</td><td>00000370</td><td>00000020</td><td>0</td><td>A</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[3]</td><td>.note.gnu.build-id</td><td>NOTE</td><td>00000000000000390</td><td>00000390</td><td>00000024</td><td>0</td><td>A</td><td>0</td><td>0</td><td>4</td></tr><tr><td>[4]</td><td>.note.ABI-tag</td><td>NOTE</td><td>000000000000003b4</td><td>000003b4</td><td>00000020</td><td>0</td><td>A</td><td>0</td><td>0</td><td>4</td></tr><tr><td>[5]</td><td>.gnu.hash</td><td>GNU_HASH</td><td>000000000000003d8</td><td>000003d8</td><td>00000024</td><td>0</td><td>A</td><td>6</td><td>0</td><td>8</td></tr><tr><td>[6]</td><td>.dynsym</td><td>DYNSYM</td><td>00000000000000400</td><td>00000400</td><td>00000678</td><td>24</td><td>A</td><td>7</td><td>1</td><td>8</td></tr><tr><td>[7]</td><td>.dynstr</td><td>STRTAB</td><td>00000000000000a78</td><td>00000a78</td><td>0000045a</td><td>0</td><td>A</td><td>0</td><td>0</td><td>1</td></tr><tr><td>[8]</td><td>.gnu.version</td><td>GNU_versym</td><td>00000000000000ed2</td><td>00000ed2</td><td>0000008a</td><td>2</td><td>A</td><td>6</td><td>0</td><td>2</td></tr><tr><td>[9]</td><td>.gnu.version_r</td><td>GNU_verneed</td><td>00000000000000f60</td><td>00000f60</td><td>00000130</td><td>0</td><td>A</td><td>7</td><td>4</td><td>8</td></tr><tr><td>[10]</td><td>.rela.dyn</td><td>RELA</td><td>00000000000001090</td><td>00001090</td><td>00004b30</td><td>24</td><td>A</td><td>6</td><td>0</td><td>8</td></tr><tr><td>[11]</td><td>.rela.plt</td><td>RELA</td><td>00000000000005bc0</td><td>00005bc0</td><td>00000030</td><td>24</td><td>AI</td><td>6</td><td>27</td><td>8</td></tr><tr><td>[12]</td><td>.init</td><td>PROGBITS</td><td>00000000000006000</td><td>00006000</td><td>0000001b</td><td>0</td><td>AX</td><td>0</td><td>0</td><td>4</td></tr><tr><td>[13]</td><td>.plt</td><td>PROGBITS</td><td>00000000000006020</td><td>00006020</td><td>00000030</td><td>16</td><td>AX</td><td>0</td><td>0</td><td>16</td></tr><tr><td>[14]</td><td>.plt.got</td><td>PROGBITS</td><td>00000000000006050</td><td>00006050</td><td>00000008</td><td>8</td><td>AX</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[15]</td><td>.text</td><td>PROGBITS</td><td>00000000000006060</td><td>00006060</td><td>00040d8b</td><td>0</td><td>AX</td><td>0</td><td>0</td><td>16</td></tr><tr><td>[16]</td><td>.fini</td><td>PROGBITS</td><td>00000000000046dec</td><td>00046dec</td><td>0000000d</td><td>0</td><td>AX</td><td>0</td><td>0</td><td>4</td></tr><tr><td>[17]</td><td>.rodata</td><td>PROGBITS</td><td>0000000000047000</td><td>00047000</td><td>000055d8</td><td>0</td><td>A</td><td>0</td><td>0</td><td>16</td></tr><tr><td>[18]</td><td>.eh_frame Header</td><td>PROGBITS</td><td>000000000004c5d8</td><td>0004c5d8</td><td>0000104c</td><td>0</td><td>A</td><td>0</td><td>0</td><td>4</td></tr><tr><td>[19]</td><td>.eh_frame</td><td>PROGBITS</td><td>000000000004d628</td><td>0004d628</td><td>00005a00</td><td>0</td><td>A</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[20]</td><td>.gcc_except_table</td><td>PROGBITS</td><td>0000000000053028</td><td>00053028</td><td>00001090</td><td>0</td><td>A</td><td>0</td><td>0</td><td>4</td></tr><tr><td>[21]</td><td>.tdata</td><td>PROGBITS</td><td>0000000000055ca0</td><td>00054ca0</td><td>00000020</td><td>0</td><td>WAT</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[22]</td><td>.tbss</td><td>NOBITS</td><td>00000000000055cc8</td><td>00054cc8</td><td>00000040</td><td>0</td><td>WAT</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[23]</td><td>.init_array</td><td>INIT_ARRAY</td><td>00000000000055cc8</td><td>00054cc8</td><td>00000010</td><td>8</td><td>WA</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[24]</td><td>.fini_array</td><td>FINI_ARRAY</td><td>00000000000055cd8</td><td>00054cd8</td><td>00000008</td><td>8</td><td>WA</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[25]</td><td>.data rel. ro</td><td>PROGBITS</td><td>00000000000055ce0</td><td>00054ce0</td><td>00002888</td><td>0</td><td>WA</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[26]</td><td>.dynamic</td><td>DYNAMIC</td><td>00000000000058568</td><td>00057568</td><td>00000230</td><td>16</td><td>WA</td><td>7</td><td>0</td><td>8</td></tr><tr><td>[27]</td><td>.got</td><td>PROGBITS</td><td>00000000000058798</td><td>00057798</td><td>00000868</td><td>8</td><td>WA</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[28]</td><td>.data</td><td>PROGBITS</td><td>00000000000059000</td><td>00058000</td><td>00000978</td><td>0</td><td>WA</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[29]</td><td>.bss</td><td>NOBITS</td><td>00000000000059978</td><td>00058978</td><td>000000f8</td><td>0</td><td>WA</td><td>0</td><td>0</td><td>8</td></tr><tr><td>[30]</td><td>.comment</td><td>PROGBITS</td><td>0000000000000000</td><td>00058978</td><td>00000057</td><td>1</td><td>MS</td><td>0</td><td>0</td><td>1</td></tr><tr><td>[31]</td><td>.symtab</td><td>SYMTAB</td><td>0000000000000000</td><td>000589d0</td><td>00004e60</td><td>24</td><td></td><td>32</td><td>494</td><td>8</td></tr><tr><td>[32]</td><td>.strtab</td><td>STRTAB</td><td>0000000000000000</td><td>0005d830</td><td>0000d625</td><td>0</td><td></td><td>0</td><td>0</td><td>1</td></tr><tr><td>[33]</td><td>.shstrtab</td><td>STRTAB</td><td>0000000000000000</td><td>0006ae55</td><td>0000013d</td><td>0</td><td></td><td>0</td><td>0</td><td>1</td></tr></tbody></table>

jonathan@blackbox:~/rust/openssl$
Overflow : Rust itself is immune

The mechanism of memory borrowing + ownership + bound checking
Ensures memory safety.

EPIC WIN !!!
Type confusions

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

```c
typedef struct cow {
    char name[16];
    int (*f)(void);
};
```

```c
typedef struct pig {
    char name[16];
    char brand[8];
};
```

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

```c
int do_milk (struct cow *v)
{
    return v->f();
}
```

What happens if brand is user controlled and we try to do_milk() a pig ?

(very common in Javascript)
# Casting Errors/Overflows

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

MOABI

## Exempli Gratia:

1) sign extension:

movsxd rdx, eax

2) Integer overflow:

mul r8
Type Confusions : Rust itself is immune

Affine typing prevents type confusions vulnerabilities.

EPIC WIN !!!
# Partial Proofs of Vulnerabilities : Motivation
# Motivation: SBOMs vulnerability assessments don't scale well

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

MAY 12, 2021

## Executive Order on Improving the Nation's Cybersecurity

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

→ BRIEFING ROOM →

→ PRESIDENTIAL ACTIONS →

By the authority vested in me as President by the Constitution and the laws of the United States of America, it is hereby ordered as follows:

**Section 1. Policy.** The United States faces persistent and increasingly sophisticated malicious cyber campaigns that threaten the public sector, the private sector, and ultimately the American people's security and privacy. The Federal Government must improve its efforts to identify, deter, protect against, detect, and respond to these actions and actors. The Federal Government must also carefully examine what occurred during any major cyber incident and apply lessons learned. But cybersecurity requires more than government action. Protecting our Nation from malicious cyber actors requires the Federal Government to partner with the private sector. The private sector must adapt to the continuously changing threat environment, ensure its products are built and operate securely, and partner with the Federal Government to foster a more secure cyberspace. In the end, the trust we place in our digital infrastructure should be proportional to how trustworthy and transparent that infrastructure is, and to the consequences we will incur if that trust is misplaced.

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

## EU Cyber Resilience Act

New EU cybersecurity rules ensure safer hardware and software.

From baby-monitors to smart-watches, products and software that contain a digital component are omnipresent in our daily lives. Less apparent to many users is the security risk such products and software may present.

The Cyber Resilience Act (CRA) aims to safeguard consumers and businesses buying or using products or software with a digital component. The Act would see inadequate security features become a thing of the past with the introduction of mandatory cybersecurity requirements for manufacturers and retailers of such products, with this protection extending throughout the product lifecycle.

The problem addressed by the Regulation is two-fold.

First is the inadequate level of cybersecurity inherent in many products, or inadequate security updates to such products and software.

Second is the inability of consumers and businesses to currently determine which products are cybersecure, or to set them up in a way that ensures their cybersecurity is protected.

The Cyber Resilience Act will guarantee:

* harmonised rules when bringing to market products or software with a digital component;

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

GUIDANCE DOCUMENT

## Select Updates for the Premarket Cybersecurity Guidance: Section 524B of the FD&C Act

Draft Guidance for Industry and Food and Drug Administration Staff

MARCH 2024

Download the Draft Guidance Document

Read the Federal Register Notice

Draft

Not for implementation. Contains non-binding recommendations.

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

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

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

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

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

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

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

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

Docket Number: FDA-2021-D-1158

Issued by:
Center for Devices and Radiological Health
Center for Biologics Evaluation and Research

FDA has developed this draft guidance to propose select updates to the FDA guidance document "Cybersecurity in Medical Devices: Quality System Considerations and Content of Premarket Submissions" (hereafter referred to as the "Premarket Cybersecurity Guidance"). FDA is proposing to add a Section VII. to the Premarket Cybersecurity Guidance to address new considerations for cyber devices. The new section identifies the cybersecurity information FDA considers to generally be necessary to support obligations under section 524B of the FD&C Act. The Premarket Cybersecurity Guidance, in its

## Software Bill of Materials are becoming mandatory

<figure><img src="image_30.png" /></figure>
# Motivation: SBOMs vulnerability assessments don't scale well

Software Bill of Materials (SBOMs) contain lists of CPEs or Package URLs (purl) describing all the components of a given Software.

They allow to perform vulnerability assessments by comparing the CPEs to the dictionaries published by the NIST for each CVE.

```json
"components": [
  {
    "type": "application",
    "name": "sshd",
    "hashes": [{
      "alg": "MD5",
      "content": "0e6e1c30f8e10e45647ba5d9d4ea6948"
    }, {
      "alg": "SHA-1",
      "content": "399e5d00e2d91628792eefe066489f64a6310486"
    }, {
      "alg": "SHA-256",
      "content": "5bd9544d2da6daf7519ee8d6efcd71d6edc16a507f86a90e233174bbebb843c2"
    }]
  }
]
{
  "type": "application",
  "description": "sshd",
  "group": "openbsd",
  "name": "openssh",
  "version": "9.6p1",
  "cpe": "cpe:2.3:a:openbsd:openssh:9.6p1:*:*:*:*:*:*:*",
  "externalReferences": [{
    "type": "website",
    "url": "https://www.openssh.com/"
  }],
  "licenses": [{
    "license": {
      "id": "BSD-2-clause"
    },
    "license": {
      "id": "BSD-3-clause"
    },
```

Software Bill of Materials are becoming mandatory
# Motivation: SBOMs vulnerability assessments don't scale well

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

MOABI

## 243 SOFTWARE MONITORED

<table><thead><tr><th>SOFTWARE</th><th>SCAN DATE</th><th>NEW CVES</th><th>Last Modified</th></tr></thead><tbody><tr><td>Hyundai.update.zip</td><td>10 August 2022</td><td>1230</td><td>8 August 2024</td></tr><tr><td>psa_rcc.zip</td><td>10 August 2022</td><td>1151</td><td>8 August 2024</td></tr><tr><td>Firmware.bin</td><td>17 October 2022</td><td>952</td><td>8 August 2024</td></tr><tr><td>Tesla_2019.20.4.2.model3.squashfs</td><td>20 June 2023</td><td>467</td><td>8 August 2024</td></tr></tbody></table>

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

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

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

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

SBOMs provide possible CVES.
For each vulnerability : is it true ?

## CONTINUOUS MONITORING

1019 new vulnerabilities identified for software Tesla_2019.20.4.2.model3.squashfs

Updated report for dnsmasq

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

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

Description

Impact

Type

Attack Vector

Certain DNSSEC aspects of the DNS protocol (in RFC 4033, 4034, 4035, 6840, and related RFCs) allow remote attackers to cause a denial of service (CPU consumption) via one or more DNSSEC responses, aka the &quot;KeyTrap&quot; issue. One of the concerns is that, when there is a zone with many DNSKEY and RRSIG records, the protocol specification implies that an algorithm must evaluate all combinations of DNSKEY and RRSIG records.

CVSS v3: 7.5 HIGH

CWE-770

CVSSv3 Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Motivation
(Bis Repetita Placent)
# Zerodays: No patch, am I vulnerable ?

## Taint analysis on binary
(no source code)

## Calling convention SYSTEM V:
RDI, RSI, RDX, RCX, R8, R9

```
00000000000011e7 <function1>:
```

```
11e7:   f3 0f 1e fa                  endbr64
11eb:   55                           push  rbp
11ec:   48 89 e5                  mov   rbp,rsp
11ef:   48 81 ec 20 01 00 00         sub   rsp,0x120
11f6:   89 bd ec fe ff ff             DWORD PTR [rbp-0x114],edi
11fc:   48 89 b5 e0 fe ff ff         mov   QWORD PTR [rbp-0x120],rsi
1203:  64 48 8b 04 25 28 00         mov   rax,QWORD PTR fs:0x28
120a:  00 00
120c:   48 89 45 f8                  mov   QWORD PTR [rbp-0x8],rax
1210:  31 c0                           xor   eax,eax
1212:  48 8b 85 e0 fe ff ff         mov   rax,QWORD PTR [rbp-0x120]
1219:  48 83 c0 08                  add   rax,0x8
121d:   48 8b 00                           mov   rax,QWORD PTR [rax]
1220:  48 89 c7                  mov   rdi,rax
1223:  e8 78 fe ff ff                  call  10a0 <strlen@plt>
1228:  48 89 c2                  mov   rdx,rax
122b:  48 8b 85 e0 fe ff ff         mov   rax,QWORD PTR [rbp-0x120]
1232:  48 83 c0 08                  add   rax,0x8
1236:  48 8b 08                           mov   rcx,QWORD PTR [rax]
1239:  48 8d 85 f0 fe ff ff         lea   rax,[rbp-0x110]
1240:  48 89 ce                  mov   rsi,rcx
1243:  48 89 c7                  mov   rdi,rax
1246:  e8 85 fe ff ff                  call  10d0 <memcpy@plt>
124b:  48 8d 85 f0 fe ff ff         lea   rax,[rbp-0x110]
1252:  48 89 c6                  mov   rsi,rax
1255:  48 8d 05 aa 0d 00 00         lea   rax,[rip+0xdaa]
125c:  48 89 c7                  mov   rdi,rax
125f:  b8 00 00 00 00                  mov   eax,0x0
1264:  e8 57 fe ff ff                  call  10c0 <printf@plt>
1269:  b8 00 00 00 00                  mov   eax,0x0
126e:  48 8b 55 f8                  mov   rdx,QWORD PTR [rbp-0x8]
1272:  64 48 2b 14 25 28 00         sub   rdx,QWORD PTR fs:0x28
1279:  00 00
127b:  74 05                           je    1282 <function1+0x9b>
127d:  e8 2e fe ff ff                  call  10b0 <__stack_chk_fail@plt>
1282:  c9                           leave
1283:  c3                           ret
```
# Zerodays : No patch, am I vulnerable ?

## Taint analysis on binary
(no source code)

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

### Vulnerability

### CWE-120 - BUFFER OVERFLOW

### Score : 7

<table><tr><td>Impact: 9</td><td>Confidence: 9</td><td>Risk: 5</td></tr><tr><td>Type</td><td colspan="2">CWE-120 - BUFFER OVERFLOW</td></tr><tr><td>Address</td><td colspan="2">00001246</td></tr><tr><td>Function</td><td colspan="2">000011e7</td></tr></table>

### Description

Vulnerability when calling function memcpy() :

* function argument 3 has the following properties: user controlled, command line argument, arithmetic operation, upper function argument 2, stack variable at offset -0x30, return value from strlen().

* source has the following properties: user controlled, command line argument, arithmetic operation, upper function argument 2, stack variable at offset -0x30,

* destination has the following properties: stack variable at offset -0x10,

* buffer overflow in third argument

### Backtrace

#00 <1246> void * __cdcl memcopy(__out_bcount_full_opt(_Size) void * _Dst, __in_bcount_opt(_Size) const void * _Src, __in size_t _Size) at: /home/jonathan/sample/sample.c:22

#01 <11e7> function1() at: /home/jonathan/sample/sample.c:19

#02 <1284> int main(int argc, char **argv, char **envp) at: /home/jonathan/sample/sample.c:29
Problem Statement :

Partial Proofs of Vulnerabilities through
Procedural Debugging
# Proving Exploitability

Industry standard to Prove exploitability : Write an exploit

This bar is too high.

If we decompose an exploit into 3 problems:

- Reach the vulnerable function

- Trigger the vulnerability

- Achieve code execution/Weaponize

The first step alone is already undecidable ("reachability problem").

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

DANGER
Proving Exploitability

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

Entry point

Vulnerable function

The "reachability problem" is
undecidable.
# Proving Exploitability : Partial Proof of Vulnerability

Let's do only step 2:

If we decompose an exploit into 3 problems:

- Reach the vulnerable function

- Trigger the vulnerability

- Achieve code execution/Weaponize

This a reasonable heuristic to determine vulnerability of the application.

We'd like to be able to call the vulnerable function directly.

Problem : How to do this out of context ?

Proposal : Let's turn the vulnerable application into a shared library !

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

DANGER
Loading Dynamic Executables :
Introduction to ELF Libification

"Generalize to simplify" : A. Grothendieck
Reverse Engineering : Compilation Process

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

Source Code

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

Compiler

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

Assembly
Code (.S)

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

Assembler

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

Object Files (.o)

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

Shared Libraries

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

Static Link Editor

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

Executables
Reverse Engineering : Disassembly

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

Source Code

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

Compiler

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

Assembly
Code (.S)

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

Assembler

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

Object Files (.o)

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

Disassembly

Executables

Static Link Editor

Undecidable
# Reverse Engineering : Decompilation

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

Undecidable
Reverse Engineering : Libification

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

Source Code

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

Compiler

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

Assembly
Code (.S)

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

Assembler

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

Object Files (.o)

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

Shared Libraries

Libification
(wld)

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

Executables

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

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

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

Static Link Editor
<figure><img src="image_67.png" /></figure>

# Executables vs Shared Libraries : How Do They Differ ?

Same headers, same segments, same
sections. They mostly differ through
their metadata (various ELF headers)

The work to be done:

Modify the various ELF headers to
turn an Executable into a Shared
Library

Tool Interface Standard (TIS)
Executable and Linking Format (ELF)
Specification
Version 1.2

TIS Committee

May 1995

ELF Header

Some object file control structures can grow, because the ELF header contains their actual sizes.
If the object file format changes, a program may encounter control structures that are larger or
smaller than expected. Programs might therefore ignore "extra" information. The treatment of
"missing" information depends on context and will be specified when and if extensions are
defined.

<caption>Figure 1-3. ELF Header</caption>

```c
#define EI_NIDENT 16
typedef struct {
    unsigned char   e_ident[EI_NIDENT];
    Elf32_Half     e_type;
    Elf32_Half     e_machine;
    Elf32_word     e_version;
    Elf32_Addr     e_entry;
    Elf32_Off       e_phoff;
    Elf32_Off       e_shoff;
    Elf32_word      e_flags;
    Elf32_Half      e_hsize;
    Elf32_Half      e_phentsize;
    Elf32_Half      e_phnum;
    Elf32_Half      e_shentsize;
    Elf32_Half      e_shnum;
    Elf32_Half      e_shstrndx;
} Elf32_Ehdr;
```

**e_ident** The initial bytes mark the file as an object file and provide machine-independent data with which to decode and interpret the file's contents. Complete descriptions appear below, in "ELF Identification."

**e_type** This member identifies the object file type.

<table><thead><tr><td>Name</td><td>Value</td><td>Meaning</td></tr></thead><tbody><tr><td>ET_NONE</td><td>0</td><td>No file type</td></tr><tr><td>ET_REL</td><td>1</td><td>Relocatable file</td></tr><tr><td>ET_EXEC</td><td>2</td><td>Executable file</td></tr><tr><td>ET_DYN</td><td>3</td><td>Shared object file</td></tr><tr><td>ET_CORE</td><td>4</td><td>Core file</td></tr><tr><td>ET_LOPROC</td><td>@xff00</td><td>Processor-specific</td></tr><tr><td>ET_HIPROC</td><td>@ffff</td><td>Processor-specific</td></tr></tbody></table>
# Automated Libification : the Witchcraft Linker

URL: https://github.com/endrazine/wcc

License: MIT/BSD-2

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

DOI 10.5281/zenodo.11405214
# Validation

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

MOABI

Test Repository:

https://github.com/endrazine/wcc-tests

<table><thead><tr><td>Version</td><td>Codename</td><td>Year</td><td>GCC Version</td><td>Passed</td><td>Failed</td></tr></thead><tbody><tr><td>24.04</td><td>noble</td><td>2024</td><td>12.3.0</td><td>440</td><td>0</td></tr><tr><td>22.04</td><td>Jammy</td><td>2022</td><td>11.2.0</td><td>435</td><td>0</td></tr><tr><td>20.04</td><td>focal</td><td>2020</td><td>9.3.0</td><td>435</td><td>0</td></tr><tr><td>18.04</td><td>bionic</td><td>2018</td><td>7.3.0</td><td>369</td><td>0</td></tr><tr><td>16.04</td><td>xenial</td><td>2016</td><td>5.3.1</td><td>363</td><td>0</td></tr><tr><td>14.04</td><td>trusty</td><td>2014</td><td>4.8.2</td><td>352</td><td>0</td></tr></tbody></table>

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

DOI 10.5281/zenodo.11301409
# Procedural Debugging

<figure><img src="image_71.png" /></figure>
# Procedural Debugging : Libification based Debugging

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

ELF Executable
or Library

Load in Memory
(+ load dependencies
& solve relocations)

function1()

...

function...()

...

function_vulnerable()

...

If the ELF is dynamically
linked, libify it and load via
dlopen().

If the ELF is statically linked, loading its segments
is enough.

We simply need a userland ELF loader.

Confere userland exec() techniques (eg: The
Grugg, phrack, 2004)

Address Space
# Procedural Debugging: Functions enumerations
(Without Control Flow Analysis, which is Undecidable)

In Dynamically linked ELFs, parse the link_map

- Provides a list of all ELFs in memory

- Dynamic linker exports iterators to symbols

- Use dlsym() function from the Dynamic Linker to obtain address of symbols.

function1()

...

function...()

...

function_vulnerable()

...

Library_1

...

Library_n

Address Space
# Procedural Debugging: Crafting Minimal Context/Arguments

Calling convention is architecture specific. On x86_64 GNU/Linux, arguments passing is done via registers:

RDI, RSI, RDX, RCX, R8, R9 for integers or pointers, and XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 for floating-point arguments.

We can craft those arguments and point RIP to `function_vulnerable()` to achieve selective procedural execution.

* Avoid reachability problem.

function1()

...

function...()

...

function_vulnerable()

...

Library_1

...

Library_n

WSH

Address Space

We would like to map the ELF in memory, solve dependencies/relocations if the ELF is dynamically linked.

Then call the potentially vulnerable function with chosen arguments, with just enough context to trigger the vulnerability.
# Binary Reflection

The Witchcraft Shell implements:

- An exposition of binary functions from the LUA interpreter.

Thanks to lua, we then implement:

- Binary introspection

- Binary intercession

=> We implement binary reflection, without source code.

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

DOI 10.5281/zenodo.13902925
Procedural Debugging

- Libify ELF executables

- Make ELF executables scriptable

- Call arbitrary functions
  (procedural debugging)

jonathan@blackbox:~$

Fichier Édition Affichage Rechercher Terminal Aide

jonathan@blackbox:~$ wsh /usr/sbin/apache2

ERROR: dlopen() /usr/sbin/apache2: cannot dynamically load
position-independent executable

** libifying /usr/sbin/apache2 to /tmp/.wsh-964913/apache2 (754232 bytes)

** loading of libified binary succeeded

> a = ap_get_server_buffer()

> print(a)

Apache/2.4.58

>

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

URL: https://github.com/endrazine/wcc

License: MIT/BSD-2

DOI

10.5281/zenodo.13902925
Oxydation of WCC

<figure><img src="image_75.png" /></figure>
## Oxydation of WCC: R++

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

- Symbol demangling in Rust is quite specific

- Done in Rust, linked to WCC

- Available from version v0.0.10

URL: https://github.com/endrazine/wcc

License: MIT/BSD-2

jonathan@blackbox:~/rust/rust2c

Fichier Édition Affichage Rechercher Terminal Aide

jonathan@blackbox:~/rust/rust2c$ cat src/lib.rs
// lib.rs
#[no_mangle]
pub extern "C" fn add_numbers(a: i32, b: i32) -> i32 {
    a + b
}
#[no_mangle]
pub extern "C" fn hello_from_rust() {
    println!("Hello from Rust!");
}
jonathan@blackbox:~/rust/rust2c$

jonathan@blackbox:~/rust/rust2c

Fichier Édition Affichage Rechercher Terminal Aide

jonathan@blackbox:~/rust/rust2c$ wsh target/release/libmyrust.so
> hello_from_rust()
Hello from Rust!
>
# Oxydation of WCC: R++

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

- Caveat: May need to copy
symbols from .symtab/.strtab
to .dynsym/.dynstr

URL: https://github.com/endrazine/wcc

License: MIT/BSD-2

# Advances in Lightweight Cross-Architecture
Procedural Debugging

Jonathan Brossard

CEDRIC/ISID

Conservatoire National des Arts et Métiers

Paris, France

jonathan.brossard@lecnam.net

**Abstract**—As embedded software is becoming more and more prevalent in mission-critical devices such as self-driving vehicles or medical equipment, Product Security Incident Response Teams (PSIRTs) face the need to debug software across multiple architectures, often different from their host desktop machines. Concomitantly, recent updates to the European legislative framework, in particular the NIS2 and Cyber Resilience Act mandate that critical vulnerabilities be reported on a daily basis. To help bridge the gap between those upcoming regulations and the reality of the industry, this article focuses on facilitating cross-architecture vulnerability validation via partial proofs of vulnerabilities by leveraging binary libification and lightweight procedural debugging.

**Index Terms**—Libification, Reverse Engineering, JIT binary translation, NIS2, CRA, lightweight debugging

## I. INTRODUCTION

Recent enhancements to the European legal framework governing Cloud service security require that Product Security Incident Response Teams (PSIRTs) operating in Europe report newly discovered vulnerabilities affecting their products and services to their respective national authorities within 24 hours. Specifically, Directive (EU) 2022/2555, known as NIS2 [1], mandates the assessment and reporting of security vulnerabilities within this timeframe.

In 2024, the NIST publicly disclosed over 40,000 vulnerabilities in the form of CVEs [3], a significant increase from approximately 29,000 in 2023. This surge leaves PSIRT teams facing the formidable challenge of assessing their services' exposure to more than 100 newly reported vulnerabilities each day. While tools like Software Bills of Materials (SBOMs) have emerged to ease this burden by automating the identification of potential vulnerabilities [21]—based solely on the versions of binaries present in containers—recent studies [22] have raised serious concerns about the reliability and reproducibility of SBOMs. As a result, PSIRT teams are often required to manually validate vulnerabilities flagged through SBOM monitoring tools [8] via extensive debugging efforts. Critically, a specific version of a software component may or may not be affected by a vulnerability, and its CVSS [4] score can vary significantly depending on compilation options [13] [14], details that are currently not captured by major SBOM standards [23] [5] [24] [28].

In this article, we devise new methodologies to quickly validate the existence of vulnerabilities in compiled binaries,

without access to their source code, since shipping compiled programs is common practice in the industry [16]. Focusing primarily on embedded devices, we will detail how binary libification and procedural debugging may be leveraged to produce partial proofs of vulnerabilities cross-architecture. Because market research over the past decade indicate an overwhelming use of GNU/Linux as a base OS in embedded devices, with a market penetration ranging from 40% to 60% depending on industry verticals [19] [17] [18], we shall focus primarily on debugging GNU/Linux, but will generalize our methodologies to other operating systems where applicable.

Our contribution to cross-architecture libification and procedural debugging is implemented into the Witchcraft Compiler Collection, a reverse engineering framework published under a permissive dual MIT/BSD license [32]. Our implementation of the Witchcraft tracer, an extension of the venerable ltrace [20] debugging tool is published under the GPL-2 open-source license.

## II. PREVIOUS WORK

In this section, we offer a brief summary of our recent work in the field of reverse engineering ELF binaries, with the aim to provide fundational knowledge for the subsequent sections, where we will aim at generalizing those findings to achieve cross-architecture debugging.

### A. Overview of binary Libification

In "Introduction to Procedural Debugging through Binary Libification" [30], we introduced the concept of *Binary libification*, which refers to the process of converting a dynamically linked ELF [11] executable into a shared library. This allows vulnerable functions to be called directly, which circumvents the traditional reachability problem [26] over the callgraph of the binary, which is undecidable. This mechanism provides flexibility in inspecting and interacting with memory corruption vulnerabilities by simplifying how functions are invoked and observed.

### B. Overview of procedural debugging

This paper also introduces *Procedural debugging* [30], a technique used to analyze vulnerabilities by executing specific program functions without having to write entire exploits, focusing on intra-procedural triggers generation. This method
<figure><img src="image_78.png" /></figure>

Oxydation of WCC : R++

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

- Caveat : May need to copy
symbols from .symtab/.strtab
to .dynsym/.dynstr

URL: https://github.com/endrazine/wcc

License: MIT/BSD-2

■ jonathan@blackbox:~/rust/openssl

Fichier

Édition

Affichage

Rechercher

Terminal
Aide

jonathan@blackbox:~/rust/openssl$ file ./target/release/openssl-test
./target/release/openssl-test: ELF 64-bit LSB pie executable, x86-64, version 1
(SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha
1]=2930591bc66720cc693193be0b3a93923bf18e18, for GNU/Linux 3.2.0, not stripped

jonathan@blackbox:~/rust/openssl$ ./target/release/openssl-test

OpenSSL version: OpenSSL 3.0.10 1 Aug 2023

OpenSSL version number: 300000a0

jonathan@blackbox:~/rust/openssl$ nm -D ./target/release/openssl-test|grep " _Z\
| _R"|wc -l

0

jonathan@blackbox:~/rust/openssl$ wunstrip ./target/release/openssl-test -o /tmp
/openssl-test2 -r

-- saved unstripped file as /tmp/openssl-test2

jonathan@blackbox:~/rust/openssl$ nm -D /tmp/openssl-test2|grep " _Z\| _R"|wc -l
252

jonathan@blackbox:~/rust/openssl$
Oxydation of WCC : R++

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

- Caveat : May need to copy
symbols from .symtab/.strtab
to .dynsym/.dynstr

URL: https://github.com/endrazine/wcc

License: MIT/BSD-2

<figure><img src="image_81.png" /></figure>
# Oxydation of WCC: R+

wsh: invalid lua syntax from mangled symbols #24

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

Open

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

sp3d opened on Jun 2, 2017

...

Running wsh on binaries with non-alphanumeric symbols (e.g. the mangled ones produced by rustc) results in output like

ERROR: Wsh internal lua initialization (Synthax Error): Wsh internal lua buffer:2070: '(' expected near '$'

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

which refers to this line in the generated lua:

function _ZN4core3num68_5LT$impl$u20$core..convert..TryFrom$LT$i16$GT$u20$for$u20$u128$GT$8try_from17h890e

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

It might be nice to support demangling, though that may complicate parsing (angle brackets, parentheses, and colons would be valid in symbol names); in any event it would be nice for these symbols to not prevent wsh from running.

Create sub-issue

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

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

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

endrazine 2 days ago

Hi sp3d,

I hope you're doing well.

I just merged support for Rust symbols.

Thanks for your patience,

j-

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

Owner

...
Partial Proofs of Vulnerabilities (in Rust bindings)

<figure><img src="image_90.png" /></figure>
<figure><img src="image_91.png" /></figure>

RUSTSEC

The Rust Security Advisory Database

About

Advisories

Report Vulnerabilities

RUSTSEC-2025-0022

Use-After-Free in Md::fetch and Cipher::fetch

**Reported** April 4, 2025

**Issued** April 4, 2025

**Package** openssl (crates.io)

**Type** Vulnerability

**Categories** memory-corruption

**References** https://github.com/sfackler/rust-openssl/pull/2390

**Patched** >=0.10.72

**Unaffected** <0.10.39

**Affected Functions**

**Version**

openssl::cipher::Cipher::fetch >=0.10.39, <0.10.72

openssl::md::Md::fetch >=0.10.39, <0.10.72

**Description**

When a Some(...) value was passed to the properties argument of either of these functions, a use-after-free would result.

In practice this would nearly always result in OpenSSL treating the properties as an empty string (due to CString::drop 's behavior).

The maintainers thank quitbug for reporting this vulnerability to us.
<figure><img src="image_92.png" /></figure>

RUSTSEC
The Rust Security Advisory Database

About

Advisories

Report Vulnerabilities

RUSTSEC-2024-0357

MemBio::get_buf has undefined behavior with empty buffers

**Reported** July 21, 2024

**Issued** July 21, 2024

**Package** openssl (crates.io)

**Type** Vulnerability

**References** https://github.com/sfackler/rust-openssl/pull/2266

**Patched** >=0.10.66

**Affected Functions** **Version**

openssl::bio::MemBio::get_buf

<0.10.66, >=0.8.0

**Description**

Previously, MemBio::get_buf called slice::from_raw_parts with a null-pointer, which violates the functions invariants, leading to undefined behavior. In debug builds this would produce an assertion failure. This is now fixed.

Advisory available under CC0-1.0 license.
# Partial Proofs of Vulnerabilities

The ability to turn ELF executables into libraries will allow us to create partial proofs of vulnerabilities in the form of WSH test scripts.

## Examples:

https://github.com/endrazine/wcc-tests/tree/main/scripts

<figure><img src="image_93.png" /></figure>
Automatic Arguments Inference

<figure><img src="image_94.png" /></figure>
# Automatic Arguments Inference

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

## Interactive function arguments discovery
<figure><img src="image_96.png" /></figure>

# Automatic Arguments Inference

Automation

<figure><img src="image_97.png" /></figure>
Context: Replaying ltrace

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

jonathan@blackbox:~

Fichier Édition Affichage Rechercher Terminal Aide

jonathan@blackbox:~$ wltrace -W /bin/cat /etc/issue.net 2>/tmp/demo.sh

Ubuntu 24.04.2 LTS

jonathan@blackbox:~$ chmod +x /tmp/demo.sh

jonathan@blackbox:~$ /tmp/demo.sh

ERROR: dlopen() /bin/cat: cannot dynamically load position-independent executable

** libifying /bin/cat to /tmp/.wsh-48767/cat (39384 bytes)

** loading of libified binary succeeded

ERROR: Bad address (14)

ERROR: Bad address (14)

Ubuntu 24.04.2 LTS

jonathan@blackbox:~$ cat /tmp/demo.sh | grep -v "^\-\-"

#!/usr/bin/wsh /bin/cat

ret_1 = llechr("/bin/cat", '/', 1); -- "/cat"

ret_2 = setlocale(LC_ALL, ""); -- "C"

ret_3 = bindtextdomain("coreutils", "/usr/share/locale"); -- "/usr/share/locale"

ret_4 = textdomain("coreutils"); -- "coreutils"

ret_7 = fstat(1, var_0x7ffc57f9be90, var_0x772d15e03240, 0); -- 0

ret_8 = getpagesize(); -- 4096

ret_9 = open("/etc/issue.net", 0, 01777); -- 3

ret_10 = fstat(3, var_0x7ffc57f9be90, 0, var_0x772d15d1b175); -- 0

ret_11 = posix_fadvise(3, 0, 0, 2); -- 0

ret_12 = aligned_alloc(4096, var_0x20000, 0, var_0x772d15d1b52e); -- var_0x772d1600e000

ret_13 = read(3, "Ubuntu 24.04.2 LTS
", 131072); -- 19

ret_14 = write(1, "Ubuntu 24.04.2 LTS
", 19); -- 19

ret_15 = read(3, "", 131072); -- 0

ret_17 = close(3); -- 0

ret_22 = fflush(var_0x772d15e045c0); -- 0

ret_28 = fflush(var_0x772d15e044e0); -- 0

ret_30 = exit(0)

jonathan@blackbox:~$
Industry Adoption

<figure><img src="image_99.png" /></figure>
The Framework is already available in major Linux distributions

Available in the repositories from:

- Debian

- Ubuntu

- Arch Linux

- Kali Linux

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

blackhat®

root@blackbox:~# apt install wcc

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

URL: https://github.com/endrazine/wcc

License: MIT/BSD-2
# Applications: Generic Code re-use outside Cybersecurity

## Code reuse:

- Source code lost/no longer compiles

- Legacy applications

- Cross platform execution

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

Courtesy of Advanced Cell Technology
# Cross Architecture Procedural Debugging (JIT)

By cross-compiling WSH to other architectures and running it within qemu-user, we benefit from JIT translation to the host architecture (eg: Aarch64 to x86_64) without a Virtual Machine, and in a single process (debugger + debuggee + JIT translator)

function1()

...

function...()

...

function_vulnerable()

...

Library_1

...

Library_n

WSH

Qemu-user (JIT)

DOI 10.5281/zenodo.13902925

Address Space
Conclusion & Future Work

<figure><img src="image_103.png" /></figure>
# Witchcraft Linker : Libification

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

Undecidable
# Witchcraft Compiler: Unlinking

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

Source Code

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

Compiler

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

Assembly
Code (.S)

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

Assembler

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

Object Files (.o)

Shared Libraries

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

Unlinking
(wcc)

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

Static Link Editor

Executables

<figure><img src="image_112.png" /></figure>
# Witchcraft Compiler: Unlinking + Relinking = Assured Patching

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

Vulnerable
Executable

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

Unlinker

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

Static Link Editor

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

Patched
Executable

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

Patched Static Library

ar -x

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

Object file Substitution
# Witchcraft Compiler: Unlinking + Instrumentation = Fuzzing

<figure><img src="image_119.png" /></figure>
<figure><img src="image_120.png" /></figure>

THANK YOU FOR YOUR ATTENTION

Jonathan Brossard

jonathan.brossard@lecnam.net

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

Systematic

Paris Region Deep Tech Ecosystem