DouPHP 감사 레코드 (실패 감사)

DouPHP 감사 레코드

0x01로 개요


DouPHP 저우 콩 껍질 네트워크 기술 유한 공사는 PHP + MySQL의 아키텍처를 기반으로 경량 기업 웹 사이트 관리 시스템을 개발, 리눅스, 윈도우,에서라도, Solaris 및 다른 플랫폼에서 실행, 스마티 템플릿 엔진을 탑재 시스템, 사용자 정의 의사 정적, DIV + CSS의 디자인, 간결한 배경 인터페이스 디자인을 사용하여 전경 템플릿, 간단한 기능이 좋은 사용자 경험, 안정성, 확장 성 및 보안 성을 가지는 경향 및 모듈 멤버로, 백 라인 모듈을 통해 설치할 수 있습니다, 주문은 중소 사이트에 대한 사이트 구축 솔루션을 제공 할 수 있습니다, 모듈.
오로지 학습의 목적을위한 감사는, 로컬 컴퓨터에서 테스트를 설정합니다.

0x02의 SQL 인젝션


프론트 데스크에서 직접 몇 개의 파일이 감사를 시작하도록 시스템은 액세스 경로를 설정하지 않기 때문에. 우리의 관심 포인트의 가치가 여기에 직접 기록 :
init.php
의 index.php를 시작하는 /include/init.php 일부 초기 설정을 만들어 포함

init.php의 매직 코트를 해제

