Sploitus

Exploit for CVE-2021-47881

githubexploit Β· 2026-08-10

Exploit Code

README170 lines
## https://sploitus.com/exploit?id=1B72B217-1BAF-501E-B07D-65FA8911424D
# CVE-2021-47881

**Local stack-based buffer overflow in dataSIMS Avionics ARINC 4.5.3 (Data Device Corporation)**

Hi, I'm [Kağan Γ‡apar](https://github.com/kagancapar). In February 2020 I found a local stack-based buffer overflow in DDC's dataSIMS avionics databus software and published a proof of concept on [Exploit-DB](https://www.exploit-db.com/exploits/49577) in February 2021. Nearly five years later, in January 2026, VulnCheck assigned it **CVE-2021-47881** as a retroactive CVE β€” I learned about the assignment after the fact, not from it.

This repository is the archival record for that finding: the original PoC preserved as-published, a byte-identical Python 3 port, an annotated breakdown of the payload, and corrections for two problems in the published CVE record.

> **Scope, up front.** This is a *record*, not a root-cause analysis. dataSIMS is closed-source commercial software, there is no vendor patch, and I have not re-tested this against a current release. What is verifiable here is verified and shown; everything else is called out in [Limitations](#limitations). If you came here expecting the depth of [CVE-2026-5201](https://github.com/kagancapar/CVE-2026-5201), read that note first.

| | |
|---|---|
| **CVE** | [CVE-2021-47881](https://vulners.com/cve/CVE-2021-47881) |
| **CWE** | [CWE-121](https://cwe.mitre.org/data/definitions/121.html) β€” Stack-based Buffer Overflow |
| **CVSS v4.0** | **6.7** MEDIUM β€” `AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N` (VulnCheck) |
| **CVSS v3.1** | **8.4** HIGH β€” `AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H` (VulnCheck) |
| **Affected** | dataSIMS Avionics **ARINC 664-1**, version 4.5.3 |
| **Vendor** | [Data Device Corporation](https://www.ddc-web.com/) |
| **CNA** | VulnCheck |
| **Discovered** | 2020-02-17 |
| **PoC published** | 2021-02-19 β€” [EDB-49577](https://www.exploit-db.com/exploits/49577) |
| **CVE published** | 2026-01-23 ([NVD](https://nvd.nist.gov/vuln/detail/CVE-2021-47881)) |
| **Vendor patch** | none published |
| **Tested on** | Windows 10 Enterprise x64 |

## Summary

The affected component is the **ARINC 664-1** module of dataSIMS 4.5.3. It reads back a result file that β€” despite the module it belongs to β€” is named `milstd1553result.txt`; the name is a vendor artifact carried over from the suite's MIL-STD-1553 lineage, not an indication of which module is affected. Supplying an over-long, attacker-shaped version of that file overflows a fixed-size stack buffer during the read-back path and overwrites the saved return address. The crash lands with full control of `EIP`:

```
EIP  42424242        <- 'BBBB' from the payload
ECX  42424242
     C0000005        <- STATUS_ACCESS_VIOLATION
```

The published PoC is 1040 bytes and stops at the `EIP` overwrite. It does not achieve code execution, and it was never intended to β€” see [Exploitability](#exploitability-honest-assessment).

## Payload anatomy

The PoC's field layout, verified by running the port (`py poc/poc_py3.py --layout`):

| Field | Offset | Length | Content |
|---|---|---|---|
| `junk` | `0` / `0x000` | 600 | `0x41` filler |
| `align` | `600` / `0x258` | 8 | `"22221111"` |
| `prop` | `608` / `0x260` | 380 | `0x43` filler |
| `imp` | `988` / `0x3dc` | 10 | `"bzhrturlu2"` |
| `imp2` | `998` / `0x3e6` | 9 | `"aracag"` `0x13` `"1z"` |
| `overwrite` | `1007` / `0x3ef` | 4 | `0x42` Γ— 4 β†’ **saved return address** |
| `buf` | `1011` / `0x3f3` | 29 | shikata_ga_nai decoder stub |
| **total** | | **1040** | `sha256 530efb5efef917082e40dcf379f5e0a526375724af18aba6f0270f794f96d066` |

**The `EIP` offset is 1007.** That is not a number you get from `!mona findmsp` or `pattern_offset.rb` β€” it is the sum of five hand-tuned fields. The original PoC was built by widening a crash until the return address moved, not by locating the offset analytically. I am noting this rather than dressing it up: a clean rewrite would find the true distance to the saved return address and drop `align`, `imp`, and `imp2` entirely, since none of them carry meaning. `imp`/`imp2` are filler strings, not imports.

## The decoder stub is inert

`buf` is a 29-byte msfvenom shikata_ga_nai stub. Disassembled with `ndisasm -b32`:

```asm
00000000  DAC1              fcmovb st1              ; junk FPU op (sgn signature)
00000002  D97424F4          fnstenv [esp-0xc]       ; GetPC
00000006  58                pop eax                 ; eax = &stub
00000007  BB0B7E9762        mov ebx,0x62977e0b      ; XOR key
0000000C  33C9              xor ecx,ecx
0000000E  B101              mov cl,0x1              ; <-- ONE 4-byte block
00000010  315819            xor [eax+0x19],ebx      ; decode block at +0x19
00000013  83E8FC            sub eax,-4              ; eax += 4
00000016  035815            add ebx,[eax+0x15]      ; key schedule
00000019  E9                db 0xe9                 ; <-- encoded block, not code
0000001A  8B                db 0x8b
0000001B  7C9C              jl 0xffffffb9
```

Two things fall out of this, and both mean the payload can never run:

1. **`mov cl,0x1`** β€” the decode loop is configured for a single 4-byte block. There is no real payload behind it, only those 4 bytes.
2. **The `\xe2\xf4` (`loop`) terminator is absent.** A complete sgn stub ends the decode loop with `loop` before the encoded body. Here execution falls straight off `add ebx,[eax+0x15]` into `E9 8B 7C 9C` β€” which at that moment is still encoded, and is not a valid instruction sequence anyway.

So the stub is a placeholder that occupies the tail of the payload. This matches how the PoC was described on Exploit-DB, and it is the honest reading: **this is a control-of-`EIP` demonstration, not a working exploit.**

## Exploitability (honest assessment)

Weighing this the way a broker or a vendor would, rather than the way the CVSS v3.1 vector does:

- **No privilege boundary is crossed.** `milstd1553result.txt` is a file the application itself produces, in a location the same user already controls. An attacker who can rewrite it can generally already run code as that user. That makes this a robustness bug far more than a security bug.
- **The PoC predates nothing.** Control of `EIP` on a 2020-era x86 build says little on its own. Turning it into execution needs a DEP/ASLR story β€” a module without `/DYNAMICBASE`, a ROP chain, or a partial overwrite. None of that was done, and I have not checked what mitigations the current build ships with.
- **It is local, and it needs the operator to load the file.** CVSS v4.0's `UI:A` reflects reality; v3.1's `UI:N` does not.

If someone wants to make this genuinely interesting, the productive surfaces are not this file at all: the kernel driver DDC ships for its 1553/664 PCIe cards (IOCTL handling β†’ LPE), any network-facing ARINC 664/AFDX frame parsing, and the *input* file formats the suite consumes from untrusted sources. Those cross real boundaries. This one does not.

## Corrections to the published record

The CVE record carries two defects worth stating plainly, since it is published under my name.

### 1. The cited vendor product is the wrong one

The record's product designation β€” "dataSIMS Avionics **ARINC 664-1** version 4.5.3" β€” is **correct**. The affected component is the ARINC 664 module, as stated in my original Exploit-DB title.

The defect is the vendor reference the CNA attached. NVD cites [BU-69414](https://www.ddc-web.com/en/connectivity/databus/milstd1553-1/software-1/bu-69414?partNumber=BU-69414), which is DDC's **MIL-STD-1553** software product page β€” a different databus stack from the one this finding affects. ARINC 664 is AFDX (profiled switched Ethernet, ARINC 664 Part 7); MIL-STD-1553 is a 1 Mbps dual-redundant command/response bus. They are unrelated standards.

The likely cause of the miscitation is the result filename. dataSIMS names the ARINC 664 module's result file `milstd1553result.txt` β€” a leftover from the suite's MIL-STD-1553 lineage. Anyone reading the CVE description and reaching for a matching vendor product page will follow that string straight to the 1553 line, which is what appears to have happened. **The filename is not evidence of the affected module**, and a record that points at the 1553 product page sends defenders auditing the wrong component.

### 2. The two CVSS vectors are mutually exclusive

Both vectors come from VulnCheck, and they contradict each other on the two things that matter:

| | v3.1 (8.4 HIGH) | v4.0 (6.7 MEDIUM) |
|---|---|---|
| User interaction | `UI:N` β€” none | `UI:A` β€” required |
| Impact | `C:H/I:H/A:H` β€” full CIA | `VC:N/VI:N/VA:H` β€” availability only |

They cannot both be right. The v4.0 vector is the defensible one: the PoC demonstrates a crash, not disclosure or integrity loss. The v3.1 score of 8.4 overstates the finding, and I would rather say so here than benefit from it.

## Reproduction

Nothing here needs the target software β€” the PoC only writes the malformed file. Triggering the overflow requires dataSIMS 4.5.3, which is licensed commercial software this repository does not distribute.

```bash
# print the field map, write nothing
py poc/poc_py3.py --layout

# write the 1040-byte payload
py poc/poc_py3.py -o milstd1553result.txt
```

Then load the file with the affected build under a debugger and observe the `EIP` overwrite. `poc/49577.py` is the original Python 2 source, archived verbatim; it will not run on Python 3.

### Python 2 β†’ 3 notes

The port produces a byte-identical 1040-byte file (`sha256 530efb5e…`). Three things had to change, and one thing that looks like a bug is not one:

- `print len(win32)` is a statement in Python 2, a `SyntaxError` in Python 3.
- The original concatenates `str` fields with a `bytes` shellcode. Python 2 allowed it because `str` *was* bytes; Python 3 raises `TypeError`.
- `open(..., "w")` must become `"wb"`. In text mode Python 3 would UTF-8 encode every byte β‰₯ `0x80` in the stub β€” `0xda` β†’ `0xc3 0x9a` β€” silently corrupting the payload and changing its length.
- `imp2 = "\x61\x72\x61\x63\x61\x67\x131\x7a"` is **not** a version-dependent quirk. `\x` takes exactly two hex digits in both Python 2 and 3, so `\x131` is `0x13` followed by the character `1`. The field is 9 bytes in both. It just reads badly.

## Limitations

Stated explicitly so nobody has to guess what was and wasn't done:

- No root-cause analysis. Closed-source binary; the overflowing function has not been identified.
- No patch, no vendor advisory, and no coordinated disclosure record β€” the 2020 finding went straight to Exploit-DB.
- Not re-tested on any release after 4.5.3, and not tested against current Windows mitigations.
- No working code execution. The `EIP` overwrite is the whole result.
- The CVE was assigned retroactively in 2026 by a third-party CNA, five years after publication, without contacting me.

## Timeline

| Date | Event |
|---|---|
| 2020-02-17 | Vulnerability found |
| 2021-02-19 | PoC published β€” [EDB-49577](https://www.exploit-db.com/exploits/49577) |
| 2026-01-22 | [VulnCheck advisory](https://www.vulncheck.com/advisories/datasims-avionics-arinc-local-buffer-overflow) published |
| 2026-01-23 | CVE-2021-47881 published to [NVD](https://nvd.nist.gov/vuln/detail/CVE-2021-47881) |
| 2026-06-17 | NVD record last modified |

## References

- https://nvd.nist.gov/vuln/detail/CVE-2021-47881
- https://vulners.com/cve/CVE-2021-47881
- https://www.vulncheck.com/advisories/datasims-avionics-arinc-local-buffer-overflow
- https://www.exploit-db.com/exploits/49577
- https://www.ddc-web.com/

## Credit

**Kağan Γ‡apar** β€” [GitHub](https://github.com/kagancapar) Β· [Exploit-DB](https://www.exploit-db.com/?author=9507) Β· [LinkedIn](https://linkedin.com/in/kagancapar) Β· [X](https://x.com/kagancapar)

Writeups: [English](en/CVE-2021-47881-ENG.md) Β· [TΓΌrkΓ§e](tr/CVE-2021-47881-TR.md)