2023.04.14 – (모의 해킹/취업 연구를 위한 연구) – (0413 Day03) SQL Injection -01
(0413 Day03) SQL 인젝션 -01
DB: 많은 사람들이 데이터를 공유하고 사용할 목적으로 정리, 통합, 관리되는 데이터의 집합체!! DB와 엑셀을 쉽게 비교해보세요! 데이터베이스: 엑셀 파일 자체(test.xlsx) 표: 엑셀 파일 안의 엑셀 시트(시트
jisu069.tistory.com
다양한 로그인 구현!!
다양한 로그인 케이스가 있지만 먼저 두 가지로 나누어서 구현했습니다.
사례 1: 식별과 인증을 동시에
사례 2: 식별 및 인증
Login1 (식별과 인증을 동시에 하는 Case 1)
- 지금까지 구현된 로그인 중 가장 쉬운 코드, 비교적 보기에 깔끔한 코드!
- 다만 로그인이 너무 쉽다.. (SQL Injection은 다양한 공격을 할 수 있다…)
<?php
session_start();
include('./connect.php');
$userId = $_POST('userId');
$userPw = $_POST('userPw');
$sql = "select * from userTestTB where userId='$userId' and userPw = '$userPw';";
$rst = mysqli_query($con, $sql);
$id = mysqli_num_rows($rst);
if(!$id){
echo "
<script>
alert(\"메롱\");
history.back();
</script>
";
}else{
$user = mysqli_fetch_array($rst);
$_SESSION('sIdx') = $user('userIdx');
$_SESSION('sId') = $user('userId');
$_SESSION('sName') = $user('userName');
$_SESSION('sPW') = $user('userPw');
$_SESSION('sEmail') = $user('userEmail');
mysqli_close($con);
echo "
<script>
location.href = \"./main.php\";
</script>
";
}
?>
현재 사용자의 ID 시험그런데 비밀번호를 모르겠습니다. SQL Injection 취약점을 통해 로그인하자!!
- test’#를 이용하여 우회를 시도하였으나 로그인 성공!!
- test’or’1’=’1 로 우회를 시도했는데 로그인 성공!!
- 위와 비슷하지만 test’ xor ‘ ‘=’ 를 이용하여 우회를 시도하여 로그인에 성공!!
- ‘ Union select ‘1’,’1′,’1′,’1′,’1′ # 우회해서 해봤는데 로그인 성공!! )
- ID: test / PW: ‘or’1’=’1 비밀번호를 이용하여 우회를 시도하였으나 로그인 성공!!!!
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Login2 (ID로 식별하고 PW로 인증하는 경우 2)
- 지금까지는 Case 1보다 안전하다고 생각했지만 그렇지 않았습니다.
- 코드는 Login1보다 길고 매우 약간 복잡한 코드입니다.
<?php
session_start();
include('./connect.php');
$userId = $_POST('userId');
$userPw = $_POST('userPw');
$sql = "select * from userTestTB where userId='$userId';";
$rst = mysqli_query($con, $sql);
$id = mysqli_num_rows($rst);
if(!$id){
echo "
<script>
alert(\"메롱\");
history.back();
</script>
";
exit;
}else{
$user = mysqli_fetch_array($rst);
$db_pw = $user('userPw');
if($db_pw == $userPw){
$_SESSION('sIdx') = $user('userIdx');
$_SESSION('sId') = $user('userId');
$_SESSION('sName') = $user('userName');
$_SESSION('sPW') = $user('userPw');
$_SESSION('sEmail') = $user('userEmail');
mysqli_close($con);
echo "
<script>
location.href = \"./main.php\";
</script>
";
}else{
echo "
<script>
alert(\"메롱!!\");
history.back();
</script>
";
exit;
};
};
?>
현재 사용자의 ID 시험그런데 비밀번호를 모르겠습니다. SQL Injection 취약점을 통해 로그인하자!!
- test’#를 이용해서 우회를 시도했지만 당연히 실패…!
- test’or’1’=’1 로 우회를 시도했지만 실패!!
- ‘ Union select ‘1’,’1′,’1′,’1′,’1′ # 우회 로그인 성공!!
- ID: test / PW: ‘or’1’=’1은 비밀번호를 이용하여 우회했는데 당연히 실패…!
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Login3 (Case1, 특수문자 금지!!)
- SQL Injection을 방지하기 위해 특수문자(‘,”,#)를 차단하면서 구현해 보았습니다.
- preg_match(pattern, character to compare) : 비교할 문자에 패턴이 있는지 찾아주는 함수!
<?php
session_start();
include('./connect.php');
$userId = $_POST('userId');
$userPw = $_POST('userPw');
$pat="/\"|#|"/';
if(preg_match($pat, $_POST('userId')) or preg_match($pat, $_POST('userPw'))){
echo "
<script>
alert(\"사용자는 보씨오 다음에도 사기치면 혼나오!! 양심껏 로그인 하씨오 \");
history.back();
</script>
";
exit;
}else{
$sql = "select * from userTestTB where userId='$userId' and userPw = '$userPw';";
$rst = mysqli_query($con, $sql);
$id = mysqli_num_rows($rst);
if(!$id){
echo "
<script>
alert(\"메롱\");
history.back();
</script>
";
}else{
$user = mysqli_fetch_array($rst);
$_SESSION('sIdx') = $user('userIdx');
$_SESSION('sId') = $user('userId');
$_SESSION('sName') = $user('userName');
$_SESSION('sPW') = $user('userPw');
$_SESSION('sEmail') = $user('userEmail');
mysqli_close($con);
echo "
<script>
location.href = \"./main.php\";
</script>
";
}
}
?>
현재 사용자의 ID 시험그런데 비밀번호를 모르겠습니다. SQL Injection 취약점을 통해 로그인하자!!
- test’#를 이용해서 우회를 시도했지만 당연히 실패…!
- test’or’1’=’1 로 우회를 시도했지만 실패!!
- ‘ union select ‘1’,’1′,’1′,’1′,’1′ # 이마저도 로그인 실패!!
- 비밀번호 쪽 ID 사용: test / PW: ‘or’1’=’1 이것도 실패…!
- 모두 실패…
Login4 (Case2, 특수문자 금지!!)
<?php
session_start();
include('./connect.php');
$userId = $_POST('userId');
$userPw = $_POST('userPw');
$pat="/\"|#|"/';
if(preg_match($pat, $_POST('userId'))){
echo"
<script>
alert(\"사용자는 보씨오 다음에도 사기치면 혼나오!! 양심껏 로그인 하씨오 \");
history.back();
</script>
";
}else{
$sql = "select * from userTestTB where userId='$userId';";
$rst = mysqli_query($con, $sql);
$id = mysqli_num_rows($rst);
if(!$id){
echo "
<script>
alert(\"메롱\");
history.back();
</script>
";
exit;
}else{
$user = mysqli_fetch_array($rst);
$db_pw = $user('userPw');
if($db_pw == $userPw){
$_SESSION('sIdx') = $user('userIdx');
$_SESSION('sId') = $user('userId');
$_SESSION('sName') = $user('userName');
$_SESSION('sPW') = $user('userPw');
$_SESSION('sEmail') = $user('userEmail');
mysqli_close($con);
echo "
<script>
location.href = \"./main.php\";
</script>
";
}else{
echo "
<script>
alert(\"메롱!!\");
history.back();
</script>
";
exit;
};
};
}
?>
현재 사용자의 ID 시험그런데 비밀번호를 모르겠습니다. SQL Injection 취약점을 통해 로그인하자!!
- test’#를 이용해서 우회를 시도했지만 당연히 실패…!
- test’or’1’=’1 로 우회를 시도했지만 실패!!
- ‘ union select ‘1’,’1′,’1′,’1′,’1′ # 이마저도 로그인 실패!!
- 비밀번호 쪽을 이용하면 ID: test / PW: ‘or’1’=’1 이것도 당연히 실패…!
- 이 역시 모두 실패했습니다.
Login5 (Case1, 해쉬함수 사용!!)
- 해시 함수를 이용한 암호화(단방향 암호화!)
- 회원가입 시 해시함수로 암호화된 비밀번호를 DB에 저장하고 로그인 시 사용한 키 값을 이용하여 사용자가 입력한 비밀번호를 암호화하여 비교합니다.
<?php
session_start();
include('./connect.php');
$userId = $_POST('userId');
$userPw = $_POST('userPw');
$salt="$5$QOPrAVIK"."$userId".'$';
$hashPw = crypt($userPw, $salt);
$sql = "select * from userTestTB where userId='$userId' and userPw = '$hashPw';";
$rst = mysqli_query($con, $sql);
$id = mysqli_num_rows($rst);
if(!$id){
echo "
<script>
alert(\"메롱\");
history.back();
</script>
";
}else{
$user = mysqli_fetch_array($rst);
$_SESSION('sIdx') = $user('userIdx');
$_SESSION('sId') = $user('userId');
$_SESSION('sName') = $user('userName');
$_SESSION('sPW') = $user('userPw');
$_SESSION('sEmail') = $user('userEmail');
mysqli_close($con);
echo "
<script>
location.href = \"./main.php\";
</script>
";
}
?>
현재 사용자의 ID 테스트 1그런데 비밀번호를 모르겠습니다. SQL Injection 취약점을 통해 로그인하자!!
- test’#!!!를 사용하여 성공적으로 우회
- test’or’1’=’1을 사용한 성공적인 우회!!!
- ‘ Union select ‘1’,’1′,’1′,’1′,’1′ # 바이패스 성공!!!
- 비밀번호 쪽을 이용해서 ‘or’1’=’1 을 사용했는데 실패!!
- 사용자가 입력한 비밀번호가 바로 선택되는 것이 아니라 해시로 암호화되어 입력되기 때문에!!
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Login6 (Case2, 해쉬함수 사용!!)
- 식별 후 인증을 진행하고, 인증 전 사용자의 비밀번호를 해시함수를 이용하여 암호화하여 비교합니다.
<?php
session_start();
include('./connect.php');
$userId = $_POST('userId');
$userPw = $_POST('userPw');
$salt="$5$QOPrAVIK"."$userId".'$';
$hashPw = crypt($userPw, $salt);
$sql = "select * from userTestTB where userId='$userId';";
$rst = mysqli_query($con, $sql);
$id = mysqli_num_rows($rst);
if(!$id){
echo "
<script>
alert(\"메롱\");
history.back();
</script>
";
exit;
}else{
$user = mysqli_fetch_array($rst);
$db_pw = $user('userPw');
if($db_pw == $hashPw){
$_SESSION('sIdx') = $user('userIdx');
$_SESSION('sId') = $user('userId');
$_SESSION('sName') = $user('userName');
$_SESSION('sPW') = $user('userPw');
$_SESSION('sEmail') = $user('userEmail');
mysqli_close($con);
echo "
<script>
location.href = \"./main.php\";
</script>
";
}else{
echo "
<script>
alert(\"메롱!!\");
history.back();
</script>
";
exit;
};
};
?>
현재 사용자의 ID 테스트 1그런데 비밀번호를 모르겠습니다. SQL Injection 취약점을 통해 로그인하자!!
- test’#를 사용한 우회 실패!!!
- test’or’1’=’1도 우회 실패!!!
- ‘ union select ‘1’,’1′,’1′,’1′,’1′ # 우회 실패!!!
- 비밀번호 쪽을 이용해서 ‘or’1’=’1 을 사용했는데 실패!!
- 위와 같이 사용자가 입력한 비밀번호는 바로 선택되는 것이 아니라 해시로 암호화하여 입력!!
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Login7 (테이블 2개로 로그인)
- 회원가입 시 모든 정보는 메인 테이블에 저장되며, 서브 테이블에는 회원 아이디와 비밀번호만 저장됩니다.
- 로그인 시 사용자의 아이디와 비밀번호를 서브 테이블과 비교하여 변수로 저장하고 메인 테이블 변수와 비교한다.
<?php
session_start();
include('./connect.php');
$userId = $_POST('userId');
$userPw = $_POST('userPw');
// 서브 테이블과 비교
$cmpsql = "select * from usercmpTB where userId='$userId' and userPw='$userPw';";
$cmprst = mysqli_query($con, $cmpsql);
$cmpuser = mysqli_fetch_array($cmprst);
$cmpId = $cmpuser('userId');
$cmpPw = $cmpuser('userPw');
// 메인 테이블의 정보와 서브테이블 정보 비교
$sql = "select * from userTestTB where userId='$cmpId' and userPw='$cmpPw';";
$rst = mysqli_query($con, $sql);
$id = mysqli_num_rows($rst);
if(!$id){
echo "
<script>
alert(\"메롱\");
history.back();
</script>
";
exit;
}else{
$user = mysqli_fetch_array($rst);
$db_pw = $user('userPw');
if($db_pw == $userPw){
$_SESSION('sIdx') = $user('userIdx');
$_SESSION('sId') = $user('userId');
$_SESSION('sName') = $user('userName');
$_SESSION('sPW') = $user('userPw');
$_SESSION('sEmail') = $user('userEmail');
mysqli_close($con);
echo "
<script>
location.href = \"./main.php\";
</script>
";
}else{
echo "
<script>
alert(\"메롱!!\");
history.back();
</script>
";
exit;
};
};
?>
현재 사용자의 ID cmp 그런데 비밀번호를 모르겠습니다. SQL Injection 취약점을 통해 로그인하자!!
- test’#를 사용한 우회 실패!!!
- test’or’1’=’1도 바이패스 실패!!!
- ‘ union select ‘1’,’1′ # 사용했는데 우회 실패!!!
- 하위 테이블에는 두 개의 열이 있으며 실패 이유는 하위 테이블과 기본 테이블의 정보가 다르기 때문입니다.
- 비밀번호 쪽을 이용해서 ‘or’1’=’1 을 사용했는데 실패!!
- 서브 테이블이 참이라도 메인 테이블 비밀번호와 다르기 때문에 실패!!
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
사용된 테이블 정보
# 메인 테이블
create table userTestTB(
userIdx int primary key auto_increment,
userId varchar(100) unique not null,
userName varchar(100) not null,
userPw varchar(200) not null,
userEmail varchar(100) not null
);
# 서브 테이블
create table usercmpTB(
userId varchar(100) unique not null,
userPw varchar(200) not null,
);
![]() |
![]() |
<- Write the login logic as you think!!! Keep looking for SQL injection vulnerabilities!!->