728x90
반응형
이론
시그널이 발생하면 커널 모드에서 실행되는데, 유저 모드의 내용을 보존하기 위해 레지스터에 값을 저장해두었다가 다시 가져오게 되며, 이를 이용해 임의의 코드를 실행할 수 있게 된다.
우선 시그널은 커널의 버전에 따라
do_signal
arch_do_signal
arch_do_signal_or_restart
의 이름의 함수로 시작되는데, syscall number에 따라 해당 시그널을 작동시킨다.
취약점
많은 syscall 중 특히 sigreturn이 취약한데, sigreturn 시스템 콜을 호출하면 restore_sigcontext 함수에 의해 스택의 데이터를 레지스터에 등록하게 되며,
static bool restore_sigcontext(struct pt_regs *regs,
struct sigcontext __user *usc,
unsigned long uc_flags)
{
struct sigcontext sc;
/* Always make any pending restarted system calls return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE))
return false;
#ifdef CONFIG_X86_32
set_user_gs(regs, sc.gs);
regs->fs = sc.fs;
regs->es = sc.es;
regs->ds = sc.ds;
#endif /* CONFIG_X86_32 */
regs->bx = sc.bx;
regs->cx = sc.cx;
regs->dx = sc.dx;
regs->si = sc.si;
regs->di = sc.di;
regs->bp = sc.bp;
regs->ax = sc.ax;
regs->sp = sc.sp;
regs->ip = sc.ip;
#ifdef CONFIG_X86_64
regs->r8 = sc.r8;
regs->r9 = sc.r9;
regs->r10 = sc.r10;
regs->r11 = sc.r11;
regs->r12 = sc.r12;
regs->r13 = sc.r13;
regs->r14 = sc.r14;
regs->r15 = sc.r15;
#endif /* CONFIG_X86_64 */
/* Get CS/SS and force CPL3 */
regs->cs = sc.cs | 0x03;
regs->ss = sc.ss | 0x03;
regs->flags = (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS);
/* disable syscall checks */
regs->orig_ax = -1;
#ifdef CONFIG_X86_64
/*
* Fix up SS if needed for the benefit of old DOSEMU and
* CRIU.
*/
if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && user_64bit_mode(regs)))
force_valid_ss(regs);
#endif
return fpu__restore_sig((void __user *)sc.fpstate,
IS_ENABLED(CONFIG_X86_32));
}
sigcontext는 위에서 보듯 스택의 값을 차례로 레지스터에 써넣는데, 아키텍처에 따라 그 구조가 다르니 구조체 생성 시 유의해야 한다.
하지만 우리의 짱짱 pwntools는 이를 제공하며, 아래와 같이 사용 가능하다.
from pwn import *
context.arch = 'amd64'
srf = SigreturnFrame() #대문자 유의
>>> srf.rax = 59
>>> srf.rsi = 11223344
>>> srf.rdi = 0x41414141
>>> print(srf)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00AAAA\x00\x00\x00\x000A\xab\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00;\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
728x90
반응형
'Tips & theory' 카테고리의 다른 글
_IO_FILE Arbitrary Address Write (0) | 2022.08.16 |
---|---|
_IO_FILE Arbitrary Address Read (0) | 2022.08.16 |
rtld_global (0) | 2022.08.15 |
seccomp 요약 (0) | 2022.08.05 |
system call table & calling conventions (0) | 2022.08.05 |