728x90

1. XSS, CSRF 차이점

 

1) XSS 

: 공격자에 의해 작성된 스크립트가 다른 사용자에게 전달되는 것으로, 다른 사용자의 웹 브라우저 내에서 적절한 검증 없이 실행되어 발생하는 취약점이다.

: 공격자가 작성한 스크립트를 통해 정상 사용자의 세션을 탈취하거나, 웹 사이트를 변조, 악의적인 사이트로 사용자를 이동시킬 수 있다.

 

Reflected XSS Stored XSS
매개변수를 통해 입력 받은 값을 다시 출력해주는 로직이 있을 때 발생하는 취약점
텍스트 입력창에 단순한 텍스트가 아닌 경고문을 출력하는 스크립트를 입력한 경우 스크립트가 실행되면 취약점이 존재
게시물에 악성 스크립트를 삽입함으로써 다른 사용자가 게시물을 열람하였을 때, 해당 브라우저에서 스크립트가 실행되고, 그때 발생한 쿠키 및 세션 정보를 공격자가 얻는 공격이다.

 

1-1) XSS 공격 대응 방안

(1) 입력 값 제한

: 사용자의 입력 값을 제한하여 스크립트를 삽입하지 못하도록 한다.

(2) 입력 값 치환

: XSS 공격은 기본적으로 <script> 태그를  사용하기 때문에 XSS 공격을 차단하기 위해 태그문자(<,>)등 위험한 문자 입력 시 필터링 하거나 인코딩 시킨다.

 

2) CSRF

: XSS 취약점과 유사하게 사용자의 입력 값 검증 및 사용자의 요청 시 세션 쿠키, 출발지 주소 등 올바르게 요청된 것인지 검증을 하지 않았을 경우 발생한다. 공격은 불특정 다수를 대상으로 진행된다.

 

2-1) CSRF  공격 대응 방안

(1) Referrer 검증

:요청 헤더에 있는 referrer 속성을 검증하여 신뢰할 수 있는 도메인에서 들어오는 요청인지 검색

(2) CSRF 토큰 사용 

: 랜덤한 수를 사용자의 세션에 저장하여 사용자의 모든 요청에 대해 서버단에서 검증하는 방법

 

 

3) XSS vs CSRF

: XSS 와 CSRF 공격의 큰 차이점은 공격이 실행되는 위치이다.

XSS CSRF
사용자 PC (클라이언트) 에서 실행되어 사용자의 정보 탈취 사용자 PC (클라이언트) 에서 실행되어 사용자의 정보 탈취

 

 

2. XSS Lv3, Lv4

1) XSS Lv3

Level 3번 문제에서 먼저 각각의 이미지를 눌렀을 때 URL부분에 #뒤 숫자가 변하는 것을 확인 할 수 있다.

 

위의 코드를 보면, 각각의 버튼은 클릭 시 chooseTab() 함수로 값을 보낸다는 걸 확인 할 수 있다.

 

주어진 4개의 힌트를 번역하자면 아래 내용과 같다.
 

1. 버그의 원인을 찾으려면 JavaScript를 검토하여 사용자가 제공한 입력을 처리하는 위치를 확인한다.
2. window.location 개체의 데이터는 공격자의 영향을 받을 수 있다.
3. 주입 지점을 파악한 후, 새로운 HTML 요소를 몰래 삽입하기 위해 무엇을 해야 하는지 생각해 봐라.
4. 이전과 같이 <script> ...를 페이로드로 사용하면 페이지가 로드된 후 추가된 스크립트를 브라우저에서 실행할 수 없다.

 

self.location.hash.substr(1) 은 url 의 # 부분에 있는 값을 가져오게 된다. 따라서 url 에 값을 입력하게 되면 chooseTab() 을 통해 화면에 출력할 수 있다.

 

다음으로 chooseTab() 을 통해 전달된 num 를 통해 html 변수에 num.jpg 를 넣어주고 있는 것을 확인 할 수 있다. 이는 num 의 값을 통해 결과가 출력되는 것으로 3번 힌트를 참고하자면 html에 새로 추가해서 문제를 풀 수 있다고 유추할 수 있다.

 html += "<img src='/static/level3/cloud" + num + ".jpg' />";

 

