본문 바로가기

코딩(Coding)

SQL 인젝션으로 웹 해킹하는 방법

반응형

SQL 인젝션으로 웹 해킹하는 방법

 

SQL 주입, PHP 및 Diwa 프로젝트에 중점

Unsplash의 Caspar Camille Rubin 사진

나는 항상 해커가 되고 싶었다. 6년 동안 저는 Php, JavaScript 및 Python으로 응용 프로그램을 작성했습니다. 제가 공부하는 동안 선생님들은 SQL 인젝션과 이를 방지하는 방법에 대해 이야기했습니다. 하지만 SQL Injection, Broken Authentication, Cross-Site Scripting과 같은 공격은 해본 적이 없습니다. 그것은 내 지식에서 누락된 부분이었고 나는 그들에 대해 더 많이 배울 수 있는 기회를 찾고 있었습니다. 그래서 우리 팀의 누군가가 최근에 나에게 와서 연구를 제안했을 때 나는 지구상에서 가장 행복한 사람이었습니다.

이 게시물에는 후속 조치가 있습니다. 웹을 해킹하고, 보안 침해에 대해 배우고, 많은 재미를 느끼는 것은 단지 시작에 불과합니다. 이 포스트에서는 특정 유형의 인젝션인 SQL 인젝션에 대해 이야기하겠습니다. 나는 역사를 다루고, 안과 밖을 설명하고, 공격을 수행하고, 애플리케이션을 보호할 수 있는 방법을 알려줄 것입니다. 우리는 PHP와 MySQL을 사용할 것입니다. 다른 프로그래밍 언어를 사용하는 경우 더 많은 콘텐츠가 제공될 예정입니다.

이제 모자를 쓰고 좋아하는 전자 음악 재생 목록을 실행하고 해킹을 시작합시다!

출처: avast.com

SQL 인젝션에 대해 이야기하기 전에 먼저 인젝션에 대해 이야기합시다. 주사는 가장 오래되고 일반적인 공격 중 하나입니다. 인젝션 공격은 네트워크에 주입되는 악성 코드로 데이터베이스에서 정보를 가져오는 것이 목표입니다. 웹 응용 프로그램(Php 응용 프로그램뿐만 아니라)을 대상으로 하며 데이터 도난 또는 손실로 이어질 수 있습니다. 최악의 시나리오에서는 전체 시스템을 손상시킬 수 있습니다. 더 이상 로그인하고 서비스에 액세스할 수 없습니다. 다시 말해 이것은 나쁘다. 정말 정말 나쁘단 말이에요. 병원을 운영하고 있고 수백 명의 환자가 수술을 기다리고 있으며 보안 번호, 이메일 및 기타 민감한 정보를 기록하고 있다고 상상해 보십시오. 주입은 전체 시스템을 차단할 수 있으며 해커는 이 정보를 얻고, 판매하고, 사용할 수 있습니다. SQL 주입, 교차 사이트 스크립팅 또는 CRLF 주입과 같은 다양한 범주의 주입이 있습니다. 이 문서는 SQL 주입에 중점을 둡니다.

글쎄, 주된 이유는 불충분한 사용자 입력 유효성 검사입니다. 즉, 코드가 개발자 측에서 안전하지 않고 쿼리가 안전하지 않음을 의미합니다. 이를 수정하려면 동적 쿼리 사용을 중지하고 쿼리가 실행될 때 코드를 보호해야 합니다. 이것이 우리가 SQL 주입을 방지하기 때문에 PHP에서 준비된 요청을 사용하는 이유입니다.

위의 코드는 Diwa 프로젝트에서 가져온 것으로 model.php 파일에 있습니다. 16행을 보세요. 보안 침해가 발생한 곳입니다. 이 코드 줄은 SQL에서 다음 문을 실행합니다.

'SELECT * FROM users WHERE email = ‘$email’ AND password = ‘$password’;'

이 줄의 목적은 사용자가 데이터베이스에 있는지 확인하고 이 경우 반환하는 것입니다. 양식 내부에서 공격자는 다음을 작성할 수 있습니다. 'OR '1'='1'' 다음 쿼리를 실행합니다.

'SELECT * FROM users WHERE email = ‘$email’ AND password = ‘$password’ OR ‘`1’ = ‘1’’;'

이것은 유효한 SQL 문이며 이후 '1'='1' `'1' = '1'`은 항상 true이고 쿼리는 사용자 테이블의 모든 행을 반환합니다. Diwa 프로젝트 내에서 이 작업을 수행하면 관리자로 로그인됩니다(잠시 후에 이 작업을 수행합니다). 그러나 더 많은 작업을 수행할 수 있고 테이블을 삭제하고 사용자 테이블이 크고 수백만 개의 행이 포함된 경우 DoS(서비스 거부) 공격을 수행할 수도 있습니다. 예를 들어 다음을 추가할 수 있습니다. thomas@example.com'; DROP TABLE users; . 다음 코드를 실행합니다.

'SELECT * FROM users WHERE email = thomas@example.com'; DROP TABLE users;

