When you deserialize JSON with JavaScriptSerializer into an object property or field, the serializer will recursively choose the most appropriate representation to which to deserialize each JSON element therein:
This allows completely generic JSON data to be deserialized and used.
Some extension methods that are helpful in working with untyped deserialized JSON from JavaScriptSerializer include:
public static class JavaScriptSerializerObjectExtensions
{
    public static object JsonElementAt(this object obj, int index)
    {
        if (index < 0)
            throw new ArgumentException();
        var array = obj as object[];
        if (array == null || index >= array.Length)
            return null;
        return array[index];
    }
    public static object JsonPropertyAt(this object obj, string name)
    {
        var dict = obj as IDictionary<string, object>;
        if (dict == null)
            return null;
        object value;
        if (!dict.TryGetValue(name, out value))
            return null;
        return value;
    }
    public static bool IsJsonArray(this object obj)
    {
        return obj is object[];
    }
    public static object [] AsJsonArray(this object obj)
    {
        return obj as object[];
    }
    public static bool IsJsonObject(this object obj)
    {
        return obj is IDictionary<string, object>;
    }
    public static IDictionary<string, object> AsJsonObject(this object obj)
    {
        return obj as IDictionary<string, object>;
    }
    public static bool IsJsonNumber(this object obj)
    {
        if (obj == null)
            return false;
        switch (Type.GetTypeCode(obj.GetType()))
        {
            case TypeCode.Int32:
            case TypeCode.Int64:
            case TypeCode.Decimal:
            case TypeCode.Double:
                return true;
            case TypeCode.Byte:
            case TypeCode.SByte:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
            case TypeCode.Int16:
            case TypeCode.Single:
                Debug.WriteLine("Unexpected integer type " + Type.GetTypeCode(obj.GetType()));
                return true;
            default:
                return false;
        }
    }
    public static bool IsJsonBoolean(this object obj)
    {
        return obj is bool;
    }
    public static bool IsJsonString(this object obj)
    {
        return obj is string;
    }
    public static bool IsDateTime(this object obj)
    {
        return obj is DateTime;
    }
    [Conditional("DEBUG")]
    public static void DebugWriteJson(this object obj)
    {
        var sb = obj.DumpJson();
        Debug.WriteLine(sb);
    }
    public static string DumpJson(this object obj)
    {
        var sb = obj.DumpJson(new StringBuilder(), 0, false, string.Empty);
        return sb.ToString();
    }
    static StringBuilder DumpJson(this object obj, StringBuilder sb, int level, bool isPropertyValue, string postfix)
    {
        if (obj == null)
            return sb;
        string prefix = new string(' ', 2 * level);
        if (obj is IList<object>)
        {
            var array = (IList<object>)obj;
            if (isPropertyValue)
                sb.AppendLine();
            sb.AppendLine(prefix + "[");
            for (int i = 0; i < array.Count; i++)
            {
                array[i].DumpJson(sb, level + 1, false, (i == array.Count - 1 ? string.Empty : ","));
            }
            sb.AppendLine(prefix + "]" + postfix);
        }
        else if (obj is IDictionary<string, object>)
        {
            if (isPropertyValue)
                sb.AppendLine();
            sb.AppendLine(prefix + "{");
            var dict = ((IDictionary<string, object>)obj).ToList();
            for (int i = 0; i < dict.Count; i++)
            {
                sb.AppendFormat("{0}  \"{1}\" : ", prefix, dict[i].Key);
                dict[i].Value.DumpJson(sb, level + 2, true, (i == dict.Count - 1 ? string.Empty : ","));
            }
            sb.AppendLine(prefix + "}" + postfix);
        }
        else if (obj.IsJsonString())
        {
            string initialPrefix = (isPropertyValue ? "" : prefix);
            sb.AppendLine(initialPrefix + '"' + obj.ToString() + '"' + postfix);
        }
        else
        {
            string initialPrefix = (isPropertyValue ? "" : prefix);
            sb.AppendLine(initialPrefix + obj.ToString().ToLower() + postfix);
        }
        return sb;
    }
Then you could do something like:
class RetData
{
    public int status { get; set; }
    public string msg { get; set; }
    public object data { get; set; }
}
        var retData = (new JavaScriptSerializer()).Deserialize<RetData>(jsonStr);
        if (retData.data.IsJsonArray())
            foreach (var obj in retData.data.AsJsonArray())
                if (obj.JsonPropertyAt("username") != null)
                    Console.WriteLine(obj.JsonPropertyAt("password"));
Or, if it looks more familiar:
        if (retData.data.IsJsonArray())
            foreach (var obj in retData.data.AsJsonArray())
                if (obj.IsJsonObject())
                {
                    var map = obj.AsJsonObject();
                    if (map.ContainsKey("username") && map.ContainsKey("password"))
                        Console.WriteLine(map["password"]);
                }
Honestly, however, this is close to re-inventing Linq-to-Json so you might want to investigate switching to Json.NET.