wargame/wargame.kr

4번 login filtering

NTART 2019. 9. 10. 06:25

 계정이 차단 당했으니 필터링을 우회하여 로그인하여라 .. sql injection 문제인줄 알았다.

 

문제를 시작하였다. 

 

 

get source를 누르기전에 ctrl u 로 소스를 보았는데 html 코드상에는 guest와 blueh4g가 막힌 것 외에는 특이점이 없는 것 같다. 

 

get source를 누르니 php 소스가 나왔다. php는 잘 모르니 한줄 한줄 공부해 보았다.

 

 

<?php

if (isset($_GET['view-source'])) {
    show_source(__FILE__
);
    exit();
}
Isset(변수) -> 변수가 설정 되어있는지 확인하는 함수이다. 설정되어 있으면 true 아니면 false 반환

cf)Empty(변수) -> 변수가 비어 있는지 확인하는 함수이다. 비어 있으면 true 아니면 false

 

$_GET -> get방식으로 변수값 가져옴

cf) get vs post

get은 url에 정보가 노출되지만 post 방식에 비해 빠르기 때문에, 간단한 요청을 할 경우 더 유용하다.

하지만 post도 html body에 써서 넘겨주기 때문에 burp suite 같은 패킷 분석툴에 정보가 노출되며 post가 더 안전하다고는 할 수 없다. 안전하려면 https..

 

show_source(__FILE__); -> 브라우저에 php 소스 보이게 하기

 

-->> html 소스를 보면 <div><a href='?view-source'>get source</a></div> 가 있는데

get source 링크를 누르면 php 소스를 보여주는 것 같다. #근데 왜 ctrl u로 봤을 때 php 소스는

안보였는지 모르겠다..



 if(isset($_POST['id']) && isset($_POST['ps'])){
  include("../lib.php"); # include for auth_code function.

include -> 외부 파일을 포함하는 함수

cf)include / include_once / require / require_once

 

-->>post방식으로 id와 ps를 받으면 ../경로의 lib.php를 함수에 포함시킨다.



  mysql_connect("localhost","login_filtering","login_filtering_pz");
  mysql_select_db ("login_filtering");
  mysql_query("set names utf8");

mysql_connect() -> mysql 서버와 연결

 

mysql_select_db()->  connect함수로 mysql서버와 연결 후에는 사용해야할 db를 선택해야 한다.

 

mysql_query() -> sql 쿼리문을 실행하는 함수

  $key = auth_code("login filtering");
  $id = mysql_real_escape_string(trim($_POST['id']));
  $ps = mysql_real_escape_string(trim($_POST['ps']));
  $row=mysql_fetch_array(mysql_query("select * from user where id='$id' and ps=md5('$ps')"));

 

php에서는 유동변수를 $로 선언한다. 첫문자는 무조건 알파벳이어야 한다. 연산도 가능

 

Mysql_real_escape_string -> Sql 명령문에 사용되는 문자열에서 특수 문자를 회피한다. -->sql injection 대비

 

mysql_fetch_array -> fetch의 사전 뜻은 가져오다, array는 배열이다. 순서대로 해석하면 mysql에서 가져와서 배열로 뽑아낸다. mysql 테이블에 저장되어 있는 쿼리를 통해 선한 후에는, 그 값을 바로 사용할 수 없다. php가 인식할 수 있는 형태를 변환해주어야 하는데 이럴 때 사용하는 함수

cf) fetch_array / fetch_assoc / fetch_row / fetch_object

 

-->> key 변수 선언, id와 ps를 escape string하여 sql injection을 못하도록 하고, mysql db에서 id와 md5 해쉬 해둔 ps를 row변수에 저장

 


  if(isset($row['id'])){
   if($id=='guest' || $id=='blueh4g'){
    echo "your account is blocked";
   }else{
    echo "login ok"."<br />";
    echo "Password : ".$key;
   }
  }else{
   echo "wrong..";
  }
 }
?>

 

-->>row에 만족하는 id를 입력 하였을 때, id가 guest이거나 blueh4g이면 block 문을 띄우고 아니면 로그인이 성공되며 $key값을 준다.

 

알려준 id는 guest와 blueh4g뿐이라 이것으로 로그인 하여야 하는데 if문으로 id자체를 차단하였다.

sql injection 문제 인 줄 알았지만 real escape string을 하여 막았놓았다.

아예 모르겠어서 검색을 해본 결과, 

php는 대소문자를 구분하지만 db 쿼리할 때는 대소문자를 구분하지 않는다. 

따라서 guest랑 Guest는 쿼리시에 같은 문자열이면서 / php소스에서는 다른 문자열이기 때문에

소스에서 guest와 blue4hg를 차단한 것을 우회하여 로그인에 성공 할 수 있었다. 

 

 

클리어~