새로운 67 줄 방화벽 클래스, 88 회선 통화 dou_firewall (). 우리는 작업을 수행했다 있는지 확인하기 위해 따라 계속

) (dou_magic_quotes에 따라

) (addslshes_deep에 따라

당신은 상관없이 $ _GET의) 최종 호출이 addslshes_deep입니다 ($ _ POST, $ _ COOKIE, _ 요청이 단일 값이나 배열에 전달 $이 모든 악 addslashes를 통해 갈 것입니다 () 세례를 볼 수 있습니다. 그리고 데이터베이스 연결 설정을 구성보고 코딩에 의해, 그래서 그냥, 우리는 INT SQL 주입을 볼 수 있습니다 dou_firewall ()를 호출, UTF-8입니다.

그러나 정규 경기에서 수행 한 포장, 쿼리의 매개 변수의 앞에 배치되지 않는 매개 변수를 따옴표를 찾을 수 없습니다 SQL 문을의 전체 텍스트를 읽은 후에 만 ​​[0-9A-ZA-Z_을.] 허용되는 시스템이라고 할 수있다 개발 매우 표준화. 그리고 정규 경기 또는 탈출의 모든 파라미터 값을 발견 가능한 모든 차 주입.

논리적 결함은 0x03


어떤 주사가 없기 때문에, 당신은 허점의 다른 유형을 감사 할 수 있습니다.
지역 환경 관찰에 의해 설정, 프론트 데스크는 기능 정보, 논리적 허점을 나타날 수 있습니다 암호 복구 기능의 배경 로그 항목을 표시하는 것입니다.

위치 : 관리자 마지막 줄에 / login.php (136), 암호가 검색 코드를 처리

elseif ($rec == 'password_reset_post') {
    // Action操作项的初始化
    $action = $check->is_rec($_POST['action']) ? $_POST['action'] : 'default';
    
    // 验证管理员用户名
    if (!$check->is_username(trim($_POST['user_name']))) {
        $dou->dou_msg($_LANG['login_password_reset_fail'], ROOT_URL . ADMIN_PATH . '/login.php?rec=password_reset', 'out');
    } else {
        $user_name = trim($_POST['user_name']);
    }
    
    // 验证对应的管理员邮箱
    if (!$check->is_email(trim($_POST['email']))) {
        $dou->dou_msg($_LANG['login_password_reset_fail'], ROOT_URL . ADMIN_PATH . '/login.php?rec=password_reset', 'out');
    } else {
        $email = trim($_POST['email']);
    }
    
    // 找回密码提交、重置密码提交
    if ($action == 'default') { // 密码找回提交操作
        // 根据用户名和邮箱获取对应的用户信息
        $user = $dou->get_row('admin', '*', "user_name = '$user_name' AND email = '$email'");
        
        // 对应的用户信息不存在
        if (!$user)
            $dou->dou_msg($_LANG['login_password_reset_wrong'], ROOT_URL . ADMIN_PATH . '/login.php?rec=password_reset', 'out');
    
        // CSRF防御令牌验证
        $firewall->check_token($_POST['token'], 'password_reset');
        
        // 生成包含找回密码链接的邮件正文
        $time = time();
        $code = substr(md5($user['user_name'] . $user['email'] . $user['password'] . $time . $user['last_login'] . DOU_SHELL) , 0 , 16) . $time;
        $site_url = rtrim(ROOT_URL, '/');
        $body = $user['user_name'] . $_LANG['login_password_reset_body_0'] . ROOT_URL . ADMIN_PATH . '/login.php?rec=password_reset' . '&uid=' . $user['user_id'] . '&code=' . $code . $_LANG['login_password_reset_body_1'] . $_CFG['site_name'] . '. ' . $site_url;
        
        // 发送找回密码邮件
        if ($dou->send_mail($user['email'], $_LANG['login_password_reset'], $body)) {
            $dou->dou_msg($_LANG['login_password_mail_success'] . $user['email'], ROOT_URL . ADMIN_PATH . '/login.php', 'out', '30');
        } else {
            $dou->dou_msg($_LANG['mail_send_fail'], ROOT_URL . ADMIN_PATH . '/login.php?rec=password_reset', 'out', '30');
        }
    } elseif ($action == 'reset') { // 密码重置操作
        // 获取会员ID和安全码
        $user_id = $check->is_number($_POST['user_id']) ? $_POST['user_id'] : '';
        $code = preg_match("/^[a-zA-Z0-9]+$/", $_POST['code']) ? $_POST['code'] : '';
        
        // 验证密码
        if (!$check->is_password($_POST['password'])) {
            $dou->dou_msg($_LANG['manager_password_cue'], '', 'out');
        } elseif (($_POST['password_confirm'] !== $_POST['password'])) {
            $dou->dou_msg($_LANG['manager_password_confirm_cue'], '', 'out');
        }

        // 找回密码操作
        if ($dou->check_password_reset($user_id, $code)) {
            // 重置密码
            $sql = "UPDATE " . $dou->table('admin') . " SET password = '" . md5($_POST['password']) . "' WHERE user_id = '$user_id'";
            $dou->query($sql);
            $dou->dou_msg($_LANG['login_password_reset_success'], ROOT_URL . ADMIN_PATH . '/login.php', 'out', '15');
        } else {
            $dou->dou_msg($_LANG['login_password_reset_fail'], ROOT_URL . ADMIN_PATH . '/login.php', 'out', '15');
        }
    }
}

?>

하여 $ REC에 ELSEIF는 $ 통해 취득 _REQUEST 그래서 우리가 얻을 또는 게시물 입력 REC = 코드의 층에 들어가 password_reset_post [ 'REC']
포스트 수신 들어, $ 동작을 얻기 위해 초기에 도면을 참조 후 사용자 이름과 이메일을 정기적으로 경기를했다, 당신은이 두 개의 매개 변수에 의해 작업이 거의 불가능하고 싶어.

다음은 $ 체크 -> is_username 및 $ 체크 -> is_email 처리 코드입니다

function is_username($username) {
        if (preg_match("/^[a-zA-Z]{1}([0-9a-zA-Z]|[._]){3,19}$/", $username)) {
            return true;
        }
    }
    
function is_email($email) {
    if (preg_match("/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/", $email)) {
        return true;
    }
}

그런 다음 $ 행동을보고 == '기본'운영

    // 找回密码提交、重置密码提交
    if ($action == 'default') { // 密码找回提交操作
        // 根据用户名和邮箱获取对应的用户信息
        $user = $dou->get_row('admin', '*', "user_name = '$user_name' AND email = '$email'");
        
        // 对应的用户信息不存在
        if (!$user)
            $dou->dou_msg($_LANG['login_password_reset_wrong'], ROOT_URL . ADMIN_PATH . '/login.php?rec=password_reset', 'out');
    
        // CSRF防御令牌验证
        $firewall->check_token($_POST['token'], 'password_reset');
        
        // 生成包含找回密码链接的邮件正文
        $time = time();
        $code = substr(md5($user['user_name'] . $user['email'] . $user['password'] . $time . $user['last_login'] . DOU_SHELL) , 0 , 16) . $time;
        $site_url = rtrim(ROOT_URL, '/');
        $body = $user['user_name'] . $_LANG['login_password_reset_body_0'] . ROOT_URL . ADMIN_PATH . '/login.php?rec=password_reset' . '&uid=' . $user['user_id'] . '&code=' . $code . $_LANG['login_password_reset_body_1'] . $_CFG['site_name'] . '. ' . $site_url;
        
        // 发送找回密码邮件
        if ($dou->send_mail($user['email'], $_LANG['login_password_reset'], $body)) {
            $dou->dou_msg($_LANG['login_password_mail_success'] . $user['email'], ROOT_URL . ADMIN_PATH . '/login.php', 'out', '30');
        } else {
            $dou->dou_msg($_LANG['mail_send_fail'], ROOT_URL . ADMIN_PATH . '/login.php?rec=password_reset', 'out', '30');
        }

데이터베이스 쿼리 및 반환 절차 종료 결과가 없습니다에 첫 번째 게시물 들어오는 사용자 이름과 사서함입니다. 그래서 암호의 목적을 재설정 할 수있는 링크를 허용하도록 사서함에 도달에게 사서함을 수정할 수있는 방법은 없습니다.

건설 암호 복구 링크를 시작하고, 사서함 사용자가 해당 링크로 전송 한 후.
비밀번호 재설정 링크는 $ 코드 (168 개 라인) 우리가 직접 비밀번호 재설정 링크를 구축 할 수 있도록, MD5는, 사용자 정보를 복수 봉합 후 계산을 포함했다. 도 더 이상 행 (170)는 접합 $ 코드 $ 본체 뒤에 사실, 코드 $ 바디, 완전하게 테마를 생성합니다. 이는 전체 코드를보고 내 릴리스 암호 복구 기능의 상단에있을 수 있습니다.

암호 재설정 링크는 다음과 같이 인쇄하기

우리는 코드 $ 녹화 == 'password_reset'의 직접 login.php 볼 수 있도록 링크를 분석함으로써, $ REC = password_reset 알고

여기에 116 $의 USER_ID 및 $ 보이스 코리아, DOU-> check_passwrod_reset (), 우리가 작업을 수행하기 위해 수행되었던 것을 보면 넣어하는 방법에 대한 $ 코드
달러 (A $) 코드를 다시 생성 앞에 $ 코드를 16 비트 라인 (98) 밖으로 (96 개) 라인을 볼 수 있습니다, 101 선 $ 코드와 $ get_code 비교를 취할. 우리는, 그래서 여기에 $ 코드 검증을 위해 여기에왔다 우리가 할 수없는 제한 우회.

하지만이 최종 거래, 다음과 같이 암호를 변경할 수있는 마지막 자리의 암호를 변경할 수있는 장소가 아니다 :

이 감사에 암호 복구 기능, 나는 허점을 찾을 수 있도록 그러나 불행하게도, 거기에 191 선은 또한 $ 코드 검증했다.

를 0x04 파일 업로드


이 감사는 파일의 감사 관리자 / 그래서이 아닌 파일 업로드 기능 않았다 프런트 데스크를 douphp
경우 감사에 그들 중 하나, 예를 들어, 읽기로는, 모든 파일 업로드 기능은 파일 클래스를 사용하여 처리됩니다 찾을
관리자 / system.php
때 $ 녹화 == '갱신'파일 업로드, 라인 (103) 통화량 $ 파일 -> 업데이트는 (), 우리는 $ 파일을 오는 방법에 대해 살펴이 걸릴 때.

20 줄을 참조하십시오 $ 파일은 오브젝트 파일의 클래스의 인스턴스

다음을 수행 __construct보고, File 클래스를 따르십시오 :

그런 다음 돌아가서 다시 봐 $ 파일 -> 업로드 ()
$ this-> FILE_TYPE에서의 경기에 대한 파일 확장자와 모양을 얻기 위해, 점 배열로 분할 한 후 여기에. 당신은 너무 여기에 화이트리스트 필터링하고, 위의 __construct의 $의 FILE_TYPE 몇 사진 형 접미사에서 볼 수있는, 그것은 우회 할 수 없습니다.

다음 직접 접합 파일 이름 및 파일을 업로드. 파일 업로드 기능을 파고 구멍이 없습니다 그래서.

0x05가 다른 취약점


CSRF
나중에 또한 배경 CSRF 존재하는지에보고, 그 결과 제 csrftoken 확인할 것 동작을 수행하기 전에 백그라운드 기능이다. 여기에서 우리는 자기가 건설 한 여부, CSRF 생성하는 방법에 대해 알아.
다음 코드의 읽기가 난수 생성에 볼 수 있습니다.

무단 액세스
권한이없는 액세스 감사의 매우 무례, 뒷 페이지 파일의 시작 부분은 init.php 포함되지 않은 파일이있는 경우 관리자가 / / 세션에 체크인을 할 init.php, 그래서 관리자 디렉토리 디렉토리 파일을 직접 볼 등이 포함 할 수 있습니다. 그러나 결국 수동으로 몇 서서 찾지 못했습니다.

이 0x06 요약

파고 여러 스토리지 XSS 배경의 총의 감사, 감사 프로세스에 익숙해 깊은 이해 코드 감사, 아마도 더 큰 수확. 이 코드는 물론, 아이디어를 몇 가지 안전 기술 개발을 배우게됩니다. 자신의 단점을 인정하지만, 코드는 느린 속도를 읽고 있습니다.
우리는 늦게, 하, 하를 통과 그들의 전투를 개선하도록 노력하겠습니다.

추천

출처www.cnblogs.com/Gcker/p/12501933.html