개발 꿀팁/PHP

ecshop 취약성 복구 정리

Jammie 2022. 7. 15. 11:48
반응형

1.ECShop에는 /api/client/api.php 파일에 문제가 있는 블라인드 버그가 있습니다. 특수 제작된 악의적인 POST 요청을 제출하면 SQL 주입 공격이 가능하며 민감한 정보를 얻거나 데이터베이스를 조작할 수 있습니다.
경로:/api/client/ includes/ lib_api.php
다음 수정사항 참조:

function API_UserLogin($post)
{
    /*SQL 주입 필터 */
    if (get_magic_quotes_gpc()) 
    {     
        $post['UserId'] = $post['UserId'];
    } 
    else 
    {     
        $post['UserId'] = addslashes($post['UserId']);     
    }
    /* end */
    $post['username'] = isset($post['UserId']) ? trim($post['UserId']) : '';

2.ecshop의 백그라운드 편집 파일/admin/shopinfo.php에서 입력 파라미터 id에 대한 올바른 형식 변환이 이루어지지 않아 정형 주입이 발생한다.
경로: /admin/shopinfo.php
다음 수정(53-71-105-123행 참조)

소스 코드:
admin_priv('shopinfo_manage');
고치다:
admin_priv('shopinfo_manage');
$_REQUEST['id'] = intval($_REQUEST['id']);

3. 파일/admin/affiliate_ck.php에서 입력 파라미터 auid에 대한 올바른 형식 변환이 이루어지지 않아 정형 주입이 발생합니다.
다음 수정사항(31행 및 51행 참조)

소스 코드:
$logdb = get_affiliate_ck();
고치다:
$_GET['auid'] = intval($_GET['auid']);
$logdb = get_affiliate_ck();

비고: 위의 내용대로 알리 클라우드를 변경해도 이 취약성이 나타날 것 같습니다. 그런 다음 파일 상단에 다음 코드를 추가하면 됩니다

$_GET['auid'] = intval($_GET['auid']);

4.ecshop의 /admin/comment_manage.php에서 입력 파라미터 sort_by, sort_order를 엄격하게 필터링하지 않아 SQL 주입을 야기합니다.
다음 수정사항 참조:

$filter['sort_by']      = empty($_REQUEST['sort_by']) ? 'add_time' : trim(htmlspecialchars($_REQUEST['sort_by']));  
$filter['sort_order']   = empty($_REQUEST['sort_order']) ? 'DESC' : trim(htmlspecialchars($_REQUEST['sort_order']));

5.ecshop은 회원가입처인 username에 대한 필터링 없이 무거운 사용자 정보를 저장할 때 셸에 바로 쓸 수 있다.
경로:/admin/integrate.php
대략 109줄, 다음을 참조하여 수정한다

$code = empty($_GET['code']) ? '' : trim(addslashes($_GET['code']));

대략 601줄, 다음을 참조하여 수정한다

 

소스 코드:
@file_put_contents(ROOT_PATH . 'data/repeat_user.php', $json->encode($repeat_user));
수정하다:
@file_put_contents(ROOT_PATH.'data/repeat_user.php','<?php die();?>'.$json->encode($repeat_user));

비고: 위의 내용대로 알리 클라우드를 변경해도 이 취약성이 나타날 것 같습니다. 그런 다음 파일 상단에 다음 코드를 추가하면 됩니다

$_GET['code'] = empty($_GET['code']) ? '' : trim(addslashes($_GET['code']));

6. ecshop 백그라운드 템플릿 컴파일은 해커가 임의의 악성코드를 삽입할 수 있게 한다.
경로:/admin/edit_languages.php
한 120번째 줄에서

$dst_items[$i] = $_POST['item_id'][$i] .' = '. '"' .$_POST['item_content'][$i]. '";';

수정하기

$dst_items[$i] = $_POST['item_id'][$i] .' = '. '\'' .$_POST['item_content'][$i]. '\';';

7. ecshop 필터링이 잘 되지 않아 SQL 주입 취약점이 발생한다.
경로: /category.php, /ecsapi/category.php
수정 방법: https://ww.cnblogs.com/LittleHann/p/4524161.html

8,ecshop의/includes/lib_insert.php 파일에서는 입력 파라미터에 대한 정확한 형식 변환이 이루어지지 않아 정형 주입이 발생하였다.
$arr['num'], $arr['id'] 있어요], $arr['type'] 이 파라미터들은 함수 첫머리에 다음과 같이 추가된다

