слідами «спамера» або Oracle DB + UTL_SMTP + SSL/TLS

На написання цієї статті мене спонукало прочитання публікації «Як я спам слав» від користувача Nike01. Керівництво поставило переді мною схожу задачу по розсилці облікових даних користувачів засобами бази даних Oracle. В якості SMTP relay повинен був виступати сервер вихідних повідомлень Яндекса, використовує SSL при авторизації.



Збір інформації
Як і Nike01, я в першу чергу став дивитися в бік пакета UTL_MAIL. Даний пакет, по суті, представляє з себе «обгортку» над UTL_SMTP і UTL_TCP і призначений в основному для відправлення простих поштових повідомлень, дозволяючи користувачеві особливо не вдаватися в тонкощі протоколу SMTP. На жаль UTL_MAIL має ряд обмежень, в їх числі — відсутність підтримки SMTP аутентифікації і отже для вирішення мого завдання він не підходить.

Далі, я звернувся до документації по пакету UTL_SMTP, як з'ясувалося — це досить потужний і гнучкий інструмент, який дозволяє задіяти практично всі команди протоколу SMTP, у тому числі має підтримку SMTP авторизації, а починаючи з версії БД 11.2.0.2 вміє і STARTTLS. Те, що треба!

Переходимо до поштового сервера. З довідки по використанню smtp.yandex.ru дізнаємося, що сервіс слухає 465 порт:


Ок. Пробуємо встановити з'єднання:

