Protections against attacks based on return-oriented programming

Detalhes bibliográficos
Autor(a) principal: Mateus Felipe Tymburibá Ferreira
Data de Publicação: 2020
Tipo de documento: Tese
Idioma: eng
Título da fonte: Repositório Institucional da UFMG
Texto Completo: http://hdl.handle.net/1843/38086
Resumo: Return-Oriented Programming (ROP) is the name of a technique used for the development of malicious code that has been widely used to force the execution of arbitrary code on vulnerable applications. Because of its wide use in attacks against modern computing systems, protections against ROP based exploits have been widely studied. Nevertheless, there is still no definitive solution against these attacks. This thesis introduces approaches that hinder the consolidation of such attacks. We created a static source code analysis that estimates the maximum density of indirect branch instructions executable by a program. Its importance stems from the fact that several protections monitor the density of indirect branches to detect ROP attacks. However, these mechanisms use unique thresholds: the frequency of indirect branches that characterizes an attack is the same for any application. In this work, we show that standard thresholds can be easily overcome. As an alternative, we created an algorithm that establishes the best threshold value for each application. Our analysis was implemented in the LLVM compiler and used to find specific thresholds for each benchmark of the SPEC CPU2006 suite. We proved the accuracy of our approach by comparing the estimated thresholds with real values obtained during the execution of these benchmarks in the Pin framework. While statically traversing all possible execution paths of a program is a theoretically undecidable problem in general situations, for the specific context of protection against ROP based attacks we managed to develop an algorithm that finds the solution for programs with up to 700,000 instructions in 25 minutes. In our second approach, we present a multilayer system to guard programs against ROP attacks. Upper layers validate most of a program's control flow at a low computational cost; thus, not compromising runtime. Lower layers provide strong enforcement guarantees to handle more suspicious flows; thus, enhancing security. Our multilayer solution combines techniques already described in the literature with a verification that we introduce: checking if the function call instruction that precedes a return address points to an executable segment of the program. We took care that our project uses micro-architectural units already available in modern versions of x86 processors. Our model imposes a small execution time overhead of 0.57% in a set of benchmarks composed by all 29 programs from SPEC CPU2006 and 209 benchmarks from the LLVM Test Suite. The new check we introduced to validate CALL instructions that precede return addresses is also effective. It reduces by almost 35x the number of gadgets available to build an attack, when compared to a similar technique traditionally employed in the literature. We also analyzed the number of false positives that slip through our layers of protection. In this experiment, we enriched our benchmark suite with the three most popular desktop browsers and four vulnerable applications for which there are known ROP exploits. Only 3.14% of all return addresses are considered invalid in these benchmarks. We demonstrate that the cost to treat these false positives bears no impact in the execution time of programs.
id UFMG_54f57159d5fa12a966ee41f564e8fa71
oai_identifier_str oai:repositorio.ufmg.br:1843/38086
network_acronym_str UFMG
network_name_str Repositório Institucional da UFMG
repository_id_str
spelling Fernando Magno Quintão Pereirahttp://lattes.cnpq.br/4608001746330875Sandro RigoHenrique Cota de FreitasÍtalo Fernando Scotá CunhaLeonardo Barbosa e Oliveirahttp://lattes.cnpq.br/5863316017246857Mateus Felipe Tymburibá Ferreira2021-09-20T00:16:52Z2021-09-20T00:16:52Z2020-07-17http://hdl.handle.net/1843/38086Return-Oriented Programming (ROP) is the name of a technique used for the development of malicious code that has been widely used to force the execution of arbitrary code on vulnerable applications. Because of its wide use in attacks against modern computing systems, protections against ROP based exploits have been widely studied. Nevertheless, there is still no definitive solution against these attacks. This thesis introduces approaches that hinder the consolidation of such attacks. We created a static source code analysis that estimates the maximum density of indirect branch instructions executable by a program. Its importance stems from the fact that several protections monitor the density of indirect branches to detect ROP attacks. However, these mechanisms use unique thresholds: the frequency of indirect branches that characterizes an attack is the same for any application. In this work, we show that standard thresholds can be easily overcome. As an alternative, we created an algorithm that establishes the best threshold value for each application. Our analysis was implemented in the LLVM compiler and used to find specific thresholds for each benchmark of the SPEC CPU2006 suite. We proved the accuracy of our approach by comparing the estimated thresholds with real values obtained during the execution of these benchmarks in the Pin framework. While statically traversing all possible execution paths of a program is a theoretically undecidable problem in general situations, for the specific context of protection against ROP based attacks we managed to develop an algorithm that finds the solution for programs with up to 700,000 instructions in 25 minutes. In our second approach, we present a multilayer system to guard programs against ROP attacks. Upper layers validate most of a program's control flow at a low computational cost; thus, not compromising runtime. Lower layers provide strong enforcement guarantees to handle more suspicious flows; thus, enhancing security. Our multilayer solution combines techniques already described in the literature with a verification that we introduce: checking if the function call instruction that precedes a return address points to an executable segment of the program. We took care that our project uses micro-architectural units already available in modern versions of x86 processors. Our model imposes a small execution time overhead of 0.57% in a set of benchmarks composed by all 29 programs from SPEC CPU2006 and 209 benchmarks from the LLVM Test Suite. The new check we introduced to validate CALL instructions that precede return addresses is also effective. It reduces by almost 35x the number of gadgets available to build an attack, when compared to a similar technique traditionally employed in the literature. We also analyzed the number of false positives that slip through our layers of protection. In this experiment, we enriched our benchmark suite with the three most popular desktop browsers and four vulnerable applications for which there are known ROP exploits. Only 3.14% of all return addresses are considered invalid in these benchmarks. We demonstrate that the cost to treat these false positives bears no impact in the execution time of programs.Programação Orientada a Retornos (ou ROP, de Return-Oriented Programming) é o nome de uma técnica usada para o desenvolvimento de códigos maliciosos que vem sendo amplamente utilizada para forçar a execução de códigos arbitrários em aplicações vulneráveis. Em função de seu vasto emprego em investidas contra sistemas computacionais modernos, proteções contra ROP têm sido extensamente estudadas. Apesar disso, ainda não existe uma solução definitiva contra esses ataques. Esta tese introduz abordagens que dificultam a consolidação de ataques dessa natureza. Criamos uma análise estática de código-fonte que estima a densidade máxima de instruções de desvio indireto executável por um programa. Sua importância advém do fato de que diversas proteções monitoram a densidade de desvios indiretos, a fim de detectar ataques ROP. Contudo, esses mecanismos utilizam limiares únicos: a frequência de desvios indiretos que caracteriza um ataque é a mesma para qualquer aplicação. Neste trabalho, mostramos que limiares padrão podem ser superados facilmente. Como alternativa, criamos um algoritmo que estabelece o melhor valor de limiar para cada aplicação. Nossa análise foi implementada no compilador LLVM e utilizada para encontrar limiares específicos para cada benchmark que compõe o SPEC CPU2006. Comprovamos a acurácia da nossa abordagem comparando os limiares estimados com valores reais obtidos durante a execução desses benchmarks no framework Pin. Apesar de percorrer estaticamente todos os possíveis caminhos de execução de um programa ser um problema teoricamente indecidível em situações gerais, para o contexto expecífico de proteção contra ataques baseados em ROP nós conseguimos desenvolver um algoritmo que encontra a solução para programas com até 700 mil instruções em 25 minutos. Em nossa segunda abordagem, apresentamos um sistema multicamadas para proteger programas contra ataques ROP. As camadas superiores validam a maior parte do fluxo de controle de um programa a um baixo custo computacional; portanto, não comprometendo o tempo de execução. As camadas inferiores fornecem fortes garantias para lidar com fluxos mais suspeitos; aumentando assim a segurança. Nossa solução multicamadas combina técnicas já descritas na literatura com uma verificação que introduzimos: checar se a instrução de chamada de função que precede um endereço de retorno aponta para um segmento executável do programa. Cuidamos para que nosso projeto utilize unidades microarquiteturais já disponíveis nas versões modernas dos processadores x86. Nosso modelo impõe uma sobrecarga no tempo de execução de apenas 0,57% em um conjunto de benchmarks compostos por todos os 29 programas do SPEC CPU2006 e 209 benchmarks do LLVM Test Suite. A nova verificação que introduzimos para validar as instruções CALL que precedem os endereços de retorno também é efetiva. Ela reduz em quase 35x o número de gadgets disponíveis para criar um ataque, quando comparada a uma técnica semelhante tradicionalmente empregada na literatura. Também analisamos o número de falsos positivos que atravessam nossas camadas de proteção. Nesse experimento, enriquecemos nosso conjunto de benchmarks com os três navegadores de desktop mais populares e quatro aplicativos vulneráveis para os quais existem explorações ROP conhecidas. Apenas 3,14% de todos os endereços de retorno são considerados inválidos nesses benchmarks. Demonstramos que o custo para tratar esses falsos positivos não afeta o tempo de execução dos programas.CAPES - Coordenação de Aperfeiçoamento de Pessoal de Nível SuperiorengUniversidade Federal de Minas GeraisPrograma de Pós-Graduação em Ciência da ComputaçãoUFMGBrasilICEX - INSTITUTO DE CIÊNCIAS EXATAShttp://creativecommons.org/licenses/by-nc-nd/3.0/pt/info:eu-repo/semantics/openAccessComputação – Teses.Compiladores (Programas de computador) – Teses.Programação (Computadores) – Teses.Algoritmos de computador – Teses.Programação Orientada a Retornos – Teses..Computação - Medidas de segurança - Teses.Return-oriented programmingProtectionSecurityStatic code analysisMultilayersProtections against attacks based on return-oriented programmingProteções contra ataques baseados em programação orientada a retornosinfo:eu-repo/semantics/publishedVersioninfo:eu-repo/semantics/doctoralThesisreponame:Repositório Institucional da UFMGinstname:Universidade Federal de Minas Gerais (UFMG)instacron:UFMGORIGINALTese_Mateus_Tymburiba-final-sem-pgs-branco.pdfTese_Mateus_Tymburiba-final-sem-pgs-branco.pdfapplication/pdf4284373https://repositorio.ufmg.br/bitstream/1843/38086/4/Tese_Mateus_Tymburiba-final-sem-pgs-branco.pdf10619aaa3ee72319bbd85761b8cc5bd5MD54LICENSElicense.txtlicense.txttext/plain; charset=utf-82118https://repositorio.ufmg.br/bitstream/1843/38086/5/license.txtcda590c95a0b51b4d15f60c9642ca272MD55CC-LICENSElicense_rdflicense_rdfapplication/rdf+xml; charset=utf-8811https://repositorio.ufmg.br/bitstream/1843/38086/2/license_rdfcfd6801dba008cb6adbd9838b81582abMD521843/380862021-09-19 21:16:52.54oai:repositorio.ufmg.br:1843/38086TElDRU7Dh0EgREUgRElTVFJJQlVJw4fDg08gTsODTy1FWENMVVNJVkEgRE8gUkVQT1NJVMOTUklPIElOU1RJVFVDSU9OQUwgREEgVUZNRwoKQ29tIGEgYXByZXNlbnRhw6fDo28gZGVzdGEgbGljZW7Dp2EsIHZvY8OqIChvIGF1dG9yIChlcykgb3UgbyB0aXR1bGFyIGRvcyBkaXJlaXRvcyBkZSBhdXRvcikgY29uY2VkZSBhbyBSZXBvc2l0w7NyaW8gSW5zdGl0dWNpb25hbCBkYSBVRk1HIChSSS1VRk1HKSBvIGRpcmVpdG8gbsOjbyBleGNsdXNpdm8gZSBpcnJldm9nw6F2ZWwgZGUgcmVwcm9kdXppciBlL291IGRpc3RyaWJ1aXIgYSBzdWEgcHVibGljYcOnw6NvIChpbmNsdWluZG8gbyByZXN1bW8pIHBvciB0b2RvIG8gbXVuZG8gbm8gZm9ybWF0byBpbXByZXNzbyBlIGVsZXRyw7RuaWNvIGUgZW0gcXVhbHF1ZXIgbWVpbywgaW5jbHVpbmRvIG9zIGZvcm1hdG9zIMOhdWRpbyBvdSB2w61kZW8uCgpWb2PDqiBkZWNsYXJhIHF1ZSBjb25oZWNlIGEgcG9sw610aWNhIGRlIGNvcHlyaWdodCBkYSBlZGl0b3JhIGRvIHNldSBkb2N1bWVudG8gZSBxdWUgY29uaGVjZSBlIGFjZWl0YSBhcyBEaXJldHJpemVzIGRvIFJJLVVGTUcuCgpWb2PDqiBjb25jb3JkYSBxdWUgbyBSZXBvc2l0w7NyaW8gSW5zdGl0dWNpb25hbCBkYSBVRk1HIHBvZGUsIHNlbSBhbHRlcmFyIG8gY29udGXDumRvLCB0cmFuc3BvciBhIHN1YSBwdWJsaWNhw6fDo28gcGFyYSBxdWFscXVlciBtZWlvIG91IGZvcm1hdG8gcGFyYSBmaW5zIGRlIHByZXNlcnZhw6fDo28uCgpWb2PDqiB0YW1iw6ltIGNvbmNvcmRhIHF1ZSBvIFJlcG9zaXTDs3JpbyBJbnN0aXR1Y2lvbmFsIGRhIFVGTUcgcG9kZSBtYW50ZXIgbWFpcyBkZSB1bWEgY8OzcGlhIGRlIHN1YSBwdWJsaWNhw6fDo28gcGFyYSBmaW5zIGRlIHNlZ3VyYW7Dp2EsIGJhY2stdXAgZSBwcmVzZXJ2YcOnw6NvLgoKVm9jw6ogZGVjbGFyYSBxdWUgYSBzdWEgcHVibGljYcOnw6NvIMOpIG9yaWdpbmFsIGUgcXVlIHZvY8OqIHRlbSBvIHBvZGVyIGRlIGNvbmNlZGVyIG9zIGRpcmVpdG9zIGNvbnRpZG9zIG5lc3RhIGxpY2Vuw6dhLiBWb2PDqiB0YW1iw6ltIGRlY2xhcmEgcXVlIG8gZGVww7NzaXRvIGRlIHN1YSBwdWJsaWNhw6fDo28gbsOjbywgcXVlIHNlamEgZGUgc2V1IGNvbmhlY2ltZW50bywgaW5mcmluZ2UgZGlyZWl0b3MgYXV0b3JhaXMgZGUgbmluZ3XDqW0uCgpDYXNvIGEgc3VhIHB1YmxpY2HDp8OjbyBjb250ZW5oYSBtYXRlcmlhbCBxdWUgdm9jw6ogbsOjbyBwb3NzdWkgYSB0aXR1bGFyaWRhZGUgZG9zIGRpcmVpdG9zIGF1dG9yYWlzLCB2b2PDqiBkZWNsYXJhIHF1ZSBvYnRldmUgYSBwZXJtaXNzw6NvIGlycmVzdHJpdGEgZG8gZGV0ZW50b3IgZG9zIGRpcmVpdG9zIGF1dG9yYWlzIHBhcmEgY29uY2VkZXIgYW8gUmVwb3NpdMOzcmlvIEluc3RpdHVjaW9uYWwgZGEgVUZNRyBvcyBkaXJlaXRvcyBhcHJlc2VudGFkb3MgbmVzdGEgbGljZW7Dp2EsIGUgcXVlIGVzc2UgbWF0ZXJpYWwgZGUgcHJvcHJpZWRhZGUgZGUgdGVyY2Vpcm9zIGVzdMOhIGNsYXJhbWVudGUgaWRlbnRpZmljYWRvIGUgcmVjb25oZWNpZG8gbm8gdGV4dG8gb3Ugbm8gY29udGXDumRvIGRhIHB1YmxpY2HDp8OjbyBvcmEgZGVwb3NpdGFkYS4KCkNBU08gQSBQVUJMSUNBw4fDg08gT1JBIERFUE9TSVRBREEgVEVOSEEgU0lETyBSRVNVTFRBRE8gREUgVU0gUEFUUk9Dw41OSU8gT1UgQVBPSU8gREUgVU1BIEFHw4pOQ0lBIERFIEZPTUVOVE8gT1UgT1VUUk8gT1JHQU5JU01PLCBWT0PDiiBERUNMQVJBIFFVRSBSRVNQRUlUT1UgVE9ET1MgRSBRVUFJU1FVRVIgRElSRUlUT1MgREUgUkVWSVPDg08gQ09NTyBUQU1Cw4lNIEFTIERFTUFJUyBPQlJJR0HDh8OVRVMgRVhJR0lEQVMgUE9SIENPTlRSQVRPIE9VIEFDT1JETy4KCk8gUmVwb3NpdMOzcmlvIEluc3RpdHVjaW9uYWwgZGEgVUZNRyBzZSBjb21wcm9tZXRlIGEgaWRlbnRpZmljYXIgY2xhcmFtZW50ZSBvIHNldSBub21lKHMpIG91IG8ocykgbm9tZXMocykgZG8ocykgZGV0ZW50b3IoZXMpIGRvcyBkaXJlaXRvcyBhdXRvcmFpcyBkYSBwdWJsaWNhw6fDo28sIGUgbsOjbyBmYXLDoSBxdWFscXVlciBhbHRlcmHDp8OjbywgYWzDqW0gZGFxdWVsYXMgY29uY2VkaWRhcyBwb3IgZXN0YSBsaWNlbsOnYS4KRepositório de PublicaçõesPUBhttps://repositorio.ufmg.br/oaiopendoar:2021-09-20T00:16:52Repositório Institucional da UFMG - Universidade Federal de Minas Gerais (UFMG)false
dc.title.pt_BR.fl_str_mv Protections against attacks based on return-oriented programming
dc.title.alternative.pt_BR.fl_str_mv Proteções contra ataques baseados em programação orientada a retornos
title Protections against attacks based on return-oriented programming
spellingShingle Protections against attacks based on return-oriented programming
Mateus Felipe Tymburibá Ferreira
Return-oriented programming
Protection
Security
Static code analysis
Multilayers
Computação – Teses.
Compiladores (Programas de computador) – Teses.
Programação (Computadores) – Teses.
Algoritmos de computador – Teses.
Programação Orientada a Retornos – Teses..
Computação - Medidas de segurança - Teses.
title_short Protections against attacks based on return-oriented programming
title_full Protections against attacks based on return-oriented programming
title_fullStr Protections against attacks based on return-oriented programming
title_full_unstemmed Protections against attacks based on return-oriented programming
title_sort Protections against attacks based on return-oriented programming
author Mateus Felipe Tymburibá Ferreira
author_facet Mateus Felipe Tymburibá Ferreira
author_role author
dc.contributor.advisor1.fl_str_mv Fernando Magno Quintão Pereira
dc.contributor.advisor1Lattes.fl_str_mv http://lattes.cnpq.br/4608001746330875
dc.contributor.referee1.fl_str_mv Sandro Rigo
dc.contributor.referee2.fl_str_mv Henrique Cota de Freitas
dc.contributor.referee3.fl_str_mv Ítalo Fernando Scotá Cunha
dc.contributor.referee4.fl_str_mv Leonardo Barbosa e Oliveira
dc.contributor.authorLattes.fl_str_mv http://lattes.cnpq.br/5863316017246857
dc.contributor.author.fl_str_mv Mateus Felipe Tymburibá Ferreira
contributor_str_mv Fernando Magno Quintão Pereira
Sandro Rigo
Henrique Cota de Freitas
Ítalo Fernando Scotá Cunha
Leonardo Barbosa e Oliveira
dc.subject.por.fl_str_mv Return-oriented programming
Protection
Security
Static code analysis
Multilayers
topic Return-oriented programming
Protection
Security
Static code analysis
Multilayers
Computação – Teses.
Compiladores (Programas de computador) – Teses.
Programação (Computadores) – Teses.
Algoritmos de computador – Teses.
Programação Orientada a Retornos – Teses..
Computação - Medidas de segurança - Teses.
dc.subject.other.pt_BR.fl_str_mv Computação – Teses.
Compiladores (Programas de computador) – Teses.
Programação (Computadores) – Teses.
Algoritmos de computador – Teses.
Programação Orientada a Retornos – Teses..
Computação - Medidas de segurança - Teses.
description Return-Oriented Programming (ROP) is the name of a technique used for the development of malicious code that has been widely used to force the execution of arbitrary code on vulnerable applications. Because of its wide use in attacks against modern computing systems, protections against ROP based exploits have been widely studied. Nevertheless, there is still no definitive solution against these attacks. This thesis introduces approaches that hinder the consolidation of such attacks. We created a static source code analysis that estimates the maximum density of indirect branch instructions executable by a program. Its importance stems from the fact that several protections monitor the density of indirect branches to detect ROP attacks. However, these mechanisms use unique thresholds: the frequency of indirect branches that characterizes an attack is the same for any application. In this work, we show that standard thresholds can be easily overcome. As an alternative, we created an algorithm that establishes the best threshold value for each application. Our analysis was implemented in the LLVM compiler and used to find specific thresholds for each benchmark of the SPEC CPU2006 suite. We proved the accuracy of our approach by comparing the estimated thresholds with real values obtained during the execution of these benchmarks in the Pin framework. While statically traversing all possible execution paths of a program is a theoretically undecidable problem in general situations, for the specific context of protection against ROP based attacks we managed to develop an algorithm that finds the solution for programs with up to 700,000 instructions in 25 minutes. In our second approach, we present a multilayer system to guard programs against ROP attacks. Upper layers validate most of a program's control flow at a low computational cost; thus, not compromising runtime. Lower layers provide strong enforcement guarantees to handle more suspicious flows; thus, enhancing security. Our multilayer solution combines techniques already described in the literature with a verification that we introduce: checking if the function call instruction that precedes a return address points to an executable segment of the program. We took care that our project uses micro-architectural units already available in modern versions of x86 processors. Our model imposes a small execution time overhead of 0.57% in a set of benchmarks composed by all 29 programs from SPEC CPU2006 and 209 benchmarks from the LLVM Test Suite. The new check we introduced to validate CALL instructions that precede return addresses is also effective. It reduces by almost 35x the number of gadgets available to build an attack, when compared to a similar technique traditionally employed in the literature. We also analyzed the number of false positives that slip through our layers of protection. In this experiment, we enriched our benchmark suite with the three most popular desktop browsers and four vulnerable applications for which there are known ROP exploits. Only 3.14% of all return addresses are considered invalid in these benchmarks. We demonstrate that the cost to treat these false positives bears no impact in the execution time of programs.
publishDate 2020
dc.date.issued.fl_str_mv 2020-07-17
dc.date.accessioned.fl_str_mv 2021-09-20T00:16:52Z
dc.date.available.fl_str_mv 2021-09-20T00:16:52Z
dc.type.status.fl_str_mv info:eu-repo/semantics/publishedVersion
dc.type.driver.fl_str_mv info:eu-repo/semantics/doctoralThesis
format doctoralThesis
status_str publishedVersion
dc.identifier.uri.fl_str_mv http://hdl.handle.net/1843/38086
url http://hdl.handle.net/1843/38086
dc.language.iso.fl_str_mv eng
language eng
dc.rights.driver.fl_str_mv http://creativecommons.org/licenses/by-nc-nd/3.0/pt/
info:eu-repo/semantics/openAccess
rights_invalid_str_mv http://creativecommons.org/licenses/by-nc-nd/3.0/pt/
eu_rights_str_mv openAccess
dc.publisher.none.fl_str_mv Universidade Federal de Minas Gerais
dc.publisher.program.fl_str_mv Programa de Pós-Graduação em Ciência da Computação
dc.publisher.initials.fl_str_mv UFMG
dc.publisher.country.fl_str_mv Brasil
dc.publisher.department.fl_str_mv ICEX - INSTITUTO DE CIÊNCIAS EXATAS
publisher.none.fl_str_mv Universidade Federal de Minas Gerais
dc.source.none.fl_str_mv reponame:Repositório Institucional da UFMG
instname:Universidade Federal de Minas Gerais (UFMG)
instacron:UFMG
instname_str Universidade Federal de Minas Gerais (UFMG)
instacron_str UFMG
institution UFMG
reponame_str Repositório Institucional da UFMG
collection Repositório Institucional da UFMG
bitstream.url.fl_str_mv https://repositorio.ufmg.br/bitstream/1843/38086/4/Tese_Mateus_Tymburiba-final-sem-pgs-branco.pdf
https://repositorio.ufmg.br/bitstream/1843/38086/5/license.txt
https://repositorio.ufmg.br/bitstream/1843/38086/2/license_rdf
bitstream.checksum.fl_str_mv 10619aaa3ee72319bbd85761b8cc5bd5
cda590c95a0b51b4d15f60c9642ca272
cfd6801dba008cb6adbd9838b81582ab
bitstream.checksumAlgorithm.fl_str_mv MD5
MD5
MD5
repository.name.fl_str_mv Repositório Institucional da UFMG - Universidade Federal de Minas Gerais (UFMG)
repository.mail.fl_str_mv
_version_ 1797971158323167232