SQL Injection
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
RootedCON은 스페인에서 가장 관련성이 높은 사이버 보안 이벤트이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술 지식을 촉진하는 임무를 가지고 있는 이 회의는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
SQL injection은 공격자가 애플리케이션의 데이터베이스 쿼리에 간섭할 수 있게 해주는 보안 결함입니다. 이 취약점은 공격자가 접근해서는 안 되는 데이터, 즉 다른 사용자의 정보나 애플리케이션이 접근할 수 있는 모든 데이터를 조회, 수정 또는 삭제할 수 있게 할 수 있습니다. 이러한 행동은 애플리케이션의 기능이나 콘텐츠에 영구적인 변경을 초래하거나 서버의 손상 또는 서비스 거부를 초래할 수 있습니다.
사이트가 SQLi 관련 입력에 대한 비정상적인 서버 응답으로 인해 **SQL injection (SQLi)**에 취약한 것으로 보일 때, 첫 번째 단계는 쿼리를 방해하지 않고 데이터 주입 방법을 이해하는 것입니다. 이는 현재 컨텍스트에서 효과적으로 벗어나는 방법을 식별하는 것을 요구합니다. 다음은 유용한 몇 가지 예입니다:
그런 다음, 오류가 없도록 쿼리를 수정하는 방법을 알아야 합니다. 쿼리를 수정하기 위해 데이터를 입력하여 이전 쿼리가 새 데이터를 수용하도록 하거나, 그냥 데이터를 입력하고 끝에 주석 기호를 추가할 수 있습니다.
쿼리가 작동할 때와 작동하지 않을 때 오류 메시지를 볼 수 있거나 차이를 발견할 수 있다면 이 단계는 더 쉬울 것입니다.
SQL 인젝션 취약점을 확인하는 신뢰할 수 있는 방법은 논리 연산을 실행하고 예상 결과를 관찰하는 것입니다. 예를 들어, ?username=Peter
와 같은 GET 매개변수를 ?username=Peter' or '1'='1
로 수정했을 때 동일한 콘텐츠가 생성된다면, 이는 SQL 인젝션 취약점을 나타냅니다.
마찬가지로, 수학적 연산의 적용은 효과적인 확인 기법으로 작용합니다. 예를 들어, ?id=1
과 ?id=2-1
에 접근했을 때 동일한 결과가 생성된다면, 이는 SQL 인젝션을 나타냅니다.
논리 연산 확인을 보여주는 예:
이 단어 목록은 제안된 방법으로 SQL 주입을 확인하기 위해 생성되었습니다:
일부 경우에는 테스트 중인 페이지에서 변화를 감지하지 못할 수 있습니다. 따라서 블라인드 SQL 주입을 발견하는 좋은 방법은 DB가 작업을 수행하게 하여 페이지 로드에 시간에 영향을 미치게 하는 것입니다. 따라서 SQL 쿼리에 완료하는 데 많은 시간이 걸리는 작업을 연결할 것입니다:
일부 경우에 sleep 함수가 허용되지 않을 수 있습니다. 그런 경우, 이러한 함수를 사용하는 대신 쿼리를 복잡한 작업을 수행하도록 만들어 여러 초가 걸리게 할 수 있습니다. 이러한 기술의 예는 각 기술에 대해 별도로 설명될 것입니다 (있는 경우).
백엔드를 식별하는 가장 좋은 방법은 다양한 백엔드의 함수를 실행해보는 것입니다. 이전 섹션의 sleep 함수 또는 다음의 함수들을 사용할 수 있습니다 (table from payloadsallthethings:
또한, 쿼리의 출력에 접근할 수 있다면, 데이터베이스의 버전을 출력할 수 있습니다.
우리는 다양한 종류의 SQL Injection을 악용하는 방법에 대해 논의할 것입니다. MySQL을 예로 사용할 것입니다.
쿼리의 출력을 볼 수 있다면, 이것이 가장 좋은 방법입니다. 우선, 초기 요청이 반환하는 열의 수를 알아내야 합니다. 이는 두 쿼리가 동일한 수의 열을 반환해야 하기 때문입니다. 이 목적을 위해 일반적으로 두 가지 방법이 사용됩니다:
쿼리의 열 수를 결정하기 위해, ORDER BY 또는 GROUP BY 절에서 사용된 숫자를 점진적으로 조정하여 잘못된 응답이 수신될 때까지 진행합니다. SQL 내에서 GROUP BY와 ORDER BY의 기능이 다르지만, 두 가지 모두 쿼리의 열 수를 확인하는 데 동일하게 활용될 수 있습니다.
쿼리가 올바를 때까지 더 많은 null 값을 선택합니다:
null
값을 사용해야 합니다. 경우에 따라 쿼리 양쪽의 열 유형이 동일해야 하며 null은 모든 경우에 유효합니다.
다음 예제에서는 모든 데이터베이스의 이름, 데이터베이스의 테이블 이름, 테이블의 열 이름을 검색합니다:
모든 데이터베이스에서 이 데이터를 발견하는 방법은 다르지만, 항상 동일한 방법론입니다.
쿼리의 출력이 보이지만 유니온 기반 주입이 불가능한 경우, 이는 숨겨진 유니온 기반 주입의 존재를 나타냅니다. 이 시나리오는 종종 블라인드 주입 상황으로 이어집니다. 블라인드 주입을 유니온 기반으로 변환하려면 백엔드에서 실행되는 쿼리를 파악해야 합니다.
이는 블라인드 주입 기술과 대상 데이터베이스 관리 시스템(DBMS)에 특정한 기본 테이블을 사용하여 수행할 수 있습니다. 이러한 기본 테이블을 이해하기 위해서는 대상 DBMS의 문서를 참조하는 것이 좋습니다.
쿼리가 추출되면, 원래 쿼리를 안전하게 종료하도록 페이로드를 조정해야 합니다. 그 후, 유니온 쿼리를 페이로드에 추가하여 새로 접근 가능한 유니온 기반 주입을 활용할 수 있습니다.
더 포괄적인 통찰력을 원하시면 Healing Blind Injections에서 제공되는 전체 기사를 참조하세요.
어떤 이유로 쿼리의 출력을 볼 수 없지만 오류 메시지는 볼 수 있는 경우, 이 오류 메시지를 사용하여 데이터베이스에서 데이터를 유출할 수 있습니다. 유니온 기반 활용과 유사한 흐름을 따라 DB를 덤프할 수 있습니다.
이 경우 쿼리의 결과나 오류를 볼 수 없지만, 쿼리가 true 또는 false 응답을 return할 때 페이지의 내용이 다르기 때문에 이를 구별할 수 있습니다. 이 경우, 이 동작을 악용하여 데이터베이스를 문자 단위로 덤프할 수 있습니다:
이것은 이전과 동일한 경우이지만 쿼리의 true/false 응답을 구분하는 대신 SQL 쿼리에서 오류가 있는지 여부를 구분할 수 있습니다(아마도 HTTP 서버가 중단되기 때문입니다). 따라서 이 경우 올바른 문자를 추측할 때마다 SQL 오류를 강제로 발생시킬 수 있습니다:
이 경우에는 페이지의 맥락에 따라 쿼리의 응답을 구분할 수 있는 방법이 없습니다. 그러나 추측한 문자가 올바른 경우 페이지가 더 오래 로드되도록 만들 수 있습니다. 우리는 이미 타이밍을 사용하여 SQLi 취약점 확인하는 이 기술을 이전에 보았습니다.
스택 쿼리를 사용하여 여러 쿼리를 연속으로 실행할 수 있습니다. 후속 쿼리가 실행되는 동안 결과는 응용 프로그램에 반환되지 않습니다. 따라서 이 기술은 주로 블라인드 취약점과 관련하여 사용되며, 두 번째 쿼리를 사용하여 DNS 조회, 조건부 오류 또는 시간 지연을 트리거할 수 있습니다.
Oracle은 스택 쿼리를 지원하지 않습니다. MySQL, Microsoft 및 PostgreSQL은 이를 지원합니다: QUERY-1-HERE; QUERY-2-HERE
다른 취약점 이용 방법이 작동하지 않는 경우, 데이터베이스가 정보를 외부 호스트로 유출하도록 시도할 수 있습니다. 예를 들어, DNS 쿼리를 통해:
sqlmap을 사용하여 SQLi 취약점을 악용하는 방법은 SQLMap Cheatsheet를 확인하세요.
우리는 이미 SQL Injection 취약점을 악용하는 모든 방법에 대해 논의했습니다. 이 책에서 데이터베이스 기술에 따라 몇 가지 더 많은 트릭을 찾아보세요:
또한 **https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**에서 MySQL, PostgreSQL, Oracle, MSSQL, SQLite 및 HQL에 관한 많은 트릭을 찾을 수 있습니다.
RootedCON은 스페인에서 가장 관련성이 높은 사이버 보안 이벤트이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술 지식을 촉진하는 사명을 가지고 이 컨그레스는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
로그인 기능을 우회하기 위해 시도할 목록:
Login bypass List이 쿼리는 인증 검사에서 원시 출력을 위해 true와 함께 MD5가 사용될 때 취약점을 보여줍니다. 이로 인해 시스템이 SQL 인젝션에 취약해집니다. 공격자는 해시될 때 예상치 못한 SQL 명령 부분을 생성하는 입력을 조작하여 이를 악용할 수 있으며, 이로 인해 무단 접근이 발생할 수 있습니다.
추천 목록:
각 줄의 목록을 사용자 이름으로 사용하고 비밀번호는 항상: Pass1234. &#xNAN;(이 페이로드는 이 섹션의 시작 부분에 언급된 큰 목록에도 포함되어 있습니다)
IF '가 이스케이프되고 있다면 %A8%27을 사용할 수 있으며, '가 이스케이프되면 다음이 생성됩니다: 0xA80x5c0x27 (╘')
Python 스크립트:
이를 위해 "마스터 객체"(사용자의 경우 admin)라는 이름의 새 객체를 생성하려고 시도해야 합니다. 다음을 수정합니다:
이름이 AdMIn인 사용자 생성 (대문자 및 소문자)
이름이 **admin=**인 사용자 생성
SQL Truncation Attack (사용자 이름 또는 이메일에 길이 제한이 있을 때) --> 이름이 admin [많은 공백] a인 사용자 생성
데이터베이스가 취약하고 사용자 이름의 최대 문자 수가 예를 들어 30일 때, admin 사용자를 가장하려면: "admin [30 공백] a"라는 사용자 이름을 생성해 보십시오. 그리고 아무 비밀번호나 입력합니다.
데이터베이스는 입력된 사용자 이름이 데이터베이스에 존재하는지 확인합니다. 존재하지 않으면, 사용자 이름을 허용된 최대 문자 수로 잘라냅니다(이 경우 "admin [25 공백]"로) 그리고 데이터베이스 내에서 사용자 "admin"의 새 비밀번호로 자동으로 모든 공백을 제거합니다(오류가 발생할 수 있지만, 이것이 작동하지 않았다는 의미는 아닙니다).
자세한 정보: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref
참고: 이 공격은 최신 MySQL 설치에서 위와 같이 더 이상 작동하지 않습니다. 비교는 여전히 기본적으로 후행 공백을 무시하지만, 필드의 길이보다 긴 문자열을 삽입하려고 하면 오류가 발생하고 삽입이 실패합니다. 이 확인에 대한 자세한 정보는: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation
VALUES 문을 종료하기 위해 필요한 만큼 ','',''
를 추가하십시오. 지연이 실행되면 SQLInjection이 있습니다.
MySQL의 ON DUPLICATE KEY UPDATE
절은 UNIQUE 인덱스 또는 PRIMARY KEY에서 중복 값이 발생하는 행을 삽입하려고 할 때 데이터베이스가 수행할 작업을 지정하는 데 사용됩니다. 다음 예제는 이 기능이 관리자의 계정 비밀번호를 수정하는 데 어떻게 악용될 수 있는지를 보여줍니다:
Example Payload Injection:
주입 페이로드는 다음과 같이 작성될 수 있으며, 두 개의 행이 users
테이블에 삽입되려고 시도됩니다. 첫 번째 행은 미끼이고, 두 번째 행은 비밀번호를 업데이트할 의도로 기존 관리자의 이메일을 대상으로 합니다:
Here's how it works:
쿼리는 두 개의 행을 삽입하려고 시도합니다: 하나는 generic_user@example.com
을 위한 것이고, 다른 하나는 admin_generic@example.com
을 위한 것입니다.
admin_generic@example.com
에 대한 행이 이미 존재하는 경우, ON DUPLICATE KEY UPDATE
절이 트리거되어 MySQL에 기존 행의 password
필드를 "bcrypt_hash_of_newpassword"로 업데이트하도록 지시합니다.
결과적으로, admin_generic@example.com
을 사용하여 bcrypt 해시에 해당하는 비밀번호로 인증을 시도할 수 있습니다 ("bcrypt_hash_of_newpassword"는 새 비밀번호의 bcrypt 해시를 나타내며, 원하는 비밀번호의 실제 해시로 대체되어야 합니다).
새로운 사용자와 사용자 이름을 생성하려고 할 때, 비밀번호와 이메일이 필요합니다:
이 기술을 사용하면 1개의 계정만 생성하여 정보를 추출할 수 있습니다. 주의할 점은 아무것도 주석을 달 필요가 없다는 것입니다.
hex2dec 및 substr 사용:
텍스트를 얻으려면 다음을 사용할 수 있습니다:
hex와 replace (그리고 substr) 사용:
RootedCON은 스페인에서 가장 관련성이 높은 사이버 보안 이벤트이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술 지식을 촉진하는 임무를 가지고, 이 컨그레스는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
Routed SQL injection은 주입 가능한 쿼리가 출력을 제공하지 않고, 주입 가능한 쿼리의 출력이 출력을 제공하는 쿼리로 전달되는 상황입니다. (From Paper)
Example:
No Space (%20) - 공백 대체를 사용한 우회
No Whitespace - 주석을 사용한 우회
No Whitespace - 괄호를 사용한 우회
No Comma - OFFSET, FROM 및 JOIN을 사용한 우회
키워드를 사용한 블랙리스트 - 대문자/소문자를 사용하여 우회
대소문자 구분 없는 키워드를 사용한 블랙리스트 - 동등한 연산자를 사용하여 우회
You can find a more in depth explaination of this trick in gosecure blog. 기본적으로 WAF를 우회하기 위해 예상치 못한 방식으로 과학적 표기를 사용할 수 있습니다:
먼저, 원래 쿼리와 플래그를 추출하려는 테이블의 열 수가 동일하다면 다음과 같이 할 수 있습니다: 0 UNION SELECT * FROM flag
열 이름을 사용하지 않고 테이블의 세 번째 열에 접근하는 것이 가능합니다 다음과 같은 쿼리를 사용하여: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
, 따라서 sqlinjection에서는 다음과 같이 보일 것입니다:
또는 comma bypass를 사용하여:
이 트릭은 https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/에서 가져왔습니다.
RootedCON은 스페인에서 가장 관련성이 높은 사이버 보안 이벤트이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술 지식을 촉진하는 임무를 가지고 있는 이 컨그레스는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)