Skip to content

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.

Terminal window
.\ysonet.exe -g TypeConfuseDelegate -h

Target declarations

VariantFormattersInputsRequirementsRuntime tokens
1BinaryFormatter, NetDataContractSerializer, SoapFormatter, LosFormattercommandbuilt-in, net-frameworknet-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
2BinaryFormatter, NetDataContractSerializer, LosFormattercommandbuilt-in, net-frameworknet-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
3BinaryFormatter, NetDataContractSerializer, SoapFormatter, LosFormattercommandbuilt-in, net-frameworknet-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)
OptionHelpDefaultRequired
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.1false

Credit: [Finders: James Forshaw] [Contributors: Alvaro Munoz, Soroush Dalili]

All modules · Full catalog JSON