홈으로 홈으로 | 무료회원가입 | 아이디/비번찾기 | 즐겨찾기
추천음악방송메인홈1대1상담음악방송청취
뽕짝아가씨(무료음악채널)
okTrot(무료음악채널)
전통가요(무료음악채널)

온라이브스토어(앱다운로드)
온라이브(방송등록및청취)

환상의뽕짝파티 무료음악
명작트로트메들리 무료음악
트로트메들리관광 무료음악
동영상노래방
가사검색

POP Player
신나는 고스톱
컴퓨터 오목
작은 음악다방
자동러시 웹플레이어신청

보안∵서버∵쿠키
윈도우∵프레임
이미지∵배경
시간∵달력∵계산
상태바∵타이틀바
음악∵영상
폼∵전송∵테이블
키보드∵마우스
효과∵링크∵메뉴
Script∵php
기타
PHP 강좌
윈도우관련팁
웹관련팁
홈페이지제작팁
기본강좌
레지스트리
윈도우서버
리눅스서버
Android
[php] SQL 인젝션 공격
2년 전
SQL 질의 공격이 현실적으로 많은 문제점을 가져 온다는 점에 최신 버전(MYSQL, MSSQL..)에서 자체적으로 필터링하고 있지만, 구버전에서 그렇지 못합니다.

SQL 질의를 신뢰할 수 없는 명령으로 인해 SQL 질의에서 접근 제어를 우회할 수 있여, 일반적인 인증과 인증 확인을 무시하고, 종종 SQL 질의가 사용자가 가질 수 없는 권한을 강제 취득하기도 합니다.

SQL 명령 인젝션이란? 공격자가 숨겨진 데이터를 노출하거나, 취약한 부분을 덮어쓰거나, 데이터베이스에 위험한 시스템 단계 명령을 실행하게 하는 SQL 명령을 생성하거나 대체하는 기술를 말합니다.

어플리케이션이 사용자 입력을 받아서, 이를 SQL 질의를 만들 떄 정적 인수로 조합함으로써 일어납니다. 유감스럽게도, 아래 예제들은 실제의 것입니다.

패스워드를 얻는 방법 중 하나는 검색 결과 페이지를 우회하는 것입니다. 공격자에게 필요한 것은 변수 중 하나라도 제대로 다뤄지지 않으면서 SQL 구문에 사용되는 것입니다.

이러한 필터는 일반적으로 SELECT 구문에서 WHERE, ORDER BY, LIMIT, OFFSET에 사용됩니다. 데이터베이스가 UNION 구조를 지원하면, 공격자는 원래 질의에 전체 질의를 덧붙여서 임의의 테이블에서 패스워드를 얻을 수 있습니다. 암호화된 패스워드 필드를 강력히 권합니다.


SQL 질의 공격