onerror 를 통해 alert() 를 실행하는 방법을 이용해서 num 부분에 없는 파일을 넣게 되면 아래 사진과 같이 문제가 해결 되었음을 확인 할 수 있다. 

(onerorr : 외부에서 파일을 로드하는 중 에러가 발생할 경우 대체 목적으로 실행되는 이벤트)

 

URL: https://xss-game.appspot.com/level3/frame#4' onerror="alert(1)"> 

 

2) XSS Lv4

아래 버튼을 클릭하면 타이머가 동작되는데 이때 URL에 timer 변수로 3 값이 전달되고 있음을 확인할 수 있다

index.html

아래 코드를 확인하면 get 방식으로 timer 변수가 넘어가는 걸 알 수 있다. 이것으로 URL에 timer=3으로 입력해도 동일하게 타이머가 동작됨을 확인할 수 있다. 

timer.html

여기 코드를 보게 되면 img 태그 부분에 onload 부분에 timer 값이 들어가게 되는 것을 확인할 수 있는데, 이 부분을 ㅅ수정을 하게 되면 원하는 값을 얻을 수 있을 거라유추할 수 있다.

 

{{ timer }} 로 변수 입력 되므로 이 부분을 timer=1');alert('attack 값으로 수정해서 전달하게 되면 아래와 같이 문제가 해결되었음을 확인 할 수 있다.

이때 주의해야할 부분은 URL에 직접입력하는 것으로 세미콜론(;) 을 %3B로 바꿔서 입력해줘야 한다.

'자기개발 > Web' 카테고리의 다른 글

[2022 리버싱: Day 18] 패킹과 언패킹  (0) 2022.02.21
[ 웹스터디 5주차 ]  (0) 2021.11.23
[ 웹 스터디 3주차 ]  (0) 2021.11.07
[ 웹 스터디 2주차 ]  (0) 2021.09.28
[ 웹 스터디 1주차 ]  (0) 2021.09.14
728x90

1. SQL Injection 공격/ 대응 방안 문서화

SQL Injection 이란?
: 악의적으로 보안 상의 취약점을 이용해, 임의의 SQL 문을 주입하고 실행하게 해 데이터베이스가 비정상적인 동작을 하도록 조작하는 공격 기법이다.

SQL 연산자
OR 
AND
like 
||
&&
=
SQL 문자열
'
?변수=값
;
문자 데이터 구분기호
url 매개변수
쿼리 구분 기호
SQL 주석
--
#
/* */
뒤에 공백이 있어야 주석처리 가능
뒤에 공백 없어도 주석처리 가능
(url에서 쓸 땐 %23으로 사용)
/*와􀀁*/사이 문자열 주석처리 가능


 SQLi 공격 과정 
1) 취약한 SQL 기반 웹 사이트을 식별하고 입력 데이터를 이용해 악의적인 SQL 쿼리를 주입한다.

2) 악의적인 SQL 쿼리는 검증되고 데이터 베이스에 의해 명령 실행된다.

3) 해커는 관리자 권한을 부여 받을 수 있게 된다.
 


SQL Injection 공격 기법
1. in-band SQLi 대역 내 SQLi

(1) Error based
: 쿼리에 고의적으로 오류를 발생시켜 시스템 권한 체크를 우회하는 공격 기법
: Error based 공격은 로그인 창에서 나타나기도 한다. 


[ webhacking.kr old 39 문제 풀이 ] 

먼저 ID에 admin 입력, PASSWD에 ‘or 1=1-- 입력해준다.

이때 --은 주석처리 이므로 user_id = ‘”&User ID&”’ and passwd=’”&passwd &”’ “ 여기서 ‘”이 주석처리 된다. 

-- 주석 처리로 인해 뒤에 쿼리가 무시되어 1=1에 대한 OR 연산도 추가가 되어 존재하는 계정으로 로그인 됩니다.


