case 1. 식별과 인증을 동시에 하는경우
<?php
require_once '../nk/tool/db_conn.php';
// //디버깅 마지막 연결 호출의 오류 반환
if ( mysqli_connect_errno() ) {
exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
if ( !isset($_POST['username'], $_POST['password']) ) {
// 오류메시지
exit('ID랑 Password를 입력하세요');
}
$username = $_POST['username'];
$password = $_POST['password'];
// 입력받은 사용자 이름과 비밀번호가 users 테이블에 있는지 확인
$query = "SELECT * FROM accounts WHERE username='$username' AND password='$password'";
$result = mysqli_query($con, $query);
if(mysqli_num_rows($result) >= 1) { // 사용자 정보가 맞으면
echo '로그인 성공';
}
else {
echo "사용자 이름 또는 비밀번호가 잘못되었습니다.";
}
우선 case 1의 경우는 로그인시 ID와 Password를 동시에 인증하는 경우이다. 위의 경우 굉장히 다양한 경우의 sql injection이 가능했다.
- ex' or '1'='1
- ex' or '1'='1'#
- ex'#
이 외에도 union을 이용하는 방법이 있다.
- ex' union select 'ex', '1','2','3'#
다만 union의 경우는 컬럼의 갯수를 알아야 한다는 단점이 있다.
실제로 위에서 db 컬럼 수를 4개로 하였으므로 비밀번호 1로 로그인이 성공했다.다만 데이터가 union select로 만든 것이 위로 올라와야 이 데이터를 사용하므로 order by 1 asc를 통해 정렬을 해주었다.
case1-1. 특수문자 금지
if (preg_match('/#/', $username) || preg_match('/#/', $password)) {
echo "사용자 이름 또는 비밀번호에 특정문자를 사용할 수 없습니다.";
} else {
// 입력받은 사용자 이름과 비밀번호가 users 테이블에 있는지 확인
$query = "SELECT * FROM accounts WHERE username='$username' AND password='$password'";
$result = mysqli_query($con, $query);
if(mysqli_num_rows($result) >= 1) { // 사용자 정보가 맞으면
echo '로그인 성공';
}
else {
echo "사용자 이름 또는 비밀번호가 잘못되었습니다.";
}
}
위의 코드에서 if문을 밖에 하나 더 만들엇다. preg_match로 #을 사용하지 못하도록 하였다. 여기서 #을 다른 특수문자로 바꾸면 그 특수문자를 사용하지 못하게 한다. 공백은 \s이다.
각각 특수문자를 바꾸어 넣어가며 sql injection을 실행한 결과 아래의 방법등으로 우회가 가능했다.
- #의 경우 주석이다. #이 막힌 경우 아래 와 같은 기호나 문자로 우회가 가능하다.
- #, --, ;%00, /* */
- ;%00은 널 문자로 널 문자가 나올 경우 문자열 종료로 간주되어 뒤의 내용은 무시된다.
- or, and 논리연산자가 막힌 경우 아래와 같은 기호로 우회 가능하다
- ||,&&
- 공백의 경우는 다음과 같이 우회 가능하다
- %09,%0a,%0b,%0c,%0d,%20, \n,/**/, (), +
case 1-2. 특정 단어를 추출하는 경우
$username = $_POST['username'];
$password = $_POST['password'];
$username = str_replace('ex','',$username);
// 입력받은 사용자 이름과 비밀번호가 users 테이블에 있는지 확인
$query = "SELECT * FROM accounts WHERE username='$username' AND password='$password'";
$result = mysqli_query($con, $query);
if(mysqli_num_rows($result) >= 1) { // 사용자 정보가 맞으면
echo '로그인 성공';
}
else {
echo "사용자 이름 또는 비밀번호가 잘못되었습니다.";
}
위 코드에서 str_replace()함수를 통해 ex를 추출하고 있다. 이경우 다음으로 우회가 가능했다.
- eexx'#
이렇게 하면 ex가 필터링 되어 추출되어 밖에있던 e와 x만 남아 ex가 된다. 같은 방식으로 다른 문자들도 우회 가능하였다.
case 2. 식별과 인증이 다른경우
<?php
require_once '../nk/tool/db_conn.php';
// //디버깅 마지막 연결 호출의 오류 반환
if ( mysqli_connect_errno() ) {
exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
if ( !isset($_POST['username'], $_POST['password']) ) {
// 오류메시지
exit('ID랑 Password를 입력하세요');
}
$username = $_POST['username'];
$password = $_POST['password'];
// 입력받은 사용자 이름과 비밀번호가 users 테이블에 있는지 확인
$query = "SELECT * FROM accounts WHERE username='$username' AND password='$password'";
$result = mysqli_query($con, $query);
$row = mysqli_fetch_assoc($result);
if(mysqli_num_rows($result) >= 1 and $password==$row["password"]) { // 사용자 정보가 맞으면
echo '로그인 성공';
}
else {
echo "사용자 이름 또는 비밀번호가 잘못되었습니다.\n";
}
?>
위 경우는 다음 방법을 통하여 로그인 가능하다
- ex' union select 'ex','dfd','dfd','dfd'#
다만 위와 같은 union select문의 경우 쿼리수와 쿼리의 타입을 맞춰주어야 한다.
case1과 같이 dfd라는 비밀번호로 로그인이 가능했다. 정렬 또한 마찬가지로 하였다.
case 2-1. 받은 함수가 암호화 된 경우
<?php
require_once '../nk/tool/db_conn.php';
// //디버깅 마지막 연결 호출의 오류 반환
if ( mysqli_connect_errno() ) {
exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
if ( !isset($_POST['username'], $_POST['password']) ) {
// 오류메시지
exit('ID랑 Password를 입력하세요');
}
$username = $_POST['username'];
$password = $_POST['password'];
// 입력받은 사용자 이름과 비밀번호가 users 테이블에 있는지 확인
$query = "SELECT * FROM accounts WHERE username='$username' AND password='$password'";
$result = mysqli_query($con, $query);
$row = mysqli_fetch_assoc($result);
if(password_verify($password,$row["password"])) { // 사용자 정보가 맞으면
echo '로그인 성공';
}
else {
echo "사용자 이름 또는 비밀번호가 잘못되었습니다.\n";
}
?>
위의 경우는 비밀번호를 해시암호화된 비밀번호와 비교를 하는 경우이다. 즉, 비밀번호에 입력된 값이 암호화되기 때문에 union select 로 새로운 데이터를 만들어도 로그인이 되지 않을 것이다.
실제로 union select 'ex','1','1'',1'#을 해 본 결과 로그인 되지 않는다.
만약 위와 같이 비밀번호를 암호화하여 비교를 하는 경우에는 암호화 방법과 해독 방법을 알아야 하는 것 같다...
'모의해킹 및 보안' 카테고리의 다른 글
XSS 보안대책 (0) | 2023.05.11 |
---|---|
XSS_공격코드 예시 (0) | 2023.05.09 |
XSS_ 공격 코드 유형 (0) | 2023.05.07 |
XSS (0) | 2023.05.07 |
Same Origin Policy (0) | 2023.04.10 |