[oracle@ora_db ~]$openssl s_client -connect smtp.yandex.ua:465
CONNECTED(00000003)
depth=2 C = PL, O = Unizeto Technologies S. A., OU = Certum Certification Authority, CN = Certum Trusted Network CA
verify return:1
depth=1 C = RU, O = Yandex LLC, OU = Yandex Certification Authority, CN = Yandex CA
verify return:1
depth=0 C = RU, O = Yandex LLC, OU = ITO, L = Moscow, ST = Russian Federation, CN = smtp.yandex.ru, emailAddress = pki@yandex-team.ru
verify return:1
---
Certificate chain
0 s:/C=RU/O=Yandex LLC/OU=ITO/L=Moscow/ST=Ukrainian Federation/CN=smtp.yandex.ru/emailAddress=pki@yandex-team.ru
i:/C=UA/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA
1 s:/C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA
i:/C=PL/O=Unizeto Technologies S. A./OU=Certum Certification Authority/CN=Certum Trusted Network CA
---
Certificate Server
-----BEGIN CERTIFICATE-----
MIIGtzCCBZ+gAwIBAgIQeNdVGMktXbH0GDaX1lgg9TAnbgkqhkig9w0baqsfadbf
MQswCQYDVQQGEwJSVTETMBEGA1UEChMKwwfuzgv4iexmqzenmcuga1uecxmewwfu
ZGV4IENlcnRpZmljYXRpb24gQXV0aG9yaxr5mriweaydvqqdewlzyw5kzxggq0ew
HhcNMTUxMDEyMTI0MTI0WhcNMTcxMDExmti0mti0wjcbmjelmakga1uebhmculux
EzARBgNVBAoMCllhbmRleCBMTEMxDDAKbgnvbasma0lutzepma0ga1uebwwgtw9z
Y293MRswGQYDVQQIDBJSdXNzaWFuIEZlzgvyyxrpb24xfzavbgnvbammdnntdhau
eWFuZGV4LnJ1MSEwHwYJKoZIhvcNAQkBfhjwa2laewfuzgv4lxrlyw0ucnuwggei
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKaoibaqdfdyjiwjsdhswhdnxnj+2TH8jc
l2Skm4k6Z9UTDcxCMbe8rvkEg3bu7EUPnftnmbgxb3kxnj73irz6plru3bo7psi3
hbWNRVDzQlcdQZmW/Iucd8IQlvN1gwDZ79eu1fWmRMThmNmiikk1ajtzntc+Dq/9
kTl4TkRzdge6KpkOn3lJFwiTozixxKKfawxqslfpradzluyt2cj88huo3r5frwwh
8nTMDITtHZVSSYw1cYNIWj+y5G3D1TA1pKcyIPI8WHqJeHIekI3t4uK9jqneaji0
clabA3fn1wdJ4jCWajdLcssJ9PJ6eJB+l4HZFt3EDhe8XiQ/69gZjQVIVrcpAgMB
AAGjggMxMIIDLTAMBgNVHRMBAf8EAjAAmgkga1udhwrimgawl6atocugkwh0dha6
Ly9jcmxzLnlhbmRleC5uZXQvY2VydHVtl3ljyxnoytiuy3jsmc2gk6aphidodhrw
Oi8veWFuZGV4LmNybC5jZXJ0dW0ucGwvewnhc2hhmi5jcmwwcqyikwybbquhaqee
ZTBjMCwGCCsGAQUFBzABhiBodHRwOi8vewfuzgv4lm9jc3atcmvzcg9uzgvylmnv
bTAzBggrBgEFBQcwAoYnaHR0cDovL3Jlcg9zaxrvcnkuy2vydhvtlnbsl3ljyxno
YTIuY2VyMB8GA1UdIwQYMBaAFDdc4xngso6hqe7sz6vq3omlxdvnmb0ga1uddgqw
BBQYy748oNmcZPHfTrybOrdqeu/mTDAOBgNVHQ8BAf8EBAMCBaAwggE/BgNVHSAE
ggE2MIIBMjCCAS4GDCqEaAGG9ncCBQEKajccarwwjqyikwybbquhagewgwh0dhbz
Oi8vd3d3LmNlcnR1bS5wbC9DUFMwgfIGccsgaqufbwicmihlmcawgvvuaxpldg8g
VGVjaG5vbG9naWVzIFMuQS4wAwIBAhqBwfvzywdlig9mihroaxmgy2vydglmawnh
dGUgaXMgc3RyaWN0bHkgc3ViamVjdGVkihrvihrozsbdrvjuvu0gq2vydglmawnh
dGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQgkenquykgaw5jb3jwb3jhdgvkigj5ihjl
ZmVyZW5jZSBoZXJlaW4gYW5kIGluIHRozsbyzxbvc2l0b3j5igf0igh0dhbzoi8v
d3d3LmNlcnR1bS5wbC9yZXBvc2l0b3J5ljadbgnvhsuefjaubggrbgefbqcdaqyi
KwYBBQUHAwIwEQYJYIZIAYb4QgEBBAQDagbamhoga1udeqrzmhgcdnntdhauewfu
ZGV4LmJ5gg5zbXRwLnlhbmRleC5reoIPc210cc55yw5kzxguy29tgg5zbxrwlnlh
bmRleC51YYISc210cC55YW5kZXguY29tlnryggpzbxrwlnlhlnj1gg5zbxrwlnlh
bmRleC5ydTANBgkqhkiG9w0BAQsFAAOCaqeaovcdtfhcdx1n6if0rbtztxjbu2tf
WcSYGu/Uif6EqqVsy44kQ8Yxresaqb8bR0FkJxSp1hxdwquxm18sdzdb4f/ealF4
Hb6ZmF5ilP0SNUccka4wI0DDTuMuBDstgbcvljpxtjhtwp9hyryoajsunux92blr
Uc11XnKQE9ltWEpKys9RQhTLDqPNrALa423zvn5jlkqmk6vvzutionroqfzmdxmq
KVVUtvGS7ZBmL8Z8ripEDBUFywAcxHC9djptuwxzus2cejbun6j0qkjp2f/aKJZR
GTgW095M/H1tEGjouYfSj21cy9ZDNiUqN1Yutg0+nGNexiRDghg44yWMeQ==
-----END CERTIFICATE-----
subject=/C=UA/O=Yandex LLC/OU=ITO/L=Moscow/ST=Ukrainian Federation/CN=smtp.yandex.ru/emailAddress=pki@yandex-team.ru
issuer=/C=UA/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA
---
No client certificate CA names sent
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 3581 bytes and written 373 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: C64B0AE4863B7F1A44ED0981E29F4D1E796F98F7FB0EF950A7A1588232F11ABC
Session-ID-ctx:
Master-Key: F704953E4A95AD4A1C06BBDF1425F4E5B1E2B8BE5EE5214484AC0DF9219E7185ABB38573904FA3CFD0B88A8FF3185061
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - b3 08 e7 79 5b 86 ba 5a-7e 71 bf f8 5f ad 66 4a ...y[..Z~q.._.fJ
0010 - 5b 4b c6 fe e4 ae 95 21-6e 60 b8 84 bd 09 8e 91 [K.....!n`......
0020 - ba a4 1e 29 b8 fc 7c 5b-72 16 ae 7e f6 f7 a9 e5 ...)..|[r..~....
0030 - 69 0a 4e 41 03 cc 79 3a-b4 f7 6d 99 81 a6 a2 ef i.NA..y:..m.....
0040 - c8 27 02 50 1d 68 0b 70-1f d1 d4 1a b7 d9 99 b8 .'.P.h.p........
0050 - b0 6d 47 ee 89 7d 5d 37-bd ab 89 a7 d2 d2 3d 1d .mG..}]7......=.
0060 - 2f e1 4b 85 ae eb ab de-3a f7 e2 18 ce 55 48 3b /.K.....:....UH;
0070 - 15 14 8f 69 45 bc 8a a4-77 b1 a0 8f 41 96 ea c7 ...iE...w...A...
0080 - f2 2d be e2 26 26 5a 06-1f f3 c0 fe 6b f7 de ab .-..&&Z.....k...
0090 - ab 04 f8 74 e5 b3 c9 25-c6 24 ba 88 44 50 3b 57 ...t...%.$..DP;W

Start Time: 1470992045
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
220 smtp2h.mail.yandex.net ESMTP (Want to use Yandex.Mail for your domain? Visit http://pdd.yandex.ru)

Відмінно, сертифікати з виведення нам знадобляться пізніше.

Реалізація
Для початку створимо Oracle wallet, в ньому ми будемо зберігати довірені сертифікати поштового сервера. Сертифікати можна взяти тут:


Стартуємо Oracle Wallet Manager командою ovm, створюємо новий wallet/задаємо пароль:


Імпортуємо довірені сертифікати, Operations > Import Trusted Certificate.:


Зберігаємо, за замовчуванням wallet зберігається тут
$ORACLE_HOME/owm/wallets/oracle/
. Далі необхідно дати права на виконання пакету UTL_SMTP:

GRANT EXECUTE on UTL_SMTP to SMTP_USER;

Створюємо ACL, даємо права на connect:

begin
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL 
( 
acl => 'smtp_acl.xml',
principal => 'SMTP_USER',
is_grant => TRUE, 
privilege => 'connect', 
); 
end;
/

На доступ до SMTP Яндекса:

begin
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL
(
acl => 'smtp_acl.xml',
host => 'smtp.yandex.ru',
lower_port => 1,
upper_port => 1024
);
end;
/

На використання wallet'а:

begin
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE
( 
acl => 'smtp_acl.xml',
principal => 'SMTP_USER',
is_grant => TRUE, 
privilege => 'use-client-certificates' 
);
end;
/

Задаємо шлях до wallet'а:

begin
DBMS_NETWORK_ACL_ADMIN.ASSIGN_WALLET_ACL
( 
acl => 'smtp_acl.xml',
wallet_path => 'file:/oracle_home/owm/wallets/oracle/'
);
end;
/

Так само нам знадобиться сконвертувати облікові дані щодо доступу до поштової скриньки(логін, пароль) base64:

select UTL_RAW.cast_to_varchar2 (
UTL_ENCODE.base64_encode (UTL_RAW.cast_to_raw ('user@yandex.ru'))) as username,
UTL_RAW.cast_to_varchar2 (
UTL_ENCODE.base64_encode (UTL_RAW.cast_to_raw ('password'))) as password
from dual;

Отримані хеші будемо застосовувати при SMTP аутентифікації.

Тестуємо!
DECLARE
c utl_smtp.connection;
l_mailhost VARCHAR2 (64) := 'smtp.yandex.ru';
l_from VARCHAR2 (64) := 'user@yandex.ru';
l_to VARCHAR2 (64) := 'user@gmail.com';
l_subject VARCHAR2 (64) := 'utl_smtp test';
crlf varchar2(2) := UTL_TCP.CRLF;
BEGIN
c := utl_smtp.open_connection(
host => l_mailhost,
port => 465,
wallet_path => 'file:/oracle_home/owm/wallets/oracle/',
wallet_password => 'password',
secure_connection_before_smtp => 'FALSE');

UTL_SMTP.STARTTLS©;
UTL_SMTP.EHLO(c, 'oracle');

utl_smtp.command( c, 'AUTH LOGIN');
utl_smtp.command( c, 'хеш на логін');
utl_smtp.command( c, 'хеш на пароль'); 

UTL_SMTP.mail (c, l_from);
UTL_SMTP.rcpt (c, l_to);
UTL_SMTP.open_data ©;
UTL_SMTP.write_data (c, 'Date:' || TO_CHAR (SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || crlf);
UTL_SMTP.write_data (c, 'From:' || l_from || crlf);
UTL_SMTP.write_data (c, 'Subject:' || l_subject || crlf);
UTL_SMTP.write_data (c, 'To:' || l_to || crlf);
UTL_SMTP.write_data (c, 'message test' || crlf);
UTL_SMTP.close_data ©;
UTL_SMTP.quit ©; 
END;
/

PL/SQL procedure successfully completed.

Повідомлення було успішно доставлене на gmail.com. Пункт 4.з реалізовано.

Спасибі за увагу!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.