(2) Union based
: Union 연산자를 이용해 원래의 요청에 추가 query를 삽입하는 공격 기법

+ union: 두 개의 쿼리를 보낼 수 있는 연산자
unionall:조회되는 데이터 중 중복행을 제거하지 않는다.
문제점 : 조회되는 컬럼 수가 동일해야만 한다.

 
- union based 공격 과정
1) 칼럼 수 찾기
order by n 이용하여 n번째 컬럼으로 오름차순 정렬 후 n번 째 컬럼이 없다면, 쿼리가 실행되지 않음(에러발생)

2) db+칼럼 이름 찾기
information_schema 이용하여 db의 메타 데이터*(테이블, 컬럼, 인덱스 등)를 담고 있는 데이터 사전
table_schema, table_name, column_name 칼럼 사용한다.

3) union 사용해서 정보 얻기
2단계에서 얻은 테이블의 칼럼 이름으로 정보를 얻을 수 있다.


2. blind SQLi ) 추론적 SQLi

(1) Boolean based
: 대입 값에 대한 참 또는 거짓의 결과를 서버의 응답 패턴을 통해 데이터를 유추

1.  비밀번호 직접 구하기
(1) ?pw=’ or length(pw)’l 을 통해 비밀번호의 길이(l)를 구할 수 있다.
(2)?pw=’ or substr(pw,p,1)=n%23 을 통해 각 자리(p) 해당하는 번호(n)을 구할 수 있다.

2.  코드 짜기

 

(2) Time based
: 대입 값에 대한 참 또는 거짓의 결과를 응답의 전송 시간을 이용하여 데이터를 유추한다.
timebased_sqli' or(length(database())=n and sleep(2);#-- 

 - DB길이 알아내기
database()을 통해 db이름을 반환
length()을 통해 db길이를 반환
db 길이가 n이면 뒤의 sleep(2) 실행하여 참이면 지정된 시간만큼 지연

 


3. out of band SQLi ) 대역 외 SQLi
: query의 결과를 다른 외부 채널을 통해 전달하는 기법

query의 결과를 DNS 서버에 보내기도 한다. 여기서 DNS 서버란 IP주소를 사람이 이해하기 쉽게 도메인 네임으로 변환해주는 서버이다. 
 

  • 대응 방안

1) 입력값 검증
사용자의 입력이 DB Query 에 동적으로 영향을 주는 경우, 입력된 값이 개발자가 의도한 값(요효값) 인지 검증한다.


2) 저장 프로시저 사용
저장 프로시저는 사용하자고 하는 Query 에 미리 형식을 지정하는 것으로 지정된 형식의 데이터가 아니면 Query 가 실행되지 않기 때문에 보안성을 크게 높인다.

3) 서버 보안
(1) 최소 권한 유저로 DB 운영
(2) 사용하지 않는 저장 프로시저와 내장함수 제거 또는 권한 제어
(3) 목적에 따라 Query 권한 수정
(4) 공용 시스템 객체의 접근 제어
(5) 신뢰할 수 있는 네트워크, 서버에 대해서만 접근 허용
(6) 에러 메시지 노출 차단

 


2. dreamhack simple_sqli 풀이

 

simple_sqli 문제는 admin으로 로그인을 성공했을 경우, flag 값이 뜨는 문제로 error based 유형이다. 

아래 주어진 파일을 열면 로그인 부분을 보게 되면 userid를 admin으로 바꿔서 query하면 flag를 얻을 수 있다.

[그림1] app.py

위에 파일에서 select * from users where userid="{userid}" and userpassword="{userpassword}" 이 부분에서 "{userid}"를 "admin" 으로 수정하고 My SQL 서버의 주석인 --을 사용하여 password 부분을 주석처리하면 password 값을 알지 않아도 flag를 얻을 수 있다.

 


3. Lord of SQLi gremlin, cobolt, goblin, orc 풀이

 

(1) Lord of SQLi gremlin

 

gremlin 문제를 누르게 되면 아래와 같은 php 언어로 된 코드들이 나온다. 

