일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- N0Named
- Python
- 구현
- xcz.kr
- MySQL
- 사칙연산
- 정렬
- 그리디 알고리즘
- HackCTF
- Forensics
- CTF
- cryptography
- 써니나타스
- php
- 문자열
- C
- Text
- SuNiNaTas
- Network
- Incognito
- Digital Forensics
- 수학
- Database
- Web
- 인코그니토
- Web Hacking
- wargame
- writeup
- misc
- 백준
- Today
- Total
보안을 그리다, 훈이
[Web Hacking] SQL Injection 실습 본문
이전에 포스팅한 [Web Hacking] SQL Injection 취약점을 토대로 실습을 진행해보았다.
[SQL Injection 실습]
- Error based SQL Injection
논리적 에러를 이용한 SQL Injection 기법으로, 입력값에 대한 검증이 없을 시 참값과 주석을 활용하여 세션을 탈취할 수 있다.
//입력된 아이디가 DB에 존재하는지 검사
$query = "select * from member where id='$id'";
$result = $connect->query($query);
앞서 제작한 게시판 웹페이지 중 [login_action.php] 페이지의 일부 소스코드를 가져왔다.
사용자가 입력한 아이디가 DB의 id 컬럼에 존재하면 그 값에 대한 전체 속성값을 가져오는 쿼리문을 통해 id 존재 여부를 파악하게 되는데, 입력값에 대한 검증이 존재하지 않기 때문에 이 부분을 악용하여 모든 권한을 가진 관리자 세션을 탈취할 수 있다.
//아이디가 있다면 비밀번호 검사
if (mysqli_num_rows($result)) { //($result) == 1 에서 수정!
$row = mysqli_fetch_assoc($result);
//비밀번호가 맞다면 세션 생성
if ($row['password'] == $pw) { //password 평문비교 취약!
$_SESSION['userid'] = $row['id'];
필자가 구현한 소스코드는 위와 같이 id와 password 검증 과정이 따로 발생한다. 즉, 입력한 id 값이 속해있는 튜플의 password 속성값을 password 입력값과 비교하기 때문에, id 입력 폼을 통한 탈취만 시연하도록 하겠다.
$query = "select * from member where id='$id'";
다시 입력한 id 값과 일치하는 DB 내 튜플의 전체 속성값을 불러오는 쿼리문을 살펴보면 where 절을 참으로 만들면 취약점이 발생하게 된다는 것을 알 수 있다.
로그인 페이지의 id 입력 폼에 필자가 주입한 임의의 SQL 구문은 ' OR 1=1 -- 이다. 주석처리 이후엔 꼭 띄어쓰기를 해야된다. 안 했다간 저처럼 고생합니다ㅜㅜ
여튼 저 구문을 쿼리문에 주입해보면..
$query = "select * from member where id='' OR 1=1 -- '";
이렇게 된다. ' OR 1=1 -- 에서 첫 싱글쿼터(')는 앞에 생성된 싱글쿼터를 닫아주는 역할을 하고 OR 연산자로 두 개의 식 중 하나만 참이면 결과값은 참이 되도록 한다. 1=1은 역시 참이며 뒤의 주석처리( -- )는 뒤에 생성된 싱글쿼터를 주석처리하여 식에 오류가 생기지 않도록 한다. 따라서 where 절은 참이 되며 첫 번째로 생성된 관리자 계정 계정을 탈취할 수 있다.
위와 같이, hooneee 계정의 permit = 1을 보면 모든 권한이 주어져있으며 관리자 계정인 것을 유추할 수 있다.
일반적으로 가장 먼저 생성된 계정은 많은 권한이 주어진 관리자 계정일 확률이 크기 때문에 SQL Injection에 대한 대응처리가 미비하다면 악의적인 사용자로 하여금 DB의 모든 자료에 접근, 생성 및 수정, 삭제까지도 할 수 있는 기회를 제공하는 것이다.
만약 그 정보가 고객들의 개인정보라면, 탈취한 개인정보를 유출한다면 더욱 심각한 상황에 직면할 수 있기에 개발 초기부터 경각심을 가지고 보안사항을 언제나 고려하고 관리해나가야 된다.
실제로 필자가 구현한 페이지에서 실습해보면,
id 값에 ' OR 1=1 -- 을 입력했음에도 불구하고, 왼쪽 상단을 보면 'hooneee님 반갑습니다.' 라며 환영인사를 해준다. 재미있다...
$query = "select * from member where id='$id' && pw='$pw'";
만약 쿼리문이 위와 같이 입력된 id 값과 pw 값이 && 연산자를 통해 한 쿼리문 내에서 조회된다면,
$query = "select * from member where id='' OR 1=1-- ' && pw='$pw'";
이처럼 ' OR 1=1 -- 의 주석처리를 사용하여 && 이후 구문인 pw 절까지 무효화시킬 수 있다. 또한 ' OR '1'='1' -- 도 참 값이므로 가능하며 다른 식을 사용해도 무방하다. pw 값을 입력 하지 않아도 관리자 계정으로 로그인됨을 확인할 수 있었다.
'Security > Web Hacking' 카테고리의 다른 글
[Web Hacking] XSS(Cross-Site Scripting) 실습 (0) | 2021.10.27 |
---|---|
[Web Hacking] XSS Cheat Sheet (0) | 2021.10.27 |
[Web Hacking] XSS(Cross-Site Scripting) 취약점 (0) | 2021.10.25 |
[Web Hacking] 2021 OWASP Top 10 목록 (0) | 2021.10.19 |
[Web Hacking] SQL Injection 취약점 (1) | 2021.05.10 |