바이너리 타입 업로드 내용이 출력 되는데요..ㅠ
본문
안녕하세요...
이런 경우는 첨이라서 질문 하나만 드립니다.
관리자 페이지 내 기본환경설정 접근 시 다음과 같은 오류가 발생합니다.
그래서 ssh 접근해서 확인해보면 바이너리 타입으로 잘 업로드 된 것을 확인할 수 있습니다.
file -bi ./ct_cli_x64 시도 시 아래 처럼 바이너리라고 분명히 나오거든요
application/x-executable; charset=binary
여전히 같은 오류 발생하는데요..
검색 해보니 몇가지 있던데 그 내용을 전부 해도 동일합니다..
시도한 내용은 다음과 같습니다.
1. 파일질라 업로드 시 바이너리 모드
이렇게 업로드 하여도 동일합니다.
2. 기존의 파일을 덮어쓰기가 아닌 "삭제" 이후 다시 시도
- 기존 파일 삭제 > 바이너리(위 스샷) 업로드 > 동일 증상
3. kcpcert 고객센터 문의 해서 새로운 파일을 받아서 재 시도
- 기존 파일 삭제 > 고객센터에서 받은 파일 넣기 > 동일 증상
4. 최신 파일 받아서 재 시도
- 기존 파일 삭제 > 최신 파일(그누보드 최신버전) > 동일 증상
5. 원래 버전 받아서 재 시도
- 기존 파일 삭제 > 설치된 그누보드 버전으로 재시도 > 동일 증상
nginx 사용자입니다.
혹시 다른 설정 혹은 nginx 에서 무언가 설정해야 하는걸까요 ???
아! 당연히 폴더 및 파일은 755권한 상태입니다.
참고로 sftp 사용자입니다.
해결하신 분이 있다면 도움 좀 부탁드립니다.
답변 2
https://github.com/gnuboard/gnuboard5/blob/v5.6.14/adm/config_form.php#L1771
이 위치에서 plugin/kcpcert/bin/ct_cli_x64 가 참조되는것 같고
https://github.com/gnuboard/gnuboard5/blob/v5.6.14/lib/common.lib.php#L3251
이 위치에서 실제 바이너리 파일 호출을 하는것 같습니다.
https://github.com/gnuboard/gnuboard5/blob/v5.6.14/lib/common.lib.php#L3298
그리고 이 위치에서 오류 메세지를 생성하는데
다시 위로 올라가 조건을 확인해보면
if(!$isbinary || !$search)
에서 !$search 조건 보다는 $isbinary 조건에 걸렸을 확률이 높을것 같고 그 조건은
https://github.com/gnuboard/gnuboard5/blob/v5.6.14/lib/common.lib.php#L3253
에서 만드는데
Unix 시스템에서 에러넘버는 128 + 신호넘버 로 리턴되므로
신호 11 은 SIGSEGV 잘못된 메모리 참조 입니다.
https://ko.wikipedia.org/wiki/%EC%84%B8%EA%B7%B8%EB%A9%98%ED%85%8C%EC%9D%B4%EC%85%98_%EC%98%A4%EB%A5%98
https://ko.wikipedia.org/wiki/%EC%8B%A0%ED%98%B8_(IPC)
추측을 해볼때
바이너리 타입의 문제가 아닌 파일을 실행하는 시스템의 메모리 문제일 가능성을 생각해볼수 있습니다.
상황 재현을 해본다면
php 프로세스에서 별도의 프로세스로 실행시키는 방식인 exec 는
ini_set('memory_limit')
와 같은 메모리 설정 으로는 영향을 주지 못하기 때문에
별도의 쉘스크립트를 만들어 테스트 해볼수 있습니다.
test-ct_cli_x64.sh
#!/bin/sh
main() {
# 가상 메모리 강제 1 바이트 제한
# 아래 주석을 풀면 139 리턴, 주석인 경우 255 리턴
#ulimit -v 1
local return_var=0
local out=''
local fpath=/absolute/path/to/plugin/kcpcert/bin/ct_cli_x64
if [ -x $fpath ]; then
out=$($fpath -h 2>&1)
#echo $out
return_var=$?
else
return_var=1
fi
return $return_var
}
main
위 쉘스크립트 만으로 간단하게 동작 확인이 되면 php 에서 호출해 재현해 볼수 있고
아래 코드는 test-ct_cli_x64.sh 파일을 extend 디렉토리에 위치시키고
extend 상위 디렉토리에서 실행하는 php 파일 내용 입니다.
include 'common.php';
ini_set('display_errors', 1);
error_reporting(E_ALL);
//echo function_exists('module_exec_check');
exec(G5_EXTEND_PATH . '/test-ct_cli_x64.sh', $out, $return_var);
$outs = implode(PHP_EOL, $out);
echo '<pre>';
echo <<<HEREDOC
out: $outs
return_var: $return_var
HEREDOC;
echo '</pre>';
결론적으로 에러코드 139 로 인한 문제가 맞다면
실행파일이 메모리 관련 문제로 정상동작 하지 않는 상황이므로
메모리 설정이 잘못된 docker 컨테이너 같은 환경은 아닌지
또는 시스템 환경을 확인하거나 시스템 레벨에서의 디버깅이 필요할것 같고
여러 다른 시스템에서의 동작 테스트로 코드나 파일 자체의 문제가 없음이 검증 된다면
문제 해결에 조금 더 도움이 될것 같습니다.
php는 스크립트 파일로 작동하기 때문에 바이너리 형태로 업로드하면 서버가 이를 인식하지못합니다.
한마디로 악성코드로 인식한다라는 것이지요 이는 보안정책에 따라서 차단된다라는뜻이기도합니다.
그외 호환성문제도 잇고 말그대로 php는 텍스트기반의 웹코드 언어이기대문에 바이너리로 업로드하는것은 올바르지 않습니다. 참고하시기 바랍니다.
따라서
선생님같은 보안에 싱경이 쓰인다면 이는 바이너리가아니고 base64같은인코딩을 해서 업로드를해주셔야한다라는것이되겠습니다.
단 서버에서 eval()함수가 활성화 되어있어야합니다. 이또한 참고하시기 바랍니다.