Post

hackmyvm Otte靶机复盘

难度-Hard

hackmyvm Otte靶机复盘

网段扫描

1
2
3
4
5
6
7
8
9
10
root@LingMj:~/tools# arp-scan -l
Interface: eth0, type: EN10MB, MAC: 00:0c:29:d1:27:55, IPv4: 192.168.137.190
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.137.1	3e:21:9c:12:bd:a3	(Unknown: locally administered)
192.168.137.64	a0:78:17:62:e5:0a	Apple, Inc.
192.168.137.96	3e:21:9c:12:bd:a3	(Unknown: locally administered)
192.168.137.114	62:2f:e8:e4:77:5d	(Unknown: locally administered)

9 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.063 seconds (124.09 hosts/sec). 4 responded

端口扫描

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
root@LingMj:~/tools# nmap -p- -sV -sC 192.168.137.96 
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-19 07:15 EDT
Nmap scan report for otte.mshome.net (192.168.137.96)
Host is up (0.019s latency).
Not shown: 65532 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
21/tcp open  ftp     ProFTPD
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r--   1 ftp      ftp            89 May 15  2021 note.txt
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 e8:38:58:1b:75:c5:53:47:32:10:d4:12:79:69:c8:ad (RSA)
|   256 35:92:34:4e:cd:65:c6:08:20:76:35:ba:d9:09:64:65 (ECDSA)
|_  256 a2:87:9f:60:a4:0d:c5:43:6a:4f:02:79:56:ff:6e:d9 (ED25519)
80/tcp open  http    Apache httpd 2.4.38
|_http-server-header: Apache/2.4.38 (Debian)
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Basic realm=Siemens - Root authentification
|_http-title: 401 Unauthorized
MAC Address: 3E:21:9C:12:BD:A3 (Unknown)
Service Info: Host: 127.0.0.1; OS: 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 31.62 seconds

获取webshell

picture 0
picture 1
picture 2
picture 3

用户名知道:thomas

picture 4
picture 5

感觉爆破ftp如果爆破ssh那不应该这个提示

picture 6

没有

picture 7

admin也不是,等着ftp爆破

picture 8
picture 9

看了wp奥我跑了ftp啥🪶没有所以我打算看看入口咋进行,这里有个很狗的东西我们还显示不了,一个登录提示奥,elinks

picture 10

正常是这个样子的,siemens

picture 11
picture 12

有点难找,目前没找到,随便找到的网站:https://www.192-168-1-1-ip.co/router/siemens/s7-1200-s7-1500/17618/

如果不是的话那就没招了,去wp扒了

picture 13

找到了

picture 14
picture 15

看一下咋写这个认证

picture 16
picture 17
picture 18
picture 19 picture 21

picture 20
picture 22

还有其他php

picture 23
picture 24
picture 25
picture 26
picture 27

php有啥呢,用fuzz跑一下

picture 28
picture 29
picture 30

什么东西一个have fun!,是密码么

picture 31

不是

picture 32
picture 33

file也不对,又卡主了不知道怎么操作

picture 34
picture 35

方向包错的换一个方式吧

picture 36

看完了没收获

picture 37

还不能看自己只剩一个

picture 38

也没有

picture 39
picture 40

开始爆破了,这shell.php一点用也没有,就一个have fun而且还不是密码

picture 41

离谱的是非得跑完这个字典真6

picture 42

还不是这个用户

提权

picture 43
picture 44

这个密码是之前那个的

picture 45

没有密码复用问题

picture 46

有信息但是不多

picture 47

真翻译真脏,哈哈哈哈

picture 48

看出来了全是xxxxx但是感觉是图片啊什么的,或者压缩包,所以我们修改一下如果是手动修改的话确实骂一下,哈哈哈哈

爆破的话是4*4**26吧还是很多感觉误解,但是前面之前不是有jpg么拿那个头应该就可以了,这是我的推测奥

picture 49
picture 50

gtp直接给我驳回了

picture 51

c的文件我随便找的

picture 52

问题是咋转回来

picture 53
picture 54
picture 55
picture 56
picture 57
picture 58

多此一举的感觉直接扫码给密码得了还非得开个网站:thomas:youareonthegoodwaybro

picture 59

私钥复用前2天学的

picture 60

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
#!/usr/bin/env python3
from datetime import datetime
import sys
import os
from os import listdir
import re

