Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 소켓
- 자바 is-a
- sqlinjection
- lord of sqlinjection`
- php
- injection
- 스프링 특징
- 마이크로서비스 아키택트
- sql
- 세션
- 스프링 종류
- Los
- 세션쿠키
- 웹 개발
- 자바 문법
- 클라이언트
- 서버
- 보안
- XSS
- 자바 Array list
- 자바
- 스프링
- 해킹
- APM
- 자바 has-a
- 웹
- Lord of sqlinjection
- 쿠키
- lord of sqlinjectin
- 스프링구조
Archives
- Today
- Total
LJ
Lord of SQLinjection ( 8번 ) troll 본문
troll 문제이다.
굉장히 쉬우므로 빠르게 소스코드 분석부터 해보자
<?php
//PHP 코드의 시작
include "./config.php";
//config.php 파일을 포함하여 데이터베이스 연결 정보와 같은 설정을 불러온다.
login_chk();
//login_chk 함수를 호출하여 사용자가 로그인했는지 확인하고 이 함수는 인증과 관련된 작업을 수행
$db = dbconnect();
//dbconnect 함수를 호출하여 데이터베이스에 연결하고, 연결 객체를 $db 변수에 저장
if(preg_match('/\'/i', $_GET['id'])) exit("No Hack ~_~");
//PHP Regular Expression Match
//$_GET['id']에 작은 따옴표(')가 포함되어 있는지 정규 표현식으로 검사
//작은 따옴표가 발견되면 "No Hack _" 메시지를 출력하고 스크립트를 종료.
//SQL 인젝션을 방지하려는 시도
if(preg_match("/admin/", $_GET['id'])) exit("HeHe");
//$_GET['id']에 "admin"이라는 문자열이 포함되어 있는지 정규 표현식으로 검사.
//"admin"이 발견되면 "HeHe" 메시지를 출력하고 스크립트를 종료
//"admin" 계정에 대한 접근을 방지하려는 시도
$query = "select id from prob_troll where id='{$_GET['id']}'";
//사용자의 입력값을 포함한 SQL 쿼리를 생성
//이 쿼리는 prob_troll 테이블에서 id가 사용자의 입력값과 일치하는 행을 선택
echo "<hr>query : <strong>{$query}</strong><hr><br>";
//생성된 쿼리를 화면에 출력
//디버깅 목적으로 사용되며, 실제 배포 환경에서는 제거하는 것이 좋다.
$result = @mysqli_fetch_array(mysqli_query($db, $query));
//데이터베이스에 쿼리를 실행하고, 결과를 배열로 가져옴.
//@ 연산자는 오류를 무시하도록 한다.
if($result['id'] == 'admin') solve("troll");
//쿼리 결과에서 id가 "admin"인지 확인.
//만약 id가 "admin"이면, solve 함수를 호출하여 특정 작업을 수행한다. 여기서는 "troll"을 인자로 전달
highlight_file(__FILE__);
//__FILE__ :현재 파일의 전체 경로와 파일명을 나타내는 PHP 매직 상수
//첫 번째 인자로 파일 경로를 받으며, 두 번째 인자로 true를 지정하면, 하이라이트된 코드를 반환하고, false (기본값)일 경우, 결과를 바로 출력
//PHP 내장 함수로, 지정된 파일의 소스 코드를 읽어 들여서 HTML로 구문 강조된 형식으로 출력
//디버깅이나 문제 해결 목적으로 사용
소스코드를 확인했을 때 id 파라미터에 admin을 삽입해야 하는데
admin을 필터링 하는 아이러니한 상황이다.
그치만 admin을 대소문자 구분없이 필터링하는 것이 아닌 소문자만 필터링하므로
admin 중 하나 이상을 대문자로 바꿔 전송하면 문제가 해결된다.
( MySql은 대소문자 구분을 하지 않기 때문에, admin이나 ADMIN이나 같은 문자열로 인식 )
글이 짧아 위의 코드를 안전한 코드로 바꿔보겠다
<?php
include "./config.php";
login_chk();
$db = dbconnect();
$id = $_GET['id'];
//사용자가 GET 요청으로 전달한 id 값을 $id 변수에 저장
if(preg_match('/\'/i', $id)) exit("No Hack ~_~");
if(preg_match("/admin/", $id)) exit("HeHe");
// Prepare statement to prevent SQL injection
$stmt = $db->prepare("SELECT id FROM prob_troll WHERE id = ?");
//SQL 인젝션을 방지하기 위해 준비된 문(Prepared Statement)을 생성
//?는 플레이스홀더로, 실제 값은 나중에 바인딩
$stmt->bind_param("s", $id);
//bind_param 메서드를 사용하여 SQL 쿼리의 플레이스홀더(?)에 $id 값을 바인딩
//"s"는 바인딩할 값이 문자열임을 나타냄
$stmt->execute();
//준비된 문을 실행
$result = $stmt->get_result()->fetch_assoc();
//get_result 메서드는 실행된 쿼리의 결과를 mysqli_result 객체로 반환
//쿼리 실행 결과를 가져와서 연관 배열로 반환
//get_result 메서드는 쿼리 결과 객체를 반환하고, fetch_assoc 메서드는 그 결과를 연관 배열로 변환
//$result = array(
// "id" => "admin"
// );
if($result && $result['id'] == 'admin') solve("troll");
highlight_file(__FILE__);
?>
- SQL 인젝션: 사용자의 입력값을 직접 쿼리에 포함시키는 것은 매우 위험하므로 이를 방지하기 위해 준비된 문(Prepared Statement)을 사용하는 것이 좋다.
- 에러 처리: @ 연산자를 사용하여 오류를 무시하지 말고, 적절한 에러 처리를 구현해야 한다.
- 디버깅 코드 제거: 쿼리를 출력하는 echo 문과 소스 코드를 출력하는 highlight_file 함수는 실제 배포 환경에서는 제거하는 것이 좋다.
'IT 보안 > 보안첼린지' 카테고리의 다른 글
Lord of SQLinjection ( 11번 ) golem (0) | 2024.05.28 |
---|---|
Lord of SQLinjection ( 9번 ) vampire (0) | 2024.05.23 |
XSS game level 6 (0) | 2024.05.20 |
XSS game level 5 (0) | 2024.05.20 |
XSS game level4 (0) | 2024.05.17 |
Comments