Dreamhack - [wargame.kr] strcmp

·2025년 8월 2일

Dreamhack-Writeups

목록 보기
31/52

[wargame.kr] strcmp

문제 링크

https://dreamhack.io/wargame/challenges/328

문제 설명

if you can bypass the strcmp function, you get the flag.

풀이과정

  1. 웹 내의 view-source를 눌러 코드를 확인해 줍니다.
    $password = sha1(md5(rand().rand().rand()).rand());
    위 코드를 통해 패스워드가 랜덤으로 생성되고 있음을 확인할 수 있습니다. (rand() 함수는 PHP 내장 함수로, 호출할 때마다 임의의 정수값을 반환합니다.)
    따라서 패스워드를 유추해서 풀이하는 방법은 불가능합니다.
  2. 다음 조건문을 통해 플래그 출력 조건을 확인할 수 있습니다:
     if (strcmp($_POST['password'], $password) == 0) {
             echo "Congratulations! Flag is <b>" . $FLAG ."</b>";
    • 입력한 패스워드 값과, 생성된 패스워드를 비교하는 함수로 strcmp()를 사용하였습니다.
    • strcmp()함수는 두 문자열이 일치하면 0을 반환합니다.
    • 그런데 이 strcmp() 함수는 PHP 5.3 버전에서 배열을 인자로 받으면 null을 반환하는 특성이 있습니다.
    • PHP의 느슨한 비교(==)에서는 null == 0 이 참이므로, 조건을 우회할 수 있습니다.
    • 즉, $_POST['password']에 배열을 전달하여 strcmp()null을 반환하게 만들면, null == 0이 참이 되어 플래그를 획득할 수 있습니다.
    • 이때 배열의 내용은 무엇이든 상관없습니다.
  3. 패스워드 입력 화면에서 개발자모드(F12)를 켜주고, HTML코드를 수정합니다.
    name="password"name="password[]"로 변경해줍니다. (name="password[]"는 폼 전송 시 해당 값을 배열로 만들어서 보내겠다는 의미입니다.)

  1. 패스워드에 아무 값이나 입력해 chk를 클릭하면, strcmp()null을 반환하고 조건문을 통과하여 플래그를 획득할 수 있습니다.

배운점

  • strcmp() 함수에 대해 배울 수 있었습니다. 또한, 느슨한 비교를 이용한다면 취약점이 생겨, 이를 이용해 공격이 가능함을 배웠습니다.
  • PHP 5.2와 5.3 이상에서 strcmp()의 배열 처리 방식이 다르다는 점을 통해, 서버의 환경과 언어 버전도 공격 설계에 중요한 요소가 될 수 있다는 걸 배웠습니다.
  • 실무에서 침해 사고 대응 시에도, 서버의 버전 또한 고려해야 됨을 알 수 있었습니다.
  • 개발자 도구를 통해 직접 HTML 코드를 수정하여 공격할 수 있었습니다. 이는 즉 "클라이언트는 신뢰할 수 없다"는 웹 보안의 기본 원칙을 다시 한번 상기시켜 주었습니다.

Summary (English)

  • The challenge involves bypassing a strcmp() function to retrieve the flag.
  • The source code shows that the password is randomly generated using rand() and hashed with md5() and sha1(), making it impossible to guess the actual value.
  • The strcmp($_POST['password'], $password) == 0 condition is used to compare the input with the server-side password.
  • In PHP 5.3 and above, if strcmp() receives an array as input, it returns null.
  • Since null == 0 evaluates to true in loose comparison, the condition can be bypassed by sending an array instead of a string.
  • This can be done by modifying the HTML input name to password[] using browser developer tools. PHP then treats the input as an array.
  • Once this is done, any input will cause strcmp() to return null, triggering the condition and printing the flag.
  • Key lessons include understanding strcmp() behavior, type juggling in PHP, version-specific behaviors (5.2 vs 5.3), and the importance of not trusting client-side inputs.
profile
CTF 풀이 및 실습 중심 학습을 기록합니다.

0개의 댓글