def show_help():
    message='''
********************************************************
* Simpler   -   A simple simplifier ;)                 *
* Version 1.0                                          *
********************************************************
Usage:  python3 simpler.py [options]

Options:
    -h/--help   : This help
    -s          : Statistics
    -l          : List the attackers IP
    -p          : ping an attacker IP
    '''
    print(message)

def show_header():
    print('''***********************************************
     _                 _
 ___(_)_ __ ___  _ __ | | ___ _ __ _ __  _   _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | |  __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
                |_|               |_|    |___/
                                @ironhackers.es

***********************************************
''')

def show_statistics():
    path = '/home/pepper/Web/Logs/'
    print('Statistics\n-----------')
    listed_files = listdir(path)
    count = len(listed_files)
    print('Number of Attackers: ' + str(count))
    level_1 = 0
    dat = datetime(1, 1, 1)
    ip_list = []
    reks = []
    ip = ''
    req = ''
    rek = ''
    for i in listed_files:
        f = open(path + i, 'r')
        lines = f.readlines()
        level2, rek = get_max_level(lines)
        fecha, requ = date_to_num(lines)
        ip = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
        if fecha > dat:
            dat = fecha
            req = requ
            ip2 = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
        if int(level2) > int(level_1):
            level_1 = level2
            ip_list = [ip]
            reks=[rek]
        elif int(level2) == int(level_1):
            ip_list.append(ip)
            reks.append(rek)
        f.close()

    print('Most Risky:')
    if len(ip_list) > 1:
        print('More than 1 ip found')
    cont = 0
    for i in ip_list:
        print('    ' + i + ' - Attack Level : ' + level_1 + ' Request: ' + reks[cont])
        cont = cont + 1

    print('Most Recent: ' + ip2 + ' --> ' + str(dat) + ' ' + req)

def list_ip():
    print('Attackers\n-----------')
    path = '/home/pepper/Web/Logs/'
    listed_files = listdir(path)
    for i in listed_files:
        f = open(path + i,'r')
        lines = f.readlines()
        level,req = get_max_level(lines)
        print(i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3] + ' - Attack Level : ' + level)
        f.close()

def date_to_num(lines):
    dat = datetime(1,1,1)
    ip = ''
    req=''
    for i in lines:
        if 'Level' in i:
            fecha=(i.split(' ')[6] + ' ' + i.split(' ')[7]).split('\n')[0]
            regex = '(\d+)-(.*)-(\d+)(.*)'
            logEx=re.match(regex, fecha).groups()
            mes = to_dict(logEx[1])
            fecha = logEx[0] + '-' + mes + '-' + logEx[2] + ' ' + logEx[3]
            fecha = datetime.strptime(fecha, '%Y-%m-%d %H:%M:%S')
            if fecha > dat:
                dat = fecha
                req = i.split(' ')[8] + ' ' + i.split(' ')[9] + ' ' + i.split(' ')[10]
    return dat, req

def to_dict(name):
    month_dict = {'Jan':'01','Feb':'02','Mar':'03','Apr':'04', 'May':'05', 'Jun':'06','Jul':'07','Aug':'08','Sep':'09','Oct':'10','Nov':'11','Dec':'12'}
    return month_dict[name]

def get_max_level(lines):
    level=0
    for j in lines:
        if 'Level' in j:
            if int(j.split(' ')[4]) > int(level):
                level = j.split(' ')[4]
                req=j.split(' ')[8] + ' ' + j.split(' ')[9] + ' ' + j.split(' ')[10]
    return level, req

def exec_ping():
    forbidden = ['&', ';', '-', '`', '||', '|']
    command = input('Enter an IP: ')
    for i in forbidden:
        if i in command:
            print('Got you')
            exit()
    os.system('ping ' + command)

if __name__ == '__main__':
    show_header()
    if len(sys.argv) != 2:
        show_help()
        exit()
    if sys.argv[1] == '-h' or sys.argv[1] == '--help':
        show_help()
        exit()
    elif sys.argv[1] == '-s':
        show_statistics()
        exit()
    elif sys.argv[1] == '-l':
        list_ip()
        exit()
    elif sys.argv[1] == '-p':
        exec_ping()
        exit()
    else:
        show_help()
        exit()

picture 61

那很简单了

picture 62

有空格问题直接${IFS}

picture 63

有思路了可以执行一个命令我不绕直接写一个就好了

picture 64

这两天这些知识点都碰到过了,哈哈哈

picture 65

非终端的话改一下改成创建私钥得了