검증되지 않는 변수를 전적 사용자의 신뢰를 믿고 필터링하지 않는다면, 문제는 커질 수 밖에 없습니다. 다음 변수에 이 질의('와 --로..)가 $query 에서 사용하는 변수 중 하나에 할당되면, 문제는 커질 수 밖에 없습니다.

예제 (ex #1

<?php
$query  = "SELECT id, name, inserted, size FROM products
                  WHERE size = '$size'
                  ORDER BY $order LIMIT $limit, $offset;";
$result = mysql_query($query);
?>

다음 질의로 비밀번호없이 누구나 접속이 가능하게 변질되어 버립니다.

예제 (ex #2
<?php
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";

$query = "SELECT * FROM users WHERE user='{$_POST['username']}'
            AND password='{$_POST['password']}'";
mysql_query($query);

echo $query;
// 결과: SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
?>

SQL UPDATE도 공격받을 수 있는데, 이런 질의를 완전한 새 질의를 덧붙일 수 있습니다. 또한 공격자가 SET 절을 다룰 수도 있습니다. 이 경우 질의를 성공적으로 변경하기 위하여 일부 스키마 정보를 가지고 있어야 합니다.

예제 (ex #3
<?php
$query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
?>

악의적인 사용자가 $uid 에 ' or uid like'%admin'; -- 값을 넣어서 관리자 패스워드를 변경하거나, $pwd 에 "hehehe', admin='yes', trusted=100 "(마지막 공백 포함)을 설정하여 권한을 얻을 수도 있습니다.

예제 (ex #4
<?php
// $uid == ' or uid like'%admin%'; --
$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like
'%admin%'; --";

// $pwd == "hehehe', admin='yes', trusted=100 "
$query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100
WHERE ...;";
?>

데이터베이스 호스트의 OS 등급 명령에 접근하는 문제시 될 예제입니다.

예제 (ex #5
<?php
$query  = "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);
?>

공격자가 $prod에 a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- 값을 제출하면, $query는:

예제 (ex #6
<?php
$query  = "SELECT * FROM products
             WHERE id LIKE '%a%'
             exec master..xp_cmdshell 'net user test testpass /ADD'--";
$result = mssql_query($query);
?>

이러한 공격은 주로 보안을 염두에 두지 않고, 쓰여진 코드 취약점에서 발생합니다. 어떠한 입력도 믿어서는 안되며, 최신 버전이라도 한번더 필터링해 주어야 합니다.

특히 클라이언트측에서 오는 입력은 믿어서는 안됩니다. select, hidden input 필드, 쿠키도 마찬가지입니다. 첫 번째, 두 번째 예제에서 그러한 질의가 큰 문제를 일으킬 수 있음을 보여주고 있습니다.
SQL 인젝션 회피


다음은 안전한 질의 예제가 됩니다.

예제 (ex #7

<?php
settype($offset, 'integer');
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET
               $offset;";

$query = sprintf("SELECT id, name FROM products ORDER BY
                    name LIMIT 20 OFFSET %d;", $offset);
?>

이러한 문제를 회피하기 위해 안전한 방법으로 문자열 회피 함수를 사용하는 것인데, mysql_real_escape_string() 가 그것입니다. mysql_real_escape_string 는 mysql_query 에서 특수 문자열을 이스케이프하기 위해 사용되며, 그러므로 SQL 인젝션 공격이 동작하지 않고 질의가 정확하게 실행될 것입니다.

예제 (ex #8
<?php
if (isset($_POST['product_name']) &&
       isset($_POST['product_description']) &&
       isset($_POST['user_id'])) {
    // 접속
    $link = mysql_connect(
      'mysql_host',
      'mysql_user',
      'mysql_password'
    );
    if(!is_resource($link)) {
        echo "서버 접속 실패\n";
        // ... 오류를 적절히 기록
    } else {
        // ON일 경우 magic_quotes_gpc/magic_quotes_sybase 효과 제거
        if(get_magic_quotes_gpc()) {
            $product_name        =
                stripslashes($_POST['product_name']);
            $product_description =
                stripslashes($_POST['product_description']);
        } else {
            $product_name        = $_POST['product_name'];
            $product_description = $_POST['product_description'];
        }
        // 안전한 질의 만들기
        $query = sprintf("INSERT INTO products (
                          `name`, `description`, `user_id`)
                           VALUES ('%s', '%s', %d)",
               mysql_real_escape_string($product_name, $link),
               mysql_real_escape_string($product_description, $link),
               $_POST['user_id']);

        mysql_query($query, $link);

        if (mysql_affected_rows($link) > 0) {
            echo "Product inserted\n";
        }
    }
} else {
    echo "Fill the form property\n";
}
?>


아니면 addslashes() 와 str_replace() 함수를 사용할 수도 있습니다. addslashes() 는 데이터베이스 질의 등에서 처리할 필요가 있는 문자 앞에 백슬래시를 붙인 문자열을 반환합니다. 이 문자들은 작은 따옴표('), 큰 따옴표("), 백슬래시(\), NUL(NULL 바이트)입니다.

addslashes()를 사용하는 대표적인 예는 데이터베이스에 데이터를 넣을 때 입니다. 예를 들어, 데이터베이스에 O'reilly 라는 이름을 넣으려고 할때, 이스케이프할 필요가 있습니다. 대부분의 데이터베이스는 \을 사용하기에 O\'reilly가 되어야 합니다. 이 데이터를 데이터베이스에 넣으면 추가한 \은 저장되지 않습니다.

예제 (ex #9
<?php
$str = "Is your name O'reilly?";

// 출력: Is your name O\'reilly?
echo addslashes($str);
?>
추천추천 : 135 추천 목록
번호 제목
3,015
 iframe 높이 100% 맞추기
3,014
 curl 함수를 이용한 HTTP REFERER 변경
3,013
 윈도우10 시스템 파일 및 Dism 검사
3,012
 텍스트 줄바꿈, 글자자르기 CSS
3,011
 jQuery Mobile에서 유용한 코드 10가지.
3,010
 [PHP] dirname()함수와 $_SERVER 관련 상수들
3,009
 [PHP] 파일 크기, 사이즈 불러오는 함수, filesize()
3,008
 [jQuery] jQuery Quick API
3,007
 [ transition ] 링크 hover 색상 변화 속도 조절
3,006
 PHP 5.3.0 에서 사라진 함수들 대체
3,005
 어떤 파일들이 include 나 require 되었는지 확인하는 함수(get_included_files)
3,004
 PHP 날짜 형식 및 계산하기(날짜 더하고 빼기)
3,003
 jQuery Mobile에서 유용한 코드 10가지.
3,002
 값이 배열 안에 존재하는지 확인하는 in_array함수
3,001
 사용자가 웹브라우저에서 뒤로가기를 했을때 감지하는 방법
3,000
 [jQuery]버튼 활성화, 비활성화
2,999
 jQuery show() / hide() / toggle() 사용법
2,998
 jquery 여러가지 이벤트
2,997
 border-radius 속성
2,996
 네이버 오픈API 음성합성 API 사용하는 PHP 샘플코드
2,995
 UTF8 한글 자르기..
2,994
 iconv 에러 발생시 계속 처리하기 옵션
2,993
 [PHP] 현재 페이지의 도메인 , URL 정보 알아내기.
2,992
 [PHP] 막강 기능 배열..
2,991
 [CSS] - Input clear `X ` 버튼 제거 ( IE, Chrome, Firefox )
2,990
 [Mobile] - 모바일웹 Href 태그속성들
2,989
 [JqueryMobile] - 현재화면의 가로세로 사이즈 구하기
2,988
 [JqueryMobile] - 화면의 가로, 세로 사이즈 구하는 방법
2,987
 jquery로 가로 넓이(width), 세로 높이(height) 자동 조절
2,986
 iframe 높이 jquery로 자동조절하기
2,985
 jQuery 오른쪽 영역의 높이를 왼쪽 영역의 높이와 동일하게 하기
2,984
 jquery에서 테이블 짝수, 홀수 번째 TR 배경색 변경하기
2,983
 jquery에서 테이블에 마우스 오버시 해당 행의 배경색상 변경하기
2,982
 jquery 스크립트내 특정값 확인하기 (디버깅)
2,981
 jquery cookie (jquery.cookie.js)
목록
인기절정뽕짝파티
트로트재생목록
인기트로트모음
지루박디스코메들리
밤무대애창곡
전자올겐경음악
종합성인가요방
못잊을옛날노래
카바레 음악
트롯디스코팡팡
관광 메들리
트롯카페
가요감상실
추억의옛노래
스페셜가요광장
BillBoard Free
추천가요모음
경음악.전자올겐
스페셜음악여행
WOLRD POPs
K-POP\BillBoard
JP\CN
POP TOP BEST
K.R.노래방

추천가요\인기
F뮤직 인기\발라드
F뮤직 애창\트로트
트로트성인가요
인기가요
프리미엄 POP
경음악\기타
프리미엄 최신가요
프리미엄 성인가요
가요축제\트롯1번지
댄스\메들리\리믹스
카페\명상\경음악\기타
뮤직트로트 부산광역시부산진구 가야동 ㅣ 개인정보취급방침
Copyright (C) musictrot All rights reserved.