2024 SWLUG/Dreamhack

4주차_CTF 문제풀이(1) - phpreg

un_plugged 2024. 5. 22. 12:19

▶문제

▶풀이

서버에 접속하니 위와 같이 닉네임과 패스워드를 입력하는 화면이 나왔다. 이 두가지를 입력해야 step 2로 넘어갈 수 있다. 문제 파일을 다운 받으니 index.php와 step2.php 두 가지 파일이 있다. 우선 step2로 넘어가야하니까 step2.php파일을 살펴보았다.

위의 사진은 복잡한 코드들 중 nickname과 password에 관련된 부분이다. name == "dnyang0310", pw == "d4y0r50ng+1+13"으로 name과 pw가 그대로 나와있었다.

근데 위의 name과 pw를 입력하면 step2로 넘어갈 수 없다.

다시 코드를 잘 보니 비밀번호에 필터링이 적용되었다는 주석을 발견할 수 있다. 즉, 사용자로부터 입력받은 값에 필터링이 적용되어 해당 값들을 그대로 입력하면 step2로 넘어갈 수 없다.

1. if문을 먼저 살펴보면 입력한 패스워드에 소문자나 대문자가 포함되어 있다면 "alphabet in the pw :("이 화면에 출력된다. 나는 패스워드에 소문자가 포함되어있어 이와 같이 출력된 것이다...

preg_match: 문자열 내에서 일치하는 부분을 찾아내는 함수

2. else문 속 name에 관련된 부분을 보면 name에서 "nyang"을 빈 문자열로 필터링하고 있다. nyang을 만나면 공백으로 지워버리기 때문에 "dnnyangyang0310"를 입력하면 중간에 nyang이 지워져 결과적으로 dnyang0310가 name이 될 수 있다.

preg_replace: 특정 패턴을 찾아 다른 문자열로 바꾸는 함수

형식: preg_replace("패턴" , "바꿀 패턴" , "바꿀 문장");

3. pw 부분은 "\d*\@\d{2,3}(31)+[^0-8]\!" 이라는 패턴이 있다. 이를 하나씩 분석해보면

① \d* : 0~9 사이 숫자 0개 이상

② \@ : 문자 @

③ \d{2,3} : 앞에 작성한 숫자 2회 혹은 3회 반복

④ (31) : 31이라는 숫자

⑤ [^0-8] : 0 - 8이 아닌 숫자

⑥ \! : 문자 !

위의 모든 요소를 조합하면 "123@12319!" 라는 문자열을 만들 수 있다. 지금 이 문자열은 d4y0r50ng 부분이므로 여기에 +1+13를 붙이면 "123@12319!+1+13" 가 비밀번호가 된다!

Step 2로 넘어갔다! step2는 system()함수를 사용해야한다고 하고 여기서 flag를 얻을 수 있으니 이와 관련된 코드를 살펴보았다.

system() : 주어진 명령을 실행하고 결과를 출력

위의 사진이 이 문제를 해결할 코드이다. 만약 cmd에 /flag가 존재한다면 Error를, 아니라면 system(cmd)를 통해 php 코드를 실행시킨다. 즉, flag라는 단어는 사용할 수 없다. 문제에서 flag는 ../dream/flag.txt에 위치하고 있다고 하였다. 그러면 이제 내가 해야할 것은

  1. flag가 위치한 파일 들어가기
  2. flag라는 단어는 작성하지 않기

이 2가지를 제출하면 답을 얻을 수 있을 것 같다.

우선, 파일의 내용을 출력하는 cat명령어를 통해 1번을 해결할 수 있을 것 같고 flag라는 단어 대신 f?ag를 작성하여 2번도 해결하였다.

이를 조합한 "cat ../dream/f?ag.txt"를 입력하면

플래그를 획득할 수 있다.

문제 풀이에 성공하였다!