Wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 crack crack crack it 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번에는 이 문제는 linux의 .htaccess 크랙이라고 하면서 htpasswd 파일을 제공합니다.

물론 htpasswd 파일을 해독하는 것은 어렵지 않지만, Bruteforce를 통해 공격할 시, 시간이 오래걸린다는 단점이 있습니다.


다행이도 문제를 빨리 풀기 위해 제공된 문자열이 있어서 빨리 풀 수 있습니다.


또한 문제 풀이와 앞서 제가 한 삽질에 대해 공유해보려 합니다.



 

 문제 이해


문제는 다음과 같습니다.


문제에서는 .htaccess 를 크랙하라고 합니다.

여기서 bruteforce 공격이 가능한지 묻고 있습니다.


허허허허허허허허허허허


문제를 들어가 살펴보도록 합시다.


htpasswd 파일을 다운로드할 수 있으며, 비밀번호를 알아내서 입력하라고 합니다.


다행이 문제에서 G4HeulB라는 값이 문자열 앞에 있다는 것을 알려주고, 문자 가지 수도 줄여주는 것을 볼 수 있습니다.


영어 lowercase와 숫자들로 이루어진 값이 얼마나 길게 비밀번호가 있을지는 모르지만 일단 bruteforcing을 수행해야 함은 명백합니다.



위의 값은 htpasswd 파일 내에 입력된 값입니다. 별로 큰 의미는 없어보입니다.

(사실은 위의 구조를 먼저 파악하고 어떤 걸로 할지 삽질을 조금 수행했습니다.... hashcat이라든가...)





 

 문제 풀이


문제를 풀기 위해서는 적절한 크랙 도구를 활용할 줄 알아야합니다.

다만 값을 계속 넘겨줘야 하니 Python 소스도 작성해야 합니다.


문제 풀이에 앞서 hashcat으로 수행한 삽질을 공유하려 합니다.

풀이를 보시려면 [문제 풀이] 소제목으로 넘어가시면 될 것 같습니다.


 

 Hashcat 삽질


구조를 파악하기 위해 먼저 파일을 열어보니 $1$ 을 기준으로 살펴보았습니다.


그런데 $apr1$은 있는데 $1$에 대한 구조 정보는 나오지 않더군요.

여기서 좀 더 검색해보니 apache: using $1$ md5 salt in place of $apr1$라는 게시글이 있더군요.


게시글 링크 : https://discussions.apple.com/thread/1356105


이 글을 요약하면 $1$가 아니라 $apr1$를 포함하여 htpasswd를 만들어야 하는데, 요것이 뭔지 모르겠지만 아마 apache2.0..몇 버전에서 나온 게 아니냐? 하는 글입니다.


그래서 apache2.0 version htpasswd 라고 검색했더니 다음과 같은 글이 나와서 궁금증을 해결하였습니다.


게시글 링크 : https://foswiki.org/Development/ImproveHtPaswdUserFlexibility


이 글에서 $1$의 내용을 한 그림으로 요약할 수 있을 것 같습니다.


표에서 crypt-MD5로 생성한 htpasswd 값에는 $1$ 값이 들어가 있고 admin:$1$3iuE5z/b$JHyXMzQOIq3cl6WlEMoZC.와 같은 예시가 있다고 말하고 있습니다.


이 값은 제공된 htpasswd 값과 일치하는 형태입니다.


hashcat의 decrypt mode에서 md5를 검색해보면 다음과 같이 나옵니다.


root@kkamikoon:~/wargame.kr/21. crack crack crack it# hashcat -h | grep md5

     10 | md5($pass.$salt)                                 | Raw Hash, Salted and/or Iterated

     20 | md5($salt.$pass)                                 | Raw Hash, Salted and/or Iterated

     30 | md5(utf16le($pass).$salt)                        | Raw Hash, Salted and/or Iterated

     40 | md5($salt.utf16le($pass))                        | Raw Hash, Salted and/or Iterated

   3800 | md5($salt.$pass.$salt)                           | Raw Hash, Salted and/or Iterated

   3710 | md5($salt.md5($pass))                            | Raw Hash, Salted and/or Iterated

   4010 | md5($salt.md5($salt.$pass))                      | Raw Hash, Salted and/or Iterated

   4110 | md5($salt.md5($pass.$salt))                      | Raw Hash, Salted and/or Iterated

   2600 | md5(md5($pass))                                  | Raw Hash, Salted and/or Iterated

   3910 | md5(md5($pass).md5($salt))                       | Raw Hash, Salted and/or Iterated

   4300 | md5(strtoupper(md5($pass)))                      | Raw Hash, Salted and/or Iterated

   4400 | md5(sha1($pass))                                 | Raw Hash, Salted and/or Iterated

   4700 | sha1(md5($pass))                                 | Raw Hash, Salted and/or Iterated

   1600 | Apache $apr1$ MD5, md5apr1, MD5 (APR)            | HTTP, SMTP, LDAP Server

    500 | md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5)        | Operating Systems

   6300 | AIX {smd5}                                       | Operating Systems 


기존에 htpasswd라면 -m 1600 모드를 이용하여 복호화를 시도할 수 있었을 것입니다.

하지만 해당 파일은 crypt-md5로 되어 있기 때문에, 불가능합니다.ㅠㅠ


관련 라이브러리 설명은 다음 링크를 참조해주세용.


md5_crypt 라이브러리 : https://passlib.readthedocs.io/en/stable/lib/passlib.hash.md5_crypt.html#passlib.hash.md5_crypt

apr1_md5_crypt 라이브러리 : https://passlib.readthedocs.io/en/stable/lib/passlib.hash.apr_md5_crypt.html

안전하다고 알려진 라이브러리 : https://passlib.readthedocs.io/en/stable/narr/quickstart.html#recommended-hashes



 

 문제 풀이


이 문제를 해결하기 위해서는 md5_crypt를 공격할 수 있는 툴인 john the ripper를 사용하면 됩니다.

john은 kali 리눅스에 기본적으로 설치되어 있는 것으로 알고 있습니다.

저는 ubuntu 18.04에서 python 소스와 함께 공격을 수행하였습니다.


이 python3 소스를 이용하여 출력되는 각각의 값을 리눅스의 파이프를 이용하여 standard input으로 john the ripper에 넣어줍니다.

import itertools, string

character_set = string.ascii_lowercase + string.digits

min_len, max_len = 2, 10

for l in range(min_len, max_len):
    for m in itertools.product(character_set, repeat=l):
        print('G4HeulB' + ''.join(m)



끝!


+ Recent posts