Exploiting an Integer Overflow (Fire and Ice) - Pwn Adventure 3
Key Takeaways
This video teaches exploiting an integer overflow in Pwn Adventure 3 to kill the boss Magmarok in the Fire & Ice Dungeon
Full Transcript
remember the boss magma rock in the Fire & Ice dungeon it's part of another quest a flag that we still need to get magma rock shoots fireballs and when he gets below half of his health he will heal himself up here's a clip from the let's play episode ok let's try this again yeah that's easy easy easy look at these skills I have this movement oh [ __ ] what is he doing now He healed kikyo like I mentioned previously the motivation for me to make the series came from Antonov bozo asking me originally to make videos about porn adventure 3 and he shared his workshop slides covering porn in 2003 with me however the CTF has always been something I wanted to do myself so he was a huge help and was of course the spark to motivate me to finally do it that means I didn't want any spoilers but he did spoil me a little bit in this very first message to me he suggested that I could make a video about the double integer overflow to kill the boss turn turn turn so anyway I knew that we had to kill magma rock with 1 or 2 integer overflows and I'm not going to pretend I didn't know that and make up a story how I figured it out myself nevertheless I think it's still interesting to actually find it it happens sometimes that you hear a software has a certain back but not technical details are known yet so you have to find it yourself and that's what I tried to do the past few videos were about reverse engineering the network protocol developing all proxy and parsing packets and I will be using that heavily here I edit again a few more packets to the parcel off-camera one you packet in particular is very important here and that is the update health packet it's a simple packet it is sent from the server to the client and comes with a health value and an ID to identify whose health it is you might discover this packet when you get damaged and slowly regenerate but you also get the health value of the monsters that you damage while implementing this I first defined the health to be an unsigned integer indicated by the capital I when unpacking the binary data though when I killed the spider I noticed that the health suddenly is extremely large and that doesn't make sense so this means we interpreted the binary data wrong in fact this tells me this is supposed to be assigned in Tijera unsigned integers are just positive numbers while signed integers means that certain binary values are interpreted as negative numbers and changing the parsing to a lowercase I shows us now a nice negative value for when we kill the spider so we keep in mind that the health is a sign value I don't want to explain here in detail how site and unsigned numbers work so I created a short bonus episode for those of you who need some additional information but with this knowledge we can put together a plan to find this mysterious integer overflow we are looking for where unsigned and site numbers are somehow carelessly mixed together in assemble this means we are looking for signed and unsigned operations in the bonus video I have shown you that addition works perfectly fine with signed and unsigned values so that wouldn't be a difference in assembler the difference is in how we interpret this data and one such interpretation happens with comparisons because with signed values minus one is smaller than a one but the equivalent unsigned value hex ffff 4.2 billions is much larger than a 1 in an x86 assembler we have different instructions for that for example for a signed comparison we would do jle jump if less or equal while with unsigned values we would do jump be jump if below or equal so greater and less than our signed interpretations of data while above and below is the unsigned interpretation and that helps us now with our plan we essentially look for where a side value like the health is handled with an unsigned instruction like below or above or the other way around we take an unsigned value and compared with less or greater instructions so a good start to look is the damage function for magma rock because in the end dealing damage to mark nirach is the only way how we as a player can interact with him or in more abstract terms that is the only input we can give to the magma Rock program this function takes an actor in item the amount of damage and the damage type as parameters we can control the damage and type of damage based on the weapon or spell views from our time debugging the game with gdb or from enums Ida recognized we know that there is physical damage fire damage cold damage and shock damage if we compare a little bit how Ida and binary ninja this assemble the damage function we can see that Ida displays a bit more information in fact it names certain variables it was able to get from the debug information embedded in the binary but we can do some of this by hand in binary ninja as well you see that it shows the types of the parameters here but didn't set the type or name of the parameters so we know our Guan is the this pointer pointing to the magma of object itself this is an actor probably our player an item and damage and damage type and we can also see here based on the calling convention which parameters correspond to which register and thus we know what kind of local variables are set here from the parameters but if we compare that now to Ida will realize that something is not right Ida said that the type would come from RSI while we thought r8 is the source so what is true now well if he would blindly rely on Ida you would have a hard time understanding what's going on but this is only true for Ida 60 for free version I don't know if it was a buck or if this analysis is only a feature from more advanced plugins in the pro version but when I asked my friend to open it in a recent version then Ida Pro does it correct so the point of the story is I rarely rely on one tool I don't understand Ida or any other tool well enough to be able to figure out issues like this I'm sure a professional reverse engineer has no issues with that but I like to compare the output from binary ninja Ida hopper radare and whatever it helps me understand this stuff better anyway let's have a closer look first we compare the damage type to one if it was not equal to one we go over here so if it's not fire damage because that is type one then we check if it's cold damage type two if it's equal we would go down here but if it's not equal so any other kind of damage we load a two into EAX move it into this address here load the damage amount into ECX load the two again down here and then perform a division so we divide the damage by two however if the damage was fire damage we go into this crazy block and xmm registers usually means that there are some floating-point calculations and there's a power float function so it takes some value to the power of something reading this forward is always a bit ugly but we can also back trace so after all of this the damage is set from EAX and e^x comes from this variable but is subtracted from zero so this makes it negative this means the damage value that was calculated is actually more like a healing value negative damages healing so let's rename it to healing and healing could be set in this block to whatever is in this unknown variable but healing is only set here if the condition before is false and it compares here the healing to that unknown value so if this unknown value is smaller than the healing then healing is set to that value which means there is a cap on the amount of healing that is calculated so doing healing larger than that value is not allowed and don't forget we are hunting for integer overflow so we need to pay attention to these comparisons and here we have JBE which is an unsigned comparison and this unknown value is the result of a subtraction from a fixed value hex to seven one zero which is ten thousand and decimal and it's subtracting a value stored at the offset hex 3/8 from our ax and our IX is this this is appointed to the current magma ROC object so taking an offset from that address means we are referring to an attribute of magma Rock let's investigate this with gdb first we need to set a breakpoint somewhere in this function and this is an external library we can't simply copy the address here but gdb knows the symbols and addresses so we can just disassemble the macro of damage function and also set a breakpoint there now we just have to walk up to magma Rock and shoot with something at him to trigger the damage function and we hit the breakpoint let's walk a few steps forward so the function prologue is done and then print this so you can see this is appointed to a magma Rock object and by dereferencing the pointer went printing we can also print the whole object including the attributes coming from inherited classes such as actor so for example mark nirach has 10,000 health or he has an attribute that healing is active and we know he can heal himself with gdb we can also now learn more about the offsets for example we can get the address of where M health is stored and calculate the offset from where magma rockstars which turns out to be hex 3/8 and the healing active attribute at offset hex 1 for 8 I've chosen to those 2 because they will be important but of course you could map out all of them like that and that is super useful for reversing with a disassembler we now head to the structures in binary ninja and create a new one that we call magma Rob and let's give it some size like hex 150 so we can fit both attributes we know in there now we don't know the other fields but we know that at offset hex 3/8 we have an integer health and at hex 1 for 8 we have a pool for healing active then we go back to our damage function and change the type from the default integer that was set for this to a magma rock pointer and now look the pointer was automatically resolved in binary ninja can tell us now that this is an offset to the health cool right so defining structures once you learn more about what stuff means is part of reversing like renaming functions and variables and so forth you slowly build up the whole picture now we know the current health of magma rock is subtracted from 10,000 so our unknown value could be called health difference it's a difference between the full health and where magma Rock currently is at so if the health difference is smaller than the healing we wanted to do then the healing is kept at the difference let's do an example if magma Rock has 9800 health then the difference is 200 and when we try to heal for 500 health points then that would be larger than 200 then the healing would be kept set to that value so we can't heal more than up to 10,000 now remember here we have an unsigned comparison on the result of a hard code at 10,000 minus the current health of Magna Rock and subtraction is always very tricky there is no check if the health is larger than 10,000 so this unsigned comparison could really screw up if the health of mark maroc were larger than 10,000 for example if the health were 15,000 then subtracting 15,000 from 10,000 would result in minus 5,000 if interpreted as a signed value but minus 5,000 is a huge value if interpreted as unsigned and so this unsigned check JBE would interpret the result as hex ffff EC 7/8 or 2.5 billion so if we now would try to heal for 5,000 HP then the check would say no 2.5 billion is not smaller than what we try to heal so we don't cap and allow to heal if this would have been a sign check so jle jump if less or equal then yeah it would be interpreted as minus 5,000 which would be smaller than the 500 we try to heal so this thing here could be unsafe if we somehow can get the health of mark nirach higher than 10,000 if it's not higher than 10,000 then the subtraction would not overflow the integer and apply a cap to the healing so while we can heal magma up with fireballs this check will always prevent us to heal higher than 10,000 so it's kind of like a chicken and egg problem right if the health would be higher than 10k we could heal him even higher but if the health is below or equal to 10k we can only heal him up to 10k but theoretically we know that the health is a signed integer we know that from killing spiders that had a negative health so if we can keep healing magma rocks so high that the value doesn't fit in a 32-bit signed integer anymore it overflows wraps around to a negative value then magma rock would be instantly dead but the problem is by itself this function here is safe we can't heal over 10 K but we know that magma Rock can also heal himself so there's a second logic somewhere that manipulates magma rocks health so if we somehow can abuse that to get over 10,000 health then we have a clear path laid out to kill Mack so now how do we find that a good way to start is just by looking at the other mark nirach functions and the tick is a function that is constantly called it's a tick like on a clock this function exists for a lot of objects so they can update their behavior according to the game's time so if mark nirach would do something it most likely would originate from in here like with any object function the first parameter is the this pointer this parameter points to the current map arak object and is passed in via RDI and so here we can see Rd is used a few times so we can change all the types to a matter of pointer and we can already see that here it checks if healing is active and the health is referenced multiple times as well now if the healing is one so true active we check if the health is less or equal to zero basically checking if Mac maroc is still alive and as you know this is a sign comparison so a negative health would be interpreted here properly then we check if Mac marks health is greater than or equal to 5,000 which we know is a trigger for healing when we got him to 50% health he initiated his healing sequence so if healing is not active he is not dead and health is under 5,000 he will switch into healing mode at least that's what I guess I haven't really reversed how the states work in this game I just see something is referenced here and it wouldn't make sense to me but we are looking for where the health is modified so let's look for something that sets or modifies the health I really wish we could look for cross references to the health attribute anyway here's one example the health is moved into EC X then we add hex 1 3 6 F to it that's 4975 in decimal and the result of the addition is moved into health so we know there is a delay between mark maroc going into healing where he does his animation and then actually healing up do you see the issue there's a race condition here a time of check time of use kind of thing the decision of mark merabh is going to heal is decided when he falls under 5,000 HP but then the actual healing happens later and the healing is not just setting the health back to 10k it's actually adding 4975 to the health this means we can push magma rock over 10,000 health we just have to kick him into healing mode by damaging him in as soon as he falls under 5,000 and he decides he's going to heal but first has to cast a spell and the animation starts we quickly switched to fireballs to heal him back up over 5,000 25 health because then a few seconds later his healing spell succeeds and heals him up for 4975 HP which then pushes him over 10k and by pushing him over 10k we know we can bypass this healing cap and keep healing him with fireballs and that could maybe kill him because healing too much can cause an integer overflow of his health making his health suddenly negative and thus instantly kill him to pull that off I modified the network proxy a bit and shoot the great balls of fire and zero cool straight down and collect those packets both of these packets cause the magic spell being shot straight down and we also know the position of mark maroc from the actors list so what we can do is we can craft a position update packet and tell the server we are standing above magma rock by setting a higher Z value than him and then we send the chute packet and because we never actually moved there the kind will keep sending the real position updates this means the server thinks we are always teleporting above magma Rock Shooter spell and teleport back we had to save chests I was thinking about how to trigger this from the game and decided to place the creation and injection of these packets into the sneaking Parsa so when we press down the sneak button this packet is sent to the server we parse it here and maybe decide to inject the two packets into the traffic and this makes fireballs or ice balls rain onto magma Rock cool huh we basically invented a new spell a meteor shower so all we have to do now is carefully damage him with cold spells or other attacks and observe his health once we get close to 5,000 we have to be careful okay now a bit of damage is missing now I take it slow I exchanged the zero cool spell with the great balls of fire spell so pressing sneak now will cast a fireball in him that will also heal him then I switched to a pistol with low damage shoot him with it in this pushes him under five thousand HP and initiate his healing sequence now we have a couple of seconds time to heal him above the threshold with some fireballs by pressing sneak healing is coming okay we were successful his healing spell is over he healed up in his health is above 10k now we just have to keep healing him and that should eventually kill him see how he sometimes shoots up that's because even though we stand here we tell the soul we are actually above him to shoot a fireball so for a split second Matt Rock thinks we are there you can see here these signed and unsigned rawhide values as a comparison at some point his health will overflow and kill him quest complete fire and ice let's loot the chests acquired flag of the lava some bosses just roll over and die [Music] you [Music]
Original Description
Part 12: Killing the boss Magmarok in the Fire & Ice Dungeon with an integer overflow.
Bonus Video Part 12.2: https://www.youtube.com/watch?v=9NYleo0r4Eg
🌴 Playlist: https://www.youtube.com/playlist?list=PLhixgUqwRTjzzBeFSHXrw9DnQtssdAwgG
-=[ ❤️ Support ]=-
→ per Video: https://www.patreon.com/join/liveoverflow
→ per Month: https://www.youtube.com/channel/UClcE-kVhqyiHCcjYwcpfj9w/join
-=[ 🐕 Social ]=-
→ Twitter: https://twitter.com/LiveOverflow/
→ Website: https://liveoverflow.com/
→ Subreddit: https://www.reddit.com/r/LiveOverflow/
→ Facebook: https://www.facebook.com/LiveOverflow/
-=[ 📄 P.S. ]=-
All links with "*" are affiliate links.
LiveOverflow / Security Flag GmbH is part of the Amazon Affiliate Partner Programm.
#PwnAdventure #CTF
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from LiveOverflow · LiveOverflow · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
LiveOverflow - Trailer
LiveOverflow
Introduction to Linux - Installation and the Terminal - bin 0x01
LiveOverflow
Writing a simple Program in C
LiveOverflow
Writing a simple Program in Python - bin 0x03
LiveOverflow
Live Hacking - Twitch Recording overthewire.org - Vortex 0x01-0x03 (3h)
LiveOverflow
Reversing and Cracking first simple Program - bin 0x05
LiveOverflow
Abusing the exception handler to leak flag - 32C3CTF readme (pwnable 200)
LiveOverflow
ROP with a very small stack - 32C3CTF teufel (pwnable 200)
LiveOverflow
Uncrackable Programs? Key validation with Algorithm and creating a Keygen - Part 1/2 - bin 0x07
LiveOverflow
Uncrackable Program? Finding a Parser Differential in loading ELF - Part 2/2 - bin 0x08
LiveOverflow
Syscalls, Kernel vs. User Mode and Linux Kernel Source Code - bin 0x09
LiveOverflow
Smashing the Stack for Fun and Profit - setuid, ssh and exploit.education - bin 0x0B
LiveOverflow
Live Hacking - EFF-CTF 2016 - Level 0-4 (Enigma Conference)
LiveOverflow
First Stack Buffer Overflow to modify Variable - bin 0x0C
LiveOverflow
First Exploit! Buffer Overflow with Shellcode - bin 0x0E
LiveOverflow
Buffer Overflows can Redirect Program Execution - bin 0x0D
LiveOverflow
Doing ret2libc with a Buffer Overflow because of restricted return pointer - bin 0x0F
LiveOverflow
Reverse engineering C programs (64bit vs 32bit) - bin 0x10
LiveOverflow
pwnable.kr - Levels: fd, collision, bof, flag
LiveOverflow
Reverse Engineering and identifying Bugs - BKPCTF cookbook (pwn 6) part 1
LiveOverflow
Leaking Heap and Libc address - BKPCTF cookbook (pwn 6) part 2
LiveOverflow
Arbitrary write with House of Force (heap exploit) - BKPCTF cookbook (pwn 6) part 3
LiveOverflow
Live Hacking - Internetwache CTF 2016 - web50, web60, web80
LiveOverflow
Live Hacking - Internetwache CTF 2016 - crypto60, crypto70, crypto90
LiveOverflow
A simple Format String exploit example - bin 0x11
LiveOverflow
NEW VIDEOS ARE COMING - loopback 0x00
LiveOverflow
HTML + CSS + JavaScript introduction - web 0x00
LiveOverflow
The HTTP Protocol: GET /test.html - web 0x01
LiveOverflow
Building Poor Man's Logic Analyzer with an Arduino - Reverse Engineering A/C Remote part 1
LiveOverflow
What is PHP and why is XSS so common there? - web 0x02
LiveOverflow
Introducing the AngularJS Javascript Framework - XSS with AngularJS 0x00
LiveOverflow
Sandbox Bypass in Version 1.0.8 - XSS with AngularJS 0x1
LiveOverflow
Capturing & Analyzing Packets with Saleae Logic Pro 8 - Reverse Engineering A/C Remote part 2
LiveOverflow
XSS Contexts and some Chrome XSS Auditor tricks - web 0x03
LiveOverflow
Previous Bypass is now fixed in version 1.4.7 - XSS with AngularJS 0x2
LiveOverflow
New Sandbox Bypass in 1.4.7 - XSS with AngularJS 0x3
LiveOverflow
The Heap: what does malloc() do? - bin 0x14
LiveOverflow
The Heap: How to exploit a Heap Overflow - bin 0x15
LiveOverflow
Reverse Engineering with Binary Ninja and gdb a key checking algorithm - TUMCTF 2016 Zwiebel part 1
LiveOverflow
Scripting radare2 with python for dynamic analysis - TUMCTF 2016 Zwiebel part 2
LiveOverflow
Live Hacking - Internetwache CTF 2016 - exp50, exp70, exp80
LiveOverflow
Sandbox bypass for the latest AngularJS version 1.5.8 - XSS with AngularJS 0x4
LiveOverflow
Channel is growing and Riscure hardware CTF starting soon - loopback 0x01
LiveOverflow
Explaining Dirty COW local root exploit - CVE-2016-5195
LiveOverflow
What is CTF? An introduction to security Capture The Flag competitions
LiveOverflow
The Heap: How do use-after-free exploits work? - bin 0x16
LiveOverflow
The Browser is a very Confused Deputy - web 0x05
LiveOverflow
The Heap: Once upon a free() - bin 0x17
LiveOverflow
Simple reversing challenge and gaming the system - BruCON CTF part 1
LiveOverflow
int0x80 from DualCore lent me his lockpicking set and I'm a horse - BruCON CTF part 2
LiveOverflow
The Heap: dlmalloc unlink() exploit - bin 0x18
LiveOverflow
MD5 Length Extension and Blind SQL Injection - BruCON CTF part 3
LiveOverflow
TCP Protocol introduction - bin 0x1A
LiveOverflow
Socket programming in python and Integer Overflow - bin 0x1B
LiveOverflow
Linux signals and core dumps - bin 0x1C
LiveOverflow
[Live] Remote oldschool dlmalloc Heap exploit - bin 0x1F
LiveOverflow
Riscure Embedded Hardware CTF setup and introduction - rhme2 Soldering
LiveOverflow
Rooting a CTF server to get all the flags with Dirty COW - CVE-2016-5195
LiveOverflow
How to learn hacking? ft. Rubber Ducky
LiveOverflow
Format String to dump binary and gain RCE - 33c3ctf ESPR (pwn 150)
LiveOverflow
Related Reads
📰
📰
📰
📰
ClickFix: When Phishing Stops Being About Clicking
Medium · Cybersecurity
Securing Your Network with Subnetting and IP Planning: Why Good Network Design Is Your First Line…
Medium · Cybersecurity
Your Payment App Is About to Become Your ID — and Scammers Already Know It
Dev.to · CaraComp
HACKING JULY DAY 15: VULN-BANK EXPLOITATION #2
Medium · Cybersecurity
🎓
Tutor Explanation
DeepCamp AI