작동하는 이유는 무엇입니까? 첫 번째 SQL 문을 끝내고 바로 뒤에 다른 SQL 문을 추가하기 때문입니다. 그래, 알아, 미쳤어.

이것은 하나의 경험 법칙입니다. 항상 사용자 입력을 확인하십시오. 대부분의 사용자는 웹사이트를 깨는 것을 원하지 않습니다. 인터넷에는 해커가 가득하지 않습니다. 그러나 사용자 입력에서 직접 SQL 문을 작성해서는 안 됩니다. 다음 두 가지 방법을 사용할 수 있습니다.

  • real_espace_string과 같은 함수로 문자열을 이스케이프합니다. 이 함수는 SQL 문에서 사용하기 위해 문자열의 특수 문자를 이스케이프합니다.
  • 빈 값을 자리 표시자로 사용하여 SQL 쿼리를 준비한 다음 변수를 자리 표시자에 바인딩하고 마지막으로 쿼리를 실행할 수 있는 준비된 요청을 사용합니다. 위의 코드 스니펫은 준비된 요청입니다. 준비된 요청은 쿼리 준비가 한 번만 수행되기 때문에 구문 분석 시간을 줄일 수도 있습니다.

운 좋게도 Symfony 및 Laravel과 같은 대부분의 Php 프레임워크는 준비된 요청을 사용하며 간단한 요청을 수행할 때 예를 들어 Doctrine과 같은 ORM을 사용하면 더 안전할 것입니다. 원시 쿼리를 작성할 때 문제가 발생합니다.

출처: 저자 —Diwa의 환영 화면

보안에 대해 더 알고 싶다면 인터넷에 수많은 프로젝트가 있습니다. 운 좋게도 OWASP의 웹사이트에는 목록이 있습니다. 다양한 프로그래밍 언어로 된 예제를 찾을 수 있습니다. 몇 가지 이유로 저는 Php와 Diwa 프로젝트를 시작하기로 결정했습니다.

  • 이 프로젝트는 Docker를 사용하고 상자 밖에서 작동합니다. GitHub에서 복제하고 도커 이미지를 빌드하고 컨테이너를 실행하면 준비가 완료됩니다.
  • 또한 이해하기 쉽습니다. 곧 우리는 더 복잡한 프로젝트를 다룰 것이지만, 특히 새로운 것을 배울 때는 항상 단순한 프로젝트부터 시작하는 것이 좋습니다.
  • Diwa는 Php로 작성되었으며 많은 사람들이 사용하는 프로그래밍 언어인 경향이 있습니다. 나는 Php가 나쁜지 아닌지 당신에게 말하려고 여기 있는 것이 아닙니다. 그러나 PHP는 모든 웹사이트의 78.9%에서 사용됩니다. 이것이 사실입니다.
  • 처음에는 프로젝트에서 SQLite를 사용했지만 대신 MySQL을 사용하고 싶었습니다. 구성을 편집하고 docker-compose 및 MySQL을 추가하는 것은 정말 간단했습니다.

내가 수정한 사항을 살펴보기 전에 로컬에서 프로젝트를 빌드하는 것으로 시작하겠습니다. 사본을 만드십시오 .env.example 그리고 이름을 .env . 내부에 아무것도 추가할 필요가 없습니다. 다른 게시물에서 사용할 것입니다.

$ docker-compose build

다음 명령을 실행하여 시작하십시오. PHP 이미지를 빌드하고 다음을 포함한 라이브러리를 설치합니다. pdo 그리고 pdo_mysql .

$ docker-compose up

그런 다음 컨테이너를 시작합니다. 이 명령은 Diwa의 앱, datadog-agent(오늘 볼 필요 없음) 및 MySQL 데이터베이스의 세 가지 컨테이너를 생성합니다. 모든 이미지를 가져오면 http://localhost:8080으로 이동합니다.

출처: 저자 — Setup Diwa를 클릭하면 바로 이동합니다!

"디와 설정!"을 클릭하십시오. 버튼: 데이터베이스 테이블을 생성하고 내부에 내용을 추가합니다. 축하합니다. 이제 Diwa가 실행 중입니다!

Diwa의 데이터베이스에는 다음 테이블이 포함되어야 합니다.

Diwa에 대한 공격을 수행하기 전에 내가 프로젝트 소스 코드를 약간 수정했음을 알아야 합니다.

나는 업데이트했다 config.php SQLite 대신 MySQL을 사용하기 위해 파일. 나는 또한 내부에 pdo 라이브러리를 추가했습니다. app 컨테이너. Dockerfile 내부에 있습니다.

나는 또한 다음을 변경하여 10행의 오타를 수정했습니다. $config['database']['host'] 에게 $config['database']['server']$.
우리 프로젝트를 해킹하자!

먼저, 그렇지 않은 경우 docker-compose를 사용하여 프로젝트를 시작합니다. docker-compose build 그리고 docker-compose up. 을보세요 "이메일 주소"
그리고 "비밀번호" 화면 상단의 입력.

출처: 저자 — 상단 탐색 모음

등록 버튼을 클릭하여 시작하고 계정을 만드십시오. 초대 코드는 3702입니다.. 당신은 그것을 찾을 수 있습니다 config.php 파일.