php 코드는 SQL 쿼리문을 이용해 id와 pw가 일치한지 확인하는 코드로 get 방식($_GET)을 이용하여 데이터 값을 받아 도메인의 뒤에 값을 주어 변수 값을 수정하면 된다.  

주소창에 ?id=admin%27%23 을 적으면 문제가 해결된다. 이는 pw를 주석처리 하는 것으로 id=admin' 이고 pw는 주석처리 되어 무시가 되는 쿼리문이 된다. 여기서 SQL 주석에 따르면 %27은 ', %23은 #으로 #은 쿼리문을 주석처리 할 때 사용한다.

 

(2) Lord of SQLi cobolt

 

gremlin 문제와 동일하게 문제를 누르면 아래 php 코드가 나타난다. 아래 php 코드에서 id가 admin이 되게끔 하면 문제가 풀린다는 것을 알 수 있다. gremlin 문제와 유사하게 id를 admin으로 참이 되게 하고 pw를 주석처리를 하게 된다면 문제는 풀리게 된다. 

if($result['id'] == 'admin'solve("cobolt");

 

(3) Lord of SQLi goblin

 

php 코드를 읽어봤을 때, id= admin 일때, goblin이 해결된다고 나와 있고, get 방식으로 no 값을 받을 수 있다.

먼저 no에 1을 넣었을 때 guest가 출력된 것을 보아 no=1이 guest 번호임을 알 수 있었다.

주소창에 no=0 or id='admin' 을 넣었지만 아래 화면이 출력되었다.

no=0 은 guest 조건에서 벗어나기 위함이고, id가 admin일 경우 문제가 해결되는 점에서 작성했지만 답안이 아니었다.

url 인코딩은 인터넷을 통해 전송 될 수 있는 포맷으로 문자를 변환하는 것으로 ASCII 문자 집합을 유효한 형식으로 변환하고, 보안 상 안전하게 변환하기 위해 16진수(hex값)으로 변환해야 한다.

 

id=admin인 문자열을 url 에 인코딩하려면 admin을 16진수로 변환하여 값을 인코딩해야 함을 알게 되었다. 

admin의 핵사값은 61646d696e 로 16진수를 사용할 때는 앞에 0x를 붙여서 써야한다.

 

주소창에 no=0||id=0x61646d696e 넣은 결과 문제가 해결되었다.

 

 

(4) Lord of SQLi orc

 

boolean based 공격 기법이라는 것을 알 수 있는 부분이 if($result['id']) echo "<h2>Hello admin</h2>";  

로 id 값이 admin일 경우 Hello admin을 출력하게 된다. 

if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc"); 

문제를 해결하기 위한 조건으로 get 방식으로 pw를 입력해서 $result['pw'] 값을 직접 구해야 한다는 것을 알 수 있다.

 

두 가지 방법 중 비밀번호를 직접 구하는 방법으로 문제를 해결하고자 한다.

 

첫 번째로 비밀번호의 길이를 먼저 구해야 한다.

?pw=' or length(pw)='l  

l이 pw의 길이로 숫자를 대입한 결과 8을 넣었을 때 hello admin 이 출력되는 것으로 보아 pw 는 8자리이다.

두 번째로 각 자리(p) 해당하는 번호(n)을 구하는 거로 

?pw=' or substr(pw, p, 1)=n%23

여기서 1은 자르고자 하는 길이로 하나씩 pw 번호를 알게 된다.

p는 pw가 8자리이기 때문에 1~8이고, n은 해당하는 숫자를 대입하여 맞다면 hello admin 이 출력되는 것으로 8자리 pw를 알 수 있다.

 

대입한 결과 ?pw=095a9852 로 orc 문제가 해결된다.

'자기개발 > Web' 카테고리의 다른 글

[2022 리버싱: Day 18] 패킹과 언패킹  (0) 2022.02.21
[ 웹스터디 5주차 ]  (0) 2021.11.23
[ 웹 스터디 4주차 ]  (0) 2021.11.16
[ 웹 스터디 2주차 ]  (0) 2021.09.28
[ 웹 스터디 1주차 ]  (0) 2021.09.14

+ Recent posts