TypeConfuseDelegate
gadget
Combines a Comparison<string> with itself, wraps it with Comparer<string>.Create, then swaps invocation-list slot 1 for Process.Start(string, string). The sorted container calls the comparer while rebuilding on deserialize, and the confused return type runs the command. The var/variant option picks the serialized root container: 1 (default) SortedSet<string>; 2 SortedDictionary<string,string>, whose serialized TreeSet<KeyValuePair<string,string>> backing set forwards key comparisons through SortedDictionary.KeyValuePairComparer; 3 the internal System.Collections.Generic.TreeSet<string>, built by reflection. Variants 2 and 3 exist for one narrow case: a binder or blocklist that rejects the exact wire type name System.Collections.Generic.SortedSet but allows the other roots. They do not defeat an allowlist, a rule that also names TreeSet, or a policy that resolves types and rejects SortedSet subclasses (TreeSet derives from SortedSet). Variants 2 and 3 refuse an input whose executable and argument strings compare equal, because both roots reject a duplicate key; variant 1 accepts it but its SortedSet then holds one element and does not fire, so make the two strings differ. SoapFormatter is a direct CLR4 document for variants 1 and 3: the target sees the native SortedSet<string> or TreeSet<string> root and ComparisonComparer<string>, with no Workflow surrogate, outer carrier, or nested BinaryFormatter stream. Variant 2 does not support SoapFormatter. All three variants target .NET Framework 4.5+; use TypeConfuseDelegateNetFx40 for exactly .NET Framework 4.0 or TypeConfuseDelegateNetFx35 for .NET Framework 3.5 / CLR2. --legacyfx is not supported because rewriting assembly versions cannot turn this Comparer<T>.Create graph into a CLR2 graph.
Declared metadata, not a runtime result. How to read evidence.
.\ysonet.exe -g TypeConfuseDelegate -hTarget declarations
| Variant | Formatters | Inputs | Requirements | Runtime tokens |
|---|---|---|---|---|
| 1 | BinaryFormatter, NetDataContractSerializer, SoapFormatter, LosFormatter | command | built-in, net-framework | net-fx-4.5, net-fx-4.5.1, net-fx-4.5.2, net-fx-4.6, net-fx-4.6.1, net-fx-4.6.2, net-fx-4.7, net-fx-4.7.1, net-fx-4.7.2, net-fx-4.8, net-fx-4.8.1 |
| 2 | BinaryFormatter, NetDataContractSerializer, LosFormatter | command | built-in, net-framework | net-fx-4.5, net-fx-4.5.1, net-fx-4.5.2, net-fx-4.6, net-fx-4.6.1, net-fx-4.6.2, net-fx-4.7, net-fx-4.7.1, net-fx-4.7.2, net-fx-4.8, net-fx-4.8.1 |
| 3 | BinaryFormatter, NetDataContractSerializer, SoapFormatter, LosFormatter | command | built-in, net-framework | net-fx-4.5, net-fx-4.5.1, net-fx-4.5.2, net-fx-4.6, net-fx-4.6.1, net-fx-4.6.2, net-fx-4.7, net-fx-4.7.1, net-fx-4.7.2, net-fx-4.8, net-fx-4.8.1 |
Variants
- 1: SortedSet (default) (default)
- 2: SortedDictionary root (evasion)
- 3: TreeSet root (internal type evasion)
Options (1)
| Option | Help | Default | Required |
|---|---|---|---|
var|variant= | Root container: 1 -> SortedSet [default], 2 -> SortedDictionary, 3 -> TreeSet (2 and 3 evade an exact SortedSet wire-name blocklist and need distinct command and argument strings) Default value: "1". Suggested values: 1, 2, 3. | 1 | false |
Credit: [Finders: James Forshaw] [Contributors: Alvaro Munoz, Soroush Dalili]