pwnable.kr (collision)

c0wb3ll ㅣ 2020. 8. 28. 11:09

pwnable.kr (collision)

pwnable.kr collision

제시해준 ssh로 접속하도록 하자.

 

ssh col@pwnable.kr -p2222 (pw : guest)

역시나 flag는 권한 거부가 발생한다

 

cat col.c

col.c 파일 내용이다.

 

col.c main() - 길이 체크
col.c main() - 플래그 조건

우선 플래그를 읽을 수 있는 조건을 확인해보자.

  1. 입력받은 인자는 20byte의 길이여야만 한다.
  2. hashcode 변수와 입력받은 인자를 check_password()함수에 넣어 받은 리턴 값과 같으면 플래그를 읽어준다.

그럼 우리가 알아야 할 내용은 아래와 같을 것이다.

  1. hashcode 변수 값
  2. 함수 check_password() 동작과정 및 리턴 값

col.c check_password()

  1. hashcode = 0x21dd09ec

    hashcode 변수의 값은 0x21dd09ec이다. 이 값과 check_password() 결과 값을 비교하여 참이면 "/bin/cat/ flag" 명령어를 실행한다.

  2. check_password 동작과정

    1. 입력받은 인자를 int형 포인터 변수 ip 에 넣는다.

    2. 포인터 변수 ip를 배열로 참조하여 int형 변수인 res와 더한 값을 res 변수 값으로 한다.

    3. res를 반환한다.

      즉, res의 값이 0x21dd09ec와 같으면 된다.

알아야 할 내용

포인터 변수인 ip에 배열로 접근하는 것을 알 수 있다. 이를 이해하기 위해 자료형의 크기와 배열에 대해 알아야 한다. ( 참고로 이러한 사용이 가능한 이유는 포인터와 배열 모두 컴퓨터 내부적으로는 포인터로 처리하기 때문이다. 자세한 사항은 내 블로그에도 있고 구글링하면 금방 나오니 궁금하면 찾아보길 바란다. ㅎ)

자료형의 크기

자료형의 크기

자료형은 각각에 맞는 크기를 가지고 있다. 문제를 풀 때 알아야 할 부분은 int* ip 라는 int형 포인터 변수이므로 int에 대해 알아야 한다. int 형 같은 경우에는 4byte의 크기를 가진다.

배열

배열은 같은 타입의 변수들로 이루어진 유한 집합으로 정의된다.

배열을 구성하는 각각의 값을 배열 요소라고 하며, 배열에서의 위치를 가르키는 숫자는 인덱스라고 한다.

여기까지는 사전적 정의이고 간단하게 말하면 그냥 변수에 숫자를 붙여 관리하는 것이다.

우리가 자주 사용하는 문자열 배열 변수 선언을 예를 들어보겠다.

char name[8] = "c0wb3ll"

이렇게 선언을 한다고 예를 들면 메모리 상태는 아래와 같을 것이다.

char name - memory

그럼 char형의 크기는 1byte이기 때문에 각각의 인덱스는 1byte만큼 차이가 나 name[0] = 'c', name[3] = 'b' 가 될 것이다.

 

대충 이 정도만 알고 넘어가면 될 것 같다.

문제 풀이

col.c check_password()

위에 내용을 이해했으면 문제를 풀어보자. 우리가 AAAABBBB를 입력했다고 하면 입력한 인자가 int형 포인터 변수에 들어가면 아래와 같이 메모리에 쌓일것이다.

 

col - input AAAABBBB int* ip memory

A는 ascii코드로 0x41이고 B는 0x42이므로 위와 같은 값이 들어가 0x4141414142424242라는 값이 들어가게 될 것이다.

이렇게 되면 int형의 크기는 4byte이므로 ip[0] = 0x41414141 이며 ip[1]은 0x42424242 이므로 for문을 2번 실핼하게 되면 0x41414141과 0x42424242를 더한 값인 0x83838383이 res의 값이 되게 된다.

 

따라서 우리는 조건문을 통과하기 위해 4byte크기의 값 5개를 입력해주되 이 합이 0x21dd09ec가 되게 하면 된다.

 

이러한 값은 무수히 많으므로 나는 가장 간단하게 0x01111111을 4번 입력하고 0x21dd09ec에서 0x04444444를 뺀 값을 입력하였다.

다만 입력하는 과정에서 문자열로 입력받기 때문에 ascii코드 외의 값을 일반적으로 입력할 수 없는데 아래와 같이 파이썬을 이용하여 해결할 수 있다.

payload

pwntools code

아래 파이썬에 있는 폰툴 모듈을 이용하여 풀 수 있다.

from pwn import *

# ssh 접속
p = ssh('col', 'pwnable.kr', 2222, 'guest')

# 파일 실행 인자 ./col $(python -c 'print "\x11\x11\x11\x01" * 4 + "\xa8\xc5\x98\x1d"')
path = './col'
argv = p32(0x01111111) * 4
argv += p32(0x1d98c5a8) # 0x21dd09ec - 0x04444444

# payload
payload = [path, argv]

s = p.run(payload)
s.interactive()