출처: 저자 — 등록 양식

이제 로그인해야 합니다. 로그인되어 있지 않다면 프로젝트를 부트스트랩할 때 문제가 발생했음을 의미합니다. 의견 섹션에서 질문하는 것이 좋습니다. 이제 로그아웃하고 홈 페이지로 돌아갈 수 있습니다. 유효하지 않은 자격 증명을 작성하고 어떤 일이 발생하는지 살펴보십시오. 다음 오류 메시지가 표시되어야 합니다. "잘못된 이메일 주소 또는 비밀번호". 이제 나는 당신이 쓰기를 원합니다 '-- 이메일 입력 및 비밀번호 필드에 임의의 문자가 있습니다.

출처: 저자

당신은 좋은 500 오류가 있어야합니다. 이것은 서버에 나쁜 일이 발생했음을 의미합니다. 서버가 오류를 생성할 정도로 나쁜 일이 발생했습니다. 이는 또한 이 웹사이트가 안전하지 않을 수 있음을 알려줍니다. 우리는 이제 내가 찾은 멋진 치트 시트로 몇 가지 공격을 시도할 것입니다. 로그인 화면 우회 섹션을 보고 그 중 일부를 작성해 보십시오. 예를 들어 다음 명령은 오류를 일으키는 것 같습니다. admin'-- , 'admin'/* 또는 1=1-- . 이 하나 'or 1=1#' 관리자로 로그인합니다. 설치된 데이터베이스에 따라 일부 명령이 변경됩니다. 그러나 여기에서 간단하게 하기 위해 먼저 `'`로 쿼리의 첫 번째 부분을 닫고 항상 참된 검증을 삽입합니다. 당신은 또한 쓸 수 있습니다 '1=1; 로깅 내부에서 작동합니다.

출처: 저자 — 네, 이제 관리자입니다.

예, 사용자 목록을 보고 자격 증명 편집, 사용자를 관리자로 승격, 계정 삭제와 같은 다양한 작업을 수행할 수 있습니다.

출처: 저자 — 저는 관리자이기 때문에 모든 계정을 편집하고 삭제할 수 있습니다.

이제 우리는 로깅 페이지를 해킹할 수 있습니다. 예를 들어 사용자 테이블과 같은 일부 테이블을 삭제하는 것은 어떻습니까? 공격자가 하지 않을 것이라는 것을 이미 알고 있는 것이 있습니다. diwa. 예를 들어 users 테이블은 diwa_users . 이것은 테이블을 생성할 때 좋은 방법입니다. users 또는 products . 접두사를 추가하려고, your-project_table 예를 들어, 이렇게 하면 앱이 더 안전해집니다. 전에 계정을 만들라고 요청했습니다. 이것이 우리가 그것을 사용할 곳입니다. 이메일 주소와 비밀번호를 묻고 싶지만 확인하기 전에 이메일 주소 뒤에 다음을 추가하세요. 'DROP TABLE diwa_users; . 다음과 같이 보여야 합니다. 이제 심호흡을 하고 엔터를 치세요.

출처: 저자 — diwa_users 테이블을 삭제하겠습니다.

아래 스크린샷을 보십시오. diwa_users 테이블을 삭제했는데 더 이상 로그인하고 가입할 수 없습니다.

출처: 작성자 — 예, 이제 데이터베이스가 손상되었습니다.

그리고 데이터베이스를 보면 diwa_tables가 사라졌습니다. 무섭죠?

출처: 저자 - 여기에서 명령줄에서 내 SQL에 액세스합니다.

데이터베이스를 재설정하고 계정을 다시 만드십시오. 이제 데이터베이스를 절전 모드로 전환합니다. 추가하는 대신 DROP TABLE추가하다 AND sleep(20); 로그인 입력이 끝나면 Enter 키를 누릅니다. 요청이 예상보다 훨씬 오래 걸린다는 사실을 알고 계셨습니까? 때문에 발생합니다 "잠" 명령이 실행됩니다. 이를 염두에 두고 이제 무한 루프를 만들고 데이터베이스를 땀 흘리도록 해야 합니다! 의견 섹션에 답변을 추가할 수 있습니다. 올바른 방향으로 가고 있는지 알려 드리겠습니다!

이 콘텐츠 SQL Injection이 마음에 드셨으면 합니다. 이제 공격을 수행하고 방지하는 방법에 대한 기본 사항을 알아야 합니다. 저는 현재 공격이 발생할 때 경고를 받기 위해 관찰 도구를 설정하는 방법에 대한 자습서를 작성하고 있습니다. 이 프로젝트를 만든 Tim Steufmehl과 검토를 위한 Tambi Gumbo에게 특별한 감사를 전합니다.

내가 다룰 다음 공격은 아마도 크로스 사이트 스크립팅일 것입니다. 이 프로젝트를 사용할지 다른 프로젝트를 사용할지 모르겠습니다. 어쨌든 동일한 구조를 적용하겠습니다. 공격 설명, 방지 방법, 공격 예시 수행.

좋은 하루 되세요, 여러분!

반응형