picture 66
picture 67

有点问题,那么我直接写入文件应该可以

picture 68
picture 69
picture 70
picture 71
picture 72

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
w3m version w3m/0.5.3+git20190105, options lang=en,m17n,image,color,ansi-color,mouse,gpm,menu,cookie,ssl,ssl-verify,external-uri-loader,w3mmailer,nntp,gopher,ipv6,alarm,mark,migemo
usage: w3m [options] [URL or filename]
options:
    -t tab           set tab width
    -r               ignore backspace effect
    -l line          # of preserved line (default 10000)
    -I charset       document charset
    -O charset       display/output charset
    -B               load bookmark
    -bookmark file   specify bookmark file
    -T type          specify content-type
    -m               internet message mode
    -v               visual startup mode
    -M               monochrome display
    -N               open URL of command line on each new tab
    -F               automatically render frames
    -cols width      specify column width (used with -dump)
    -ppc count       specify the number of pixels per character (4.0...32.0)
    -ppl count       specify the number of pixels per line (4.0...64.0)
    -dump            dump formatted page into stdout
    -dump_head       dump response of HEAD request into stdout
    -dump_source     dump page source into stdout
    -dump_both       dump HEAD and source into stdout
    -dump_extra      dump HEAD, source, and extra information into stdout
    -post file       use POST method with file content
    -header string   insert string as a header
    +<num>           goto <num> line
    -num             show line number
    -no-proxy        don't use proxy
    -4               IPv4 only (-o dns_order=4)
    -6               IPv6 only (-o dns_order=6)
    -no-mouse        don't use mouse
    -cookie          use cookie (-no-cookie: don't use cookie)
    -graph           use DEC special graphics for border of table and menu
    -no-graph        use ASCII character for border of table and menu
    -s               squeeze multiple blank lines
    -W               toggle search wrap mode
    -X               don't use termcap init/deinit
    -title[=TERM]    set buffer name to terminal title string
    -o opt=value     assign value to config option
    -show-option     print all config options
    -config file     specify config file
    -help            print this usage message
    -version         print w3m version
    -reqlog          write request logfile
    -debug           DO NOT USE

picture 73

用-v

picture 75

picture 74

picture 76

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
#!/usr/bin/env python

import sys
import time
import subprocess
import datetime
import re


digits_re = re.compile("([0-9eE.+]*)")
to = 2.0
CLS='\033[2J\033[;H'
digit_chars = set('0123456789.')


def isfloat(v):
    try:
        float(v)
    except ValueError:
        return False
    return True

def total_seconds(td):
    return (td.microseconds + (td.seconds + td.days * 24. * 3600) * 10**6) / 10**6

def main(cmd):
    prevp = []
    prevt = None

    while True:
        t0 = datetime.datetime.now()
        out = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]

        p = digits_re.split(out.decode())

        if len(prevp) != len(p):
            s = p
        else:
            s = []
            i = 0
            for i, (n, o) in enumerate(zip(p, prevp)):
                if isfloat(n) and isfloat(o) and float(n) > float(o):
                    td = t0 - prevt
                    v = (float(n) - float(o)) / total_seconds(td)
                    if v > 1000000000:
                        v, suffix = v / 1000000000., 'g'
                    elif v > 1000000:
                        v, suffix = v / 1000000., 'm'
                    elif v > 1000:
                        v, suffix = v / 1000.,'k'
                    else:
                        suffix = ''
                    s.append('\x1b[7m')
                    s.append('%*s' % (len(n), '%.1f%s/s' % (v, suffix)))
                    s.append('\x1b[0m')
                else:
                    s.append(n)
            s += n[i:]

        prefix = "%sEvery %.1fs: %s\t\t%s" % (CLS, to, ' '.join(cmd), t0)
        sys.stdout.write(prefix + '\n\n' + ''.join(s).rstrip() + '\n')
        sys.stdout.flush()

        prevt = t0
        prevp = p
        time.sleep(to)

if __name__ == '__main__':
    try:
        main(sys.argv[1:])
    except KeyboardInterrupt:
        print('Interrupted')
        sys.exit(0)
    except SystemExit:
        os._exit(0)

picture 78

picture 77

那很简单了

picture 79
picture 80

结束

userflag:e1e4e2e00a00df7b40c5436155ab4996

rootflag:84decf19261819687b63c8210cd28f7c

This post is licensed under CC BY 4.0 by the author.