Re: [exim] Tainted issues - left me dazed and confused...

トップ ページ
このメッセージを削除
このメッセージに返信
著者: Jeremy Harris
日付:  
To: exim-users
題目: Re: [exim] Tainted issues - left me dazed and confused...
On 24/01/2021 16:21, Mark Elkins via Exim-users wrote:
> remote_smtp:
>   driver = smtp
>   message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
>   dnssec_request_domains = *
>   hosts_try_dane = *
>   return_path = ${address:$reply_address}
>   dkim_domain = ${lc:${domain_data:$h_from:}}
>   dkim_selector = ${substr_2_4:$tod_zulu}
>   dkim_private_key = ${if exists{/etc/exim/dkim/${lc:${domain_data:$h_from:}}-${substr_2_4:$tod_zulu}.pem}{/etc/exim/dkim/${lc:${domain_data:$h_from:}}-${substr_2_4:$tod_zulu}.pem}{0}}
>   dkim_canon=relaxed
>
> /etc/exim contains the director 'dkim' with various files.... this basically allows me to have many DKIM-ed domains and to roll the DKIM signatures appropriately.
>
> All my users are in a MySQL Database - if that helps with de-tainting.... although I did think using "domain_data" was the correct way to go. This user use port 587 with a username/password (from MySQL) in order to hand over the email to EXIM for delivery.
>
> # ls -l
> total 216
> drwxr-xr-x 2 root root 16384 Jan 24 17:28 dkim
> -rw-r--r-- 1 root root 45830 Jan 24 18:01 exim.conf
>
> # ls -l dkim
> ...
> -rw-r--r-- 1 root root 891 Jan 24 17:28 posix.co.za-2101.pem
> -rw-r--r-- 1 root root 272 Jan 24 17:28 posix.co.za-2101.pub
>
> Error from the log look like....
>
> 2021-01-24 18:02:55 SMTP connection from [197.185.109.217]:35388 I=[192.96.24.20]:587 (TCP/IP connection count = 1)
> 2021-01-24 18:02:55 1l3hqp-005HHq-Fl <= "mje@??? H=([160.124.48.164]) [197.185.109.217]:35388 I=[192.96.24.20]:587 P=esmtpsa X=TLS1.3:TLS_AES_128_GCM_SHA256:128 CV=no A=PLAIN:mje@??? S=14670 id=a4b55a63-19dd-7584-88f1-f2bfcc13d9f2@??? T="test via auth"
> 2021-01-24 18:02:55 SMTP connection from ([160.124.48.164]) [197.185.109.217]:35388 I=[192.96.24.20]:587 closed by QUIT
> 2021-01-24 18:02:56 1l3hqp-005HHq-Fl Tainted filename '/etc/exim/dkim/posix.co.za-2101.pem'
> 2021-01-24 18:02:56 1l3hqp-005HHq-Fl unable to open file for reading: /etc/exim/dkim/posix.co.za-2101.pem
> 2021-01-24 18:02:56 1l3hqp-005HHq-Fl => mje@??? R=dnslookup T=remote_smtp H=mail.vweb.co.za [2001:42a0::16] I=[2001:42a0::20] X=TLS1.3:TLS_AES_256_GCM_SHA384:256 CV=yes K C="250- 14187 byte chunk, total 14923\\n250 OK id=1l3hqq-00HQK7-3l"
> 2021-01-24 18:02:56 1l3hqp-005HHq-Fl Completed
>
> ... so mail is delivered but the DKIM signing does not happen. How do I fix this. The whole "Tainted" subject still leaves me feeling dazed and confused.


The basic point is that information provided by a potential adversary should
not be used for expansion or as a filename, without first being validated
against trusted information. Taint is Exim's means for tracking this
untrustworthy information.


Your example:
> 2021-01-24 18:02:56 1l3hqp-005HHq-Fl Tainted filename '/etc/exim/dkim/posix.co.za-2101.pem'


was trying to use '/etc/exim/dkim/posix.co.za-2101.pem' as a filename. I'm guessing this use
was from

>    dkim_private_key = ${if exists{/etc/exim/dkim/${lc:${domain_data:$h_from:}}-${substr_2_4:$tod_zulu}.pem}{/etc/exim/dkim/${lc:${domain_data:$h_from:}}-${substr_2_4:$tod_zulu}.pem}{0}}


which has two possible taitned sources: $domain_data and $h_from: .
However, I don't see what you're trying to express with ${domain_data:$h_from:} - this looks
entirely bogus syntax, so I can't see you were actually running tha to produce the log you give.

Note that ${domain:<string>} is not using the $domain variable, but is trying to pull the domain
part out of a local_part@domain syntax address.

Once you've fixed that, $h_from: will be tainted - having been supplied by your potential attacker.
You could consider doing some suitable lookup in a local DB (and "DB" can be your whole
filesystem, cf. the dsearch lookup method) in order to validate it. Read the docs on lookups
and the taint-status of results of lookups. Since you have a directory /etc/exim/dkim/
populated with acceptable files, this seems most simple. And you get the 'exists' test done
that way.
--
Cheers,
Jeremy