한 289줄에다가:
$arr['num'] = intval($arr['num']);
$arr['id'] = intval($arr['id']);
한 454줄에다가:
$arr['id'] = intval($arr['id']);
$arr['type'] = addslashes($arr['type']);
한 495줄에다가:
$arr['id'] = intval($arr['id']);

9. ECSHOP 결제 플러그인에 SQL 주입 취약성이 있습니다. 이 취약성은 /includes/modules/payment/alipay.php 파일에 있습니다. 이 파일은 ECshop의 알리페이 플러그인입니다.ECShop에서는 str_replace 함수를 문자열로 대체하기 때문에 해커는 원 따옴표 제한 구조 SQL 주입구를 우회할 수 있다.알리페이 카드를 켜면 이 취약점을 이용해 사이트 데이터를 얻을 수 있고 로그인도 필요 없다

검색 코드:

$order_sn = str_replace($_GET['subject'], '', $_GET['out_trade_no']);

다음 구절을 고치다:

$order_sn = trim(addslashes($order_sn));

Exshop 백그라운드 템플릿 편집 취약성
상세설명참조: https://www.cnblogs.com/LittleHann/p/4272255.html

취약성 파일:/admin/mail_template.php 및/includes/cls_template.php
/admin/mail_template.php 파일에 다음 코드 추가 (php 키워드를 일부 필터링함)

/*------------------------------------------------------ */
//--템플릿 내용 저장
/*------------------------------------------------------ */

elseif ($_REQUEST['act'] == 'save_template')
{ 
    if (empty($_POST['subject']))
    {
       sys_msg($_LANG['subject_empty'], 1, array(), false);
    }
    else
    {
        $subject = trim($_POST['subject']);
    }

    if (empty($_POST['content']))
    {
       sys_msg($_LANG['content_empty'], 1, array(), false);
    }
    else
    {
        $content = trim($_POST['content']);
    }

    $type   = intval($_POST['is_html']);
    $tpl_id = intval($_POST['tpl']);

    /*php 키워드를 일부 필터링했습니다*/    
    $temp_check = preg_replace("/([^a-zA-Z0-9_]{1,1})+(extract|parse_str|str_replace|unserialize|ob_start|require|include|array_map|preg_replace|copy|fputs|fopen|file_put_contents|file_get_contents|fwrite|eval|phpinfo|assert|base64_decode|create_function|call_user_func)+( |\()/is", "", $content);
    $temp_check = preg_replace("/<\?[^><]+(\?>){0,1}|<\%[^><]+(\%>){0,1}|<\%=[^><]+(\%>){0,1}|<script[^>]+language[^>]*=[^>]*php[^>]*>[^><]*(<\/script\s*>){0,1}/iU", "", $temp_check); 
    $content = $temp_check;
    /*php 키워드를 일부 필터링했습니다*/

    $sql = "UPDATE " .$ecs->table('mail_templates'). " SET ".
                "template_subject = '" .str_replace('\\\'\\\'', '\\\'', $subject). "', ".
                "template_content = '" .str_replace('\\\'\\\'', '\\\'', $content).  "', ".
                "is_html = '$type', ".
                "last_modify = '" .gmtime(). "' ".
            "WHERE template_id='$tpl_id'";

    if ($db->query($sql, "SILENT"))
    {
        $link[0]=array('href' => 'mail_template.php?act=list', 'text' => $_LANG['update_success']);
        sys_msg($_LANG['update_success'], 0, $link);
    }
    else
    {
         sys_msg($_LANG['update_failed'], 1, array(), false);
    }
}

/includes/cls_template.php 파일 대체 함수(fetch_str():

function fetch_str($source)
    { 
        if (!defined('ECS_ADMIN'))
        {
            $source = $this->smarty_prefilter_preCompile($source);
        }
        $source=preg_replace("/([^a-zA-Z0-9_]{1,1})+(copy|fputs|fopen|file_put_contents|fwrite|eval|phpinfo)+( |\()/is", "", $source);
        $source=preg_replace("/<\?[^><]+\?>|<\%[^><]+\%>|<script[^>]+language[^>]*=[^>]*php[^>]*>[^><]*<\/script\s*>/iU", "", $source);
        return preg_replace("/{([^\}\{\n]*)}/e", "\$this->select('\\1');", $source);
        //return preg_replace_callback("/{([^\}\{\n]*)}/", function($r) { return $this->select($r[1]); }, $source);//수식자 /e 在 PHP5.5.x 중은 이미 폐기되었다
    }

 

반응형