2014-05-16 4 views
0

PHP 기반 CMS를 실행하는 해킹 된 웹 사이트를 정리하고 있습니다. 사이트에있는 모든 PHP 파일은 파일의 첫 번째 줄의 시작 부분에 삽입 된 다음 문자열했다 : (. 내가 명확성을 위해 base64로 문자열을 절단 한)sed가 bash 스크립트를 멈추게합니다.

<?php /**/ eval(base64_decode("aWYoZnVuY3Rpb25"));?> 

내 목표는이를 제거하는 것입니다 bash 스크립트를 통한 문자열. 먼저 모든 파일을 반복 할 수 있는지 확인했습니다.

#!/bin/bash 
# de-malware-ifier 

for i in $(find ~/Sites/www.domain.com -name '*.php'); do 
    echo "file $i" 
done 

예상대로 작동하여 수백 개의 감염 파일의 파일 이름을 인쇄합니다.

난 후 교체 된 장소에 악 문자열을 각 파일에 대한 bash는 스크립트를 수정하려고 :

#!/bin/bash 
# de-malware-ifier 

for i in $(find ~/Sites/www.domain.com -name '*.php'); do 
    echo "file $i" 
    evil='<?php /**/ eval(base64_decode("aWYoZnVuY3Rpb25"));?>' 
    sed 's/$evil//' 
done 

그러나,이 스크립트를 실행하면 첫 번째 파일에 달려 있습니다. 왜이 스크립트가 매달려 있으며, 내가 원하는 결과를주기 위해이 스크립트를 어떻게 수정해야합니까?

저는 Mac OSX입니다.

+0

일반적으로 알고있는 변경 사항 *을 취소하면 서버 제어권을 다시 확보 할 수 없습니다. 공격자는 시스템을 "정리"한 후에 백도어 (또는 여러 개)를 설치하여 즉시 다시 허용 할 수 있습니다. 서버를 손상시킨 후 최상의 방법은 처음부터 다시 작성하거나 침입이 발생하기 전에 백업에서 복원하는 것입니다. [이 ServerFault 질문 및 답변] (http://serverfault.com/questions/6190/reinstall-after-a-root-compromise)을 참조하십시오. –

+2

'for i in $ (command)'에 대해주의하십시오.이 구문을 피해야합니다. 자세한 내용은이 답변을 참조하십시오. http://stackoverflow.com/questions/19606864/ffmpeg-in-a-bash-pipe/19607361#19607361 –

+0

@GordonDavisson 감사합니다.이 질문을 읽는 다른 사람들에게 유용한 팁입니다. 내 특정 경우에, www.domain.com은 어쨌든 오프라인으로 전환하기 위해 기한이 지난 상태였습니다. 나는 해킹 된 서버 복구보다는 기본적인 bash 스크립팅에 대한 학습 과제로 간주하고있다. – unruthless

답변

1

걸려있는 이유는 sed에 파일 이름을 지정하지 않아서 표준 입력에 대한 입력을 기다리고 있기 때문입니다.

당신은 사용해야 파일을 편집하려면 :

sed -i bak 's/foo/bar/' "$i" 

참고이 스크립트를 해결하기에 충분하지입니다. 기타 문제는 다음과 같습니다.

  1. 패턴에 sed의 특수 문자가 많이 포함되어 있습니다. 당신은 그들을 벗어나야 할 것입니다. 대신 fgrep -v을 사용할 수 있는지 확인하십시오.
  2. $evil은 작은 따옴표로 확장되지 않습니다. 큰 따옴표를 사용하십시오.
+0

'fgrep -v'는 라인의 일치하는 부분뿐만 아니라 일치하는 전체 라인을 제거합니다. – Barmar

+0

'bak'이 그 명령의 맥락에서 무엇을하는지 설명 할 수 있습니까? 나는 일반적으로 sed와 bash 스크립팅에 익숙하다. – unruthless

+1

'man sed' :'-i extension' 지정된 확장명을 가진 백업을 저장하여 현재 위치에서 파일을 편집합니다. 길이가 0 인 확장자 이 주어지면 백업이 저장되지 않습니다. 내부 편집 파일 인 경우 공간이 부족한 상황에서 손상이나 부분 내용의 위험이 있으므로 0 길이 확장을 지정하지 않는 것이 좋습니다. –

0

입력이 없습니다.

이 시도 :

#!/bin/bash 
# de-malware-ifier 

for i in $(find ~/Sites/www.domain.com -name '*.php'); do 
    echo "file $i" 
    evil='<?php \/\*\*\/ eval(base64_decode("aWYoZnVuY3Rpb25"));?>' 
    sed -i "s/$evil//" $i 
done 

PS를 : 당신이 "$ 악"에 다른 뭔가를 탈출해야 할 경우 나는 확실하지 않다.

+0

for for in $ (command) ...이 구문을 피해야합니다. 자세한 내용을 보려면이 답변을 참조하십시오. http://stackoverflow.com/questions/19606864/ffmpeg-in-a-bash-pipe/19607361#19607361 –

+1

'for for i in'을 사용하지 마십시오. 절대로 sed를 사용하지 마십시오. 당신은 검색 공간에서 RE를 원하지 않으며 단어 분리와 globbing 문제를 피하기 위해 항상 변수 (''$ i '')를 인용합니다. –

0

다른 사람들도 지적했듯이 sed 명령의 파일 이름은 누락되었지만 sed는 문자열에서만 작동 할 수 있으므로 sed는 사용하지 마십시오. 외관상으로는 sed 옵션에 시간을 낭비하는 대신, sed에게 regexp가 아닌 문자열로 검색 패턴을 처리하도록 플래그를 제공 할 수 있다면 GNU 녀석들은 훨씬 더 좋은 결과를 얻었을 것입니다.

어쨌든 - 대신이 시도 : 나는 또한 파일 이름에 루프를 고정

tmp="/usr/tmp/tmp$$" 
trap 'rm -f "$tmp"; exit' 0 
find ~/Sites/www.domain.com -name '*.php' | 
while IFS= read -r i; do 
    echo "file $i" 
    evil='<?php /**/ eval(base64_decode("aWYoZnVuY3Rpb25"));?>' 
    awk -v evil="$evil" 's=index($0,evil){$0 = substr($0,1,s-1) substr($0,s+length(evil)} 1' "$i" > "$tmp" $$ mv "$tmp" "$i" 
done 

. for i in $(...)을 사용하지 마십시오. 공백이 포함 된 파일 이름에 대해서는 실패합니다. 줄 바꿈이 포함 된 파일 이름이있는 경우 내가 게시 한 루프가 실패합니다.

수동으로 tmp 파일을 지정하지 않으려면 GNU awk에 -i inplace 플래그가 있어야합니다.

관련 문제