Ret2win - arm64
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Find an introduction to arm64 in:
Introduction to ARM64v8Code
Compile without pie and canary:
Finding the offset
Pattern option
This example was created using GEF:
Stat gdb with gef, create pattern and use it:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252F547KJNbEtV2bQdcJeuxg%252Fimage.png%3Falt%3Dmedia%26token%3D99679c9b-3b82-411a-a8c4-928259bd905a&width=768&dpr=4&quality=100&sign=2f298f98&sv=1)
arm64 will try to return to the address in the register x30 (which was compromised), we can use that to find the pattern offset:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252F7fKN3zauOWoHkylaXjiC%252Fimage.png%3Falt%3Dmedia%26token%3D93655cc5-f662-4ef6-bcd3-4c19b600470f&width=768&dpr=4&quality=100&sign=17c21832&sv=1)
The offset is 72 (9x48).
Stack offset option
Start by getting the stack address where the pc register is stored:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252Fj5ASEtOUghsO0FYobCpO%252Fimage.png%3Falt%3Dmedia%26token%3D70932b67-af81-4728-b46e-6fc0b4744930&width=768&dpr=4&quality=100&sign=1e585134&sv=1)
Now set a breakpoint after the read()
and continue until the read()
is executed and set a pattern such as 13371337:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252F9P2kOgt9OV36dyaZzV2Q%252Fimage.png%3Falt%3Dmedia%26token%3Dc3e7c1a8-d502-433c-97c5-23e5cad83480&width=768&dpr=4&quality=100&sign=19a87564&sv=1)
Find where this pattern is stored in memory:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252F1Ubr39GF2yJjrxvbpFxj%252Fimage.png%3Falt%3Dmedia%26token%3D3e50111e-7200-4eb1-9ca2-25b91c6d3815&width=768&dpr=4&quality=100&sign=78bd9a93&sv=1)
Then: 0xfffffffff148 - 0xfffffffff100 = 0x48 = 72
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252FUM3AmHV9lUgefHh96zgY%252Fimage.png%3Falt%3Dmedia%26token%3D51c4ed24-26c5-4327-a8a7-19f9cc0b3bf5&width=768&dpr=4&quality=100&sign=367edb85&sv=1)
No PIE
Regular
Get the address of the win
function:
Exploit:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252FPXi4Cv7WFis9wMg3Bbwb%252Fimage.png%3Falt%3Dmedia%26token%3D89ee0bbb-7668-4d8d-afa4-da9ffee72454&width=768&dpr=4&quality=100&sign=c8bca9cf&sv=1)
Off-by-1
Actually this is going to by more like a off-by-2 in the stored PC in the stack. Instead of overwriting all the return address we are going to overwrite only the last 2 bytes with 0x06c4
.
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252FlwMkrL9Arn7jiZiefXCc%252Fimage.png%3Falt%3Dmedia%26token%3Dc0fc08c4-1de7-428b-9976-7df0161c1bbd&width=768&dpr=4&quality=100&sign=befee16&sv=1)
You can find another off-by-one example in ARM64 in https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/, which is a real off-by-one in a fictitious vulnerability.
With PIE
Compile the binary without the -no-pie
argument
Off-by-2
Without a leak we don't know the exact address of the winning function but we can know the offset of the function from the binary and knowing that the return address we are overwriting is already pointing to a close address, it's possible to leak the offset to the win function (0x7d4) in this case and just use that offset:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252F6O4FJoCvDlch5cHvKZjS%252Fimage.png%3Falt%3Dmedia%26token%3De44caf7e-599d-4969-8c03-631210b83ca9&width=768&dpr=4&quality=100&sign=76b8996c&sv=1)
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Last updated